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 /** | 53 /** |
58 * The native new tab page, represented by some basic data such as title and url , and an Android | 54 * The native new tab page, represented by some basic data such as title and url , and an Android |
59 * View that displays the page. | 55 * View that displays the page. |
60 */ | 56 */ |
61 public class NewTabPageView extends FrameLayout | 57 public class NewTabPageView extends FrameLayout |
62 implements MostVisitedURLsObserver, OnLayoutChangeListener { | 58 implements MostVisitedURLsObserver, OnLayoutChangeListener { |
63 | 59 |
64 static final int MAX_MOST_VISITED_SITES = 12; | 60 static final int MAX_MOST_VISITED_SITES = 12; |
65 private static final int SHADOW_COLOR = 0x11000000; | 61 private static final int SHADOW_COLOR = 0x11000000; |
66 private static final long SNAP_SCROLL_DELAY_MS = 30; | 62 private static final long SNAP_SCROLL_DELAY_MS = 30; |
67 | 63 |
68 private static final String ICON_NTP_FIELD_TRIAL_NAME = "IconNTP"; | |
69 private static final String ICON_NTP_ENABLED_GROUP = "Enabled"; | |
70 | |
71 // Taken from https://support.google.com/googleplay/answer/1727131?hl=en-GB | 64 // Taken from https://support.google.com/googleplay/answer/1727131?hl=en-GB |
72 private static final String[] SUPPORTED_SAMSUNG_DEVICES = { | 65 private static final String[] SUPPORTED_SAMSUNG_DEVICES = { |
73 "sm-g920", // Galaxy S6 | 66 "sm-g920", // Galaxy S6 |
74 "sm-g925", // Galaxy S6 Edge | 67 "sm-g925", // Galaxy S6 Edge |
75 "404sc", // Galaxy S6 Edge | 68 "404sc", // Galaxy S6 Edge |
76 "scv31", // Galaxy S6 Edge | 69 "scv31", // Galaxy S6 Edge |
77 "sm-g890", // Galaxy S6 Active | 70 "sm-g890", // Galaxy S6 Active |
78 "sm-g800", // Galaxy S5 mini | 71 "sm-g800", // Galaxy S5 mini |
79 "sm-g860", // Galaxy S5 K Sport | 72 "sm-g860", // Galaxy S5 K Sport |
80 "sm-g870", // Galaxy S5 Active | 73 "sm-g870", // Galaxy S5 Active |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
205 | 198 |
206 /** | 199 /** |
207 * Gets the default search provider's logo and calls logoObserver with t he result. | 200 * Gets the default search provider's logo and calls logoObserver with t he result. |
208 * @param logoObserver The callback to notify when the logo is available . | 201 * @param logoObserver The callback to notify when the logo is available . |
209 */ | 202 */ |
210 void getSearchProviderLogo(LogoObserver logoObserver); | 203 void getSearchProviderLogo(LogoObserver logoObserver); |
211 | 204 |
212 /** | 205 /** |
213 * Called when the NTP has completely finished loading (all views will b e inflated | 206 * Called when the NTP has completely finished loading (all views will b e inflated |
214 * and any dependent resources will have been loaded). | 207 * and any dependent resources will have been loaded). |
208 * @param mostVisitedItems The MostVisitedItem shown on the NTP. Used to record metrics. | |
215 */ | 209 */ |
216 void onLoadingComplete(); | 210 void onLoadingComplete(MostVisitedItem[] mostVisitedItems); |
217 } | 211 } |
218 | 212 |
219 /** | 213 /** |
220 * Returns a title suitable for display for a link (e.g. a most visited item ). If |title| is | 214 * Returns a title suitable for display for a link (e.g. a most visited item ). If |title| is |
221 * non-empty, this simply returns it. Otherwise, returns a shortened form of the URL. | 215 * non-empty, this simply returns it. Otherwise, returns a shortened form of the URL. |
222 */ | 216 */ |
223 static String getTitleForDisplay(String title, String url) { | 217 static String getTitleForDisplay(String title, String url) { |
224 if (TextUtils.isEmpty(title) && url != null) { | 218 if (TextUtils.isEmpty(title) && url != null) { |
225 Uri uri = Uri.parse(url); | 219 Uri uri = Uri.parse(url); |
226 String host = uri.getHost(); | 220 String host = uri.getHost(); |
227 String path = uri.getPath(); | 221 String path = uri.getPath(); |
228 if (host == null) host = ""; | 222 if (host == null) host = ""; |
229 if (TextUtils.isEmpty(path) || path.equals("/")) path = ""; | 223 if (TextUtils.isEmpty(path) || path.equals("/")) path = ""; |
230 title = host + path; | 224 title = host + path; |
231 } | 225 } |
232 return title; | 226 return title; |
233 } | 227 } |
234 | 228 |
235 /** | 229 /** |
236 * Default constructor required for XML inflation. | 230 * Default constructor required for XML inflation. |
237 */ | 231 */ |
238 public NewTabPageView(Context context, AttributeSet attrs) { | 232 public NewTabPageView(Context context, AttributeSet attrs) { |
239 super(context, attrs); | 233 super(context, attrs); |
240 } | 234 } |
241 | 235 |
242 private boolean isIconNtpEnabled() { | |
243 // Query the field trial state first, to ensure that UMA reports the cor rect group. | |
244 String fieldTrialGroup = FieldTrialList.findFullName(ICON_NTP_FIELD_TRIA L_NAME); | |
245 CommandLine commandLine = CommandLine.getInstance(); | |
246 if (commandLine.hasSwitch(ChromeSwitches.DISABLE_ICON_NTP)) return false ; | |
247 if (commandLine.hasSwitch(ChromeSwitches.ENABLE_ICON_NTP)) return true; | |
248 return fieldTrialGroup.equals(ICON_NTP_ENABLED_GROUP); | |
249 } | |
250 | |
251 /** | 236 /** |
252 * Initializes the NTP. This must be called immediately after inflation, bef ore this object is | 237 * Initializes the NTP. This must be called immediately after inflation, bef ore this object is |
253 * used in any other way. | 238 * used in any other way. |
254 * | 239 * |
255 * @param manager NewTabPageManager used to perform various actions when the user interacts | 240 * @param manager NewTabPageManager used to perform various actions when the user interacts |
256 * with the page. | 241 * with the page. |
257 * @param isSingleUrlBarMode Whether the NTP is in single URL bar mode. | 242 * @param isSingleUrlBarMode Whether the NTP is in single URL bar mode. |
258 * @param searchProviderHasLogo Whether the search provider has a logo. | 243 * @param searchProviderHasLogo Whether the search provider has a logo. |
244 * @param isIconMode Whether to show the icon-based design, as opposed to th e thumbnail design. | |
259 */ | 245 */ |
260 public void initialize(NewTabPageManager manager, boolean isSingleUrlBarMode , | 246 public void initialize(NewTabPageManager manager, boolean isSingleUrlBarMode , |
261 boolean searchProviderHasLogo) { | 247 boolean searchProviderHasLogo, boolean isIconMode) { |
262 mManager = manager; | 248 mManager = manager; |
263 | 249 |
264 mScrollView = (NewTabScrollView) findViewById(R.id.ntp_scrollview); | 250 mScrollView = (NewTabScrollView) findViewById(R.id.ntp_scrollview); |
265 mScrollView.enableBottomShadow(SHADOW_COLOR); | 251 mScrollView.enableBottomShadow(SHADOW_COLOR); |
266 mContentView = (ViewGroup) findViewById(R.id.ntp_content); | 252 mContentView = (ViewGroup) findViewById(R.id.ntp_content); |
267 | 253 |
268 mMostVisitedDesign = isIconNtpEnabled() | 254 mMostVisitedDesign = isIconMode |
269 ? new IconMostVisitedDesign(getContext()) | 255 ? new IconMostVisitedDesign(getContext()) |
270 : new ThumbnailMostVisitedDesign(getContext()); | 256 : new ThumbnailMostVisitedDesign(getContext()); |
271 ViewStub mostVisitedLayoutStub = (ViewStub) findViewById(R.id.most_visit ed_layout_stub); | 257 ViewStub mostVisitedLayoutStub = (ViewStub) findViewById(R.id.most_visit ed_layout_stub); |
272 mostVisitedLayoutStub.setLayoutResource(mMostVisitedDesign.getMostVisite dLayoutId()); | 258 mostVisitedLayoutStub.setLayoutResource(mMostVisitedDesign.getMostVisite dLayoutId()); |
273 mMostVisitedLayout = (ViewGroup) mostVisitedLayoutStub.inflate(); | 259 mMostVisitedLayout = (ViewGroup) mostVisitedLayoutStub.inflate(); |
274 mMostVisitedDesign.initMostVisitedLayout(mMostVisitedLayout, searchProvi derHasLogo); | 260 mMostVisitedDesign.initMostVisitedLayout(mMostVisitedLayout, searchProvi derHasLogo); |
275 | 261 |
276 mSearchProviderLogoView = (LogoView) findViewById(R.id.search_provider_l ogo); | 262 mSearchProviderLogoView = (LogoView) findViewById(R.id.search_provider_l ogo); |
277 mSearchBoxView = findViewById(R.id.search_box); | 263 mSearchBoxView = findViewById(R.id.search_box); |
278 mNoSearchLogoSpacer = findViewById(R.id.no_search_logo_spacer); | 264 mNoSearchLogoSpacer = findViewById(R.id.no_search_logo_spacer); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
467 * is complete. | 453 * is complete. |
468 */ | 454 */ |
469 private void loadTaskCompleted() { | 455 private void loadTaskCompleted() { |
470 assert mPendingLoadTasks > 0; | 456 assert mPendingLoadTasks > 0; |
471 mPendingLoadTasks--; | 457 mPendingLoadTasks--; |
472 if (mPendingLoadTasks == 0) { | 458 if (mPendingLoadTasks == 0) { |
473 if (mLoadHasCompleted) { | 459 if (mLoadHasCompleted) { |
474 assert false; | 460 assert false; |
475 } else { | 461 } else { |
476 mLoadHasCompleted = true; | 462 mLoadHasCompleted = true; |
477 mManager.onLoadingComplete(); | 463 mManager.onLoadingComplete(mMostVisitedItems); |
478 mMostVisitedDesign.onLoadingComplete(); | |
479 // Load the logo after everything else is finished, since it's l ower priority. | 464 // Load the logo after everything else is finished, since it's l ower priority. |
480 loadSearchProviderLogo(); | 465 loadSearchProviderLogo(); |
481 } | 466 } |
482 } | 467 } |
483 } | 468 } |
484 | 469 |
485 /** | 470 /** |
486 * Loads the search provider logo (e.g. Google doodle), if any. | 471 * Loads the search provider logo (e.g. Google doodle), if any. |
487 */ | 472 */ |
488 private void loadSearchProviderLogo() { | 473 private void loadSearchProviderLogo() { |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
749 item = oldItem; | 734 item = oldItem; |
750 item.setIndex(i); | 735 item.setIndex(i); |
751 oldItems[j] = null; | 736 oldItems[j] = null; |
752 break; | 737 break; |
753 } | 738 } |
754 } | 739 } |
755 | 740 |
756 // If nothing can be reused, create a new item. | 741 // If nothing can be reused, create a new item. |
757 if (item == null) { | 742 if (item == null) { |
758 String displayTitle = getTitleForDisplay(title, url); | 743 String displayTitle = getTitleForDisplay(title, url); |
744 item = new MostVisitedItem(mManager, title, url, i); | |
759 View view = mMostVisitedDesign.createMostVisitedItemView(inflate r, url, title, | 745 View view = mMostVisitedDesign.createMostVisitedItemView(inflate r, url, title, |
760 displayTitle, i, isInitialLoad); | 746 displayTitle, item, isInitialLoad); |
761 item = new MostVisitedItem(mManager, title, url, i, view); | 747 item.initView(view); |
762 } | 748 } |
763 | 749 |
764 mMostVisitedItems[i] = item; | 750 mMostVisitedItems[i] = item; |
765 mMostVisitedLayout.addView(item.getView()); | 751 mMostVisitedLayout.addView(item.getView()); |
766 } | 752 } |
767 | 753 |
768 mHasReceivedMostVisitedSites = true; | 754 mHasReceivedMostVisitedSites = true; |
769 updateMostVisitedPlaceholderVisibility(); | 755 updateMostVisitedPlaceholderVisibility(); |
770 | 756 |
771 if (isInitialLoad) { | 757 if (isInitialLoad) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
829 * Interface for creating the most visited layout and tiles. | 815 * Interface for creating the most visited layout and tiles. |
830 * TODO(newt): delete this once a single design has been chosen. | 816 * TODO(newt): delete this once a single design has been chosen. |
831 */ | 817 */ |
832 private interface MostVisitedDesign { | 818 private interface MostVisitedDesign { |
833 int getNumberOfTiles(boolean searchProviderHasLogo); | 819 int getNumberOfTiles(boolean searchProviderHasLogo); |
834 int getMostVisitedLayoutId(); | 820 int getMostVisitedLayoutId(); |
835 int getMostVisitedLayoutBleed(); | 821 int getMostVisitedLayoutBleed(); |
836 void initMostVisitedLayout(ViewGroup mostVisitedLayout, boolean searchPr oviderHasLogo); | 822 void initMostVisitedLayout(ViewGroup mostVisitedLayout, boolean searchPr oviderHasLogo); |
837 void setSearchProviderHasLogo(View mostVisitedLayout, boolean hasLogo); | 823 void setSearchProviderHasLogo(View mostVisitedLayout, boolean hasLogo); |
838 View createMostVisitedItemView(LayoutInflater inflater, String url, Stri ng title, | 824 View createMostVisitedItemView(LayoutInflater inflater, String url, Stri ng title, |
839 String displayTitle, int index, boolean isInitialLoad); | 825 String displayTitle, MostVisitedItem item, boolean isInitialLoad ); |
840 void onFaviconUpdated(String url); | 826 void onFaviconUpdated(String url); |
841 void onLoadingComplete(); | |
842 } | 827 } |
843 | 828 |
844 /** | 829 /** |
845 * The old most visited design, where each tile shows a thumbnail of the pag e, a small favicon, | 830 * The old most visited design, where each tile shows a thumbnail of the pag e, a small favicon, |
846 * and the title. | 831 * and the title. |
847 */ | 832 */ |
848 private class ThumbnailMostVisitedDesign implements MostVisitedDesign { | 833 private class ThumbnailMostVisitedDesign implements MostVisitedDesign { |
849 | 834 |
850 private static final int NUM_TILES = 6; | 835 private static final int NUM_TILES = 6; |
851 private static final int FAVICON_CORNER_RADIUS_DP = 2; | 836 private static final int FAVICON_CORNER_RADIUS_DP = 2; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
883 @Override | 868 @Override |
884 public void initMostVisitedLayout(ViewGroup mostVisitedLayout, | 869 public void initMostVisitedLayout(ViewGroup mostVisitedLayout, |
885 boolean searchProviderHasLogo) { | 870 boolean searchProviderHasLogo) { |
886 } | 871 } |
887 | 872 |
888 @Override | 873 @Override |
889 public void setSearchProviderHasLogo(View mostVisitedLayout, boolean has Logo) {} | 874 public void setSearchProviderHasLogo(View mostVisitedLayout, boolean has Logo) {} |
890 | 875 |
891 @Override | 876 @Override |
892 public View createMostVisitedItemView(LayoutInflater inflater, final Str ing url, | 877 public View createMostVisitedItemView(LayoutInflater inflater, final Str ing url, |
893 String title, String displayTitle, int index, final boolean isIn itialLoad) { | 878 String title, String displayTitle, final MostVisitedItem item, |
879 final boolean isInitialLoad) { | |
894 final MostVisitedItemView view = (MostVisitedItemView) inflater.infl ate( | 880 final MostVisitedItemView view = (MostVisitedItemView) inflater.infl ate( |
895 R.layout.most_visited_item, mMostVisitedLayout, false); | 881 R.layout.most_visited_item, mMostVisitedLayout, false); |
896 view.init(displayTitle); | 882 view.init(displayTitle); |
897 | 883 |
898 ThumbnailCallback thumbnailCallback = new ThumbnailCallback() { | 884 ThumbnailCallback thumbnailCallback = new ThumbnailCallback() { |
899 @Override | 885 @Override |
900 public void onMostVisitedURLsThumbnailAvailable(Bitmap thumbnail ) { | 886 public void onMostVisitedURLsThumbnailAvailable(Bitmap thumbnail , |
887 boolean isLocalThumbnail) { | |
901 view.setThumbnail(thumbnail); | 888 view.setThumbnail(thumbnail); |
889 if (thumbnail == null) { | |
890 item.setTileType(MostVisitedTileType.THUMBNAIL_DEFAULT); | |
891 } else if (isLocalThumbnail) { | |
892 item.setTileType(MostVisitedTileType.THUMBNAIL_LOCAL); | |
893 } else { | |
894 item.setTileType(MostVisitedTileType.THUMBNAIL_SERVER); | |
895 } | |
902 mSnapshotMostVisitedChanged = true; | 896 mSnapshotMostVisitedChanged = true; |
903 if (isInitialLoad) loadTaskCompleted(); | 897 if (isInitialLoad) loadTaskCompleted(); |
904 } | 898 } |
905 }; | 899 }; |
906 if (isInitialLoad) mPendingLoadTasks++; | 900 if (isInitialLoad) mPendingLoadTasks++; |
907 mManager.getURLThumbnail(url, thumbnailCallback); | 901 mManager.getURLThumbnail(url, thumbnailCallback); |
908 | 902 |
909 FaviconImageCallback faviconCallback = new FaviconImageCallback() { | 903 FaviconImageCallback faviconCallback = new FaviconImageCallback() { |
910 @Override | 904 @Override |
911 public void onFaviconAvailable(Bitmap image, String iconUrl) { | 905 public void onFaviconAvailable(Bitmap image, String iconUrl) { |
(...skipping 25 matching lines...) Expand all Loading... | |
937 image = mFaviconGenerator.generateIconForUrl(url); | 931 image = mFaviconGenerator.generateIconForUrl(url); |
938 } | 932 } |
939 view.setFavicon(image); | 933 view.setFavicon(image); |
940 mSnapshotMostVisitedChanged = true; | 934 mSnapshotMostVisitedChanged = true; |
941 } | 935 } |
942 }; | 936 }; |
943 mManager.getLocalFaviconImageForURL(url, mDesiredFaviconSize, fa viconCallback); | 937 mManager.getLocalFaviconImageForURL(url, mDesiredFaviconSize, fa viconCallback); |
944 break; | 938 break; |
945 } | 939 } |
946 } | 940 } |
947 | |
948 @Override | |
949 public void onLoadingComplete() {} | |
950 } | 941 } |
951 | 942 |
952 /** | 943 /** |
953 * The new-fangled design for most visited tiles, where each tile shows a la rge icon and title. | 944 * The new-fangled design for most visited tiles, where each tile shows a la rge icon and title. |
954 */ | 945 */ |
955 private class IconMostVisitedDesign implements MostVisitedDesign { | 946 private class IconMostVisitedDesign implements MostVisitedDesign { |
956 | 947 |
957 private static final int NUM_TILES = 8; | 948 private static final int NUM_TILES = 8; |
958 private static final int NUM_TILES_NO_LOGO = 12; | 949 private static final int NUM_TILES_NO_LOGO = 12; |
959 private static final int MAX_ROWS = 2; | 950 private static final int MAX_ROWS = 2; |
960 private static final int MAX_ROWS_NO_LOGO = 3; | 951 private static final int MAX_ROWS_NO_LOGO = 3; |
961 | 952 |
962 private static final int ICON_CORNER_RADIUS_DP = 4; | 953 private static final int ICON_CORNER_RADIUS_DP = 4; |
963 private static final int ICON_TEXT_SIZE_DP = 20; | 954 private static final int ICON_TEXT_SIZE_DP = 20; |
964 private static final int ICON_BACKGROUND_COLOR = 0xff787878; | 955 private static final int ICON_BACKGROUND_COLOR = 0xff787878; |
965 private static final int ICON_MIN_SIZE_PX = 48; | 956 private static final int ICON_MIN_SIZE_PX = 48; |
966 | 957 |
967 private int mMostVisitedLayoutBleed; | 958 private int mMostVisitedLayoutBleed; |
968 private int mMinIconSize; | 959 private int mMinIconSize; |
969 private int mDesiredIconSize; | 960 private int mDesiredIconSize; |
970 private RoundedIconGenerator mIconGenerator; | 961 private RoundedIconGenerator mIconGenerator; |
971 | 962 |
972 private int mNumGrayIcons; | |
973 private int mNumColorIcons; | |
974 private int mNumRealIcons; | |
975 | |
976 IconMostVisitedDesign(Context context) { | 963 IconMostVisitedDesign(Context context) { |
977 Resources res = context.getResources(); | 964 Resources res = context.getResources(); |
978 mMostVisitedLayoutBleed = res.getDimensionPixelSize( | 965 mMostVisitedLayoutBleed = res.getDimensionPixelSize( |
979 R.dimen.icon_most_visited_layout_bleed); | 966 R.dimen.icon_most_visited_layout_bleed); |
980 mDesiredIconSize = res.getDimensionPixelSize(R.dimen.icon_most_visit ed_icon_size); | 967 mDesiredIconSize = res.getDimensionPixelSize(R.dimen.icon_most_visit ed_icon_size); |
981 // On ldpi devices, mDesiredIconSize could be even smaller than ICON _MIN_SIZE_PX. | 968 // On ldpi devices, mDesiredIconSize could be even smaller than ICON _MIN_SIZE_PX. |
982 mMinIconSize = Math.min(mDesiredIconSize, ICON_MIN_SIZE_PX); | 969 mMinIconSize = Math.min(mDesiredIconSize, ICON_MIN_SIZE_PX); |
983 int desiredIconSizeDp = Math.round( | 970 int desiredIconSizeDp = Math.round( |
984 mDesiredIconSize / res.getDisplayMetrics().density); | 971 mDesiredIconSize / res.getDisplayMetrics().density); |
985 mIconGenerator = new RoundedIconGenerator( | 972 mIconGenerator = new RoundedIconGenerator( |
(...skipping 25 matching lines...) Expand all Loading... | |
1011 | 998 |
1012 @Override | 999 @Override |
1013 public void setSearchProviderHasLogo(View mostVisitedLayout, boolean has Logo) { | 1000 public void setSearchProviderHasLogo(View mostVisitedLayout, boolean has Logo) { |
1014 int paddingTop = getResources().getDimensionPixelSize(hasLogo | 1001 int paddingTop = getResources().getDimensionPixelSize(hasLogo |
1015 ? R.dimen.icon_most_visited_layout_padding_top | 1002 ? R.dimen.icon_most_visited_layout_padding_top |
1016 : R.dimen.icon_most_visited_layout_no_logo_padding_top); | 1003 : R.dimen.icon_most_visited_layout_no_logo_padding_top); |
1017 mostVisitedLayout.setPadding(0, paddingTop, 0, 0); | 1004 mostVisitedLayout.setPadding(0, paddingTop, 0, 0); |
1018 } | 1005 } |
1019 | 1006 |
1020 class LargeIconCallbackImpl implements LargeIconCallback { | 1007 class LargeIconCallbackImpl implements LargeIconCallback { |
1021 private String mUrl; | 1008 private MostVisitedItem mItem; |
1022 private IconMostVisitedItemView mView; | |
1023 private boolean mIsInitialLoad; | 1009 private boolean mIsInitialLoad; |
1024 | 1010 |
1025 public LargeIconCallbackImpl(String url, IconMostVisitedItemView vie w, | 1011 public LargeIconCallbackImpl(MostVisitedItem item, boolean isInitial Load) { |
1026 boolean isInitialLoad) { | 1012 mItem = item; |
1027 mUrl = url; | |
1028 mView = view; | |
1029 mIsInitialLoad = isInitialLoad; | 1013 mIsInitialLoad = isInitialLoad; |
1030 } | 1014 } |
1031 | 1015 |
1032 @Override | 1016 @Override |
1033 public void onLargeIconAvailable(Bitmap icon, int fallbackColor) { | 1017 public void onLargeIconAvailable(Bitmap icon, int fallbackColor) { |
1018 IconMostVisitedItemView view = (IconMostVisitedItemView) mItem.g etView(); | |
1034 if (icon == null) { | 1019 if (icon == null) { |
1035 mIconGenerator.setBackgroundColor(fallbackColor); | 1020 mIconGenerator.setBackgroundColor(fallbackColor); |
1036 icon = mIconGenerator.generateIconForUrl(mUrl); | 1021 icon = mIconGenerator.generateIconForUrl(mItem.getUrl()); |
1037 mView.setIcon(new BitmapDrawable(getResources(), icon)); | 1022 view.setIcon(new BitmapDrawable(getResources(), icon)); |
1038 if (mIsInitialLoad) { | 1023 mItem.setTileType(fallbackColor == ICON_BACKGROUND_COLOR |
1039 if (fallbackColor == ICON_BACKGROUND_COLOR) { | 1024 ? MostVisitedTileType.ICON_DEFAULT : MostVisitedTile Type.ICON_COLOR); |
1040 mNumGrayIcons++; | |
1041 } else { | |
1042 mNumColorIcons++; | |
1043 } | |
1044 } | |
1045 } else { | 1025 } else { |
1046 RoundedBitmapDrawable roundedIcon = RoundedBitmapDrawableFac tory.create( | 1026 RoundedBitmapDrawable roundedIcon = RoundedBitmapDrawableFac tory.create( |
1047 getResources(), icon); | 1027 getResources(), icon); |
1048 int cornerRadius = Math.round(ICON_CORNER_RADIUS_DP | 1028 int cornerRadius = Math.round(ICON_CORNER_RADIUS_DP |
1049 * getResources().getDisplayMetrics().density * icon. getWidth() | 1029 * getResources().getDisplayMetrics().density * icon. getWidth() |
1050 / mDesiredIconSize); | 1030 / mDesiredIconSize); |
1051 roundedIcon.setCornerRadius(cornerRadius); | 1031 roundedIcon.setCornerRadius(cornerRadius); |
1052 roundedIcon.setAntiAlias(true); | 1032 roundedIcon.setAntiAlias(true); |
1053 roundedIcon.setFilterBitmap(true); | 1033 roundedIcon.setFilterBitmap(true); |
1054 mView.setIcon(roundedIcon); | 1034 view.setIcon(roundedIcon); |
1055 if (mIsInitialLoad) mNumRealIcons++; | 1035 mItem.setTileType(MostVisitedTileType.ICON_REAL); |
1056 } | 1036 } |
1057 mSnapshotMostVisitedChanged = true; | 1037 mSnapshotMostVisitedChanged = true; |
1058 if (mIsInitialLoad) loadTaskCompleted(); | 1038 if (mIsInitialLoad) loadTaskCompleted(); |
1059 } | 1039 } |
1060 }; | 1040 } |
1061 | 1041 |
1062 @Override | 1042 @Override |
1063 public View createMostVisitedItemView(LayoutInflater inflater, final Str ing url, | 1043 public View createMostVisitedItemView(LayoutInflater inflater, final Str ing url, |
1064 String title, String displayTitle, int index, final boolean isIn itialLoad) { | 1044 String title, String displayTitle, MostVisitedItem item, |
1045 final boolean isInitialLoad) { | |
1065 final IconMostVisitedItemView view = (IconMostVisitedItemView) infla ter.inflate( | 1046 final IconMostVisitedItemView view = (IconMostVisitedItemView) infla ter.inflate( |
1066 R.layout.icon_most_visited_item, mMostVisitedLayout, false); | 1047 R.layout.icon_most_visited_item, mMostVisitedLayout, false); |
1067 view.setTitle(displayTitle); | 1048 view.setTitle(displayTitle); |
1068 | 1049 |
1069 LargeIconCallback iconCallback = new LargeIconCallbackImpl(url, view , isInitialLoad); | 1050 LargeIconCallback iconCallback = new LargeIconCallbackImpl(item, isI nitialLoad); |
1070 if (isInitialLoad) mPendingLoadTasks++; | 1051 if (isInitialLoad) mPendingLoadTasks++; |
1071 mManager.getLargeIconForUrl(url, mMinIconSize, iconCallback); | 1052 mManager.getLargeIconForUrl(url, mMinIconSize, iconCallback); |
1072 | 1053 |
1073 return view; | 1054 return view; |
1074 } | 1055 } |
1075 | 1056 |
1076 @Override | 1057 @Override |
1077 public void onFaviconUpdated(final String url) { | 1058 public void onFaviconUpdated(final String url) { |
1078 // Find a matching most visited item. | 1059 // Find a matching most visited item. |
1079 for (MostVisitedItem item : mMostVisitedItems) { | 1060 for (MostVisitedItem item : mMostVisitedItems) { |
1080 if (!item.getUrl().equals(url)) continue; | 1061 if (item.getUrl().equals(url)) { |
1081 | 1062 LargeIconCallback iconCallback = new LargeIconCallbackImpl(i tem, false); |
1082 final IconMostVisitedItemView view = (IconMostVisitedItemView) i tem.getView(); | 1063 mManager.getLargeIconForUrl(url, mMinIconSize, iconCallback) ; |
1083 LargeIconCallback iconCallback = new LargeIconCallbackImpl(url, view, false); | 1064 break; |
1084 mManager.getLargeIconForUrl(url, mMinIconSize, iconCallback); | 1065 } |
1085 break; | |
1086 } | 1066 } |
1087 } | 1067 } |
1088 | |
1089 @Override | |
1090 public void onLoadingComplete() { | |
1091 RecordHistogram.recordCount100Histogram("NewTabPage.IconsGray", mNum GrayIcons); | |
newt (away)
2015/09/28 22:34:21
these metrics are now recorded in most_visited_sit
| |
1092 RecordHistogram.recordCount100Histogram("NewTabPage.IconsColor", mNu mColorIcons); | |
1093 RecordHistogram.recordCount100Histogram("NewTabPage.IconsReal", mNum RealIcons); | |
1094 } | |
1095 } | 1068 } |
1096 } | 1069 } |
OLD | NEW |