blob: 1aeb6cf0a41099d9a167d5aaa023cd1252e215cc [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.ntp;
import android.net.Uri;
import android.support.annotation.IntDef;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.NativePage;
import org.chromium.chrome.browser.NativePageHost;
import org.chromium.chrome.browser.TabLoadStatus;
import org.chromium.chrome.browser.UrlConstants;
import org.chromium.chrome.browser.bookmarks.BookmarkPage;
import org.chromium.chrome.browser.download.DownloadPage;
import org.chromium.chrome.browser.explore_sites.ExploreSitesPage;
import org.chromium.chrome.browser.feed.FeedNewTabPage;
import org.chromium.chrome.browser.history.HistoryPage;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.content_public.browser.LoadUrlParams;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Creates NativePage objects to show chrome-native:// URLs using the native Android view system.
*/
public class NativePageFactory {
private static NativePageBuilder sNativePageBuilder = new NativePageBuilder();
@VisibleForTesting
static class NativePageBuilder {
protected NativePage buildNewTabPage(ChromeActivity activity, Tab tab,
TabModelSelector tabModelSelector) {
if (tab.isIncognito()) {
return new IncognitoNewTabPage(activity, new TabShim(tab));
}
if (ChromeFeatureList.isEnabled(ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS)) {
return new FeedNewTabPage(activity, new TabShim(tab), tabModelSelector);
}
return new NewTabPage(activity, new TabShim(tab), tabModelSelector);
}
protected NativePage buildBookmarksPage(ChromeActivity activity, Tab tab) {
return new BookmarkPage(activity, new TabShim(tab));
}
protected NativePage buildDownloadsPage(ChromeActivity activity, Tab tab) {
return new DownloadPage(activity, new TabShim(tab));
}
protected NativePage buildExploreSitesPage(ChromeActivity activity, Tab tab) {
return new ExploreSitesPage(activity, new TabShim(tab));
}
protected NativePage buildHistoryPage(ChromeActivity activity, Tab tab) {
return new HistoryPage(activity, new TabShim(tab));
}
protected NativePage buildRecentTabsPage(ChromeActivity activity, Tab tab) {
RecentTabsManager recentTabsManager =
new RecentTabsManager(tab, tab.getProfile(), activity);
return new RecentTabsPage(activity, recentTabsManager);
}
}
@IntDef({NativePageType.NONE, NativePageType.CANDIDATE, NativePageType.NTP,
NativePageType.BOOKMARKS, NativePageType.RECENT_TABS, NativePageType.DOWNLOADS,
NativePageType.HISTORY, NativePageType.EXPLORE})
@Retention(RetentionPolicy.SOURCE)
public @interface NativePageType {
int NONE = 0;
int CANDIDATE = 1;
int NTP = 2;
int BOOKMARKS = 3;
int RECENT_TABS = 4;
int DOWNLOADS = 5;
int HISTORY = 6;
int EXPLORE = 7;
}
private static @NativePageType int nativePageType(
String url, NativePage candidatePage, boolean isIncognito) {
if (url == null) return NativePageType.NONE;
Uri uri = Uri.parse(url);
if (!UrlConstants.CHROME_NATIVE_SCHEME.equals(uri.getScheme())) {
return NativePageType.NONE;
}
String host = uri.getHost();
if (candidatePage != null && candidatePage.getHost().equals(host)) {
return NativePageType.CANDIDATE;
}
if (UrlConstants.NTP_HOST.equals(host)) {
return NativePageType.NTP;
} else if (UrlConstants.BOOKMARKS_HOST.equals(host)) {
return NativePageType.BOOKMARKS;
} else if (UrlConstants.DOWNLOADS_HOST.equals(host)) {
return NativePageType.DOWNLOADS;
} else if (UrlConstants.HISTORY_HOST.equals(host)) {
return NativePageType.HISTORY;
} else if (UrlConstants.RECENT_TABS_HOST.equals(host) && !isIncognito) {
return NativePageType.RECENT_TABS;
} else if (UrlConstants.EXPLORE_HOST.equals(host)) {
return NativePageType.EXPLORE;
} else {
return NativePageType.NONE;
}
}
/**
* Returns a NativePage for displaying the given URL if the URL is a valid chrome-native URL,
* or null otherwise. If candidatePage is non-null and corresponds to the URL, it will be
* returned. Otherwise, a new NativePage will be constructed.
*
* @param url The URL to be handled.
* @param candidatePage A NativePage to be reused if it matches the url, or null.
* @param tab The Tab that will show the page.
* @param tabModelSelector The TabModelSelector containing the tab.
* @param activity The activity used to create the views for the page.
* @return A NativePage showing the specified url or null.
*/
public static NativePage createNativePageForURL(String url, NativePage candidatePage,
Tab tab, TabModelSelector tabModelSelector, ChromeActivity activity) {
return createNativePageForURL(url, candidatePage, tab, tabModelSelector, activity,
tab.isIncognito());
}
@VisibleForTesting
static NativePage createNativePageForURL(String url, NativePage candidatePage,
Tab tab, TabModelSelector tabModelSelector, ChromeActivity activity,
boolean isIncognito) {
NativePage page;
switch (nativePageType(url, candidatePage, isIncognito)) {
case NativePageType.NONE:
return null;
case NativePageType.CANDIDATE:
page = candidatePage;
break;
case NativePageType.NTP:
page = sNativePageBuilder.buildNewTabPage(activity, tab, tabModelSelector);
break;
case NativePageType.BOOKMARKS:
page = sNativePageBuilder.buildBookmarksPage(activity, tab);
break;
case NativePageType.DOWNLOADS:
page = sNativePageBuilder.buildDownloadsPage(activity, tab);
break;
case NativePageType.HISTORY:
page = sNativePageBuilder.buildHistoryPage(activity, tab);
break;
case NativePageType.RECENT_TABS:
page = sNativePageBuilder.buildRecentTabsPage(activity, tab);
break;
case NativePageType.EXPLORE:
page = sNativePageBuilder.buildExploreSitesPage(activity, tab);
break;
default:
assert false;
return null;
}
if (page != null) page.updateForUrl(url);
return page;
}
/**
* Returns whether the URL would navigate to a native page.
*
* @param url The URL to be checked.
* @param isIncognito Whether the page will be displayed in incognito mode.
* @return Whether the host and the scheme of the passed in URL matches one of the supported
* native pages.
*/
public static boolean isNativePageUrl(String url, boolean isIncognito) {
return nativePageType(url, null, isIncognito) != NativePageType.NONE;
}
@VisibleForTesting
static void setNativePageBuilderForTesting(NativePageBuilder builder) {
sNativePageBuilder = builder;
}
/** Simple implementation of NativePageHost backed by a {@link Tab} */
private static class TabShim implements NativePageHost {
private final Tab mTab;
public TabShim(Tab mTab) {
this.mTab = mTab;
}
@Override
public int loadUrl(LoadUrlParams urlParams, boolean incognito) {
if (incognito && !mTab.isIncognito()) {
mTab.getTabModelSelector().openNewTab(urlParams,
TabModel.TabLaunchType.FROM_LONGPRESS_FOREGROUND, mTab,
/* incognito = */ true);
return TabLoadStatus.DEFAULT_PAGE_LOAD;
}
return mTab.loadUrl(urlParams);
}
@Override
public boolean isIncognito() {
return mTab.isIncognito();
}
@Override
public int getParentId() {
return mTab.getParentId();
}
@Override
public Tab getActiveTab() {
return mTab;
}
@Override
public boolean isVisible() {
return mTab == mTab.getTabModelSelector().getCurrentTab();
}
}
}