blob: 230fe6f0ff55cc7ce820dd405ee6bf088038f861 [file] [log] [blame]
// 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.tasks.tab_management;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.support.v7.content.res.AppCompatResources;
import androidx.annotation.ColorInt;
import org.chromium.base.Callback;
import org.chromium.chrome.browser.favicon.FaviconHelper;
import org.chromium.chrome.browser.favicon.FaviconUtils;
import org.chromium.chrome.browser.native_page.NativePageFactory;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.tab_ui.R;
/**
* Provider for processed favicons in Tab list.
*/
public class TabListFaviconProvider {
private static Drawable sRoundedGlobeDrawable;
private static Drawable sRoundedChromeDrawable;
private final int mFaviconSize;
private final Profile mProfile;
private final FaviconHelper mFaviconHelper;
private final Context mContext;
@ColorInt
private final int mDefaultIconColor;
@ColorInt
private final int mIncognitoIconColor;
/**
* Construct the provider that provides favicons for tab list.
* @param context The context to use for accessing {@link android.content.res.Resources}
* @param profile The profile to use for getting favicons.
*/
public TabListFaviconProvider(Context context, Profile profile) {
mContext = context;
mFaviconSize = context.getResources().getDimensionPixelSize(R.dimen.default_favicon_size);
mProfile = profile;
mFaviconHelper = new FaviconHelper();
if (sRoundedGlobeDrawable == null) {
Drawable globeDrawable =
AppCompatResources.getDrawable(context, R.drawable.ic_globe_24dp);
Bitmap globeBitmap =
Bitmap.createBitmap(mFaviconSize, mFaviconSize, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(globeBitmap);
globeDrawable.setBounds(0, 0, mFaviconSize, mFaviconSize);
globeDrawable.draw(canvas);
sRoundedGlobeDrawable = processBitmap(globeBitmap);
}
if (sRoundedChromeDrawable == null) {
Bitmap chromeBitmap =
BitmapFactory.decodeResource(context.getResources(), R.drawable.chromelogo16);
sRoundedChromeDrawable = processBitmap(chromeBitmap);
}
mDefaultIconColor = mContext.getResources().getColor(R.color.default_icon_color);
mIncognitoIconColor = mContext.getResources().getColor(R.color.default_icon_color_white);
}
private Drawable processBitmap(Bitmap bitmap) {
return FaviconUtils.createRoundedBitmapDrawable(
Bitmap.createScaledBitmap(bitmap, mFaviconSize, mFaviconSize, true));
}
/**
* @return The scaled rounded Globe Drawable as default favicon.
* @param isIncognito Whether the {@link Drawable} is used for incognito mode.
*/
public Drawable getDefaultFaviconDrawable(boolean isIncognito) {
return getRoundedGlobeDrawable(isIncognito);
}
/**
* Asynchronously get the processed favicon Drawable.
* @param url The URL whose favicon is requested.
* @param isIncognito Whether the tab is incognito or not.
* @param faviconCallback The callback that requests for favicon.
*/
public void getFaviconForUrlAsync(
String url, boolean isIncognito, Callback<Drawable> faviconCallback) {
if (NativePageFactory.isNativePageUrl(url, isIncognito)) {
faviconCallback.onResult(getRoundedChromeDrawable(isIncognito));
} else {
mFaviconHelper.getLocalFaviconImageForURL(
mProfile, url, mFaviconSize, (image, iconUrl) -> {
if (image == null) {
faviconCallback.onResult(getRoundedGlobeDrawable(isIncognito));
} else {
faviconCallback.onResult(processBitmap(image));
}
});
}
}
/**
* Synchronously get the processed favicon Drawable.
* @param url The URL whose favicon is requested.
* @param isIncognito Whether the tab is incognito or not.
* @param icon The favicon that was received.
* @return The processed favicon.
*/
public Drawable getFaviconForUrlSync(String url, boolean isIncognito, Bitmap icon) {
if (icon == null) {
boolean isNativeUrl = NativePageFactory.isNativePageUrl(url, isIncognito);
return isNativeUrl ? getRoundedChromeDrawable(isIncognito)
: getRoundedGlobeDrawable(isIncognito);
} else {
return processBitmap(icon);
}
}
private Drawable getRoundedChromeDrawable(boolean isIncognito) {
@ColorInt
int color = isIncognito ? mIncognitoIconColor : mDefaultIconColor;
// Since static variable is still loaded when activity is destroyed due to configuration
// changes, e.g. light/dark theme changes, setColorFilter is needed when we retrieve the
// drawable. setColorFilter would be a no-op if color and the mode are the same.
sRoundedChromeDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
return sRoundedChromeDrawable;
}
private Drawable getRoundedGlobeDrawable(boolean isIncognito) {
@ColorInt
int color = isIncognito ? mIncognitoIconColor : mDefaultIconColor;
// Since static variable is still loaded when activity is destroyed due to configuration
// changes, e.g. light/dark theme changes, setColorFilter is needed when we retrieve the
// drawable. setColorFilter would be a no-op if color and the mode are the same.
sRoundedGlobeDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
return sRoundedGlobeDrawable;
}
}