Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5218)

Unified Diff: chrome/android/java_staging/src/org/chromium/chrome/browser/document/DocumentTab.java

Issue 1141283003: Upstream oodles of Chrome for Android code into Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final patch? Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java_staging/src/org/chromium/chrome/browser/document/DocumentTab.java
diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/document/DocumentTab.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/document/DocumentTab.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce3203ab4c66da4a8660154c6b3e77f6002aabc6
--- /dev/null
+++ b/chrome/android/java_staging/src/org/chromium/chrome/browser/document/DocumentTab.java
@@ -0,0 +1,350 @@
+// 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.document;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.util.LongSparseArray;
+
+import org.chromium.base.ObserverList.RewindableIterator;
+import org.chromium.base.VisibleForTesting;
+import org.chromium.base.metrics.RecordUserAction;
+import org.chromium.chrome.browser.ChromeMobileApplication;
+import org.chromium.chrome.browser.ContentViewUtil;
+import org.chromium.chrome.browser.EmptyTabObserver;
+import org.chromium.chrome.browser.IntentHandler;
+import org.chromium.chrome.browser.Tab;
+import org.chromium.chrome.browser.TabObserver;
+import org.chromium.chrome.browser.TabState;
+import org.chromium.chrome.browser.TabUma.TabCreationState;
+import org.chromium.chrome.browser.WarmupManager;
+import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
+import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulator;
+import org.chromium.chrome.browser.contextmenu.ContextMenuPopulator;
+import org.chromium.chrome.browser.preferences.PrefServiceBridge;
+import org.chromium.chrome.browser.tab.ChromeTab;
+import org.chromium.chrome.browser.tabmodel.TabModel;
+import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
+import org.chromium.chrome.browser.tabmodel.document.ActivityDelegate;
+import org.chromium.content_public.browser.LoadUrlParams;
+import org.chromium.content_public.browser.WebContents;
+import org.chromium.content_public.common.Referrer;
+import org.chromium.ui.base.PageTransition;
+import org.chromium.ui.base.WindowAndroid;
+
+/**
+ * A Tab child class with Chrome documents specific functionality.
+ */
+public class DocumentTab extends ChromeTab {
+ private static final int DESIRED_ICON_SIZE_DP = 32;
+
+ /**
+ * Observer class with extra calls specific to Chrome Documents
+ */
+ public static class DocumentTabObserver extends EmptyTabObserver {
+ /**
+ * Called when a Favicon is received for the current document.
+ * @param image The favicon image that was received.
+ */
+ protected void onFaviconReceived(Bitmap image) { }
+
+ /**
+ * Called when a tab is set to be covered or uncovered by child activity.
+ */
+ protected void onSetCoveredByChildActivity() { }
+ }
+
+ private int mDesiredIconSizePx;
+ private boolean mDidRestoreState;
+
+ // Whether this document tab was constructed from passed-in web contents pointer.
+ private boolean mCreatedFromWebContents;
+
+ private final DocumentActivity mActivity;
+
+ // Whether this tab is covered by its child activity.
+ private boolean mIsCoveredByChildActivity;
+
+ /**
+ * Standard constructor for the document tab.
+ * @param activity The document activity that will hold on to this tab.
+ * @param incognito Whether the tab is incognito.
+ * @param windowAndroid The window that this tab should be using.
+ * @param url The url to load on creation.
+ * @param parentTabId The id of the parent tab.
+ */
+ private DocumentTab(DocumentActivity activity, boolean incognito,
+ WindowAndroid windowAndroid, String url, int parentTabId) {
+ super(ActivityDelegate.getTabIdFromIntent(activity.getIntent()), activity,
+ incognito, windowAndroid, TabLaunchType.FROM_EXTERNAL_APP, parentTabId, null, null);
+ mActivity = activity;
+ initialize(url, null, activity.getTabContentManager(), false);
+ }
+
+ /**
+ * Constructor for document tab from a frozen state.
+ * @param activity The document activity that will hold on to this tab.
+ * @param incognito Whether the tab is incognito.
+ * @param windowAndroid The window that this tab should be using.
+ * @param url The url to load on creation.
+ * @param tabState The {@link TabState} the tab will be recreated from.
+ * @param parentTabId The id of the parent tab.
+ */
+ private DocumentTab(DocumentActivity activity, boolean incognito,
+ WindowAndroid windowAndroid, String url, TabState tabState, int parentTabId) {
+ super(ActivityDelegate.getTabIdFromIntent(activity.getIntent()), activity,
+ incognito, windowAndroid, TabLaunchType.FROM_RESTORE, parentTabId,
+ TabCreationState.FROZEN_ON_RESTORE, tabState);
+ mActivity = activity;
+ initialize(url, null, activity.getTabContentManager(), true);
+ }
+
+ /**
+ * Constructor for tab opened via JS.
+ * @param activity The document activity that will hold on to this tab.
+ * @param incognito Whether the tab is incognito.
+ * @param windowAndroid The window that this tab should be using.
+ * @param url The url to load on creation.
+ * @param parentTabId The id of the parent tab.
+ * @param webContents An optional {@link WebContents} object to use.
+ */
+ private DocumentTab(DocumentActivity activity, boolean incognito,
+ WindowAndroid windowAndroid, String url, int parentTabId, WebContents webContents) {
+ super(ActivityDelegate.getTabIdFromIntent(activity.getIntent()), activity,
+ incognito, windowAndroid, TabLaunchType.FROM_LONGPRESS_FOREGROUND,
+ parentTabId, null, null);
+ mActivity = activity;
+ initialize(url, webContents, activity.getTabContentManager(), false);
+ mCreatedFromWebContents = true;
+ }
+
+ @Override
+ protected void initContentViewCore(WebContents webContents) {
+ super.initContentViewCore(webContents);
+ getContentViewCore().setFullscreenRequiredForOrientationLock(false);
+ }
+
+ /**
+ * Initializes the tab with native web contents.
+ * @param url The url to use for looking up potentially pre-rendered web contents.
+ * @param webContents Optionally, a pre-created web contents.
+ * @param unfreeze Whether we want to initialize the tab from tab state.
+ */
+ private void initialize(String url, WebContents webContents,
+ TabContentManager tabContentManager, boolean unfreeze) {
+ mDesiredIconSizePx = (int) (DESIRED_ICON_SIZE_DP
+ * mActivity.getResources().getDisplayMetrics().density);
+
+ if (!unfreeze && webContents == null) {
+ webContents = WarmupManager.getInstance().hasPrerenderedUrl(url)
+ ? WarmupManager.getInstance().takePrerenderedWebContents()
+ : ContentViewUtil.createWebContents(isIncognito(), false);
+ }
+ initialize(webContents, tabContentManager, false);
+ if (unfreeze) mDidRestoreState = unfreezeContents();
+
+ getView().requestFocus();
+ }
+
+ @Override
+ public void onFaviconAvailable(Bitmap image) {
+ super.onFaviconAvailable(image);
+ if (image == null) return;
+ if (image.getWidth() < mDesiredIconSizePx || image.getHeight() < mDesiredIconSizePx) {
+ return;
+ }
+ RewindableIterator<TabObserver> observers = getTabObservers();
+ while (observers.hasNext()) {
+ TabObserver observer = observers.next();
+ if (observer instanceof DocumentTabObserver) {
+ ((DocumentTabObserver) observer).onFaviconReceived(image);
+ }
+ }
+ }
+
+ private class DocumentContextMenuItemDelegate extends TabChromeContextMenuItemDelegate {
+ @Override
+ public boolean isIncognitoSupported() {
+ return PrefServiceBridge.getInstance().isIncognitoModeEnabled();
+ }
+
+ @Override
+ public boolean canLoadOriginalImage() {
+ return mUsedSpdyProxy && !mUsedSpdyProxyWithPassthrough;
+ }
+
+ @Override
+ public boolean startDownload(String url, boolean isLink) {
+ if (isLink && shouldInterceptContextMenuDownload(url)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void onOpenInNewTab(String url, Referrer referrer) {
+ PendingDocumentData params = new PendingDocumentData();
+ params.referrer = referrer;
+ ChromeLauncherActivity.launchDocumentInstance(
+ getWindowAndroid().getActivity().get(), isIncognito(),
+ ChromeLauncherActivity.LAUNCH_MODE_AFFILIATED, url,
+ DocumentMetricIds.STARTED_BY_CONTEXT_MENU,
+ PageTransition.AUTO_TOPLEVEL, false, params);
+ }
+
+ @Override
+ public void onOpenInNewIncognitoTab(String url) {
+ ChromeLauncherActivity.launchDocumentInstance(
+ getWindowAndroid().getActivity().get(), true,
+ ChromeLauncherActivity.LAUNCH_MODE_FOREGROUND,
+ url, DocumentMetricIds.STARTED_BY_CONTEXT_MENU,
+ PageTransition.AUTO_TOPLEVEL, false, null);
+ }
+
+ @Override
+ public void onOpenImageInNewTab(String url, Referrer referrer) {
+ boolean useOriginal = isSpdyProxyEnabledForUrl(url);
+
+ LoadUrlParams loadUrlParams = new LoadUrlParams(url);
+ loadUrlParams.setVerbatimHeaders(useOriginal ? PAGESPEED_PASSTHROUGH_HEADER : null);
+ loadUrlParams.setReferrer(referrer);
+ mActivity.getTabModelSelector().openNewTab(loadUrlParams,
+ TabLaunchType.FROM_LONGPRESS_BACKGROUND, DocumentTab.this, isIncognito());
+ }
+
+ @Override
+ public void onOpenImageUrl(String url, Referrer referrer) {
+ LoadUrlParams loadUrlParams = new LoadUrlParams(url);
+ loadUrlParams.setTransitionType(PageTransition.AUTO_BOOKMARK);
+ loadUrlParams.setReferrer(referrer);
+ loadUrl(loadUrlParams);
+ }
+
+ @Override
+ public void onSearchByImageInNewTab() {
+ RecordUserAction.record("MobileContextMenuSearchByImage");
+ triggerSearchByImage();
+ }
+ }
+
+ @Override
+ protected ContextMenuPopulator createContextMenuPopulator() {
+ return new ChromeContextMenuPopulator(new DocumentContextMenuItemDelegate());
+ }
+
+ /**
+ * A web contents delegate for handling opening new windows in Document mode.
+ */
+ public class DocumentTabChromeWebContentsDelegateAndroidImpl
+ extends TabChromeWebContentsDelegateAndroidImpl {
+ private final LongSparseArray<String> mContentsToUrlMapping = new LongSparseArray<String>();
+
+ @Override
+ public void webContentsCreated(WebContents sourceWebContents, long openerRenderFrameId,
+ String frameName, String targetUrl, WebContents newWebContents) {
+ super.webContentsCreated(sourceWebContents, openerRenderFrameId, frameName,
+ targetUrl, newWebContents);
+ long nativeNewWebContents =
+ ContentViewUtil.getNativeWebContentsFromWebContents(newWebContents);
+ mContentsToUrlMapping.put(nativeNewWebContents, targetUrl);
+ DocumentWebContentsDelegate.getInstance().attachDelegate(newWebContents);
+ }
+
+ @Override
+ public boolean addNewContents(WebContents sourceWebContents, WebContents webContents,
+ int disposition, Rect initialPosition, boolean userGesture) {
+ if (isClosing()) return false;
+ long nativeWebContents =
+ ContentViewUtil.getNativeWebContentsFromWebContents(webContents);
+ String url = mContentsToUrlMapping.get(nativeWebContents);
+ if (url == null) url = "";
+ PendingDocumentData data = new PendingDocumentData();
+ data.webContents = webContents;
+ data.webContentsPaused = true;
+ ChromeLauncherActivity.launchDocumentInstance(
+ getWindowAndroid().getActivity().get(), isIncognito(),
+ ChromeLauncherActivity.LAUNCH_MODE_AFFILIATED, url,
+ DocumentMetricIds.STARTED_BY_WINDOW_OPEN,
+ PageTransition.AUTO_TOPLEVEL,
+ false, data);
+
+ return true;
+ }
+
+ /**
+ * TODO(dfalcantara): remove this when DocumentActivity.getTabModelSelector()
+ * will return the right TabModelSelector.
+ */
+ @Override
+ protected TabModel getTabModel() {
+ return ChromeMobileApplication.getDocumentTabModelSelector().getModel(isIncognito());
+ }
+ }
+
+ @Override
+ protected TabChromeWebContentsDelegateAndroid createWebContentsDelegate() {
+ return new DocumentTabChromeWebContentsDelegateAndroidImpl();
+ }
+
+ /**
+ * @return Whether or not the tab's state was restored.
+ */
+ public boolean didRestoreState() {
+ return mDidRestoreState;
+ }
+
+ /**
+ * @return Whether this tab was created using web contents passed to it.
+ */
+ public boolean isCreatedWithWebContents() {
+ return mCreatedFromWebContents;
+ }
+
+ /**
+ * Create a DocumentTab.
+ * @param activity The activity the tab will be residing in.
+ * @param incognito Whether the tab is incognito.
+ * @param window The window the activity is using.
+ * @param url The url that should be displayed by the tab.
+ * @param webContents A {@link WebContents} object.
+ * @param tabState State that was previously persisted to disk for the Tab.
+ * @return The created {@link DocumentTab}.
+ */
+ static DocumentTab create(DocumentActivity activity, boolean incognito, WindowAndroid window,
+ String url, WebContents webContents, boolean webContentsPaused, TabState tabState) {
+ int parentTabId = activity.getIntent().getIntExtra(
+ IntentHandler.EXTRA_PARENT_TAB_ID, Tab.INVALID_TAB_ID);
+ if (webContents != null) {
+ DocumentTab tab = new DocumentTab(
+ activity, incognito, window, url, parentTabId, webContents);
+ if (webContentsPaused) webContents.resumeLoadingCreatedWebContents();
+ return tab;
+ }
+
+ if (tabState == null) {
+ return new DocumentTab(activity, incognito, window, url, parentTabId);
+ } else {
+ return new DocumentTab(activity, incognito, window, "", tabState, parentTabId);
+ }
+ }
+
+ @Override
+ public boolean isCoveredByChildActivity() {
+ return mIsCoveredByChildActivity;
+ }
+
+ @Override
+ @VisibleForTesting
+ public void setCoveredByChildActivity(boolean isCoveredByChildActivity) {
+ mIsCoveredByChildActivity = isCoveredByChildActivity;
+ RewindableIterator<TabObserver> observers = getTabObservers();
+ while (observers.hasNext()) {
+ TabObserver observer = observers.next();
+ if (observer instanceof DocumentTabObserver) {
+ ((DocumentTabObserver) observer).onSetCoveredByChildActivity();
+ }
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698