Commit e1735d5c authored by Jinsuk Kim's avatar Jinsuk Kim Committed by Commit Bot

Android: Factor out favicon-related stuff out of Tab

TabFavicon is Tab userdata that provides API for the active
web contents' favicon. This was a part of Tab class but
factored out into its own class.

Bug: 877878, 925242
Change-Id: I49eba08918a2a86985f2b8aea5d4c7e15d666108
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1482434
Commit-Queue: Jinsuk Kim <jinsukkim@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Reviewed-by: default avatarTheresa <twellington@chromium.org>
Cr-Commit-Position: refs/heads/master@{#637993}
parent 5bb996fe
......@@ -2346,6 +2346,7 @@ generate_jni("jni_headers") {
"java/src/org/chromium/chrome/browser/suggestions/SuggestionsEventReporterBridge.java",
"java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java",
"java/src/org/chromium/chrome/browser/tab/Tab.java",
"java/src/org/chromium/chrome/browser/tab/TabFavicon.java",
"java/src/org/chromium/chrome/browser/tab/TabState.java",
"java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java",
"java/src/org/chromium/chrome/browser/tabmodel/SingleTabModel.java",
......
......@@ -20,6 +20,7 @@ import org.chromium.chrome.browser.favicon.FaviconHelper.DefaultFaviconHelper;
import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabFavicon;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.ui.base.DeviceFormFactor;
import org.chromium.ui.resources.ResourceManager;
......@@ -125,7 +126,7 @@ public class LayerTitleCache implements TitleCache {
boolean isHTSEnabled = !DeviceFormFactor.isNonMultiDisplayContextOnTablet(tab.getActivity())
&& ChromeFeatureList.isEnabled(ChromeFeatureList.HORIZONTAL_TAB_SWITCHER_ANDROID);
boolean isDarkTheme = tab.isIncognito() && !isHTSEnabled;
Bitmap originalFavicon = tab.getFavicon();
Bitmap originalFavicon = TabFavicon.getBitmap(tab);
if (originalFavicon == null) {
originalFavicon = mDefaultFaviconHelper.getDefaultFaviconBitmap(
mContext, tab.getUrl(), !isDarkTheme);
......
......@@ -9,8 +9,6 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Rect;
import android.net.Uri;
......@@ -185,17 +183,6 @@ public class Tab
private boolean mIsClosing;
private boolean mIsShowingErrorPage;
private Bitmap mFavicon;
private int mFaviconWidth;
private int mFaviconHeight;
private String mFaviconUrl;
/**
* The size in pixels at which favicons will be drawn. Ideally mFavicon will have this size to
* avoid scaling artifacts.
*/
private int mIdealFaviconSize;
/** Whether or not the TabState has changed. */
private boolean mIsTabStateDirty = true;
......@@ -396,9 +383,6 @@ public class Tab
mLaunchType = type;
mLaunchTypeAtCreation = type;
Resources resources = mThemedApplicationContext.getResources();
mIdealFaviconSize = resources.getDimensionPixelSize(R.dimen.default_favicon_size);
TabThemeColorHelper.createForTab(this);
// Restore data from the TabState, if it existed.
......@@ -1421,6 +1405,7 @@ public class Tab
updateInteractableState();
mWebContentsDelegate = mDelegateFactory.createWebContentsDelegate(this);
TabWebContentsObserver.from(this);
TabFavicon.from(this);
int parentId = getParentId();
if (parentId != INVALID_TAB_ID) {
......@@ -1663,22 +1648,6 @@ public class Tab
return mIsTitleDirectionRtl;
}
/**
* @return The bitmap of the favicon scaled to 16x16dp. null if no favicon
* is specified or it requires the default favicon.
*/
public Bitmap getFavicon() {
// If we have no content or a native page, return null.
if (isNativePage() || getWebContents() == null) return null;
// Use the cached favicon only if the page wasn't changed.
if (mFavicon != null && mFaviconUrl != null && mFaviconUrl.equals(getUrl())) {
return mFavicon;
}
return nativeGetFavicon(mNativeTabAndroid);
}
/**
* Loads the tab if it's not loaded (e.g. because it was killed in background).
* This will trigger a regular load for tabs with pending lazy first load (tabs opened in
......@@ -1904,49 +1873,6 @@ public class Tab
return mWebContentsDelegate;
}
private boolean isIdealFaviconSize(int width, int height) {
return width == mIdealFaviconSize && height == mIdealFaviconSize;
}
/**
* @param width new favicon's width.
* @param height new favicon's height.
* @return true iff the new favicon should replace the current one.
*/
private boolean isBetterFavicon(int width, int height) {
if (isIdealFaviconSize(width, height)) return true;
// Prefer square favicons over rectangular ones
if (mFaviconWidth != mFaviconHeight && width == height) return true;
if (mFaviconWidth == mFaviconHeight && width != height) return false;
// Do not update favicon if it's already at least as big as the ideal size in both dimens
if (mFaviconWidth >= mIdealFaviconSize && mFaviconHeight >= mIdealFaviconSize) return false;
// Update favicon if the new one is larger in one dimen, but not smaller in the other
return (width > mFaviconWidth && !(height < mFaviconHeight))
|| (!(width < mFaviconWidth) && height > mFaviconHeight);
}
@CalledByNative
protected void onFaviconAvailable(Bitmap icon) {
if (icon == null) return;
String url = getUrl();
boolean pageUrlChanged = !url.equals(mFaviconUrl);
// This method will be called multiple times if the page has more than one favicon.
// We are trying to use the |mIdealFaviconSize|x|mIdealFaviconSize| DP icon here, or the
// first one larger than that received. Bitmap.createScaledBitmap will return the original
// bitmap if it is already |mIdealFaviconSize|x|mIdealFaviconSize| DP.
if (pageUrlChanged || isBetterFavicon(icon.getWidth(), icon.getHeight())) {
mFavicon = Bitmap.createScaledBitmap(icon, mIdealFaviconSize, mIdealFaviconSize, true);
mFaviconWidth = icon.getWidth();
mFaviconHeight = icon.getHeight();
mFaviconUrl = url;
}
for (TabObserver observer : mObservers) observer.onFaviconUpdated(this, icon);
}
/**
* Checks if this tab is currently presented in the context of custom tabs. Tabs can be moved
* between different activities so the returned value might change over the lifetime of the tab.
......@@ -2626,7 +2552,6 @@ public class Tab
long intentReceivedTimestamp);
private native void nativeSetActiveNavigationEntryTitleForUrl(long nativeTabAndroid, String url,
String title);
private native Bitmap nativeGetFavicon(long nativeTabAndroid);
private native void nativeCreateHistoricalTab(long nativeTabAndroid);
private native void nativeUpdateBrowserControlsState(
long nativeTabAndroid, int constraints, int current, boolean animate);
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.tab;
import android.content.res.Resources;
import android.graphics.Bitmap;
import org.chromium.base.ObserverList.RewindableIterator;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.chrome.R;
import org.chromium.content_public.browser.WebContents;
/**
* Fetches a favicon for active WebContents in a Tab.
*/
public class TabFavicon extends TabWebContentsUserData {
private static final Class<TabFavicon> USER_DATA_KEY = TabFavicon.class;
private final Tab mTab;
private final long mNativeTabFavicon;
/**
* The size in pixels at which favicons will be drawn. Ideally mFavicon will have this size to
* avoid scaling artifacts.
*/
private final int mIdealFaviconSize;
private Bitmap mFavicon;
private int mFaviconWidth;
private int mFaviconHeight;
private String mFaviconUrl;
static TabFavicon from(Tab tab) {
TabFavicon favicon = get(tab);
if (favicon == null) {
favicon = tab.getUserDataHost().setUserData(USER_DATA_KEY, new TabFavicon(tab));
}
return favicon;
}
private static TabFavicon get(Tab tab) {
return tab.getUserDataHost().getUserData(USER_DATA_KEY);
}
/**
* @param tab Tab containing the web contents's favicon.
* @return {@link Bitmap} of the favicon.
*/
public static Bitmap getBitmap(Tab tab) {
TabFavicon tabFavicon = get(tab);
return tabFavicon != null ? tabFavicon.getFavicon() : null;
}
private TabFavicon(Tab tab) {
super(tab);
Resources resources = tab.getThemedApplicationContext().getResources();
mIdealFaviconSize = resources.getDimensionPixelSize(R.dimen.default_favicon_size);
mTab = tab;
mNativeTabFavicon = nativeInit();
}
@Override
public void initWebContents(WebContents webContents) {
nativeSetWebContents(mNativeTabFavicon, webContents);
}
@Override
public void cleanupWebContents(WebContents webContents) {
nativeResetWebContents(mNativeTabFavicon);
}
@Override
public void destroyInternal() {
nativeOnDestroyed(mNativeTabFavicon);
}
/**
* @return The bitmap of the favicon scaled to 16x16dp. null if no favicon
* is specified or it requires the default favicon.
*/
private Bitmap getFavicon() {
// If we have no content or a native page, return null.
if (mTab.isNativePage() || mTab.getWebContents() == null) return null;
// Use the cached favicon only if the page wasn't changed.
if (mFavicon != null && mFaviconUrl != null && mFaviconUrl.equals(mTab.getUrl())) {
return mFavicon;
}
return nativeGetFavicon(mNativeTabFavicon);
}
/**
* @param width new favicon's width.
* @param height new favicon's height.
* @return true iff the new favicon should replace the current one.
*/
private boolean isBetterFavicon(int width, int height) {
if (isIdealFaviconSize(width, height)) return true;
// Prefer square favicons over rectangular ones
if (mFaviconWidth != mFaviconHeight && width == height) return true;
if (mFaviconWidth == mFaviconHeight && width != height) return false;
// Do not update favicon if it's already at least as big as the ideal size in both dimens
if (mFaviconWidth >= mIdealFaviconSize && mFaviconHeight >= mIdealFaviconSize) return false;
// Update favicon if the new one is larger in one dimen, but not smaller in the other
return (width > mFaviconWidth && !(height < mFaviconHeight))
|| (!(width < mFaviconWidth) && height > mFaviconHeight);
}
private boolean isIdealFaviconSize(int width, int height) {
return width == mIdealFaviconSize && height == mIdealFaviconSize;
}
@CalledByNative
private void onFaviconAvailable(Bitmap icon) {
if (icon == null) return;
String url = mTab.getUrl();
boolean pageUrlChanged = !url.equals(mFaviconUrl);
// This method will be called multiple times if the page has more than one favicon.
// We are trying to use the |mIdealFaviconSize|x|mIdealFaviconSize| DP icon here, or the
// first one larger than that received. Bitmap.createScaledBitmap will return the original
// bitmap if it is already |mIdealFaviconSize|x|mIdealFaviconSize| DP.
if (pageUrlChanged || isBetterFavicon(icon.getWidth(), icon.getHeight())) {
mFavicon = Bitmap.createScaledBitmap(icon, mIdealFaviconSize, mIdealFaviconSize, true);
mFaviconWidth = icon.getWidth();
mFaviconHeight = icon.getHeight();
mFaviconUrl = url;
}
RewindableIterator<TabObserver> observers = mTab.getTabObservers();
while (observers.hasNext()) observers.next().onFaviconUpdated(mTab, icon);
}
private native long nativeInit();
private native void nativeOnDestroyed(long nativeTabFavicon);
private native void nativeSetWebContents(long nativeTabFavicon, WebContents webContents);
private native void nativeResetWebContents(long nativeTabFavicon);
private native Bitmap nativeGetFavicon(long nativeTabFavicon);
}
......@@ -16,6 +16,7 @@ import org.chromium.chrome.browser.favicon.FaviconHelper;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tab.EmptyTabObserver;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabFavicon;
import org.chromium.chrome.browser.tab.TabObserver;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
......@@ -202,7 +203,7 @@ class TabListMediator {
new PropertyModel.Builder(TabProperties.ALL_KEYS_TAB_GRID)
.with(TabProperties.TAB_ID, tab.getId())
.with(TabProperties.TITLE, tab.getTitle())
.with(TabProperties.FAVICON, tab.getFavicon())
.with(TabProperties.FAVICON, TabFavicon.getBitmap(tab))
.with(TabProperties.IS_SELECTED, isSelected)
.with(TabProperties.TAB_SELECTED_LISTENER, mTabSelectedListener)
.with(TabProperties.TAB_CLOSED_LISTENER, mTabClosedListener)
......
......@@ -35,6 +35,7 @@ import org.chromium.base.annotations.UsedByReflection;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.tab.EmptyTabObserver;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabFavicon;
import org.chromium.chrome.browser.tab.TabObserver;
import org.chromium.chrome.browser.util.ColorUtils;
......@@ -333,7 +334,7 @@ public class AccessibilityTabModelListItem extends FrameLayout implements OnClic
private void updateFavicon() {
if (mTab != null) {
Bitmap bitmap = mTab.getFavicon();
Bitmap bitmap = TabFavicon.getBitmap(mTab);
if (bitmap != null) {
// Don't tint favicon bitmaps.
ApiCompatibilityUtils.setImageTintList(mFaviconView, null);
......
......@@ -1527,6 +1527,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java",
"java/src/org/chromium/chrome/browser/tab/TabContextMenuPopulator.java",
"java/src/org/chromium/chrome/browser/tab/TabDelegateFactory.java",
"java/src/org/chromium/chrome/browser/tab/TabFavicon.java",
"java/src/org/chromium/chrome/browser/tab/TabFullscreenHandler.java",
"java/src/org/chromium/chrome/browser/tab/TabGestureStateListener.java",
"java/src/org/chromium/chrome/browser/tab/TabIdManager.java",
......
......@@ -20,7 +20,6 @@ import static org.chromium.chrome.browser.tasks.tab_list_ui.GridTabSwitcherMedia
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.view.View;
import org.junit.After;
......@@ -356,7 +355,6 @@ public class GridTabSwitcherMediatorUnitTest {
doReturn(id).when(tab).getId();
doReturn("").when(tab).getUrl();
doReturn(title).when(tab).getTitle();
doReturn(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)).when(tab).getFavicon();
doReturn(false).when(tab).isClosing();
return tab;
}
......
......@@ -287,7 +287,6 @@ public class TabListMediatorUnitTest {
doReturn(id).when(tab).getId();
doReturn("").when(tab).getUrl();
doReturn(title).when(tab).getTitle();
doReturn(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)).when(tab).getFavicon();
return tab;
}
}
......@@ -2506,6 +2506,8 @@ jumbo_split_static_library("browser") {
"android/subresource_filter/test_subresource_filter_publisher.cc",
"android/tab_android.cc",
"android/tab_android.h",
"android/tab_favicon.cc",
"android/tab_favicon.h",
"android/tab_printer.cc",
"android/tab_printer.h",
"android/tab_state.cc",
......
......@@ -50,7 +50,6 @@
#include "components/bookmarks/browser/bookmark_utils.h"
#include "components/bookmarks/managed/managed_bookmark_service.h"
#include "components/dom_distiller/core/url_utils.h"
#include "components/favicon/content/content_favicon_driver.h"
#include "components/navigation_interception/intercept_navigation_delegate.h"
#include "components/navigation_interception/navigation_params.h"
#include "components/sessions/content/content_live_tab.h"
......@@ -71,17 +70,11 @@
#include "jni/Tab_jni.h"
#include "net/base/escape.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "skia/ext/image_operations.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "ui/android/view_android.h"
#include "ui/android/window_android.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/window_open_disposition.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/android/java_bitmap.h"
#include "ui/gfx/favicon_size.h"
#include "ui/gfx/image/image_skia.h"
using base::android::AttachCurrentThread;
using base::android::ConvertUTF8ToJavaString;
......@@ -310,25 +303,6 @@ bool TabAndroid::HasPrerenderedUrl(GURL gurl) {
return false;
}
void TabAndroid::OnFaviconUpdated(favicon::FaviconDriver* favicon_driver,
NotificationIconType notification_icon_type,
const GURL& icon_url,
bool icon_url_changed,
const gfx::Image& image) {
if (notification_icon_type != NON_TOUCH_LARGEST &&
notification_icon_type != TOUCH_LARGEST) {
return;
}
SkBitmap favicon = image.AsImageSkia().GetRepresentation(1.0f).GetBitmap();
if (favicon.empty())
return;
JNIEnv* env = base::android::AttachCurrentThread();
Java_Tab_onFaviconAvailable(env, weak_java_tab_.get(env),
gfx::ConvertToJavaBitmap(&favicon));
}
bool TabAndroid::IsCurrentlyACustomTab() {
JNIEnv* env = base::android::AttachCurrentThread();
return Java_Tab_isCurrentlyACustomTab(env, weak_java_tab_.get(env));
......@@ -366,12 +340,6 @@ void TabAndroid::InitWebContents(
web_contents_delegate_->LoadProgressChanged(web_contents(), 0);
web_contents()->SetDelegate(web_contents_delegate_.get());
favicon::FaviconDriver* favicon_driver =
favicon::ContentFaviconDriver::FromWebContents(web_contents_.get());
if (favicon_driver)
favicon_driver->AddObserver(this);
synced_tab_delegate_->SetWebContents(web_contents(), jparent_tab_id);
// Verify that the WebContents this tab represents matches the expected
......@@ -411,12 +379,6 @@ void TabAndroid::DestroyWebContents(JNIEnv* env,
WebContentsObserver::Observe(nullptr);
favicon::FaviconDriver* favicon_driver =
favicon::ContentFaviconDriver::FromWebContents(web_contents_.get());
if (favicon_driver)
favicon_driver->RemoveObserver(this);
web_contents()->SetDelegate(nullptr);
if (delete_native) {
......@@ -583,36 +545,6 @@ void TabAndroid::SetActiveNavigationEntryTitleForUrl(
entry->SetTitle(title);
}
ScopedJavaLocalRef<jobject> TabAndroid::GetFavicon(
JNIEnv* env,
const JavaParamRef<jobject>& obj) {
ScopedJavaLocalRef<jobject> bitmap;
favicon::FaviconDriver* favicon_driver =
favicon::ContentFaviconDriver::FromWebContents(web_contents_.get());
if (!favicon_driver)
return bitmap;
// Always return the default favicon in Android.
SkBitmap favicon = favicon_driver->GetFavicon().AsBitmap();
if (!favicon.empty()) {
const float device_scale_factor =
display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
int target_size_dip = device_scale_factor * gfx::kFaviconSize;
if (favicon.width() != target_size_dip ||
favicon.height() != target_size_dip) {
favicon =
skia::ImageOperations::Resize(favicon,
skia::ImageOperations::RESIZE_BEST,
target_size_dip,
target_size_dip);
}
bitmap = gfx::ConvertToJavaBitmap(&favicon);
}
return bitmap;
}
prerender::PrerenderManager* TabAndroid::GetPrerenderManager() const {
Profile* profile = GetProfile();
if (!profile)
......
......@@ -17,7 +17,6 @@
#include "base/strings/string16.h"
#include "chrome/browser/android/tab_state.h"
#include "chrome/browser/sync/glue/synced_tab_delegate_android.h"
#include "components/favicon/core/favicon_driver_observer.h"
#include "components/infobars/core/infobar_manager.h"
#include "components/omnibox/browser/location_bar_model.h"
#include "components/sessions/core/session_id.h"
......@@ -47,8 +46,7 @@ namespace prerender {
class PrerenderManager;
}
class TabAndroid : public favicon::FaviconDriverObserver,
public content::WebContentsObserver {
class TabAndroid : public content::WebContentsObserver {
public:
// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser
......@@ -115,13 +113,6 @@ class TabAndroid : public favicon::FaviconDriverObserver,
bool HasPrerenderedUrl(GURL gurl);
// Overridden from favicon::FaviconDriverObserver:
void OnFaviconUpdated(favicon::FaviconDriver* favicon_driver,
NotificationIconType notification_icon_type,
const GURL& icon_url,
bool icon_url_changed,
const gfx::Image& image) override;
// Returns true if this tab is currently presented in the context of custom
// tabs. Tabs can be moved between different activities so the returned value
// might change over the lifetime of the tab.
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/android/tab_favicon.h"
#include "components/favicon/content/content_favicon_driver.h"
#include "content/public/browser/web_contents.h"
#include "jni/TabFavicon_jni.h"
#include "skia/ext/image_operations.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/android/java_bitmap.h"
#include "ui/gfx/favicon_size.h"
#include "ui/gfx/image/image_skia.h"
using base::android::JavaParamRef;
using base::android::ScopedJavaLocalRef;
TabFavicon::TabFavicon(JNIEnv* env, const JavaParamRef<jobject>& obj)
: jobj_(env, obj) {}
TabFavicon::~TabFavicon() = default;
void TabFavicon::SetWebContents(JNIEnv* env,
const JavaParamRef<jobject>& obj,
const JavaParamRef<jobject>& jweb_contents) {
favicon_driver_ = favicon::ContentFaviconDriver::FromWebContents(
content::WebContents::FromJavaWebContents(jweb_contents));
if (favicon_driver_)
favicon_driver_->AddObserver(this);
}
void TabFavicon::ResetWebContents(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
if (favicon_driver_) {
favicon_driver_->RemoveObserver(this);
favicon_driver_ = nullptr;
}
}
void TabFavicon::OnDestroyed(JNIEnv* env, const JavaParamRef<jobject>& obj) {
delete this;
}
ScopedJavaLocalRef<jobject> TabFavicon::GetFavicon(
JNIEnv* env,
const JavaParamRef<jobject>& obj) {
ScopedJavaLocalRef<jobject> bitmap;
if (!favicon_driver_)
return bitmap;
// Always return the default favicon in Android.
SkBitmap favicon = favicon_driver_->GetFavicon().AsBitmap();
if (!favicon.empty()) {
const float device_scale_factor =
display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
int target_size_dip = device_scale_factor * gfx::kFaviconSize;
if (favicon.width() != target_size_dip ||
favicon.height() != target_size_dip) {
favicon = skia::ImageOperations::Resize(
favicon, skia::ImageOperations::RESIZE_BEST, target_size_dip,
target_size_dip);
}
bitmap = gfx::ConvertToJavaBitmap(&favicon);
}
return bitmap;
}
void TabFavicon::OnFaviconUpdated(favicon::FaviconDriver* favicon_driver,
NotificationIconType notification_icon_type,
const GURL& icon_url,
bool icon_url_changed,
const gfx::Image& image) {
if (notification_icon_type != NON_TOUCH_LARGEST &&
notification_icon_type != TOUCH_LARGEST) {
return;
}
SkBitmap favicon = image.AsImageSkia().GetRepresentation(1.0f).GetBitmap();
if (favicon.empty())
return;
JNIEnv* env = base::android::AttachCurrentThread();
Java_TabFavicon_onFaviconAvailable(env, jobj_,
gfx::ConvertToJavaBitmap(&favicon));
}
static jlong JNI_TabFavicon_Init(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
return reinterpret_cast<intptr_t>(new TabFavicon(env, obj));
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ANDROID_TAB_FAVICON_H_
#define CHROME_BROWSER_ANDROID_TAB_FAVICON_H_
#include "base/android/scoped_java_ref.h"
#include "components/favicon/core/favicon_driver_observer.h"
namespace favicon {
class FaviconDriver;
}
// Native Favicon provider for Tab. Managed by Java layer.
class TabFavicon : public favicon::FaviconDriverObserver {
public:
TabFavicon(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
~TabFavicon() override;
void SetWebContents(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jobject>& jweb_contents);
void ResetWebContents(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
void OnDestroyed(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
base::android::ScopedJavaLocalRef<jobject> GetFavicon(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
// favicon::FaviconDriverObserver
void OnFaviconUpdated(favicon::FaviconDriver* favicon_driver,
NotificationIconType notification_icon_type,
const GURL& icon_url,
bool icon_url_changed,
const gfx::Image& image) override;
private:
base::android::ScopedJavaGlobalRef<jobject> jobj_;
favicon::FaviconDriver* favicon_driver_;
};
#endif // CHROME_BROWSER_ANDROID_TAB_FAVICON_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment