| 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.app.Activity; | 7 import android.app.Activity; |
| 8 import android.app.Dialog; | 8 import android.app.Dialog; |
| 9 import android.content.Context; | 9 import android.content.Context; |
| 10 import android.graphics.Bitmap; | 10 import android.graphics.Bitmap; |
| 11 import android.graphics.Canvas; | 11 import android.graphics.Canvas; |
| 12 import android.graphics.Rect; | 12 import android.graphics.Rect; |
| 13 import android.view.ContextMenu; | 13 import android.view.ContextMenu; |
| 14 import android.view.LayoutInflater; | 14 import android.view.LayoutInflater; |
| 15 import android.view.Menu; | 15 import android.view.Menu; |
| 16 import android.view.MenuItem.OnMenuItemClickListener; | 16 import android.view.MenuItem.OnMenuItemClickListener; |
| 17 import android.view.View; | 17 import android.view.View; |
| 18 | 18 |
| 19 import org.chromium.base.ApiCompatibilityUtils; | 19 import org.chromium.base.ApiCompatibilityUtils; |
| 20 import org.chromium.base.CommandLine; |
| 21 import org.chromium.base.FieldTrialList; |
| 20 import org.chromium.base.VisibleForTesting; | 22 import org.chromium.base.VisibleForTesting; |
| 21 import org.chromium.base.metrics.RecordHistogram; | 23 import org.chromium.base.metrics.RecordHistogram; |
| 22 import org.chromium.base.metrics.RecordUserAction; | 24 import org.chromium.base.metrics.RecordUserAction; |
| 23 import org.chromium.chrome.R; | 25 import org.chromium.chrome.R; |
| 26 import org.chromium.chrome.browser.ChromeSwitches; |
| 24 import org.chromium.chrome.browser.NativePage; | 27 import org.chromium.chrome.browser.NativePage; |
| 25 import org.chromium.chrome.browser.UrlConstants; | 28 import org.chromium.chrome.browser.UrlConstants; |
| 26 import org.chromium.chrome.browser.compositor.layouts.content.InvalidationAwareT
humbnailProvider; | 29 import org.chromium.chrome.browser.compositor.layouts.content.InvalidationAwareT
humbnailProvider; |
| 27 import org.chromium.chrome.browser.document.DocumentMetricIds; | 30 import org.chromium.chrome.browser.document.DocumentMetricIds; |
| 28 import org.chromium.chrome.browser.enhancedbookmarks.EnhancedBookmarkUtils; | 31 import org.chromium.chrome.browser.enhancedbookmarks.EnhancedBookmarkUtils; |
| 29 import org.chromium.chrome.browser.favicon.FaviconHelper; | 32 import org.chromium.chrome.browser.favicon.FaviconHelper; |
| 30 import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconAvailabilityCall
back; | 33 import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconAvailabilityCall
back; |
| 31 import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback; | 34 import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback; |
| 32 import org.chromium.chrome.browser.favicon.LargeIconBridge; | 35 import org.chromium.chrome.browser.favicon.LargeIconBridge; |
| 33 import org.chromium.chrome.browser.favicon.LargeIconBridge.LargeIconCallback; | 36 import org.chromium.chrome.browser.favicon.LargeIconBridge.LargeIconCallback; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 56 import java.util.concurrent.TimeUnit; | 59 import java.util.concurrent.TimeUnit; |
| 57 | 60 |
| 58 import jp.tomorrowkey.android.gifplayer.BaseGifImage; | 61 import jp.tomorrowkey.android.gifplayer.BaseGifImage; |
| 59 | 62 |
| 60 /** | 63 /** |
| 61 * Provides functionality when the user interacts with the NTP. | 64 * Provides functionality when the user interacts with the NTP. |
| 62 */ | 65 */ |
| 63 public class NewTabPage | 66 public class NewTabPage |
| 64 implements NativePage, InvalidationAwareThumbnailProvider, TemplateUrlSe
rviceObserver { | 67 implements NativePage, InvalidationAwareThumbnailProvider, TemplateUrlSe
rviceObserver { |
| 65 | 68 |
| 66 // The number of times that an opt-out promo will be shown. | 69 private static final String ICON_NTP_FIELD_TRIAL_NAME = "IconNTP"; |
| 70 private static final String ICON_NTP_ENABLED_PREFIX = "Enabled"; |
| 71 |
| 72 // The number of times that the document-mode opt-out promo will be shown. |
| 67 private static final int MAX_OPT_OUT_PROMO_COUNT = 10; | 73 private static final int MAX_OPT_OUT_PROMO_COUNT = 10; |
| 68 | 74 |
| 69 // MostVisitedItem Context menu item IDs. | 75 // MostVisitedItem Context menu item IDs. |
| 70 static final int ID_OPEN_IN_NEW_TAB = 0; | 76 static final int ID_OPEN_IN_NEW_TAB = 0; |
| 71 static final int ID_OPEN_IN_INCOGNITO_TAB = 1; | 77 static final int ID_OPEN_IN_INCOGNITO_TAB = 1; |
| 72 static final int ID_REMOVE = 2; | 78 static final int ID_REMOVE = 2; |
| 73 | 79 |
| 74 private static MostVisitedSites sMostVisitedSitesForTests; | 80 private static MostVisitedSites sMostVisitedSitesForTests; |
| 75 | 81 |
| 76 private final Tab mTab; | 82 private final Tab mTab; |
| 77 private final TabModelSelector mTabModelSelector; | 83 private final TabModelSelector mTabModelSelector; |
| 78 private final Activity mActivity; | 84 private final Activity mActivity; |
| 79 | 85 |
| 80 private final Profile mProfile; | 86 private final Profile mProfile; |
| 81 private final String mTitle; | 87 private final String mTitle; |
| 82 private final int mBackgroundColor; | 88 private final int mBackgroundColor; |
| 83 private final NewTabPageView mNewTabPageView; | 89 private final NewTabPageView mNewTabPageView; |
| 84 | 90 |
| 85 private MostVisitedSites mMostVisitedSites; | 91 private MostVisitedSites mMostVisitedSites; |
| 86 private FaviconHelper mFaviconHelper; | 92 private FaviconHelper mFaviconHelper; |
| 87 private LargeIconBridge mLargeIconBridge; | 93 private LargeIconBridge mLargeIconBridge; |
| 88 private LogoBridge mLogoBridge; | 94 private LogoBridge mLogoBridge; |
| 89 private boolean mSearchProviderHasLogo; | 95 private boolean mSearchProviderHasLogo; |
| 96 private boolean mIsIconMode; |
| 90 private final boolean mOptOutPromoShown; | 97 private final boolean mOptOutPromoShown; |
| 91 private String mOnLogoClickUrl; | 98 private String mOnLogoClickUrl; |
| 92 private String mAnimatedLogoUrl; | 99 private String mAnimatedLogoUrl; |
| 93 private FakeboxDelegate mFakeboxDelegate; | 100 private FakeboxDelegate mFakeboxDelegate; |
| 94 | 101 |
| 95 // The timestamp at which the constructor was called. | 102 // The timestamp at which the constructor was called. |
| 96 private final long mConstructedTimeNs; | 103 private final long mConstructedTimeNs; |
| 97 | 104 |
| 98 private boolean mIsLoaded; | 105 private boolean mIsLoaded; |
| 99 | 106 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 | 199 |
| 193 private void recordOpenedMostVisitedItem(MostVisitedItem item) { | 200 private void recordOpenedMostVisitedItem(MostVisitedItem item) { |
| 194 if (mIsDestroyed) return; | 201 if (mIsDestroyed) return; |
| 195 NewTabPageUma.recordAction(NewTabPageUma.ACTION_OPENED_MOST_VISITED_
ENTRY); | 202 NewTabPageUma.recordAction(NewTabPageUma.ACTION_OPENED_MOST_VISITED_
ENTRY); |
| 196 NewTabPageUma.recordExplicitUserNavigation( | 203 NewTabPageUma.recordExplicitUserNavigation( |
| 197 item.getUrl(), NewTabPageUma.RAPPOR_ACTION_VISITED_SUGGESTED
_TILE); | 204 item.getUrl(), NewTabPageUma.RAPPOR_ACTION_VISITED_SUGGESTED
_TILE); |
| 198 RecordHistogram.recordEnumeratedHistogram("NewTabPage.MostVisited",
item.getIndex(), | 205 RecordHistogram.recordEnumeratedHistogram("NewTabPage.MostVisited",
item.getIndex(), |
| 199 NewTabPageView.MAX_MOST_VISITED_SITES); | 206 NewTabPageView.MAX_MOST_VISITED_SITES); |
| 200 RecordHistogram.recordMediumTimesHistogram("NewTabPage.MostVisitedTi
me", | 207 RecordHistogram.recordMediumTimesHistogram("NewTabPage.MostVisitedTi
me", |
| 201 System.nanoTime() - mConstructedTimeNs, TimeUnit.NANOSECONDS
); | 208 System.nanoTime() - mConstructedTimeNs, TimeUnit.NANOSECONDS
); |
| 202 mMostVisitedSites.recordOpenedMostVisitedItem(item.getIndex()); | 209 mMostVisitedSites.recordOpenedMostVisitedItem(item.getIndex(), item.
getTileType()); |
| 203 } | 210 } |
| 204 | 211 |
| 205 private void recordDocumentOptOutPromoClick(int which) { | 212 private void recordDocumentOptOutPromoClick(int which) { |
| 206 RecordHistogram.recordEnumeratedHistogram("DocumentActivity.OptOutCl
ick", which, | 213 RecordHistogram.recordEnumeratedHistogram("DocumentActivity.OptOutCl
ick", which, |
| 207 DocumentMetricIds.OPT_OUT_CLICK_COUNT); | 214 DocumentMetricIds.OPT_OUT_CLICK_COUNT); |
| 208 } | 215 } |
| 209 | 216 |
| 210 @Override | 217 @Override |
| 211 public boolean shouldShowOptOutPromo() { | 218 public boolean shouldShowOptOutPromo() { |
| 212 if (!FeatureUtilities.isDocumentMode(mActivity)) return false; | 219 if (!FeatureUtilities.isDocumentMode(mActivity)) return false; |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 if (mIsDestroyed) return; | 385 if (mIsDestroyed) return; |
| 379 mOnLogoClickUrl = logo != null ? logo.onClickUrl : null; | 386 mOnLogoClickUrl = logo != null ? logo.onClickUrl : null; |
| 380 mAnimatedLogoUrl = logo != null ? logo.animatedLogoUrl : nul
l; | 387 mAnimatedLogoUrl = logo != null ? logo.animatedLogoUrl : nul
l; |
| 381 logoObserver.onLogoAvailable(logo, fromCache); | 388 logoObserver.onLogoAvailable(logo, fromCache); |
| 382 } | 389 } |
| 383 }; | 390 }; |
| 384 mLogoBridge.getCurrentLogo(wrapperCallback); | 391 mLogoBridge.getCurrentLogo(wrapperCallback); |
| 385 } | 392 } |
| 386 | 393 |
| 387 @Override | 394 @Override |
| 388 public void onLoadingComplete() { | 395 public void onLoadingComplete(MostVisitedItem[] items) { |
| 389 long loadTimeMs = (System.nanoTime() - mConstructedTimeNs) / 1000000
; | 396 long loadTimeMs = (System.nanoTime() - mConstructedTimeNs) / 1000000
; |
| 390 RecordHistogram.recordTimesHistogram( | 397 RecordHistogram.recordTimesHistogram( |
| 391 "Tab.NewTabOnload", loadTimeMs, TimeUnit.MILLISECONDS); | 398 "Tab.NewTabOnload", loadTimeMs, TimeUnit.MILLISECONDS); |
| 392 mIsLoaded = true; | 399 mIsLoaded = true; |
| 393 | 400 |
| 394 if (mIsDestroyed) return; | 401 if (mIsDestroyed) return; |
| 395 mMostVisitedSites.onLoadingComplete(); | 402 |
| 403 int tileTypes[] = new int[items.length]; |
| 404 for (int i = 0; i < items.length; i++) { |
| 405 tileTypes[i] = items[i].getTileType(); |
| 406 } |
| 407 mMostVisitedSites.recordTileTypeMetrics(tileTypes, mIsIconMode); |
| 396 } | 408 } |
| 397 }; | 409 }; |
| 398 | 410 |
| 399 /** | 411 /** |
| 400 * Constructs a NewTabPage. | 412 * Constructs a NewTabPage. |
| 401 * @param activity The activity used for context to create the new tab page'
s View. | 413 * @param activity The activity used for context to create the new tab page'
s View. |
| 402 * @param tab The Tab that is showing this new tab page. | 414 * @param tab The Tab that is showing this new tab page. |
| 403 * @param tabModelSelector The TabModelSelector used to open tabs. | 415 * @param tabModelSelector The TabModelSelector used to open tabs. |
| 404 */ | 416 */ |
| 405 public NewTabPage(Activity activity, Tab tab, TabModelSelector tabModelSelec
tor) { | 417 public NewTabPage(Activity activity, Tab tab, TabModelSelector tabModelSelec
tor) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 418 // because the user can dismiss the promo. To ensure the UI is consiste
nt, cache the | 430 // because the user can dismiss the promo. To ensure the UI is consiste
nt, cache the |
| 419 // value initially and ignore further updates. | 431 // value initially and ignore further updates. |
| 420 mOptOutPromoShown = mNewTabPageManager.shouldShowOptOutPromo(); | 432 mOptOutPromoShown = mNewTabPageManager.shouldShowOptOutPromo(); |
| 421 | 433 |
| 422 mMostVisitedSites = buildMostVisitedSites(mProfile); | 434 mMostVisitedSites = buildMostVisitedSites(mProfile); |
| 423 mLogoBridge = new LogoBridge(mProfile); | 435 mLogoBridge = new LogoBridge(mProfile); |
| 424 updateSearchProviderHasLogo(); | 436 updateSearchProviderHasLogo(); |
| 425 | 437 |
| 426 LayoutInflater inflater = LayoutInflater.from(activity); | 438 LayoutInflater inflater = LayoutInflater.from(activity); |
| 427 mNewTabPageView = (NewTabPageView) inflater.inflate(R.layout.new_tab_pag
e, null); | 439 mNewTabPageView = (NewTabPageView) inflater.inflate(R.layout.new_tab_pag
e, null); |
| 440 mIsIconMode = isIconNtpEnabled(); |
| 428 mNewTabPageView.initialize(mNewTabPageManager, isInSingleUrlBarMode(acti
vity), | 441 mNewTabPageView.initialize(mNewTabPageManager, isInSingleUrlBarMode(acti
vity), |
| 429 mSearchProviderHasLogo); | 442 mSearchProviderHasLogo, mIsIconMode); |
| 430 } | 443 } |
| 431 | 444 |
| 432 private static MostVisitedSites buildMostVisitedSites(Profile profile) { | 445 private static MostVisitedSites buildMostVisitedSites(Profile profile) { |
| 433 if (sMostVisitedSitesForTests != null) { | 446 if (sMostVisitedSitesForTests != null) { |
| 434 return sMostVisitedSitesForTests; | 447 return sMostVisitedSitesForTests; |
| 435 } else { | 448 } else { |
| 436 return new MostVisitedSites(profile); | 449 return new MostVisitedSites(profile); |
| 437 } | 450 } |
| 438 } | 451 } |
| 439 | 452 |
| 453 private boolean isIconNtpEnabled() { |
| 454 // Query the field trial state first, to ensure that UMA reports the cor
rect group. |
| 455 String fieldTrialGroup = FieldTrialList.findFullName(ICON_NTP_FIELD_TRIA
L_NAME); |
| 456 CommandLine commandLine = CommandLine.getInstance(); |
| 457 if (commandLine.hasSwitch(ChromeSwitches.DISABLE_ICON_NTP)) return false
; |
| 458 if (commandLine.hasSwitch(ChromeSwitches.ENABLE_ICON_NTP)) return true; |
| 459 return fieldTrialGroup.startsWith(ICON_NTP_ENABLED_PREFIX); |
| 460 } |
| 461 |
| 440 /** @return The view container for the new tab page. */ | 462 /** @return The view container for the new tab page. */ |
| 441 @VisibleForTesting | 463 @VisibleForTesting |
| 442 NewTabPageView getNewTabPageView() { | 464 NewTabPageView getNewTabPageView() { |
| 443 return mNewTabPageView; | 465 return mNewTabPageView; |
| 444 } | 466 } |
| 445 | 467 |
| 446 /** | 468 /** |
| 447 * Updates whether the NewTabPage should animate on URL focus changes. | 469 * Updates whether the NewTabPage should animate on URL focus changes. |
| 448 * @param disable Whether to disable the animations. | 470 * @param disable Whether to disable the animations. |
| 449 */ | 471 */ |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 public void onBookmarkSelected(String url, String title, Bitmap favicon)
{ | 641 public void onBookmarkSelected(String url, String title, Bitmap favicon)
{ |
| 620 if (mDialog != null) mDialog.dismiss(); | 642 if (mDialog != null) mDialog.dismiss(); |
| 621 mTab.loadUrl(new LoadUrlParams(url)); | 643 mTab.loadUrl(new LoadUrlParams(url)); |
| 622 } | 644 } |
| 623 | 645 |
| 624 public void setDialog(Dialog dialog) { | 646 public void setDialog(Dialog dialog) { |
| 625 mDialog = dialog; | 647 mDialog = dialog; |
| 626 } | 648 } |
| 627 } | 649 } |
| 628 } | 650 } |
| OLD | NEW |