Chromium Code Reviews| 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 |