| Index: chrome/android/java_staging/src/org/chromium/chrome/browser/customtabs/CustomTab.java
|
| diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/customtabs/CustomTab.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/customtabs/CustomTab.java
|
| deleted file mode 100644
|
| index 21bd420aba6624a53a46b0583c58fd6355dd398b..0000000000000000000000000000000000000000
|
| --- a/chrome/android/java_staging/src/org/chromium/chrome/browser/customtabs/CustomTab.java
|
| +++ /dev/null
|
| @@ -1,307 +0,0 @@
|
| -// 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.customtabs;
|
| -
|
| -import android.app.Activity;
|
| -import android.content.Context;
|
| -import android.content.Intent;
|
| -import android.content.pm.ResolveInfo;
|
| -import android.os.SystemClock;
|
| -import android.os.TransactionTooLargeException;
|
| -import android.text.TextUtils;
|
| -import android.view.ContextMenu;
|
| -import android.view.Menu;
|
| -
|
| -import org.chromium.base.Log;
|
| -import org.chromium.base.VisibleForTesting;
|
| -import org.chromium.base.metrics.RecordHistogram;
|
| -import org.chromium.chrome.R;
|
| -import org.chromium.chrome.browser.ChromeActivity;
|
| -import org.chromium.chrome.browser.EmptyTabObserver;
|
| -import org.chromium.chrome.browser.Tab;
|
| -import org.chromium.chrome.browser.UrlUtilities;
|
| -import org.chromium.chrome.browser.WebContentsFactory;
|
| -import org.chromium.chrome.browser.banners.AppBannerManager;
|
| -import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulator;
|
| -import org.chromium.chrome.browser.contextmenu.ContextMenuParams;
|
| -import org.chromium.chrome.browser.contextmenu.ContextMenuPopulator;
|
| -import org.chromium.chrome.browser.externalnav.ExternalNavigationDelegateImpl;
|
| -import org.chromium.chrome.browser.externalnav.ExternalNavigationHandler;
|
| -import org.chromium.chrome.browser.tab.ChromeTab;
|
| -import org.chromium.chrome.browser.tab.TabIdManager;
|
| -import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
|
| -import org.chromium.content_public.browser.LoadUrlParams;
|
| -import org.chromium.content_public.browser.WebContents;
|
| -import org.chromium.ui.base.WindowAndroid;
|
| -
|
| -import java.util.concurrent.TimeUnit;
|
| -
|
| -/**
|
| - * A chrome tab that is only used as a custom tab.
|
| - */
|
| -public class CustomTab extends ChromeTab {
|
| - private static class CustomTabObserver extends EmptyTabObserver {
|
| - private CustomTabsConnection mCustomTabsConnection;
|
| - private long mSessionId;
|
| - private long mIntentReceivedTimestamp;
|
| - private long mPageLoadStartedTimestamp;
|
| -
|
| - private static final int STATE_RESET = 0;
|
| - private static final int STATE_WAITING_LOAD_START = 1;
|
| - private static final int STATE_WAITING_LOAD_FINISH = 2;
|
| - private int mCurrentState;
|
| -
|
| - public CustomTabObserver(CustomTabsConnection customTabsConnection, long sessionId) {
|
| - mCustomTabsConnection = customTabsConnection;
|
| - mSessionId = sessionId;
|
| - resetPageLoadTracking();
|
| - }
|
| -
|
| - /**
|
| - * Tracks the next page load, with timestamp as the origin of time.
|
| - */
|
| - public void trackNextPageLoadFromTimestamp(long timestamp) {
|
| - mIntentReceivedTimestamp = timestamp;
|
| - mCurrentState = STATE_WAITING_LOAD_START;
|
| - }
|
| -
|
| - @Override
|
| - public void onLoadUrl(Tab tab, LoadUrlParams params, int loadType) {
|
| - mCustomTabsConnection.registerLaunch(mSessionId, params.getUrl());
|
| - }
|
| -
|
| - @Override
|
| - public void onPageLoadStarted(Tab tab, String url) {
|
| - if (mCurrentState == STATE_WAITING_LOAD_START) {
|
| - mPageLoadStartedTimestamp = SystemClock.elapsedRealtime();
|
| - mCurrentState = STATE_WAITING_LOAD_FINISH;
|
| - }
|
| - mCustomTabsConnection.notifyPageLoadStarted(mSessionId, url);
|
| - }
|
| -
|
| - @Override
|
| - public void onPageLoadFinished(Tab tab) {
|
| - long pageLoadFinishedTimestamp = SystemClock.elapsedRealtime();
|
| - mCustomTabsConnection.notifyPageLoadFinished(mSessionId, tab.getUrl());
|
| - // Both histograms (commit and PLT) are reported here, to make sure
|
| - // that they are always recorded together, and that we only record
|
| - // commits for successful navigations.
|
| - if (mCurrentState == STATE_WAITING_LOAD_FINISH && mIntentReceivedTimestamp > 0) {
|
| - long timeToPageLoadStartedMs = mPageLoadStartedTimestamp - mIntentReceivedTimestamp;
|
| - long timeToPageLoadFinishedMs =
|
| - pageLoadFinishedTimestamp - mIntentReceivedTimestamp;
|
| - // Same bounds and bucket count as "Startup.FirstCommitNavigationTime"
|
| - RecordHistogram.recordCustomTimesHistogram(
|
| - "CustomTabs.IntentToFirstCommitNavigationTime", timeToPageLoadStartedMs,
|
| - 1, TimeUnit.MINUTES.toMillis(1), TimeUnit.MILLISECONDS, 225);
|
| - // Same bounds and bucket count as PLT histograms.
|
| - RecordHistogram.recordCustomTimesHistogram("CustomTabs.IntentToPageLoadedTime",
|
| - timeToPageLoadFinishedMs, 10, TimeUnit.MINUTES.toMillis(10),
|
| - TimeUnit.MILLISECONDS, 100);
|
| - }
|
| - resetPageLoadTracking();
|
| - }
|
| -
|
| - @Override
|
| - public void onPageLoadFailed(Tab tab, int errorCode) {
|
| - resetPageLoadTracking();
|
| - }
|
| -
|
| - private void resetPageLoadTracking() {
|
| - mCurrentState = STATE_RESET;
|
| - mIntentReceivedTimestamp = -1;
|
| - }
|
| - }
|
| -
|
| - private ExternalNavigationHandler mNavigationHandler;
|
| - private CustomTabNavigationDelegate mNavigationDelegate;
|
| - private TabChromeContextMenuItemDelegate
|
| - mContextMenuDelegate = new TabChromeContextMenuItemDelegate() {
|
| - @Override
|
| - public boolean startDownload(String url, boolean isLink) {
|
| - // Behave similarly to ChromeTabChromeContextMenuItemDelegate in ChromeTab.
|
| - return !isLink || !shouldInterceptContextMenuDownload(url);
|
| - }
|
| - };
|
| -
|
| - private CustomTabObserver mTabObserver;
|
| -
|
| - /**
|
| - * Construct an CustomTab. It might load a prerendered {@link WebContents} for the URL, if
|
| - * {@link CustomTabsConnectionService} has successfully warmed up for the url.
|
| - */
|
| - public CustomTab(ChromeActivity activity, WindowAndroid windowAndroid,
|
| - long sessionId, String url, String referrer, int parentTabId) {
|
| - super(TabIdManager.getInstance().generateValidId(Tab.INVALID_TAB_ID), activity, false,
|
| - windowAndroid, TabLaunchType.FROM_EXTERNAL_APP, parentTabId, null, null);
|
| - CustomTabsConnection customTabsConnection =
|
| - CustomTabsConnection.getInstance(activity.getApplication());
|
| - WebContents webContents = customTabsConnection.takePrerenderedUrl(sessionId, url, referrer);
|
| - if (webContents == null) {
|
| - webContents = WebContentsFactory.createWebContents(isIncognito(), false);
|
| - }
|
| - initialize(webContents, activity.getTabContentManager(), false);
|
| - getView().requestFocus();
|
| - mTabObserver = new CustomTabObserver(customTabsConnection, sessionId);
|
| - addObserver(mTabObserver);
|
| - }
|
| -
|
| - /**
|
| - * Loads a URL and tracks its load time, from the timestamp of the intent arrival.
|
| - *
|
| - * @param params As in {@link Tab#loadUrl(LoadUrlParams)}.
|
| - * @param timestamp Timestamp of the intent arrival, as returned by
|
| - * {@link SystemClock#elapsedRealtime()}.
|
| - */
|
| - void loadUrlAndTrackFromTimestamp(LoadUrlParams params, long timestamp) {
|
| - mTabObserver.trackNextPageLoadFromTimestamp(timestamp);
|
| - loadUrl(params);
|
| - }
|
| -
|
| - @Override
|
| - protected InterceptNavigationDelegateImpl createInterceptNavigationDelegate() {
|
| - mNavigationDelegate = new CustomTabNavigationDelegate(mActivity);
|
| - mNavigationHandler = new ExternalNavigationHandler(mNavigationDelegate);
|
| - return new InterceptNavigationDelegateImpl(mNavigationHandler);
|
| - }
|
| -
|
| - /**
|
| - * @return The {@link ExternalNavigationHandler} in this tab. For test purpose only.
|
| - */
|
| - @VisibleForTesting
|
| - ExternalNavigationHandler getExternalNavigationHandler() {
|
| - return mNavigationHandler;
|
| - }
|
| -
|
| - /**
|
| - * @return The {@link CustomTabNavigationDelegate} in this tab. For test purpose only.
|
| - */
|
| - @VisibleForTesting
|
| - CustomTabNavigationDelegate getExternalNavigationDelegate() {
|
| - return mNavigationDelegate;
|
| - }
|
| -
|
| - @Override
|
| - protected AppBannerManager createAppBannerManager() {
|
| - return null;
|
| - }
|
| -
|
| - @Override
|
| - protected ContextMenuPopulator createContextMenuPopulator() {
|
| - return new ChromeContextMenuPopulator(mContextMenuDelegate) {
|
| - @Override
|
| - public void buildContextMenu(ContextMenu menu, Context context,
|
| - ContextMenuParams params) {
|
| - String linkUrl = params.getLinkUrl();
|
| - if (linkUrl != null) linkUrl = linkUrl.trim();
|
| - if (!TextUtils.isEmpty(linkUrl)) {
|
| - menu.add(Menu.NONE, org.chromium.chrome.R.id.contextmenu_copy_link_address_text,
|
| - Menu.NONE, org.chromium.chrome.R.string.contextmenu_copy_link_address);
|
| - }
|
| -
|
| - String linkText = params.getLinkText();
|
| - if (linkText != null) linkText = linkText.trim();
|
| - if (!TextUtils.isEmpty(linkText)) {
|
| - menu.add(Menu.NONE, org.chromium.chrome.R.id.contextmenu_copy_link_text,
|
| - Menu.NONE, org.chromium.chrome.R.string.contextmenu_copy_link_text);
|
| - }
|
| - if (params.isImage()) {
|
| - menu.add(Menu.NONE, R.id.contextmenu_save_image, Menu.NONE,
|
| - R.string.contextmenu_save_image);
|
| - menu.add(Menu.NONE, R.id.contextmenu_open_image, Menu.NONE,
|
| - R.string.contextmenu_open_image);
|
| - menu.add(Menu.NONE, R.id.contextmenu_copy_image, Menu.NONE,
|
| - R.string.contextmenu_copy_image);
|
| - menu.add(Menu.NONE, R.id.contextmenu_copy_image_url, Menu.NONE,
|
| - R.string.contextmenu_copy_image_url);
|
| - } else if (UrlUtilities.isDownloadableScheme(params.getLinkUrl())) {
|
| - // "Save link" is not shown for image.
|
| - menu.add(Menu.NONE, R.id.contextmenu_save_link_as, Menu.NONE,
|
| - R.string.contextmenu_save_link);
|
| - }
|
| - }
|
| - };
|
| - }
|
| -
|
| - /**
|
| - * A custom external navigation delegate that forbids the intent picker from showing up.
|
| - */
|
| - static class CustomTabNavigationDelegate extends ExternalNavigationDelegateImpl {
|
| - private static final String TAG = "cr.customtabs";
|
| - private boolean mHasActivityStarted;
|
| -
|
| - /**
|
| - * Constructs a new instance of {@link CustomTabNavigationDelegate}.
|
| - */
|
| - public CustomTabNavigationDelegate(Activity activity) {
|
| - super(activity);
|
| - }
|
| -
|
| - @Override
|
| - public void startActivity(Intent intent) {
|
| - super.startActivity(intent);
|
| - mHasActivityStarted = true;
|
| - }
|
| -
|
| - @Override
|
| - public boolean startActivityIfNeeded(Intent intent) {
|
| - try {
|
| - if (resolveDefaultHandlerForIntent(intent)) {
|
| - if (getActivity().startActivityIfNeeded(intent, -1)) {
|
| - mHasActivityStarted = true;
|
| - return true;
|
| - } else {
|
| - return false;
|
| - }
|
| - } else {
|
| - // If we failed to find the default handler of the intent, fall back to chrome.
|
| - return false;
|
| - }
|
| - } catch (RuntimeException e) {
|
| - logTransactionTooLargeOrRethrow(e, intent);
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Resolve the default external handler of an intent.
|
| - * @return Whether the default external handler is found: if chrome turns out to be the
|
| - * default handler, this method will return false.
|
| - */
|
| - private boolean resolveDefaultHandlerForIntent(Intent intent) {
|
| - try {
|
| - ResolveInfo info = getActivity().getPackageManager().resolveActivity(intent, 0);
|
| - if (info != null) {
|
| - final String chromePackage = getActivity().getPackageName();
|
| - // If a default handler is found and it is not chrome itself, fire the intent.
|
| - if (info.match != 0 && !chromePackage.equals(info.activityInfo.packageName)) {
|
| - return true;
|
| - }
|
| - }
|
| - } catch (RuntimeException e) {
|
| - logTransactionTooLargeOrRethrow(e, intent);
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - /**
|
| - * @return Whether an external activity has started to handle a url. For testing only.
|
| - */
|
| - @VisibleForTesting
|
| - public boolean hasExternalActivityStarted() {
|
| - return mHasActivityStarted;
|
| - }
|
| -
|
| - private static void logTransactionTooLargeOrRethrow(RuntimeException e, Intent intent) {
|
| - // See http://crbug.com/369574.
|
| - if (e.getCause() != null && e.getCause() instanceof TransactionTooLargeException) {
|
| - Log.e(TAG, "Could not resolve Activity for intent " + intent.toString(), e);
|
| - } else {
|
| - throw e;
|
| - }
|
| - }
|
| - }
|
| -
|
| -}
|
|
|