Commit 450316ff authored by Ted Choc's avatar Ted Choc Committed by Commit Bot

Use the chrome icon as the default favicon for the NTP.

BUG=834602

Change-Id: I88271052cacbf42db040e1925854d6dc02889323
Reviewed-on: https://chromium-review.googlesource.com/1199627Reviewed-by: default avatarMatthew Jones <mdjones@chromium.org>
Commit-Queue: Ted Choc <tedchoc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#589248}
parent 21d97eba
......@@ -9,5 +9,5 @@
<item android:state_pressed="true" android:color="#80FFFFFF" />
<item android:state_activated="true" android:color="#80FFFFFF" />
<item android:state_enabled="false" android:color="#33FFFFFF" />
<item android:color="#FFFFFF"/>
<item android:color="@color/default_icon_color_white"/>
</selector>
......@@ -6,7 +6,6 @@ package org.chromium.chrome.browser;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
......@@ -29,6 +28,7 @@ import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.ThreadUtils;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.favicon.FaviconHelper;
import org.chromium.chrome.browser.favicon.FaviconHelper.DefaultFaviconHelper;
import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback;
import org.chromium.chrome.browser.history.HistoryManagerUtils;
import org.chromium.chrome.browser.profiles.Profile;
......@@ -57,7 +57,7 @@ public class NavigationPopup extends ListPopupWindow implements AdapterView.OnIt
private final int mFaviconSize;
private Bitmap mDefaultFavicon;
private DefaultFaviconHelper mDefaultFaviconHelper;
/**
* Loads the favicons asynchronously.
......@@ -118,6 +118,7 @@ public class NavigationPopup extends ListPopupWindow implements AdapterView.OnIt
public void dismiss() {
if (mInitialized) mFaviconHelper.destroy();
mInitialized = false;
if (mDefaultFaviconHelper != null) mDefaultFaviconHelper.clearCache();
super.dismiss();
}
......@@ -169,17 +170,14 @@ public class NavigationPopup extends ListPopupWindow implements AdapterView.OnIt
* @param pageUrl the page for which the favicon was retrieved.
* @param favicon the favicon data.
*/
private void onFaviconAvailable(String pageUrl, Object favicon) {
private void onFaviconAvailable(String pageUrl, Bitmap favicon) {
if (favicon == null) {
if (mDefaultFavicon == null) {
mDefaultFavicon = BitmapFactory.decodeResource(
mContext.getResources(), R.drawable.default_favicon);
}
favicon = mDefaultFavicon;
if (mDefaultFaviconHelper == null) mDefaultFaviconHelper = new DefaultFaviconHelper();
favicon = mDefaultFaviconHelper.getDefaultFaviconBitmap(mContext, pageUrl, true);
}
for (int i = 0; i < mHistory.getEntryCount(); i++) {
NavigationEntry entry = mHistory.getEntryAtIndex(i);
if (TextUtils.equals(pageUrl, entry.getUrl())) entry.updateFavicon((Bitmap) favicon);
if (TextUtils.equals(pageUrl, entry.getUrl())) entry.updateFavicon(favicon);
}
mAdapter.notifyDataSetChanged();
}
......
......@@ -15,6 +15,7 @@ import org.chromium.base.annotations.JNINamespace;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.compositor.layouts.content.TitleBitmapFactory;
import org.chromium.chrome.browser.favicon.FaviconHelper;
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;
......@@ -41,6 +42,7 @@ public class LayerTitleCache implements TitleCache {
private ResourceManager mResourceManager;
private FaviconHelper mFaviconHelper;
private DefaultFaviconHelper mDefaultFaviconHelper;
/** Responsible for building titles on light themes or standard tabs. */
protected TitleBitmapFactory mStandardTitleBitmapFactory;
......@@ -61,10 +63,9 @@ public class LayerTitleCache implements TitleCache {
mNativeLayerTitleCache = nativeInit(fadeWidthPx, faviconStartPaddingPx, faviconEndPaddingPx,
R.drawable.spinner, R.drawable.spinner_white);
mFaviconSize = res.getDimensionPixelSize(R.dimen.compositor_tab_title_favicon_size);
mStandardTitleBitmapFactory =
new TitleBitmapFactory(context, false, R.drawable.default_favicon);
mDarkTitleBitmapFactory =
new TitleBitmapFactory(context, true, R.drawable.default_favicon_white);
mStandardTitleBitmapFactory = new TitleBitmapFactory(context, false);
mDarkTitleBitmapFactory = new TitleBitmapFactory(context, true);
mDefaultFaviconHelper = new DefaultFaviconHelper();
}
/**
......@@ -119,9 +120,12 @@ public class LayerTitleCache implements TitleCache {
private String getUpdatedTitleInternal(Tab tab, String titleString,
boolean fetchFaviconFromHistory) {
final int tabId = tab.getId();
Bitmap originalFavicon = tab.getFavicon();
boolean isDarkTheme = tab.isIncognito();
Bitmap originalFavicon = tab.getFavicon();
if (originalFavicon == null) {
originalFavicon = mDefaultFaviconHelper.getDefaultFaviconBitmap(
mContext, tab.getUrl(), !isDarkTheme);
}
boolean isRtl = tab.isTitleDirectionRtl();
TitleBitmapFactory titleBitmapFactory =
......@@ -135,8 +139,7 @@ public class LayerTitleCache implements TitleCache {
}
title.set(titleBitmapFactory.getTitleBitmap(mContext, titleString),
titleBitmapFactory.getFaviconBitmap(mContext, originalFavicon),
fetchFaviconFromHistory);
titleBitmapFactory.getFaviconBitmap(originalFavicon), fetchFaviconFromHistory);
if (mNativeLayerTitleCache != 0) {
nativeUpdateLayer(mNativeLayerTitleCache, tabId, title.getTitleResId(),
......@@ -216,6 +219,7 @@ public class LayerTitleCache implements TitleCache {
toDelete.unregister();
}
mTitles.clear();
mDefaultFaviconHelper.clearCache();
if (title != null) mTitles.put(exceptId, title);
......
......@@ -10,8 +10,6 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.TextPaint;
import android.text.TextUtils;
......@@ -33,7 +31,6 @@ public class TitleBitmapFactory {
private static final int MAX_NUM_TITLE_CHAR = 1000;
private final int mMaxWidth;
private final int mNullFaviconResourceId;
private final TextPaint mTextPaint;
private int mFaviconDimension;
......@@ -44,11 +41,8 @@ public class TitleBitmapFactory {
/**
* @param context The current Android's context.
* @param incognito Whether the title are for incognito mode.
* @param nullFaviconResourceId A drawable resource id of a default favicon.
*/
public TitleBitmapFactory(Context context, boolean incognito, int nullFaviconResourceId) {
mNullFaviconResourceId = nullFaviconResourceId;
public TitleBitmapFactory(Context context, boolean incognito) {
Resources res = context.getResources();
int textColor = ApiCompatibilityUtils.getColor(res, incognito
? R.color.compositor_tab_title_bar_text_incognito
......@@ -82,26 +76,24 @@ public class TitleBitmapFactory {
/**
* Generates the favicon bitmap.
*
* @param context Android's UI context.
* @param favicon The favicon of the tab.
* @return The Bitmap with the favicon.
*/
public Bitmap getFaviconBitmap(Context context, Bitmap favicon) {
public Bitmap getFaviconBitmap(Bitmap favicon) {
assert favicon != null;
try {
Bitmap b = Bitmap.createBitmap(
mFaviconDimension, mFaviconDimension, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
if (favicon == null) {
Drawable drawable = ApiCompatibilityUtils.getDrawable(
context.getResources(), mNullFaviconResourceId);
if (drawable instanceof BitmapDrawable) {
favicon = ((BitmapDrawable) drawable).getBitmap();
}
}
if (favicon != null) {
c.drawBitmap(favicon, Math.round((mFaviconDimension - favicon.getWidth()) / 2.0f),
Math.round((mFaviconDimension - favicon.getHeight()) / 2.0f), null);
if (favicon.getWidth() > mFaviconDimension || favicon.getHeight() > mFaviconDimension) {
float scale = (float) mFaviconDimension
/ Math.max(favicon.getWidth(), favicon.getHeight());
c.scale(scale, scale);
} else {
c.translate(Math.round((mFaviconDimension - favicon.getWidth()) / 2.0f),
Math.round((mFaviconDimension - favicon.getHeight()) / 2.0f));
}
c.drawBitmap(favicon, 0, 0, null);
return b;
} catch (OutOfMemoryError ex) {
Log.e(TAG, "OutOfMemoryError while building favicon texture.");
......
......@@ -4,9 +4,21 @@
package org.chromium.chrome.browser.favicon;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ntp.NewTabPage;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.content_public.browser.WebContents;
......@@ -48,6 +60,81 @@ public class FaviconHelper {
public void onIconAvailabilityChecked(boolean newlyAvailable);
}
/**
* Helper for generating default favicons and sharing the same icon between multiple views.
*/
public static class DefaultFaviconHelper {
private Bitmap mChromeDarkBitmap;
private Bitmap mChromeLightBitmap;
private Bitmap mDefaultDarkBitmap;
private Bitmap mDefaultLightBitmap;
private int getResourceId(String url) {
return NewTabPage.isNTPUrl(url) ? R.drawable.chromelogo16 : R.drawable.default_favicon;
}
private Bitmap createBitmap(Context context, String url, boolean useDarkIcon) {
Bitmap origBitmap =
BitmapFactory.decodeResource(context.getResources(), getResourceId(url));
Bitmap tintedBitmap = Bitmap.createBitmap(
origBitmap.getWidth(), origBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(tintedBitmap);
@ColorInt
int tintColor = ApiCompatibilityUtils.getColor(context.getResources(),
useDarkIcon ? R.color.default_icon_color : R.color.default_icon_color_white);
Paint p = new Paint();
p.setColorFilter(new PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_IN));
c.drawBitmap(origBitmap, 0f, 0f, p);
return tintedBitmap;
}
/**
* Generate a default favicon bitmap for the given URL.
* @param context The context used to fetch the default icons.
* @param url The URL of the page whose icon is being generated.
* @param useDarkIcon Whether a dark icon should be used.
* @return The favicon.
*/
public Bitmap getDefaultFaviconBitmap(Context context, String url, boolean useDarkIcon) {
boolean isNtp = NewTabPage.isNTPUrl(url);
Bitmap bitmap = isNtp ? (useDarkIcon ? mChromeDarkBitmap : mChromeLightBitmap)
: (useDarkIcon ? mDefaultDarkBitmap : mDefaultLightBitmap);
if (bitmap != null) return bitmap;
bitmap = createBitmap(context, url, useDarkIcon);
if (isNtp && useDarkIcon) {
mChromeDarkBitmap = bitmap;
} else if (isNtp) {
mChromeLightBitmap = bitmap;
} else if (useDarkIcon) {
mDefaultDarkBitmap = bitmap;
} else {
mDefaultLightBitmap = bitmap;
}
return bitmap;
}
/**
* Generate a default favicon drawable for the given URL.
* @param context The context used to fetch the default icons.
* @param url The URL of the page whose icon is being generated.
* @param useDarkIcon Whether a dark icon should be used.
* @return The favicon.
*/
public Drawable getDefaultFaviconDrawable(
Context context, String url, boolean useDarkIcon) {
return new BitmapDrawable(
context.getResources(), getDefaultFaviconBitmap(context, url, useDarkIcon));
}
/** Clears any of the cached default drawables. */
public void clearCache() {
mChromeDarkBitmap = null;
mChromeLightBitmap = null;
mDefaultDarkBitmap = null;
mDefaultLightBitmap = null;
}
}
/**
* Allocate and initialize the C++ side of this class.
*/
......
......@@ -20,6 +20,7 @@ import org.chromium.base.ContextUtils;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.UrlConstants;
import org.chromium.chrome.browser.favicon.FaviconHelper.DefaultFaviconHelper;
import org.chromium.chrome.browser.history.HistoryProvider.BrowsingHistoryObserver;
import org.chromium.chrome.browser.preferences.Pref;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
......@@ -43,6 +44,7 @@ public class HistoryAdapter extends DateDividedAdapter implements BrowsingHistor
private final HistoryProvider mHistoryProvider;
private final HistoryManager mHistoryManager;
private final ArrayList<HistoryItemView> mItemViews;
private final DefaultFaviconHelper mFaviconHelper;
private RecyclerView mRecyclerView;
private View mPrivacyDisclaimerBottomSpace;
......@@ -68,6 +70,7 @@ public class HistoryAdapter extends DateDividedAdapter implements BrowsingHistor
mHistoryProvider = provider;
mHistoryProvider.setObserver(this);
mHistoryManager = manager;
mFaviconHelper = new DefaultFaviconHelper();
mItemViews = new ArrayList<>();
}
......@@ -78,6 +81,7 @@ public class HistoryAdapter extends DateDividedAdapter implements BrowsingHistor
mHistoryProvider.destroy();
mIsDestroyed = true;
mRecyclerView = null;
mFaviconHelper.clearCache();
}
/**
......@@ -193,6 +197,7 @@ public class HistoryAdapter extends DateDividedAdapter implements BrowsingHistor
new SelectableItemViewHolder<>(v, mSelectionDelegate);
HistoryItemView itemView = (HistoryItemView) viewHolder.itemView;
itemView.setRemoveButtonVisible(!mSelectionDelegate.isSelectionEnabled());
itemView.setFaviconHelper(mFaviconHelper);
mItemViews.add(itemView);
return viewHolder;
}
......
......@@ -16,6 +16,7 @@ import android.view.View;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.favicon.FaviconHelper.DefaultFaviconHelper;
import org.chromium.chrome.browser.favicon.IconType;
import org.chromium.chrome.browser.favicon.LargeIconBridge.LargeIconCallback;
import org.chromium.chrome.browser.preferences.Pref;
......@@ -36,6 +37,7 @@ public class HistoryItemView extends SelectableItemView<HistoryItem> implements
private HistoryManager mHistoryManager;
private final RoundedIconGenerator mIconGenerator;
private DefaultFaviconHelper mFaviconHelper;
private final int mMinIconSize;
private final int mDisplayedIconSize;
......@@ -94,7 +96,7 @@ public class HistoryItemView extends SelectableItemView<HistoryItem> implements
ApiCompatibilityUtils.getColor(getResources(), R.color.google_red_700));
} else {
setIconDrawable(
ApiCompatibilityUtils.getDrawable(getResources(), R.drawable.default_favicon));
mFaviconHelper.getDefaultFaviconDrawable(getContext(), item.getUrl(), true));
if (mHistoryManager != null) requestIcon();
mTitleView.setTextColor(
......@@ -113,6 +115,13 @@ public class HistoryItemView extends SelectableItemView<HistoryItem> implements
if (!getItem().wasBlockedVisit()) requestIcon();
}
/**
* @param helper The helper for fetching default favicons.
*/
public void setFaviconHelper(DefaultFaviconHelper helper) {
mFaviconHelper = helper;
}
/**
* Removes the item associated with this view.
*/
......
......@@ -22,9 +22,9 @@ import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.favicon.FaviconHelper.DefaultFaviconHelper;
import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback;
import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSession;
import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSessionTab;
......@@ -100,7 +100,7 @@ public class RecentTabsRowAdapter extends BaseExpandableListAdapter {
private final Activity mActivity;
private final List<Group> mGroups;
private final Drawable mDefaultFavicon;
private final DefaultFaviconHelper mDefaultFaviconHelper;
private final RecentTabsManager mRecentTabsManager;
private final RecentlyClosedTabsGroup mRecentlyClosedTabsGroup = new RecentlyClosedTabsGroup();
private final SeparatorGroup mVisibleSeparatorGroup = new SeparatorGroup(true);
......@@ -678,7 +678,7 @@ public class RecentTabsRowAdapter extends BaseExpandableListAdapter {
mFaviconCache = new FaviconCache(MAX_NUM_FAVICONS_TO_CACHE);
Resources resources = activity.getResources();
mDefaultFavicon = ApiCompatibilityUtils.getDrawable(resources, R.drawable.default_favicon);
mDefaultFaviconHelper = new DefaultFaviconHelper();
mFaviconSize = resources.getDimensionPixelSize(R.dimen.default_favicon_size);
mIconGenerator = ViewUtils.createDefaultRoundedIconGenerator(
......@@ -723,7 +723,9 @@ public class RecentTabsRowAdapter extends BaseExpandableListAdapter {
Drawable image = mFaviconCache.getSyncedFaviconImage(url);
if (image == null) {
image = faviconDrawable(mRecentTabsManager.getSyncedFaviconImageForURL(url), url);
image = (image == null) ? mDefaultFavicon : image;
image = (image == null)
? mDefaultFaviconHelper.getDefaultFaviconDrawable(mActivity, url, true)
: image;
mFaviconCache.putSyncedFaviconImage(url, image);
}
viewHolder.imageView.setImageDrawable(image);
......@@ -733,7 +735,7 @@ public class RecentTabsRowAdapter extends BaseExpandableListAdapter {
Drawable image;
if (url == null) {
// URL is null for print jobs, for example.
image = mDefaultFavicon;
image = mDefaultFaviconHelper.getDefaultFaviconDrawable(mActivity, url, true);
} else {
image = mFaviconCache.getLocalFaviconImage(url);
if (image == null) {
......@@ -742,14 +744,16 @@ public class RecentTabsRowAdapter extends BaseExpandableListAdapter {
public void onFaviconAvailable(Bitmap bitmap, String iconUrl) {
if (this != viewHolder.imageCallback) return;
Drawable image = faviconDrawable(bitmap, url);
image = (image == null) ? mDefaultFavicon : image;
image = image == null ? mDefaultFaviconHelper.getDefaultFaviconDrawable(
mActivity, url, true)
: image;
mFaviconCache.putLocalFaviconImage(url, image);
viewHolder.imageView.setImageDrawable(image);
}
};
viewHolder.imageCallback = imageCallback;
mRecentTabsManager.getLocalFaviconForUrl(url, mFaviconSize, imageCallback);
image = mDefaultFavicon;
image = mDefaultFaviconHelper.getDefaultFaviconDrawable(mActivity, url, true);
}
}
viewHolder.imageView.setImageDrawable(image);
......
......@@ -17,6 +17,9 @@
<color name="default_icon_color_blue" tools:ignore="UnusedResources">
@color/modern_blue_600
</color>
<color name="default_icon_color_white" tools:ignore="UnusedResources">
@android:color/white
</color>
<!-- Modern color palette -->
<color name="modern_blue_300">#8AB4F8</color>
......
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