| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.ntp; | 5 package org.chromium.chrome.browser.ntp; |
| 6 | 6 |
| 7 import android.annotation.SuppressLint; | 7 import android.annotation.SuppressLint; |
| 8 import android.content.Context; | 8 import android.content.Context; |
| 9 import android.content.res.Resources; | 9 import android.content.res.Resources; |
| 10 import android.graphics.Bitmap; | 10 import android.graphics.Bitmap; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 import android.view.MotionEvent; | 25 import android.view.MotionEvent; |
| 26 import android.view.View; | 26 import android.view.View; |
| 27 import android.view.View.OnLayoutChangeListener; | 27 import android.view.View.OnLayoutChangeListener; |
| 28 import android.view.ViewGroup; | 28 import android.view.ViewGroup; |
| 29 import android.view.ViewStub; | 29 import android.view.ViewStub; |
| 30 import android.widget.Button; | 30 import android.widget.Button; |
| 31 import android.widget.FrameLayout; | 31 import android.widget.FrameLayout; |
| 32 import android.widget.ImageView; | 32 import android.widget.ImageView; |
| 33 import android.widget.TextView; | 33 import android.widget.TextView; |
| 34 | 34 |
| 35 import org.chromium.base.CommandLine; | |
| 36 import org.chromium.base.FieldTrialList; | |
| 37 import org.chromium.base.VisibleForTesting; | 35 import org.chromium.base.VisibleForTesting; |
| 38 import org.chromium.base.metrics.RecordHistogram; | |
| 39 import org.chromium.chrome.R; | 36 import org.chromium.chrome.R; |
| 40 import org.chromium.chrome.browser.ChromeSwitches; | |
| 41 import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconAvailabilityCall
back; | 37 import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconAvailabilityCall
back; |
| 42 import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback; | 38 import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback; |
| 43 import org.chromium.chrome.browser.favicon.LargeIconBridge.LargeIconCallback; | 39 import org.chromium.chrome.browser.favicon.LargeIconBridge.LargeIconCallback; |
| 44 import org.chromium.chrome.browser.ntp.LogoBridge.Logo; | 40 import org.chromium.chrome.browser.ntp.LogoBridge.Logo; |
| 45 import org.chromium.chrome.browser.ntp.LogoBridge.LogoObserver; | 41 import org.chromium.chrome.browser.ntp.LogoBridge.LogoObserver; |
| 46 import org.chromium.chrome.browser.ntp.MostVisitedItem.MostVisitedItemManager; | 42 import org.chromium.chrome.browser.ntp.MostVisitedItem.MostVisitedItemManager; |
| 47 import org.chromium.chrome.browser.ntp.NewTabPage.OnSearchBoxScrollListener; | 43 import org.chromium.chrome.browser.ntp.NewTabPage.OnSearchBoxScrollListener; |
| 48 import org.chromium.chrome.browser.profiles.MostVisitedSites.MostVisitedURLsObse
rver; | 44 import org.chromium.chrome.browser.profiles.MostVisitedSites.MostVisitedURLsObse
rver; |
| 49 import org.chromium.chrome.browser.profiles.MostVisitedSites.ThumbnailCallback; | 45 import org.chromium.chrome.browser.profiles.MostVisitedSites.ThumbnailCallback; |
| 50 import org.chromium.chrome.browser.util.ViewUtils; | 46 import org.chromium.chrome.browser.util.ViewUtils; |
| 51 import org.chromium.chrome.browser.widget.RoundedIconGenerator; | 47 import org.chromium.chrome.browser.widget.RoundedIconGenerator; |
| 52 import org.chromium.ui.text.SpanApplier; | 48 import org.chromium.ui.text.SpanApplier; |
| 53 import org.chromium.ui.text.SpanApplier.SpanInfo; | 49 import org.chromium.ui.text.SpanApplier.SpanInfo; |
| 54 | 50 |
| 55 import java.util.Locale; | 51 import java.util.Locale; |
| 56 | 52 |
| 57 import jp.tomorrowkey.android.gifplayer.BaseGifImage; | 53 import jp.tomorrowkey.android.gifplayer.BaseGifImage; |
| 58 | 54 |
| 59 /** | 55 /** |
| 60 * The native new tab page, represented by some basic data such as title and url
, and an Android | 56 * The native new tab page, represented by some basic data such as title and url
, and an Android |
| 61 * View that displays the page. | 57 * View that displays the page. |
| 62 */ | 58 */ |
| 63 public class NewTabPageView extends FrameLayout | 59 public class NewTabPageView extends FrameLayout |
| 64 implements MostVisitedURLsObserver, OnLayoutChangeListener { | 60 implements MostVisitedURLsObserver, OnLayoutChangeListener { |
| 65 | 61 |
| 66 static final int MAX_MOST_VISITED_SITES = 12; | 62 static final int MAX_MOST_VISITED_SITES = 12; |
| 67 private static final int SHADOW_COLOR = 0x11000000; | 63 private static final int SHADOW_COLOR = 0x11000000; |
| 68 private static final long SNAP_SCROLL_DELAY_MS = 30; | 64 private static final long SNAP_SCROLL_DELAY_MS = 30; |
| 69 | 65 |
| 70 private static final String ICON_NTP_FIELD_TRIAL_NAME = "IconNTP"; | |
| 71 private static final String ICON_NTP_ENABLED_GROUP = "Enabled"; | |
| 72 | |
| 73 // Taken from https://support.google.com/googleplay/answer/1727131?hl=en-GB | 66 // Taken from https://support.google.com/googleplay/answer/1727131?hl=en-GB |
| 74 private static final String[] SUPPORTED_SAMSUNG_DEVICES = { | 67 private static final String[] SUPPORTED_SAMSUNG_DEVICES = { |
| 75 "sm-g920", // Galaxy S6 | 68 "sm-g920", // Galaxy S6 |
| 76 "sm-g925", // Galaxy S6 Edge | 69 "sm-g925", // Galaxy S6 Edge |
| 77 "404sc", // Galaxy S6 Edge | 70 "404sc", // Galaxy S6 Edge |
| 78 "scv31", // Galaxy S6 Edge | 71 "scv31", // Galaxy S6 Edge |
| 79 "sm-g890", // Galaxy S6 Active | 72 "sm-g890", // Galaxy S6 Active |
| 80 "sm-g800", // Galaxy S5 mini | 73 "sm-g800", // Galaxy S5 mini |
| 81 "sm-g860", // Galaxy S5 K Sport | 74 "sm-g860", // Galaxy S5 K Sport |
| 82 "sm-g870", // Galaxy S5 Active | 75 "sm-g870", // Galaxy S5 Active |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 | 201 |
| 209 /** | 202 /** |
| 210 * Gets the default search provider's logo and calls logoObserver with t
he result. | 203 * Gets the default search provider's logo and calls logoObserver with t
he result. |
| 211 * @param logoObserver The callback to notify when the logo is available
. | 204 * @param logoObserver The callback to notify when the logo is available
. |
| 212 */ | 205 */ |
| 213 void getSearchProviderLogo(LogoObserver logoObserver); | 206 void getSearchProviderLogo(LogoObserver logoObserver); |
| 214 | 207 |
| 215 /** | 208 /** |
| 216 * Called when the NTP has completely finished loading (all views will b
e inflated | 209 * Called when the NTP has completely finished loading (all views will b
e inflated |
| 217 * and any dependent resources will have been loaded). | 210 * and any dependent resources will have been loaded). |
| 211 * @param mostVisitedItems The MostVisitedItem shown on the NTP. Used to
record metrics. |
| 218 */ | 212 */ |
| 219 void onLoadingComplete(); | 213 void onLoadingComplete(MostVisitedItem[] mostVisitedItems); |
| 220 } | 214 } |
| 221 | 215 |
| 222 /** | 216 /** |
| 223 * Returns a title suitable for display for a link (e.g. a most visited item
). If |title| is | 217 * Returns a title suitable for display for a link (e.g. a most visited item
). If |title| is |
| 224 * non-empty, this simply returns it. Otherwise, returns a shortened form of
the URL. | 218 * non-empty, this simply returns it. Otherwise, returns a shortened form of
the URL. |
| 225 */ | 219 */ |
| 226 static String getTitleForDisplay(String title, String url) { | 220 static String getTitleForDisplay(String title, String url) { |
| 227 if (TextUtils.isEmpty(title) && url != null) { | 221 if (TextUtils.isEmpty(title) && url != null) { |
| 228 Uri uri = Uri.parse(url); | 222 Uri uri = Uri.parse(url); |
| 229 String host = uri.getHost(); | 223 String host = uri.getHost(); |
| 230 String path = uri.getPath(); | 224 String path = uri.getPath(); |
| 231 if (host == null) host = ""; | 225 if (host == null) host = ""; |
| 232 if (TextUtils.isEmpty(path) || path.equals("/")) path = ""; | 226 if (TextUtils.isEmpty(path) || path.equals("/")) path = ""; |
| 233 title = host + path; | 227 title = host + path; |
| 234 } | 228 } |
| 235 return title; | 229 return title; |
| 236 } | 230 } |
| 237 | 231 |
| 238 /** | 232 /** |
| 239 * Default constructor required for XML inflation. | 233 * Default constructor required for XML inflation. |
| 240 */ | 234 */ |
| 241 public NewTabPageView(Context context, AttributeSet attrs) { | 235 public NewTabPageView(Context context, AttributeSet attrs) { |
| 242 super(context, attrs); | 236 super(context, attrs); |
| 243 } | 237 } |
| 244 | 238 |
| 245 private boolean isIconNtpEnabled() { | |
| 246 // Query the field trial state first, to ensure that UMA reports the cor
rect group. | |
| 247 String fieldTrialGroup = FieldTrialList.findFullName(ICON_NTP_FIELD_TRIA
L_NAME); | |
| 248 CommandLine commandLine = CommandLine.getInstance(); | |
| 249 if (commandLine.hasSwitch(ChromeSwitches.DISABLE_ICON_NTP)) return false
; | |
| 250 if (commandLine.hasSwitch(ChromeSwitches.ENABLE_ICON_NTP)) return true; | |
| 251 return fieldTrialGroup.equals(ICON_NTP_ENABLED_GROUP); | |
| 252 } | |
| 253 | |
| 254 /** | 239 /** |
| 255 * Initializes the NTP. This must be called immediately after inflation, bef
ore this object is | 240 * Initializes the NTP. This must be called immediately after inflation, bef
ore this object is |
| 256 * used in any other way. | 241 * used in any other way. |
| 257 * | 242 * |
| 258 * @param manager NewTabPageManager used to perform various actions when the
user interacts | 243 * @param manager NewTabPageManager used to perform various actions when the
user interacts |
| 259 * with the page. | 244 * with the page. |
| 260 * @param isSingleUrlBarMode Whether the NTP is in single URL bar mode. | 245 * @param isSingleUrlBarMode Whether the NTP is in single URL bar mode. |
| 261 * @param searchProviderHasLogo Whether the search provider has a logo. | 246 * @param searchProviderHasLogo Whether the search provider has a logo. |
| 247 * @param isIconMode Whether to show the icon-based design, as opposed to th
e thumbnail design. |
| 262 */ | 248 */ |
| 263 public void initialize(NewTabPageManager manager, boolean isSingleUrlBarMode
, | 249 public void initialize(NewTabPageManager manager, boolean isSingleUrlBarMode
, |
| 264 boolean searchProviderHasLogo) { | 250 boolean searchProviderHasLogo, boolean isIconMode) { |
| 265 mManager = manager; | 251 mManager = manager; |
| 266 | 252 |
| 267 mScrollView = (NewTabScrollView) findViewById(R.id.ntp_scrollview); | 253 mScrollView = (NewTabScrollView) findViewById(R.id.ntp_scrollview); |
| 268 mScrollView.enableBottomShadow(SHADOW_COLOR); | 254 mScrollView.enableBottomShadow(SHADOW_COLOR); |
| 269 mContentView = (ViewGroup) findViewById(R.id.ntp_content); | 255 mContentView = (ViewGroup) findViewById(R.id.ntp_content); |
| 270 | 256 |
| 271 mMostVisitedDesign = isIconNtpEnabled() | 257 mMostVisitedDesign = isIconMode |
| 272 ? new IconMostVisitedDesign(getContext()) | 258 ? new IconMostVisitedDesign(getContext()) |
| 273 : new ThumbnailMostVisitedDesign(getContext()); | 259 : new ThumbnailMostVisitedDesign(getContext()); |
| 274 ViewStub mostVisitedLayoutStub = (ViewStub) findViewById(R.id.most_visit
ed_layout_stub); | 260 ViewStub mostVisitedLayoutStub = (ViewStub) findViewById(R.id.most_visit
ed_layout_stub); |
| 275 mostVisitedLayoutStub.setLayoutResource(mMostVisitedDesign.getMostVisite
dLayoutId()); | 261 mostVisitedLayoutStub.setLayoutResource(mMostVisitedDesign.getMostVisite
dLayoutId()); |
| 276 mMostVisitedLayout = (ViewGroup) mostVisitedLayoutStub.inflate(); | 262 mMostVisitedLayout = (ViewGroup) mostVisitedLayoutStub.inflate(); |
| 277 mMostVisitedDesign.initMostVisitedLayout(mMostVisitedLayout, searchProvi
derHasLogo); | 263 mMostVisitedDesign.initMostVisitedLayout(mMostVisitedLayout, searchProvi
derHasLogo); |
| 278 | 264 |
| 279 mSearchProviderLogoView = (LogoView) findViewById(R.id.search_provider_l
ogo); | 265 mSearchProviderLogoView = (LogoView) findViewById(R.id.search_provider_l
ogo); |
| 280 mSearchBoxView = findViewById(R.id.search_box); | 266 mSearchBoxView = findViewById(R.id.search_box); |
| 281 mNoSearchLogoSpacer = findViewById(R.id.no_search_logo_spacer); | 267 mNoSearchLogoSpacer = findViewById(R.id.no_search_logo_spacer); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 * is complete. | 456 * is complete. |
| 471 */ | 457 */ |
| 472 private void loadTaskCompleted() { | 458 private void loadTaskCompleted() { |
| 473 assert mPendingLoadTasks > 0; | 459 assert mPendingLoadTasks > 0; |
| 474 mPendingLoadTasks--; | 460 mPendingLoadTasks--; |
| 475 if (mPendingLoadTasks == 0) { | 461 if (mPendingLoadTasks == 0) { |
| 476 if (mLoadHasCompleted) { | 462 if (mLoadHasCompleted) { |
| 477 assert false; | 463 assert false; |
| 478 } else { | 464 } else { |
| 479 mLoadHasCompleted = true; | 465 mLoadHasCompleted = true; |
| 480 mManager.onLoadingComplete(); | 466 mManager.onLoadingComplete(mMostVisitedItems); |
| 481 mMostVisitedDesign.onLoadingComplete(); | |
| 482 // Load the logo after everything else is finished, since it's l
ower priority. | 467 // Load the logo after everything else is finished, since it's l
ower priority. |
| 483 loadSearchProviderLogo(); | 468 loadSearchProviderLogo(); |
| 484 } | 469 } |
| 485 } | 470 } |
| 486 } | 471 } |
| 487 | 472 |
| 488 /** | 473 /** |
| 489 * Loads the search provider logo (e.g. Google doodle), if any. | 474 * Loads the search provider logo (e.g. Google doodle), if any. |
| 490 */ | 475 */ |
| 491 private void loadSearchProviderLogo() { | 476 private void loadSearchProviderLogo() { |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 item = oldItem; | 751 item = oldItem; |
| 767 item.setIndex(i); | 752 item.setIndex(i); |
| 768 oldItems[j] = null; | 753 oldItems[j] = null; |
| 769 break; | 754 break; |
| 770 } | 755 } |
| 771 } | 756 } |
| 772 | 757 |
| 773 // If nothing can be reused, create a new item. | 758 // If nothing can be reused, create a new item. |
| 774 if (item == null) { | 759 if (item == null) { |
| 775 String displayTitle = getTitleForDisplay(title, url); | 760 String displayTitle = getTitleForDisplay(title, url); |
| 761 item = new MostVisitedItem(mManager, title, url, i); |
| 776 View view = mMostVisitedDesign.createMostVisitedItemView(inflate
r, url, title, | 762 View view = mMostVisitedDesign.createMostVisitedItemView(inflate
r, url, title, |
| 777 displayTitle, i, isInitialLoad); | 763 displayTitle, item, isInitialLoad); |
| 778 item = new MostVisitedItem(mManager, title, url, i, view); | 764 item.initView(view); |
| 779 } | 765 } |
| 780 | 766 |
| 781 mMostVisitedItems[i] = item; | 767 mMostVisitedItems[i] = item; |
| 782 mMostVisitedLayout.addView(item.getView()); | 768 mMostVisitedLayout.addView(item.getView()); |
| 783 } | 769 } |
| 784 | 770 |
| 785 mHasReceivedMostVisitedSites = true; | 771 mHasReceivedMostVisitedSites = true; |
| 786 updateMostVisitedPlaceholderVisibility(); | 772 updateMostVisitedPlaceholderVisibility(); |
| 787 | 773 |
| 788 if (isInitialLoad) { | 774 if (isInitialLoad) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 846 * Interface for creating the most visited layout and tiles. | 832 * Interface for creating the most visited layout and tiles. |
| 847 * TODO(newt): delete this once a single design has been chosen. | 833 * TODO(newt): delete this once a single design has been chosen. |
| 848 */ | 834 */ |
| 849 private interface MostVisitedDesign { | 835 private interface MostVisitedDesign { |
| 850 int getNumberOfTiles(boolean searchProviderHasLogo); | 836 int getNumberOfTiles(boolean searchProviderHasLogo); |
| 851 int getMostVisitedLayoutId(); | 837 int getMostVisitedLayoutId(); |
| 852 int getMostVisitedLayoutBleed(); | 838 int getMostVisitedLayoutBleed(); |
| 853 void initMostVisitedLayout(ViewGroup mostVisitedLayout, boolean searchPr
oviderHasLogo); | 839 void initMostVisitedLayout(ViewGroup mostVisitedLayout, boolean searchPr
oviderHasLogo); |
| 854 void setSearchProviderHasLogo(View mostVisitedLayout, boolean hasLogo); | 840 void setSearchProviderHasLogo(View mostVisitedLayout, boolean hasLogo); |
| 855 View createMostVisitedItemView(LayoutInflater inflater, String url, Stri
ng title, | 841 View createMostVisitedItemView(LayoutInflater inflater, String url, Stri
ng title, |
| 856 String displayTitle, int index, boolean isInitialLoad); | 842 String displayTitle, MostVisitedItem item, boolean isInitialLoad
); |
| 857 void onFaviconUpdated(String url); | 843 void onFaviconUpdated(String url); |
| 858 void onLoadingComplete(); | |
| 859 } | 844 } |
| 860 | 845 |
| 861 /** | 846 /** |
| 862 * The old most visited design, where each tile shows a thumbnail of the pag
e, a small favicon, | 847 * The old most visited design, where each tile shows a thumbnail of the pag
e, a small favicon, |
| 863 * and the title. | 848 * and the title. |
| 864 */ | 849 */ |
| 865 private class ThumbnailMostVisitedDesign implements MostVisitedDesign { | 850 private class ThumbnailMostVisitedDesign implements MostVisitedDesign { |
| 866 | 851 |
| 867 private static final int NUM_TILES = 6; | 852 private static final int NUM_TILES = 6; |
| 868 private static final int FAVICON_CORNER_RADIUS_DP = 2; | 853 private static final int FAVICON_CORNER_RADIUS_DP = 2; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 900 @Override | 885 @Override |
| 901 public void initMostVisitedLayout(ViewGroup mostVisitedLayout, | 886 public void initMostVisitedLayout(ViewGroup mostVisitedLayout, |
| 902 boolean searchProviderHasLogo) { | 887 boolean searchProviderHasLogo) { |
| 903 } | 888 } |
| 904 | 889 |
| 905 @Override | 890 @Override |
| 906 public void setSearchProviderHasLogo(View mostVisitedLayout, boolean has
Logo) {} | 891 public void setSearchProviderHasLogo(View mostVisitedLayout, boolean has
Logo) {} |
| 907 | 892 |
| 908 @Override | 893 @Override |
| 909 public View createMostVisitedItemView(LayoutInflater inflater, final Str
ing url, | 894 public View createMostVisitedItemView(LayoutInflater inflater, final Str
ing url, |
| 910 String title, String displayTitle, int index, final boolean isIn
itialLoad) { | 895 String title, String displayTitle, final MostVisitedItem item, |
| 896 final boolean isInitialLoad) { |
| 911 final MostVisitedItemView view = (MostVisitedItemView) inflater.infl
ate( | 897 final MostVisitedItemView view = (MostVisitedItemView) inflater.infl
ate( |
| 912 R.layout.most_visited_item, mMostVisitedLayout, false); | 898 R.layout.most_visited_item, mMostVisitedLayout, false); |
| 913 view.init(displayTitle); | 899 view.init(displayTitle); |
| 914 | 900 |
| 915 ThumbnailCallback thumbnailCallback = new ThumbnailCallback() { | 901 ThumbnailCallback thumbnailCallback = new ThumbnailCallback() { |
| 916 @Override | 902 @Override |
| 917 public void onMostVisitedURLsThumbnailAvailable(Bitmap thumbnail
) { | 903 public void onMostVisitedURLsThumbnailAvailable(Bitmap thumbnail
, |
| 904 boolean isLocalThumbnail) { |
| 918 view.setThumbnail(thumbnail); | 905 view.setThumbnail(thumbnail); |
| 906 if (thumbnail == null) { |
| 907 item.setTileType(MostVisitedTileType.THUMBNAIL_DEFAULT); |
| 908 } else if (isLocalThumbnail) { |
| 909 item.setTileType(MostVisitedTileType.THUMBNAIL_LOCAL); |
| 910 } else { |
| 911 item.setTileType(MostVisitedTileType.THUMBNAIL_SERVER); |
| 912 } |
| 919 mSnapshotMostVisitedChanged = true; | 913 mSnapshotMostVisitedChanged = true; |
| 920 if (isInitialLoad) loadTaskCompleted(); | 914 if (isInitialLoad) loadTaskCompleted(); |
| 921 } | 915 } |
| 922 }; | 916 }; |
| 923 if (isInitialLoad) mPendingLoadTasks++; | 917 if (isInitialLoad) mPendingLoadTasks++; |
| 924 mManager.getURLThumbnail(url, thumbnailCallback); | 918 mManager.getURLThumbnail(url, thumbnailCallback); |
| 925 | 919 |
| 926 FaviconImageCallback faviconCallback = new FaviconImageCallback() { | 920 FaviconImageCallback faviconCallback = new FaviconImageCallback() { |
| 927 @Override | 921 @Override |
| 928 public void onFaviconAvailable(Bitmap image, String iconUrl) { | 922 public void onFaviconAvailable(Bitmap image, String iconUrl) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 954 image = mFaviconGenerator.generateIconForUrl(url); | 948 image = mFaviconGenerator.generateIconForUrl(url); |
| 955 } | 949 } |
| 956 view.setFavicon(image); | 950 view.setFavicon(image); |
| 957 mSnapshotMostVisitedChanged = true; | 951 mSnapshotMostVisitedChanged = true; |
| 958 } | 952 } |
| 959 }; | 953 }; |
| 960 mManager.getLocalFaviconImageForURL(url, mDesiredFaviconSize, fa
viconCallback); | 954 mManager.getLocalFaviconImageForURL(url, mDesiredFaviconSize, fa
viconCallback); |
| 961 break; | 955 break; |
| 962 } | 956 } |
| 963 } | 957 } |
| 964 | |
| 965 @Override | |
| 966 public void onLoadingComplete() {} | |
| 967 } | 958 } |
| 968 | 959 |
| 969 /** | 960 /** |
| 970 * The new-fangled design for most visited tiles, where each tile shows a la
rge icon and title. | 961 * The new-fangled design for most visited tiles, where each tile shows a la
rge icon and title. |
| 971 */ | 962 */ |
| 972 private class IconMostVisitedDesign implements MostVisitedDesign { | 963 private class IconMostVisitedDesign implements MostVisitedDesign { |
| 973 | 964 |
| 974 private static final int NUM_TILES = 8; | 965 private static final int NUM_TILES = 8; |
| 975 private static final int NUM_TILES_NO_LOGO = 12; | 966 private static final int NUM_TILES_NO_LOGO = 12; |
| 976 private static final int MAX_ROWS = 2; | 967 private static final int MAX_ROWS = 2; |
| 977 private static final int MAX_ROWS_NO_LOGO = 3; | 968 private static final int MAX_ROWS_NO_LOGO = 3; |
| 978 | 969 |
| 979 private static final int ICON_CORNER_RADIUS_DP = 4; | 970 private static final int ICON_CORNER_RADIUS_DP = 4; |
| 980 private static final int ICON_TEXT_SIZE_DP = 20; | 971 private static final int ICON_TEXT_SIZE_DP = 20; |
| 981 private static final int ICON_BACKGROUND_COLOR = 0xff787878; | 972 private static final int ICON_BACKGROUND_COLOR = 0xff787878; |
| 982 private static final int ICON_MIN_SIZE_PX = 48; | 973 private static final int ICON_MIN_SIZE_PX = 48; |
| 983 | 974 |
| 984 private int mMostVisitedLayoutBleed; | 975 private int mMostVisitedLayoutBleed; |
| 985 private int mMinIconSize; | 976 private int mMinIconSize; |
| 986 private int mDesiredIconSize; | 977 private int mDesiredIconSize; |
| 987 private RoundedIconGenerator mIconGenerator; | 978 private RoundedIconGenerator mIconGenerator; |
| 988 | 979 |
| 989 private int mNumGrayIcons; | |
| 990 private int mNumColorIcons; | |
| 991 private int mNumRealIcons; | |
| 992 | |
| 993 IconMostVisitedDesign(Context context) { | 980 IconMostVisitedDesign(Context context) { |
| 994 Resources res = context.getResources(); | 981 Resources res = context.getResources(); |
| 995 mMostVisitedLayoutBleed = res.getDimensionPixelSize( | 982 mMostVisitedLayoutBleed = res.getDimensionPixelSize( |
| 996 R.dimen.icon_most_visited_layout_bleed); | 983 R.dimen.icon_most_visited_layout_bleed); |
| 997 mDesiredIconSize = res.getDimensionPixelSize(R.dimen.icon_most_visit
ed_icon_size); | 984 mDesiredIconSize = res.getDimensionPixelSize(R.dimen.icon_most_visit
ed_icon_size); |
| 998 // On ldpi devices, mDesiredIconSize could be even smaller than ICON
_MIN_SIZE_PX. | 985 // On ldpi devices, mDesiredIconSize could be even smaller than ICON
_MIN_SIZE_PX. |
| 999 mMinIconSize = Math.min(mDesiredIconSize, ICON_MIN_SIZE_PX); | 986 mMinIconSize = Math.min(mDesiredIconSize, ICON_MIN_SIZE_PX); |
| 1000 int desiredIconSizeDp = Math.round( | 987 int desiredIconSizeDp = Math.round( |
| 1001 mDesiredIconSize / res.getDisplayMetrics().density); | 988 mDesiredIconSize / res.getDisplayMetrics().density); |
| 1002 mIconGenerator = new RoundedIconGenerator( | 989 mIconGenerator = new RoundedIconGenerator( |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1028 | 1015 |
| 1029 @Override | 1016 @Override |
| 1030 public void setSearchProviderHasLogo(View mostVisitedLayout, boolean has
Logo) { | 1017 public void setSearchProviderHasLogo(View mostVisitedLayout, boolean has
Logo) { |
| 1031 int paddingTop = getResources().getDimensionPixelSize(hasLogo | 1018 int paddingTop = getResources().getDimensionPixelSize(hasLogo |
| 1032 ? R.dimen.icon_most_visited_layout_padding_top | 1019 ? R.dimen.icon_most_visited_layout_padding_top |
| 1033 : R.dimen.icon_most_visited_layout_no_logo_padding_top); | 1020 : R.dimen.icon_most_visited_layout_no_logo_padding_top); |
| 1034 mostVisitedLayout.setPadding(0, paddingTop, 0, 0); | 1021 mostVisitedLayout.setPadding(0, paddingTop, 0, 0); |
| 1035 } | 1022 } |
| 1036 | 1023 |
| 1037 class LargeIconCallbackImpl implements LargeIconCallback { | 1024 class LargeIconCallbackImpl implements LargeIconCallback { |
| 1038 private String mUrl; | 1025 private MostVisitedItem mItem; |
| 1039 private IconMostVisitedItemView mView; | |
| 1040 private boolean mIsInitialLoad; | 1026 private boolean mIsInitialLoad; |
| 1041 | 1027 |
| 1042 public LargeIconCallbackImpl(String url, IconMostVisitedItemView vie
w, | 1028 public LargeIconCallbackImpl(MostVisitedItem item, boolean isInitial
Load) { |
| 1043 boolean isInitialLoad) { | 1029 mItem = item; |
| 1044 mUrl = url; | |
| 1045 mView = view; | |
| 1046 mIsInitialLoad = isInitialLoad; | 1030 mIsInitialLoad = isInitialLoad; |
| 1047 } | 1031 } |
| 1048 | 1032 |
| 1049 @Override | 1033 @Override |
| 1050 public void onLargeIconAvailable(Bitmap icon, int fallbackColor) { | 1034 public void onLargeIconAvailable(Bitmap icon, int fallbackColor) { |
| 1035 IconMostVisitedItemView view = (IconMostVisitedItemView) mItem.g
etView(); |
| 1051 if (icon == null) { | 1036 if (icon == null) { |
| 1052 mIconGenerator.setBackgroundColor(fallbackColor); | 1037 mIconGenerator.setBackgroundColor(fallbackColor); |
| 1053 icon = mIconGenerator.generateIconForUrl(mUrl); | 1038 icon = mIconGenerator.generateIconForUrl(mItem.getUrl()); |
| 1054 mView.setIcon(new BitmapDrawable(getResources(), icon)); | 1039 view.setIcon(new BitmapDrawable(getResources(), icon)); |
| 1055 if (mIsInitialLoad) { | 1040 mItem.setTileType(fallbackColor == ICON_BACKGROUND_COLOR |
| 1056 if (fallbackColor == ICON_BACKGROUND_COLOR) { | 1041 ? MostVisitedTileType.ICON_DEFAULT : MostVisitedTile
Type.ICON_COLOR); |
| 1057 mNumGrayIcons++; | |
| 1058 } else { | |
| 1059 mNumColorIcons++; | |
| 1060 } | |
| 1061 } | |
| 1062 } else { | 1042 } else { |
| 1063 RoundedBitmapDrawable roundedIcon = RoundedBitmapDrawableFac
tory.create( | 1043 RoundedBitmapDrawable roundedIcon = RoundedBitmapDrawableFac
tory.create( |
| 1064 getResources(), icon); | 1044 getResources(), icon); |
| 1065 int cornerRadius = Math.round(ICON_CORNER_RADIUS_DP | 1045 int cornerRadius = Math.round(ICON_CORNER_RADIUS_DP |
| 1066 * getResources().getDisplayMetrics().density * icon.
getWidth() | 1046 * getResources().getDisplayMetrics().density * icon.
getWidth() |
| 1067 / mDesiredIconSize); | 1047 / mDesiredIconSize); |
| 1068 roundedIcon.setCornerRadius(cornerRadius); | 1048 roundedIcon.setCornerRadius(cornerRadius); |
| 1069 roundedIcon.setAntiAlias(true); | 1049 roundedIcon.setAntiAlias(true); |
| 1070 roundedIcon.setFilterBitmap(true); | 1050 roundedIcon.setFilterBitmap(true); |
| 1071 mView.setIcon(roundedIcon); | 1051 view.setIcon(roundedIcon); |
| 1072 if (mIsInitialLoad) mNumRealIcons++; | 1052 mItem.setTileType(MostVisitedTileType.ICON_REAL); |
| 1073 } | 1053 } |
| 1074 mSnapshotMostVisitedChanged = true; | 1054 mSnapshotMostVisitedChanged = true; |
| 1075 if (mIsInitialLoad) loadTaskCompleted(); | 1055 if (mIsInitialLoad) loadTaskCompleted(); |
| 1076 } | 1056 } |
| 1077 }; | 1057 } |
| 1078 | 1058 |
| 1079 @Override | 1059 @Override |
| 1080 public View createMostVisitedItemView(LayoutInflater inflater, final Str
ing url, | 1060 public View createMostVisitedItemView(LayoutInflater inflater, final Str
ing url, |
| 1081 String title, String displayTitle, int index, final boolean isIn
itialLoad) { | 1061 String title, String displayTitle, MostVisitedItem item, |
| 1062 final boolean isInitialLoad) { |
| 1082 final IconMostVisitedItemView view = (IconMostVisitedItemView) infla
ter.inflate( | 1063 final IconMostVisitedItemView view = (IconMostVisitedItemView) infla
ter.inflate( |
| 1083 R.layout.icon_most_visited_item, mMostVisitedLayout, false); | 1064 R.layout.icon_most_visited_item, mMostVisitedLayout, false); |
| 1084 view.setTitle(displayTitle); | 1065 view.setTitle(displayTitle); |
| 1085 | 1066 |
| 1086 LargeIconCallback iconCallback = new LargeIconCallbackImpl(url, view
, isInitialLoad); | 1067 LargeIconCallback iconCallback = new LargeIconCallbackImpl(item, isI
nitialLoad); |
| 1087 if (isInitialLoad) mPendingLoadTasks++; | 1068 if (isInitialLoad) mPendingLoadTasks++; |
| 1088 mManager.getLargeIconForUrl(url, mMinIconSize, iconCallback); | 1069 mManager.getLargeIconForUrl(url, mMinIconSize, iconCallback); |
| 1089 | 1070 |
| 1090 return view; | 1071 return view; |
| 1091 } | 1072 } |
| 1092 | 1073 |
| 1093 @Override | 1074 @Override |
| 1094 public void onFaviconUpdated(final String url) { | 1075 public void onFaviconUpdated(final String url) { |
| 1095 // Find a matching most visited item. | 1076 // Find a matching most visited item. |
| 1096 for (MostVisitedItem item : mMostVisitedItems) { | 1077 for (MostVisitedItem item : mMostVisitedItems) { |
| 1097 if (!item.getUrl().equals(url)) continue; | 1078 if (item.getUrl().equals(url)) { |
| 1098 | 1079 LargeIconCallback iconCallback = new LargeIconCallbackImpl(i
tem, false); |
| 1099 final IconMostVisitedItemView view = (IconMostVisitedItemView) i
tem.getView(); | 1080 mManager.getLargeIconForUrl(url, mMinIconSize, iconCallback)
; |
| 1100 LargeIconCallback iconCallback = new LargeIconCallbackImpl(url,
view, false); | 1081 break; |
| 1101 mManager.getLargeIconForUrl(url, mMinIconSize, iconCallback); | 1082 } |
| 1102 break; | |
| 1103 } | 1083 } |
| 1104 } | 1084 } |
| 1105 | |
| 1106 @Override | |
| 1107 public void onLoadingComplete() { | |
| 1108 RecordHistogram.recordCount100Histogram("NewTabPage.IconsGray", mNum
GrayIcons); | |
| 1109 RecordHistogram.recordCount100Histogram("NewTabPage.IconsColor", mNu
mColorIcons); | |
| 1110 RecordHistogram.recordCount100Histogram("NewTabPage.IconsReal", mNum
RealIcons); | |
| 1111 } | |
| 1112 } | 1085 } |
| 1113 } | 1086 } |
| OLD | NEW |