Chromium Code Reviews| Index: chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java |
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java |
| index d2e96f466a649fb7e9ea91322cec15f2138344cc..532427c15a1e07fd4152709c6f1aea8c97e4a3b3 100644 |
| --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java |
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java |
| @@ -9,9 +9,7 @@ |
| import android.graphics.Canvas; |
| import android.graphics.Point; |
| import android.graphics.Rect; |
| -import android.net.Uri; |
| import android.os.Build; |
| -import android.os.SystemClock; |
| import android.support.v4.view.ViewCompat; |
| import android.support.v7.widget.RecyclerView; |
| import android.text.TextUtils; |
| @@ -19,12 +17,9 @@ |
| import android.view.View; |
| import org.chromium.base.ApiCompatibilityUtils; |
| -import org.chromium.base.Callback; |
| import org.chromium.base.CommandLine; |
| import org.chromium.base.ContextUtils; |
| import org.chromium.base.Log; |
| -import org.chromium.base.ObserverList; |
| -import org.chromium.base.ThreadUtils; |
| import org.chromium.base.VisibleForTesting; |
| import org.chromium.base.metrics.RecordHistogram; |
| import org.chromium.base.metrics.RecordUserAction; |
| @@ -34,28 +29,17 @@ |
| import org.chromium.chrome.browser.ChromeSwitches; |
| import org.chromium.chrome.browser.NativePage; |
| import org.chromium.chrome.browser.UrlConstants; |
| -import org.chromium.chrome.browser.bookmarks.BookmarkUtils; |
| import org.chromium.chrome.browser.compositor.layouts.content.InvalidationAwareThumbnailProvider; |
| import org.chromium.chrome.browser.download.DownloadManagerService; |
| -import org.chromium.chrome.browser.download.DownloadUtils; |
| import org.chromium.chrome.browser.favicon.FaviconHelper; |
| -import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback; |
| -import org.chromium.chrome.browser.favicon.FaviconHelper.IconAvailabilityCallback; |
| import org.chromium.chrome.browser.favicon.LargeIconBridge; |
| -import org.chromium.chrome.browser.favicon.LargeIconBridge.LargeIconCallback; |
| import org.chromium.chrome.browser.metrics.StartupMetrics; |
| -import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; |
| import org.chromium.chrome.browser.ntp.LogoBridge.Logo; |
| import org.chromium.chrome.browser.ntp.LogoBridge.LogoObserver; |
| import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager; |
| -import org.chromium.chrome.browser.ntp.snippets.KnownCategories; |
| -import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; |
| import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge; |
| import org.chromium.chrome.browser.ntp.snippets.SnippetsConfig; |
| import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; |
| -import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; |
| -import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; |
| -import org.chromium.chrome.browser.preferences.PrefServiceBridge; |
| import org.chromium.chrome.browser.profiles.MostVisitedSites; |
| import org.chromium.chrome.browser.profiles.MostVisitedSites.MostVisitedURLsObserver; |
| import org.chromium.chrome.browser.profiles.Profile; |
| @@ -64,27 +48,25 @@ |
| import org.chromium.chrome.browser.snackbar.Snackbar; |
| import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarController; |
| import org.chromium.chrome.browser.suggestions.SuggestionsMetricsReporter; |
| +import org.chromium.chrome.browser.suggestions.SuggestionsNavigationDelegate; |
| +import org.chromium.chrome.browser.suggestions.SuggestionsNavigationDelegateImpl; |
| +import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegateImpl; |
| import org.chromium.chrome.browser.sync.SyncSessionsMetrics; |
| import org.chromium.chrome.browser.tab.EmptyTabObserver; |
| import org.chromium.chrome.browser.tab.Tab; |
| import org.chromium.chrome.browser.tab.TabObserver; |
| import org.chromium.chrome.browser.tabmodel.TabModel; |
| -import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; |
| import org.chromium.chrome.browser.tabmodel.TabModelSelector; |
| import org.chromium.chrome.browser.tabmodel.TabModelUtils; |
| -import org.chromium.chrome.browser.tabmodel.document.TabDelegate; |
| import org.chromium.chrome.browser.util.UrlUtilities; |
| import org.chromium.content_public.browser.LoadUrlParams; |
| import org.chromium.content_public.browser.NavigationController; |
| import org.chromium.content_public.browser.NavigationEntry; |
| -import org.chromium.content_public.common.Referrer; |
| import org.chromium.net.NetworkChangeNotifier; |
| import org.chromium.ui.base.DeviceFormFactor; |
| import org.chromium.ui.base.PageTransition; |
| import org.chromium.ui.mojom.WindowOpenDisposition; |
| -import java.util.HashSet; |
| -import java.util.Set; |
| import java.util.concurrent.TimeUnit; |
| import jp.tomorrowkey.android.gifplayer.BaseGifImage; |
| @@ -109,9 +91,6 @@ |
| // Key for the scroll position data that may be stored in a navigation entry. |
| private static final String NAVIGATION_ENTRY_SCROLL_POSITION_KEY = "NewTabPageScrollPosition"; |
| - private static final String CHROME_CONTENT_SUGGESTIONS_REFERRER = |
| - "https://www.googleapis.com/auth/chrome-content-suggestions"; |
| - |
| private static MostVisitedSites sMostVisitedSitesForTests; |
| private static SuggestionsSource sSuggestionsSourceForTests; |
| @@ -119,11 +98,11 @@ |
| private final TabModelSelector mTabModelSelector; |
| private final ChromeActivity mActivity; |
| - private final Profile mProfile; |
| private final String mTitle; |
| private final int mBackgroundColor; |
| private final int mThemeColor; |
| private final NewTabPageView mNewTabPageView; |
| + private final NewTabPageManagerImpl mNewTabPageManager; |
| private TabObserver mTabObserver; |
| private MostVisitedSites mMostVisitedSites; |
| @@ -148,8 +127,6 @@ |
| // Whether destroy() has been called. |
| private boolean mIsDestroyed; |
| - private final ObserverList<DestructionObserver> mDestructionObservers = new ObserverList<>(); |
| - |
| /** |
| * Allows clients to listen for updates to the scroll changes of the search box on the |
| * NTP. |
| @@ -228,11 +205,16 @@ public static void setSuggestionsSourceForTests(SuggestionsSource suggestionsSou |
| sSuggestionsSourceForTests = suggestionsSource; |
| } |
| - private final NewTabPageManager mNewTabPageManager = new NewTabPageManager() { |
| - private static final String NTP_OFFLINE_PAGES_FEATURE_NAME = "NTPOfflinePages"; |
| + private class NewTabPageManagerImpl |
| + extends SuggestionsUiDelegateImpl implements NewTabPageManager { |
| + public NewTabPageManagerImpl(SuggestionsSource suggestionsSource, |
| + SuggestionsMetricsReporter metricsReporter, |
| + SuggestionsNavigationDelegate navigationDelegate, Profile profile, Tab currentTab) { |
| + super(suggestionsSource, metricsReporter, navigationDelegate, profile, currentTab); |
| + } |
| private boolean isNtpOfflinePagesEnabled() { |
| - return ChromeFeatureList.isEnabled(NTP_OFFLINE_PAGES_FEATURE_NAME); |
| + return ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_OFFLINE_PAGES_FEATURE_NAME); |
| } |
| @Override |
| @@ -281,7 +263,8 @@ public void openMostVisitedItem(int windowDisposition, MostVisitedItem item) { |
| return; |
| } |
| - openUrl(windowDisposition, new LoadUrlParams(url, PageTransition.AUTO_BOOKMARK)); |
| + getNavigationDelegate().openUrl( |
| + windowDisposition, new LoadUrlParams(url, PageTransition.AUTO_BOOKMARK)); |
| } |
| @Override |
| @@ -290,16 +273,6 @@ public void removeMostVisitedItem(MostVisitedItem item) { |
| showMostVisitedItemRemovedSnackbar(item.getUrl()); |
| } |
| - @Override |
| - public void onLearnMoreClicked() { |
| - if (mIsDestroyed) return; |
| - NewTabPageUma.recordAction(NewTabPageUma.ACTION_CLICKED_LEARN_MORE); |
| - String url = "https://support.google.com/chrome/?p=new_tab"; |
| - // TODO(mastiz): Change this to LINK? |
| - openUrl(WindowOpenDisposition.CURRENT_TAB, |
| - new LoadUrlParams(url, PageTransition.AUTO_BOOKMARK)); |
| - } |
| - |
| @TargetApi(Build.VERSION_CODES.LOLLIPOP) |
| private boolean switchToExistingTab(String url) { |
| String matchPattern = CommandLine.getInstance().getSwitchValue( |
| @@ -328,144 +301,6 @@ private boolean matchURLs(String url1, String url2, boolean matchByHost) { |
| return matchByHost ? UrlUtilities.sameHost(url1, url2) : url1.equals(url2); |
| } |
| - public SuggestionsMetricsReporter getSuggestionsMetricsReporter() { |
| - return mSnippetsBridge; |
| - } |
| - |
| - @Override |
| - public void openSnippet(int windowOpenDisposition, SnippetArticle article) { |
| - mSnippetsBridge.onSuggestionOpened(article, windowOpenDisposition); |
| - NewTabPageUma.recordAction(NewTabPageUma.ACTION_OPENED_SNIPPET); |
| - |
| - if (article.mIsAssetDownload) { |
| - assert windowOpenDisposition == WindowOpenDisposition.CURRENT_TAB |
| - || windowOpenDisposition == WindowOpenDisposition.NEW_WINDOW |
| - || windowOpenDisposition == WindowOpenDisposition.NEW_FOREGROUND_TAB; |
| - DownloadUtils.openFile( |
| - article.getAssetDownloadFile(), article.getAssetDownloadMimeType(), false); |
| - return; |
| - } |
| - |
| - if (article.isRecentTab()) { |
| - assert windowOpenDisposition == WindowOpenDisposition.CURRENT_TAB; |
| - // TODO(vitaliii): Add a debug check that the result is true after crbug.com/662924 |
| - // is resolved. |
| - openRecentTabSnippet(article); |
| - return; |
| - } |
| - |
| - // TODO(treib): Also track other dispositions. crbug.com/665915 |
| - if (windowOpenDisposition == WindowOpenDisposition.CURRENT_TAB) { |
| - NewTabPageUma.monitorContentSuggestionVisit(mTab, article.mCategory); |
| - } |
| - |
| - LoadUrlParams loadUrlParams; |
| - // We explicitly open an offline page only for offline page downloads. For all other |
| - // sections the URL is opened and it is up to Offline Pages whether to open its offline |
| - // page (e.g. when offline). |
| - if (article.isDownload() && !article.mIsAssetDownload) { |
| - assert article.getOfflinePageOfflineId() != null; |
| - assert windowOpenDisposition == WindowOpenDisposition.CURRENT_TAB |
| - || windowOpenDisposition == WindowOpenDisposition.NEW_WINDOW |
| - || windowOpenDisposition == WindowOpenDisposition.NEW_FOREGROUND_TAB; |
| - loadUrlParams = OfflinePageUtils.getLoadUrlParamsForOpeningOfflineVersion( |
| - article.mUrl, article.getOfflinePageOfflineId()); |
| - // Extra headers are not read in loadUrl, but verbatim headers are. |
| - loadUrlParams.setVerbatimHeaders(loadUrlParams.getExtraHeadersString()); |
| - } else { |
| - loadUrlParams = new LoadUrlParams(article.mUrl, PageTransition.AUTO_BOOKMARK); |
| - } |
| - |
| - // For article suggestions, we set the referrer. This is exploited |
| - // to filter out these history entries for NTP tiles. |
| - // TODO(mastiz): Extend this with support for other categories. |
| - if (article.mCategory == KnownCategories.ARTICLES) { |
| - loadUrlParams.setReferrer(new Referrer( |
| - CHROME_CONTENT_SUGGESTIONS_REFERRER, Referrer.REFERRER_POLICY_ALWAYS)); |
| - } |
| - |
| - openUrl(windowOpenDisposition, loadUrlParams); |
| - } |
| - |
| - private boolean openRecentTabSnippet(SnippetArticle recentTabArticle) { |
| - TabModel tabModel = mTabModelSelector.getModel(false); |
| - int tabId = Integer.parseInt(recentTabArticle.getRecentTabId()); |
| - int tabIndex = TabModelUtils.getTabIndexById(tabModel, tabId); |
| - if (tabIndex == TabModel.INVALID_TAB_INDEX) return false; |
| - TabModelUtils.setIndex(tabModel, tabIndex); |
| - return true; |
| - } |
| - |
| - private void openUrl(int windowOpenDisposition, LoadUrlParams loadUrlParams) { |
| - assert !mIsDestroyed; |
| - switch (windowOpenDisposition) { |
| - case WindowOpenDisposition.CURRENT_TAB: |
| - mTab.loadUrl(loadUrlParams); |
| - break; |
| - case WindowOpenDisposition.NEW_FOREGROUND_TAB: |
| - openUrlInNewTab(loadUrlParams, false); |
| - break; |
| - case WindowOpenDisposition.OFF_THE_RECORD: |
| - openUrlInNewTab(loadUrlParams, true); |
| - break; |
| - case WindowOpenDisposition.NEW_WINDOW: |
| - openUrlInNewWindow(loadUrlParams); |
| - break; |
| - case WindowOpenDisposition.SAVE_TO_DISK: |
| - saveUrlForOffline(loadUrlParams.getUrl()); |
| - break; |
| - default: |
| - assert false; |
| - } |
| - } |
| - |
| - @Override |
| - public boolean isOpenInNewWindowEnabled() { |
| - return MultiWindowUtils.getInstance().isOpenInOtherWindowSupported(mActivity); |
| - } |
| - |
| - @Override |
| - public boolean isOpenInIncognitoEnabled() { |
| - return PrefServiceBridge.getInstance().isIncognitoModeEnabled(); |
| - } |
| - |
| - private void openUrlInNewWindow(LoadUrlParams loadUrlParams) { |
| - TabDelegate tabDelegate = new TabDelegate(false); |
| - tabDelegate.createTabInOtherWindow(loadUrlParams, mActivity, mTab.getParentId()); |
| - } |
| - |
| - private void openUrlInNewTab(LoadUrlParams loadUrlParams, boolean incognito) { |
| - mTabModelSelector.openNewTab( |
| - loadUrlParams, TabLaunchType.FROM_LONGPRESS_BACKGROUND, mTab, incognito); |
| - } |
| - |
| - private void saveUrlForOffline(String url) { |
| - OfflinePageBridge.getForProfile(mProfile) |
| - .savePageLater(url, "ntp_suggestions", true /* userRequested */); |
| - } |
| - |
| - @Override |
| - public void navigateToBookmarks() { |
| - if (mIsDestroyed) return; |
| - RecordUserAction.record("MobileNTPSwitchToBookmarks"); |
| - BookmarkUtils.showBookmarkManager(mActivity); |
| - } |
| - |
| - @Override |
| - public void navigateToRecentTabs() { |
| - if (mIsDestroyed) return; |
| - RecordUserAction.record("MobileNTPSwitchToOpenTabs"); |
| - mTab.loadUrl(new LoadUrlParams(UrlConstants.RECENT_TABS_URL)); |
| - } |
| - |
| - @Override |
| - public void navigateToDownloadManager() { |
| - if (mIsDestroyed) return; |
| - assert DownloadUtils.isDownloadHomeEnabled(); |
| - RecordUserAction.record("MobileNTPSwitchToDownloadManager"); |
| - DownloadUtils.showDownloadManager(mActivity, mTab); |
| - } |
| - |
| @Override |
| public void focusSearchBox(boolean beginVoiceSearch, String pastedText) { |
| if (mIsDestroyed) return; |
| @@ -485,83 +320,6 @@ public void setMostVisitedURLsObserver(MostVisitedURLsObserver observer, int num |
| } |
| @Override |
| - public void getLocalFaviconImageForURL( |
| - String url, int size, FaviconImageCallback faviconCallback) { |
| - if (mIsDestroyed) return; |
| - if (mFaviconHelper == null) mFaviconHelper = new FaviconHelper(); |
| - mFaviconHelper.getLocalFaviconImageForURL(mProfile, url, size, faviconCallback); |
| - } |
| - |
| - @Override |
| - public void getLargeIconForUrl(String url, int size, LargeIconCallback callback) { |
| - if (mIsDestroyed) return; |
| - if (mLargeIconBridge == null) mLargeIconBridge = new LargeIconBridge(mProfile); |
| - mLargeIconBridge.getLargeIconForUrl(url, size, callback); |
| - } |
| - |
| - @Override |
| - public void ensureIconIsAvailable(String pageUrl, String iconUrl, boolean isLargeIcon, |
| - boolean isTemporary, IconAvailabilityCallback callback) { |
| - if (mIsDestroyed) return; |
| - if (mFaviconHelper == null) mFaviconHelper = new FaviconHelper(); |
| - mFaviconHelper.ensureIconIsAvailable(mProfile, mTab.getWebContents(), pageUrl, iconUrl, |
| - isLargeIcon, isTemporary, callback); |
| - } |
| - |
| - private boolean isLocalUrl(String url) { |
| - return "file".equals(Uri.parse(url).getScheme()); |
| - } |
| - |
| - @Override |
| - public void getUrlsAvailableOffline( |
| - Set<String> pageUrls, final Callback<Set<String>> callback) { |
| - final Set<String> urlsAvailableOffline = new HashSet<>(); |
| - if (mIsDestroyed || !isNtpOfflinePagesEnabled()) { |
| - callback.onResult(urlsAvailableOffline); |
| - return; |
| - } |
| - |
| - HashSet<String> urlsToCheckForOfflinePage = new HashSet<>(); |
| - |
| - for (String pageUrl : pageUrls) { |
| - if (isLocalUrl(pageUrl)) { |
| - urlsAvailableOffline.add(pageUrl); |
| - } else { |
| - urlsToCheckForOfflinePage.add(pageUrl); |
| - } |
| - } |
| - |
| - final long offlineQueryStartTime = SystemClock.elapsedRealtime(); |
| - |
| - OfflinePageBridge offlinePageBridge = OfflinePageBridge.getForProfile(mProfile); |
| - |
| - // TODO(dewittj): Remove this code by making the NTP badging available after the NTP is |
| - // fully loaded. |
| - if (offlinePageBridge == null || !offlinePageBridge.isOfflinePageModelLoaded()) { |
| - // Posting a task to avoid potential re-entrancy issues. |
| - ThreadUtils.postOnUiThread(new Runnable() { |
| - @Override |
| - public void run() { |
| - callback.onResult(urlsAvailableOffline); |
| - } |
| - }); |
| - return; |
| - } |
| - |
| - offlinePageBridge.checkPagesExistOffline( |
| - urlsToCheckForOfflinePage, new Callback<Set<String>>() { |
| - @Override |
| - public void onResult(Set<String> urlsWithOfflinePages) { |
| - urlsAvailableOffline.addAll(urlsWithOfflinePages); |
| - callback.onResult(urlsAvailableOffline); |
| - RecordHistogram.recordTimesHistogram("NewTabPage.OfflineUrlsLoadTime", |
| - SystemClock.elapsedRealtime() - offlineQueryStartTime, |
| - TimeUnit.MILLISECONDS); |
| - } |
| - }); |
| - } |
| - |
| - @Override |
| public void onLogoClicked(boolean isAnimatedLogoShowing) { |
| if (mIsDestroyed) return; |
| @@ -645,12 +403,6 @@ public SuggestionsSource getSuggestionsSource() { |
| } |
| @Override |
| - public void addDestructionObserver(DestructionObserver destructionObserver) { |
| - if (mIsDestroyed) return; |
| - mDestructionObservers.addObserver(destructionObserver); |
| - } |
| - |
| - @Override |
| public boolean isCurrentPage() { |
| if (mIsDestroyed) return false; |
| if (mFakeboxDelegate == null) return false; |
| @@ -676,7 +428,17 @@ public NewTabPage(ChromeActivity activity, Tab tab, TabModelSelector tabModelSel |
| mTab = tab; |
| mActivity = activity; |
| mTabModelSelector = tabModelSelector; |
| - mProfile = tab.getProfile(); |
| + Profile profile = tab.getProfile(); |
| + |
| + if (SnippetsConfig.isEnabled()) { |
| + mSnippetsBridge = new SnippetsBridge(profile); |
| + } |
| + |
| + SuggestionsNavigationDelegateImpl navigationDelegate = |
|
Michael van Ouwerkerk
2017/01/16 15:31:15
Can this be of type SuggestionsNavigationDelegate?
|
| + new SuggestionsNavigationDelegateImpl(mActivity, profile, tab, tabModelSelector); |
| + mNewTabPageManager = new NewTabPageManagerImpl( |
| + mSnippetsBridge, mSnippetsBridge, navigationDelegate, profile, tab); |
| + mNewTabPageManager.addDestructionObserver(navigationDelegate); |
| mTitle = activity.getResources().getString(R.string.button_new_tab); |
| mBackgroundColor = ApiCompatibilityUtils.getColor(activity.getResources(), R.color.ntp_bg); |
| @@ -720,14 +482,10 @@ public void onPageLoadStarted(Tab tab, String url) { |
| } |
| }; |
| mTab.addObserver(mTabObserver); |
| - mMostVisitedSites = buildMostVisitedSites(mProfile); |
| - mLogoBridge = new LogoBridge(mProfile); |
| + mMostVisitedSites = buildMostVisitedSites(profile); |
| + mLogoBridge = new LogoBridge(profile); |
| updateSearchProviderHasLogo(); |
| - if (SnippetsConfig.isEnabled()) { |
| - mSnippetsBridge = new SnippetsBridge(mProfile); |
| - } |
| - |
| LayoutInflater inflater = LayoutInflater.from(activity); |
| mNewTabPageView = (NewTabPageView) inflater.inflate(R.layout.new_tab_page_view, null); |
| mNewTabPageView.initialize(mNewTabPageManager, mTab, mSearchProviderHasLogo, |
| @@ -967,10 +725,7 @@ public void destroy() { |
| if (mMostVisitedItemRemovedController != null) { |
| mTab.getSnackbarManager().dismissSnackbars(mMostVisitedItemRemovedController); |
| } |
| - for (DestructionObserver observer : mDestructionObservers) { |
| - observer.onDestroy(); |
| - } |
| - mDestructionObservers.clear(); |
| + mNewTabPageManager.onDestroy(); |
| TemplateUrlService.getInstance().removeObserver(this); |
| mTab.removeObserver(mTabObserver); |
| mTabObserver = null; |