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

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java

Issue 1358923002: Extract TabChromeWebContentsDelegateAndroid into a separate class. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@chrometab10
Patch Set: Move renderer hung calls Created 5 years, 3 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/src/org/chromium/chrome/browser/tab/Tab.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
index 0319b413344239826acb8ac8e64634a2ffeda6c6..6d595cf684d2d22aa7852c04719d1a03e3e83be3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -4,25 +4,18 @@
package org.chromium.chrome.browser.tab;
-import android.annotation.TargetApi;
import android.app.Activity;
-import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Color;
-import android.graphics.Rect;
-import android.media.AudioManager;
-import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.provider.Browser;
import android.text.TextUtils;
import android.util.Log;
-import android.util.Pair;
import android.view.ContextMenu;
-import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
@@ -44,13 +37,11 @@ import org.chromium.base.metrics.RecordUserAction;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.AccessibilityUtil;
import org.chromium.chrome.browser.ChromeActivity;
-import org.chromium.chrome.browser.ChromeApplication;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.ChromeWebContentsDelegateAndroid;
import org.chromium.chrome.browser.FrozenNativePage;
import org.chromium.chrome.browser.IntentHandler.TabOpenType;
import org.chromium.chrome.browser.NativePage;
-import org.chromium.chrome.browser.RepostFormWarningDialog;
import org.chromium.chrome.browser.SwipeRefreshHandler;
import org.chromium.chrome.browser.TabState;
import org.chromium.chrome.browser.TabState.WebContentsState;
@@ -65,19 +56,14 @@ import org.chromium.chrome.browser.contextmenu.ContextMenuPopulator;
import org.chromium.chrome.browser.contextmenu.ContextMenuPopulatorWrapper;
import org.chromium.chrome.browser.crash.MinidumpUploadService;
import org.chromium.chrome.browser.customtabs.CustomTabActivity;
-import org.chromium.chrome.browser.document.DocumentUtils;
-import org.chromium.chrome.browser.document.DocumentWebContentsDelegate;
import org.chromium.chrome.browser.download.ChromeDownloadDelegate;
import org.chromium.chrome.browser.fullscreen.FullscreenManager;
import org.chromium.chrome.browser.help.HelpAndFeedback;
import org.chromium.chrome.browser.infobar.InfoBarContainer;
-import org.chromium.chrome.browser.media.MediaCaptureNotificationService;
import org.chromium.chrome.browser.metrics.UmaSessionStats;
import org.chromium.chrome.browser.metrics.UmaUtils;
import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings;
import org.chromium.chrome.browser.omnibox.geo.GeolocationHeader;
-import org.chromium.chrome.browser.policy.PolicyAuditor;
-import org.chromium.chrome.browser.policy.PolicyAuditor.AuditEvent;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
import org.chromium.chrome.browser.printing.TabPrinter;
import org.chromium.chrome.browser.profiles.Profile;
@@ -86,13 +72,10 @@ import org.chromium.chrome.browser.snackbar.SnackbarManager;
import org.chromium.chrome.browser.ssl.ConnectionSecurityLevel;
import org.chromium.chrome.browser.ssl.SecurityStateModel;
import org.chromium.chrome.browser.tab.TabUma.TabCreationState;
-import org.chromium.chrome.browser.tabmodel.TabCreatorManager.TabCreator;
-import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType;
import org.chromium.chrome.browser.tabmodel.TabModelBase;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
-import org.chromium.chrome.browser.tabmodel.TabModelUtils;
import org.chromium.chrome.browser.util.FeatureUtilities;
import org.chromium.components.navigation_interception.InterceptNavigationDelegate;
import org.chromium.content.browser.ActivityContentVideoViewClient;
@@ -100,7 +83,6 @@ import org.chromium.content.browser.ContentVideoViewClient;
import org.chromium.content.browser.ContentView;
import org.chromium.content.browser.ContentViewClient;
import org.chromium.content.browser.ContentViewCore;
-import org.chromium.content_public.browser.InvalidateTypes;
import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.WebContentsObserver;
@@ -348,7 +330,7 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
private float mPreviousFullscreenTopControlsOffsetY = Float.NaN;
private float mPreviousFullscreenContentOffsetY = Float.NaN;
private float mPreviousFullscreenOverdrawBottomHeight = Float.NaN;
- private int mFullscreenHungRendererToken = FullscreenManager.INVALID_TOKEN;
+ int mFullscreenHungRendererToken = FullscreenManager.INVALID_TOKEN;
/**
* The UMA object used to report stats for this tab. Note that this may be null under certain
@@ -384,34 +366,6 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
protected Handler mHandler;
- private final Runnable mCloseContentsRunnable = new Runnable() {
- @Override
- public void run() {
- boolean isSelected = mActivity.getTabModelSelector().getCurrentTab() == Tab.this;
- mActivity.getTabModelSelector().closeTab(Tab.this);
-
- // If the parent Tab belongs to another Activity, fire the Intent to bring it back.
- if (isSelected && getParentIntent() != null
- && mActivity.getIntent() != getParentIntent()) {
- boolean mayLaunch = FeatureUtilities.isDocumentMode(mActivity)
- ? isParentInAndroidOverview() : true;
- if (mayLaunch) mActivity.startActivity(getParentIntent());
- }
- }
-
- /** If the API allows it, returns whether a Task still exists for the parent Activity. */
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- private boolean isParentInAndroidOverview() {
- ActivityManager activityManager =
- (ActivityManager) mActivity.getSystemService(Context.ACTIVITY_SERVICE);
- for (ActivityManager.AppTask task : activityManager.getAppTasks()) {
- Intent taskIntent = DocumentUtils.getBaseIntentFromTask(task);
- if (taskIntent != null && taskIntent.filterEquals(getParentIntent())) return true;
- }
- return false;
- }
- };
-
/**
* A default {@link ChromeContextMenuItemDelegate} that supports some of the context menu
* functionality.
@@ -519,317 +473,7 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
}
}
- /**
- * A basic {@link ChromeWebContentsDelegateAndroid} that forwards some calls to the registered
- * {@link TabObserver}s. Meant to be overridden by subclasses.
- */
- public class TabChromeWebContentsDelegateAndroid
- extends ChromeWebContentsDelegateAndroid {
- @Override
- public void onLoadProgressChanged(int progress) {
- if (!isLoading()) return;
- notifyLoadProgress(getProgress());
- }
-
- @Override
- public void onLoadStarted() {
- for (TabObserver observer : mObservers) observer.onLoadStarted(Tab.this);
- }
-
- @Override
- public void onLoadStopped() {
- for (TabObserver observer : mObservers) observer.onLoadStopped(Tab.this);
- }
-
- @Override
- public void onUpdateUrl(String url) {
- for (TabObserver observer : mObservers) observer.onUpdateUrl(Tab.this, url);
- }
-
- @Override
- public void showRepostFormWarningDialog() {
- // When the dialog is visible, keeping the refresh animation active
- // in the background is distracting and unnecessary (and likely to
- // jank when the dialog is shown).
- if (mSwipeRefreshHandler != null) {
- mSwipeRefreshHandler.reset();
- }
- RepostFormWarningDialog warningDialog = new RepostFormWarningDialog(
- new Runnable() {
- @Override
- public void run() {
- getWebContents().getNavigationController().cancelPendingReload();
- }
- }, new Runnable() {
- @Override
- public void run() {
- getWebContents().getNavigationController().continuePendingReload();
- }
- });
- warningDialog.show(mActivity.getFragmentManager(), null);
- }
- @Override
- public void toggleFullscreenModeForTab(boolean enableFullscreen) {
- if (mFullscreenManager != null) {
- mFullscreenManager.setPersistentFullscreenMode(enableFullscreen);
- }
-
- for (TabObserver observer : mObservers) {
- observer.onToggleFullscreenMode(Tab.this, enableFullscreen);
- }
- }
-
- @Override
- public void navigationStateChanged(int flags) {
- if ((flags & InvalidateTypes.TAB) != 0) {
- MediaCaptureNotificationService.updateMediaNotificationForTab(
- getApplicationContext(), getId(), isCapturingAudio(),
- isCapturingVideo(), getUrl());
- }
- if ((flags & InvalidateTypes.TITLE) != 0) {
- // Update cached title then notify observers.
- updateTitle();
- }
- if ((flags & InvalidateTypes.URL) != 0) {
- for (TabObserver observer : mObservers) observer.onUrlUpdated(Tab.this);
- }
- }
-
- @Override
- public void visibleSSLStateChanged() {
- for (TabObserver observer : mObservers) observer.onSSLStateUpdated(Tab.this);
- }
-
- @Override
- public void webContentsCreated(WebContents sourceWebContents, long openerRenderFrameId,
- String frameName, String targetUrl, WebContents newWebContents) {
- for (TabObserver observer : mObservers) {
- observer.webContentsCreated(Tab.this, sourceWebContents, openerRenderFrameId,
- frameName, targetUrl, newWebContents);
- }
- // The URL can't be taken from the WebContents if it's paused. Save it for later.
- assert mWebContentsUrlMapping == null;
- mWebContentsUrlMapping = Pair.create(newWebContents, targetUrl);
-
- // TODO(dfalcantara): Re-remove this once crbug.com/508366 is fixed.
- TabCreator tabCreator = mActivity.getTabCreator(isIncognito());
-
- if (tabCreator != null && tabCreator.createsTabsAsynchronously()) {
- DocumentWebContentsDelegate.getInstance().attachDelegate(newWebContents);
- }
- }
-
- @Override
- public void rendererUnresponsive() {
- super.rendererUnresponsive();
- if (mNativeTabAndroid != 0) nativeOnRendererUnresponsive(mNativeTabAndroid);
- if (mFullscreenManager == null) return;
- mFullscreenHungRendererToken =
- mFullscreenManager.showControlsPersistentAndClearOldToken(
- mFullscreenHungRendererToken);
- }
-
- @Override
- public void rendererResponsive() {
- super.rendererResponsive();
- if (mNativeTabAndroid != 0) nativeOnRendererResponsive(mNativeTabAndroid);
- if (mFullscreenManager == null) return;
- mFullscreenManager.hideControlsPersistent(mFullscreenHungRendererToken);
- mFullscreenHungRendererToken = FullscreenManager.INVALID_TOKEN;
- }
-
- @Override
- public boolean isFullscreenForTabOrPending() {
- return mFullscreenManager == null
- ? false : mFullscreenManager.getPersistentFullscreenMode();
- }
-
- @Override
- public void openNewTab(String url, String extraHeaders, byte[] postData, int disposition,
- boolean isRendererInitiated) {
- Tab.this.openNewTab(
- url, extraHeaders, postData, disposition, true, isRendererInitiated);
- }
-
- private Pair<WebContents, String> mWebContentsUrlMapping;
-
- protected TabModel getTabModel() {
- // TODO(dfalcantara): Remove this when DocumentActivity.getTabModelSelector()
- // can return a TabModelSelector that activateContents() can use.
- return mActivity.getTabModelSelector().getModel(isIncognito());
- }
-
- @Override
- public boolean shouldResumeRequestsForCreatedWindow() {
- // Pause the WebContents if an Activity has to be created for it first.
- TabCreator tabCreator = mActivity.getTabCreator(isIncognito());
- assert tabCreator != null;
- return !tabCreator.createsTabsAsynchronously();
- }
-
- @Override
- public boolean addNewContents(WebContents sourceWebContents, WebContents webContents,
- int disposition, Rect initialPosition, boolean userGesture) {
- assert mWebContentsUrlMapping.first == webContents;
-
- TabCreator tabCreator = mActivity.getTabCreator(isIncognito());
- assert tabCreator != null;
-
- // Grab the URL, which might not be available via the Tab.
- String url = mWebContentsUrlMapping.second;
- mWebContentsUrlMapping = null;
-
- // Skip opening a new Tab if it doesn't make sense.
- if (isClosing()) return false;
-
- // Creating new Tabs asynchronously requires starting a new Activity to create the Tab,
- // so the Tab returned will always be null. There's no way to know synchronously
- // whether the Tab is created, so assume it's always successful.
- boolean createdSuccessfully = tabCreator.createTabWithWebContents(
- webContents, getId(), TabLaunchType.FROM_LONGPRESS_FOREGROUND, url);
- boolean success = tabCreator.createsTabsAsynchronously() || createdSuccessfully;
- if (success && disposition == WindowOpenDisposition.NEW_POPUP) {
- PolicyAuditor auditor =
- ((ChromeApplication) getApplicationContext()).getPolicyAuditor();
- auditor.notifyAuditEvent(getApplicationContext(), AuditEvent.OPEN_POPUP_URL_SUCCESS,
- url, "");
- }
-
- return success;
- }
-
- @Override
- public void activateContents() {
- boolean activityIsDestroyed = false;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- activityIsDestroyed = mActivity.isDestroyed();
- }
- if (activityIsDestroyed || !isInitialized()) {
- Log.e(TAG, "Activity destroyed before calling activateContents(). Bailing out.");
- return;
- }
-
- TabModel model = getTabModel();
- int index = model.indexOf(Tab.this);
- if (index == TabModel.INVALID_TAB_INDEX) return;
- TabModelUtils.setIndex(model, index);
- bringActivityToForeground();
- }
-
- /**
- * Brings chrome's Activity to foreground, if it is not so.
- */
- protected void bringActivityToForeground() {
- // This intent is sent in order to get the activity back to the foreground if it was
- // not already. The previous call will activate the right tab in the context of the
- // TabModel but will only show the tab to the user if Chrome was already in the
- // foreground.
- // The intent is getting the tabId mostly because it does not cost much to do so.
- // When receiving the intent, the tab associated with the tabId should already be
- // active.
- // Note that calling only the intent in order to activate the tab is slightly slower
- // because it will change the tab when the intent is handled, which happens after
- // Chrome gets back to the foreground.
- Intent newIntent = Tab.createBringTabToFrontIntent(Tab.this.getId());
- newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
- getApplicationContext().startActivity(newIntent);
- }
-
- @Override
- public void closeContents() {
- // Execute outside of callback, otherwise we end up deleting the native
- // objects in the middle of executing methods on them.
- mHandler.removeCallbacks(mCloseContentsRunnable);
- mHandler.post(mCloseContentsRunnable);
- }
-
- @Override
- public boolean takeFocus(boolean reverse) {
- if (reverse) {
- View menuButton = mActivity.findViewById(R.id.menu_button);
- if (menuButton == null || !menuButton.isShown()) {
- menuButton = mActivity.findViewById(R.id.document_menu_button);
- }
- if (menuButton != null && menuButton.isShown()) {
- return menuButton.requestFocus();
- }
-
- View tabSwitcherButton = mActivity.findViewById(R.id.tab_switcher_button);
- if (tabSwitcherButton != null && tabSwitcherButton.isShown()) {
- return tabSwitcherButton.requestFocus();
- }
- } else {
- View urlBar = mActivity.findViewById(R.id.url_bar);
- if (urlBar != null) return urlBar.requestFocus();
- }
- return false;
- }
-
- @Override
- public void handleKeyboardEvent(KeyEvent event) {
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- if (mActivity.onKeyDown(event.getKeyCode(), event)) return;
-
- // Handle the Escape key here (instead of in KeyboardShortcuts.java), so it doesn't
- // interfere with other parts of the activity (e.g. the URL bar).
- if (event.getKeyCode() == KeyEvent.KEYCODE_ESCAPE && event.hasNoModifiers()) {
- WebContents wc = getWebContents();
- if (wc != null) wc.stop();
- return;
- }
- }
- handleMediaKey(event);
- }
-
- /**
- * Redispatches unhandled media keys. This allows bluetooth headphones with play/pause or
- * other buttons to function correctly.
- */
- @TargetApi(19)
- private void handleMediaKey(KeyEvent e) {
- if (Build.VERSION.SDK_INT < 19) return;
- switch (e.getKeyCode()) {
- case KeyEvent.KEYCODE_MUTE:
- case KeyEvent.KEYCODE_HEADSETHOOK:
- case KeyEvent.KEYCODE_MEDIA_PLAY:
- case KeyEvent.KEYCODE_MEDIA_PAUSE:
- case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
- case KeyEvent.KEYCODE_MEDIA_STOP:
- case KeyEvent.KEYCODE_MEDIA_NEXT:
- case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
- case KeyEvent.KEYCODE_MEDIA_REWIND:
- case KeyEvent.KEYCODE_MEDIA_RECORD:
- case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
- case KeyEvent.KEYCODE_MEDIA_CLOSE:
- case KeyEvent.KEYCODE_MEDIA_EJECT:
- case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK:
- AudioManager am = (AudioManager) mActivity.getSystemService(
- Context.AUDIO_SERVICE);
- am.dispatchMediaKeyEvent(e);
- break;
- default:
- break;
- }
- }
-
- /**
- * @return Whether audio is being captured.
- */
- private boolean isCapturingAudio() {
- return !isClosing()
- && ChromeWebContentsDelegateAndroid.nativeIsCapturingAudio(getWebContents());
- }
-
- /**
- * @return Whether video is being captured.
- */
- private boolean isCapturingVideo() {
- return !isClosing()
- && ChromeWebContentsDelegateAndroid.nativeIsCapturingVideo(getWebContents());
- }
- }
private class TabContentViewClient extends ContentViewClient {
@Override
@@ -2221,7 +1865,7 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
return mTitle;
}
- private void updateTitle() {
+ void updateTitle() {
if (isFrozen()) return;
// When restoring the tabs, the title will no longer be populated, so request it from the
@@ -2558,7 +2202,7 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
* @return An instance of a {@link TabChromeWebContentsDelegateAndroid}.
*/
protected TabChromeWebContentsDelegateAndroid createWebContentsDelegate() {
- return new TabChromeWebContentsDelegateAndroid();
+ return new TabChromeWebContentsDelegateAndroid(this, mActivity);
}
/**
@@ -3250,6 +2894,15 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
return mDownloadDelegate.shouldInterceptContextMenuDownload(url);
}
+ void resetSwipeRefreshHandler() {
+ // When the dialog is visible, keeping the refresh animation active
+ // in the background is distracting and unnecessary (and likely to
+ // jank when the dialog is shown).
+ if (mSwipeRefreshHandler != null) {
+ mSwipeRefreshHandler.reset();
+ }
+ }
+
/**
* Checks if spdy proxy is enabled for input url.
* @param url Input url to check for spdy setting.
@@ -3318,8 +2971,6 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
private native void nativeDetachOverlayContentViewCore(long nativeTabAndroid,
ContentViewCore content);
private native boolean nativeHasPrerenderedUrl(long nativeTabAndroid, String url);
- private native void nativeOnRendererUnresponsive(long nativeTabAndroid);
- private native void nativeOnRendererResponsive(long nativeTabAndroid);
private static native void nativeRecordStartupToCommitUma();
}

Powered by Google App Engine
This is Rietveld 408576698