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 |