blob: 34892236e6f0d55d1ae921a52bdd3b55b68ef8dd [file] [log] [blame]
Jinsuk Kime1735d5c2019-03-06 03:42:101// Copyright 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/android/tab_favicon.h"
6
Andrew Grieve4a42c22e2019-06-24 16:14:297#include "chrome/android/chrome_jni_headers/TabFavicon_jni.h"
Jinsuk Kime1735d5c2019-03-06 03:42:108#include "components/favicon/content/content_favicon_driver.h"
9#include "content/public/browser/web_contents.h"
Jinsuk Kime1735d5c2019-03-06 03:42:1010#include "skia/ext/image_operations.h"
11#include "ui/display/display.h"
12#include "ui/display/screen.h"
13#include "ui/gfx/android/java_bitmap.h"
14#include "ui/gfx/favicon_size.h"
15#include "ui/gfx/image/image_skia.h"
16
17using base::android::JavaParamRef;
18using base::android::ScopedJavaLocalRef;
19
20TabFavicon::TabFavicon(JNIEnv* env, const JavaParamRef<jobject>& obj)
21 : jobj_(env, obj) {}
22
23TabFavicon::~TabFavicon() = default;
24
25void TabFavicon::SetWebContents(JNIEnv* env,
26 const JavaParamRef<jobject>& obj,
27 const JavaParamRef<jobject>& jweb_contents) {
28 favicon_driver_ = favicon::ContentFaviconDriver::FromWebContents(
29 content::WebContents::FromJavaWebContents(jweb_contents));
30 if (favicon_driver_)
31 favicon_driver_->AddObserver(this);
32}
33
34void TabFavicon::ResetWebContents(JNIEnv* env,
35 const JavaParamRef<jobject>& obj) {
36 if (favicon_driver_) {
37 favicon_driver_->RemoveObserver(this);
38 favicon_driver_ = nullptr;
39 }
40}
41
42void TabFavicon::OnDestroyed(JNIEnv* env, const JavaParamRef<jobject>& obj) {
43 delete this;
44}
45
46ScopedJavaLocalRef<jobject> TabFavicon::GetFavicon(
47 JNIEnv* env,
48 const JavaParamRef<jobject>& obj) {
49 ScopedJavaLocalRef<jobject> bitmap;
50
51 if (!favicon_driver_)
52 return bitmap;
53
54 // Always return the default favicon in Android.
55 SkBitmap favicon = favicon_driver_->GetFavicon().AsBitmap();
56 if (!favicon.empty()) {
57 const float device_scale_factor =
58 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
59 int target_size_dip = device_scale_factor * gfx::kFaviconSize;
60 if (favicon.width() != target_size_dip ||
61 favicon.height() != target_size_dip) {
62 favicon = skia::ImageOperations::Resize(
63 favicon, skia::ImageOperations::RESIZE_BEST, target_size_dip,
64 target_size_dip);
65 }
66
67 bitmap = gfx::ConvertToJavaBitmap(&favicon);
68 }
69 return bitmap;
70}
71
72void TabFavicon::OnFaviconUpdated(favicon::FaviconDriver* favicon_driver,
73 NotificationIconType notification_icon_type,
74 const GURL& icon_url,
75 bool icon_url_changed,
76 const gfx::Image& image) {
77 if (notification_icon_type != NON_TOUCH_LARGEST &&
78 notification_icon_type != TOUCH_LARGEST) {
79 return;
80 }
81
82 SkBitmap favicon = image.AsImageSkia().GetRepresentation(1.0f).GetBitmap();
83 if (favicon.empty())
84 return;
85
86 JNIEnv* env = base::android::AttachCurrentThread();
87 Java_TabFavicon_onFaviconAvailable(env, jobj_,
88 gfx::ConvertToJavaBitmap(&favicon));
89}
90
91static jlong JNI_TabFavicon_Init(JNIEnv* env,
92 const JavaParamRef<jobject>& obj) {
93 return reinterpret_cast<intptr_t>(new TabFavicon(env, obj));
94}