| 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 a88063610d22b56e782c5cfaddd3ccf9e09ac6ea..44faade0141a2d1de1323fbe0c1fd46d0f637015 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
|
| @@ -22,6 +22,7 @@ import android.text.TextUtils;
|
| import android.util.Log;
|
| import android.util.Pair;
|
| import android.view.ContextMenu;
|
| +import android.view.ContextThemeWrapper;
|
| import android.view.KeyEvent;
|
| import android.view.View;
|
| import android.view.View.OnClickListener;
|
| @@ -163,13 +164,6 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| /** Used for logging. */
|
| private static final String TAG = "Tab";
|
|
|
| - /**
|
| - * The {@link Activity} used to create {@link View}s and other Android components. Unlike
|
| - * {@link #mApplicationContext}, this is not publicly exposed to help prevent leaking the
|
| - * {@link Activity}.
|
| - */
|
| - protected final ChromeActivity mActivity;
|
| -
|
| private long mNativeTabAndroid;
|
|
|
| /** Unique id of this tab (within its container). */
|
| @@ -184,6 +178,8 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| */
|
| private final Context mApplicationContext;
|
|
|
| + private final ContextThemeWrapper mThemedContext;
|
| +
|
| /** Gives {@link Tab} a way to interact with the Android window. */
|
| private final WindowAndroid mWindowAndroid;
|
|
|
| @@ -388,23 +384,25 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| private final Runnable mCloseContentsRunnable = new Runnable() {
|
| @Override
|
| public void run() {
|
| - boolean isSelected = mActivity.getTabModelSelector().getCurrentTab() == Tab.this;
|
| - mActivity.getTabModelSelector().closeTab(Tab.this);
|
| + TabModelSelector selector = getTabModelSelector();
|
| + if (selector == null) return;
|
| + boolean isSelected = selector.getCurrentTab() == Tab.this;
|
| + selector.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)
|
| + && getActivity().getIntent() != getParentIntent()) {
|
| + boolean mayLaunch = FeatureUtilities.isDocumentMode(mApplicationContext)
|
| ? isParentInAndroidOverview() : true;
|
| - if (mayLaunch) mActivity.startActivity(getParentIntent());
|
| + if (mayLaunch) getActivity().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);
|
| + ActivityManager activityManager = (ActivityManager) mApplicationContext.
|
| + getSystemService(Context.ACTIVITY_SERVICE);
|
| for (ActivityManager.AppTask task : activityManager.getAppTasks()) {
|
| Intent taskIntent = DocumentUtils.getBaseIntentFromTask(task);
|
| if (taskIntent != null && taskIntent.filterEquals(getParentIntent())) return true;
|
| @@ -467,10 +465,11 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
|
|
| @Override
|
| public void onOpenInNewTab(String url, Referrer referrer) {
|
| + if (getTabModelSelector() == null) return;
|
| RecordUserAction.record("MobileNewTabOpened");
|
| LoadUrlParams loadUrlParams = new LoadUrlParams(url);
|
| loadUrlParams.setReferrer(referrer);
|
| - mActivity.getTabModelSelector().openNewTab(loadUrlParams,
|
| + getTabModelSelector().openNewTab(loadUrlParams,
|
| TabLaunchType.FROM_LONGPRESS_BACKGROUND, Tab.this, isIncognito());
|
| }
|
|
|
| @@ -486,8 +485,9 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
|
|
| @Override
|
| public void onOpenInNewIncognitoTab(String url) {
|
| + if (getTabModelSelector() == null) return;
|
| RecordUserAction.record("MobileNewTabOpened");
|
| - mActivity.getTabModelSelector().openNewTab(new LoadUrlParams(url),
|
| + getTabModelSelector().openNewTab(new LoadUrlParams(url),
|
| TabLaunchType.FROM_LONGPRESS_FOREGROUND, Tab.this, true);
|
| }
|
|
|
| @@ -506,11 +506,12 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
|
|
| @Override
|
| public void onOpenImageInNewTab(String url, Referrer referrer) {
|
| + if (getTabModelSelector() == null) return;
|
| boolean useOriginal = isSpdyProxyEnabledForUrl(url);
|
| LoadUrlParams loadUrlParams = new LoadUrlParams(url);
|
| loadUrlParams.setVerbatimHeaders(useOriginal ? PAGESPEED_PASSTHROUGH_HEADERS : null);
|
| loadUrlParams.setReferrer(referrer);
|
| - mActivity.getTabModelSelector().openNewTab(loadUrlParams,
|
| + getTabModelSelector().openNewTab(loadUrlParams,
|
| TabLaunchType.FROM_LONGPRESS_BACKGROUND, Tab.this, isIncognito());
|
| }
|
|
|
| @@ -552,9 +553,8 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| // 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();
|
| - }
|
| + if (mSwipeRefreshHandler != null) mSwipeRefreshHandler.reset();
|
| + if (getActivity() == null) return;
|
| RepostFormWarningDialog warningDialog = new RepostFormWarningDialog(
|
| new Runnable() {
|
| @Override
|
| @@ -567,7 +567,7 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| getWebContents().getNavigationController().continuePendingReload();
|
| }
|
| });
|
| - warningDialog.show(mActivity.getFragmentManager(), null);
|
| + warningDialog.show(getActivity().getFragmentManager(), null);
|
| }
|
|
|
| @Override
|
| @@ -609,12 +609,13 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| observer.webContentsCreated(Tab.this, sourceWebContents, openerRenderFrameId,
|
| frameName, targetUrl, newWebContents);
|
| }
|
| + if (getActivity() == null) return;
|
| // 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());
|
| + TabCreator tabCreator = getActivity().getTabCreator(isIncognito());
|
|
|
| if (tabCreator != null && tabCreator.createsTabsAsynchronously()) {
|
| DocumentWebContentsDelegate.getInstance().attachDelegate(newWebContents);
|
| @@ -656,15 +657,17 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| private Pair<WebContents, String> mWebContentsUrlMapping;
|
|
|
| protected TabModel getTabModel() {
|
| + if (getTabModelSelector() == null) return null;
|
| // TODO(dfalcantara): Remove this when DocumentActivity.getTabModelSelector()
|
| // can return a TabModelSelector that activateContents() can use.
|
| - return mActivity.getTabModelSelector().getModel(isIncognito());
|
| + return getTabModelSelector().getModel(isIncognito());
|
| }
|
|
|
| @Override
|
| public boolean shouldResumeRequestsForCreatedWindow() {
|
| + if (getActivity() == null) return false;
|
| // Pause the WebContents if an Activity has to be created for it first.
|
| - TabCreator tabCreator = mActivity.getTabCreator(isIncognito());
|
| + TabCreator tabCreator = getActivity().getTabCreator(isIncognito());
|
| assert tabCreator != null;
|
| return !tabCreator.createsTabsAsynchronously();
|
| }
|
| @@ -673,8 +676,8 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| public boolean addNewContents(WebContents sourceWebContents, WebContents webContents,
|
| int disposition, Rect initialPosition, boolean userGesture) {
|
| assert mWebContentsUrlMapping.first == webContents;
|
| -
|
| - TabCreator tabCreator = mActivity.getTabCreator(isIncognito());
|
| + if (getActivity() == null) return false;
|
| + TabCreator tabCreator = getActivity().getTabCreator(isIncognito());
|
| assert tabCreator != null;
|
|
|
| // Grab the URL, which might not be available via the Tab.
|
| @@ -703,8 +706,9 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| @Override
|
| public void activateContents() {
|
| boolean activityIsDestroyed = false;
|
| - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
| - activityIsDestroyed = mActivity.isDestroyed();
|
| + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1
|
| + && getActivity() != null) {
|
| + activityIsDestroyed = getActivity().isDestroyed();
|
| }
|
| if (activityIsDestroyed || !isInitialized()) {
|
| Log.e(TAG, "Activity destroyed before calling activateContents(). Bailing out.");
|
| @@ -748,21 +752,23 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
|
|
| @Override
|
| public boolean takeFocus(boolean reverse) {
|
| + if (getActivity() == null) return false;
|
| + Activity activity = getActivity();
|
| if (reverse) {
|
| - View menuButton = mActivity.findViewById(R.id.menu_button);
|
| + View menuButton = activity.findViewById(R.id.menu_button);
|
| if (menuButton == null || !menuButton.isShown()) {
|
| - menuButton = mActivity.findViewById(R.id.document_menu_button);
|
| + menuButton = activity.findViewById(R.id.document_menu_button);
|
| }
|
| if (menuButton != null && menuButton.isShown()) {
|
| return menuButton.requestFocus();
|
| }
|
|
|
| - View tabSwitcherButton = mActivity.findViewById(R.id.tab_switcher_button);
|
| + View tabSwitcherButton = activity.findViewById(R.id.tab_switcher_button);
|
| if (tabSwitcherButton != null && tabSwitcherButton.isShown()) {
|
| return tabSwitcherButton.requestFocus();
|
| }
|
| } else {
|
| - View urlBar = mActivity.findViewById(R.id.url_bar);
|
| + View urlBar = activity.findViewById(R.id.url_bar);
|
| if (urlBar != null) return urlBar.requestFocus();
|
| }
|
| return false;
|
| @@ -770,8 +776,9 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
|
|
| @Override
|
| public void handleKeyboardEvent(KeyEvent event) {
|
| + if (getActivity() == null) return;
|
| if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
| - if (mActivity.onKeyDown(event.getKeyCode(), event)) return;
|
| + if (getActivity().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).
|
| @@ -806,7 +813,7 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| case KeyEvent.KEYCODE_MEDIA_CLOSE:
|
| case KeyEvent.KEYCODE_MEDIA_EJECT:
|
| case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK:
|
| - AudioManager am = (AudioManager) mActivity.getSystemService(
|
| + AudioManager am = (AudioManager) mApplicationContext.getSystemService(
|
| Context.AUDIO_SERVICE);
|
| am.dispatchMediaKeyEvent(e);
|
| break;
|
| @@ -885,7 +892,7 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
|
|
| @Override
|
| public void performWebSearch(String searchQuery) {
|
| - if (TextUtils.isEmpty(searchQuery)) return;
|
| + if (TextUtils.isEmpty(searchQuery) || getTabModelSelector() == null) return;
|
| String url = TemplateUrlService.getInstance().getUrlForSearchQuery(searchQuery);
|
| String headers = GeolocationHeader.getGeoHeader(getApplicationContext(), url,
|
| isIncognito());
|
| @@ -893,13 +900,14 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| LoadUrlParams loadUrlParams = new LoadUrlParams(url);
|
| loadUrlParams.setVerbatimHeaders(headers);
|
| loadUrlParams.setTransitionType(PageTransition.GENERATED);
|
| - mActivity.getTabModelSelector().openNewTab(loadUrlParams,
|
| + getTabModelSelector().openNewTab(loadUrlParams,
|
| TabLaunchType.FROM_LONGPRESS_FOREGROUND, Tab.this, isIncognito());
|
| }
|
|
|
| @Override
|
| public ContentVideoViewClient getContentVideoViewClient() {
|
| - return new ActivityContentVideoViewClient(mActivity) {
|
| + assert getActivity() != null;
|
| + return new ActivityContentVideoViewClient(getActivity()) {
|
| @Override
|
| public void enterFullscreenVideo(View view) {
|
| super.enterFullscreenVideo(view);
|
| @@ -1154,17 +1162,17 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| * @param window An instance of a {@link WindowAndroid}.
|
| * @param frozenState State containing information about this Tab, if it was persisted.
|
| */
|
| - public Tab(int id, int parentId, boolean incognito, ChromeActivity activity,
|
| + public Tab(int id, int parentId, boolean incognito, Context context,
|
| WindowAndroid window, TabLaunchType type, TabState frozenState) {
|
| mId = TabIdManager.getInstance().generateValidId(id);
|
| mParentId = parentId;
|
| mIncognito = incognito;
|
| - mActivity = activity;
|
| - mApplicationContext = activity != null ? activity.getApplicationContext() : null;
|
| + mApplicationContext = context != null ? context.getApplicationContext() : null;
|
| + mThemedContext = new ContextThemeWrapper(mApplicationContext, R.style.MainTheme);
|
| mWindowAndroid = window;
|
| mLaunchType = type;
|
| - if (mActivity != null) {
|
| - Resources resources = mActivity.getResources();
|
| + if (mApplicationContext != null) {
|
| + Resources resources = mApplicationContext.getResources();
|
| mIdealFaviconSize = resources.getDimensionPixelSize(R.dimen.default_favicon_size);
|
| mDefaultThemeColor = mIncognito
|
| ? ApiCompatibilityUtils.getColor(resources, R.color.incognito_primary_color)
|
| @@ -1196,6 +1204,18 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| };
|
| }
|
|
|
| + protected ChromeActivity getActivity() {
|
| + if (getWindowAndroid() == null) return null;
|
| + Activity activity = getWindowAndroid().getActivity().get();
|
| + if (!(activity instanceof ChromeActivity)) return null;
|
| + return (ChromeActivity) activity;
|
| + }
|
| +
|
| + protected TabModelSelector getTabModelSelector() {
|
| + if (getActivity() == null) return null;
|
| + return getActivity().getTabModelSelector();
|
| + }
|
| +
|
| /**
|
| * TODO(aurimas): remove this method once Tab and ChromeTab are merged.
|
| */
|
| @@ -1451,7 +1471,7 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| if (printingController == null) return;
|
|
|
| printingController.setPendingPrint(new TabPrinter(this),
|
| - new PrintManagerDelegateImpl(mActivity));
|
| + new PrintManagerDelegateImpl(mApplicationContext));
|
| }
|
|
|
| /**
|
| @@ -1857,7 +1877,7 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| * @return {@link AppBannerManager} to be used for this tab. May be null.
|
| */
|
| protected AppBannerManager createAppBannerManager() {
|
| - return new AppBannerManager(this, mActivity);
|
| + return new AppBannerManager(this);
|
| }
|
|
|
| /**
|
| @@ -2009,9 +2029,9 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| * {@link ContentViewCore}.
|
| */
|
| protected void initContentViewCore(WebContents webContents) {
|
| - ContentViewCore cvc = new ContentViewCore(mActivity);
|
| - ContentView cv = ContentView.createContentView(mActivity, cvc);
|
| - cv.setContentDescription(mActivity.getResources().getString(
|
| + ContentViewCore cvc = new ContentViewCore(mThemedContext);
|
| + ContentView cv = ContentView.createContentView(mThemedContext, cvc);
|
| + cv.setContentDescription(mApplicationContext.getResources().getString(
|
| R.string.accessibility_content_view));
|
| cvc.initialize(cv, cv, webContents, getWindowAndroid());
|
| setContentViewCore(cvc);
|
| @@ -2045,7 +2065,7 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| assert false;
|
| mContentViewParent.removeAllViews();
|
| }
|
| - mContentViewParent = new FrameLayout(mActivity);
|
| + mContentViewParent = new FrameLayout(mThemedContext);
|
| mContentViewParent.addView(cvc.getContainerView(),
|
| new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
|
|
|
| @@ -2064,13 +2084,14 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| if (mInfoBarContainer == null) {
|
| // The InfoBarContainer needs to be created after the ContentView has been natively
|
| // initialized.
|
| - mInfoBarContainer = new InfoBarContainer(mActivity, getId(), mContentViewParent, this);
|
| + mInfoBarContainer = new InfoBarContainer(
|
| + mThemedContext, getId(), mContentViewParent, this);
|
| } else {
|
| mInfoBarContainer.onParentViewChanged(getId(), mContentViewParent);
|
| }
|
| mInfoBarContainer.setContentViewCore(mContentViewCore);
|
|
|
| - mSwipeRefreshHandler = new SwipeRefreshHandler(mActivity);
|
| + mSwipeRefreshHandler = new SwipeRefreshHandler(mThemedContext);
|
| mSwipeRefreshHandler.setContentViewCore(mContentViewCore);
|
|
|
| for (TabObserver observer : mObservers) observer.onContentChanged(this);
|
| @@ -2080,11 +2101,15 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| // web views.
|
| mContentViewCore.setShouldSetAccessibilityFocusOnPageLoad(true);
|
|
|
| - mDownloadDelegate = new ChromeDownloadDelegate(mActivity,
|
| - mActivity.getTabModelSelector(), this);
|
| + mDownloadDelegate = new ChromeDownloadDelegate(mThemedContext, this);
|
| cvc.setDownloadDelegate(mDownloadDelegate);
|
| }
|
|
|
| + public boolean closeTab() {
|
| + if (getTabModelSelector() == null) return false;
|
| + return getTabModelSelector().closeTab(this);
|
| + }
|
| +
|
| /**
|
| * Constructs and shows a sad tab (Aw, Snap!).
|
| */
|
| @@ -2110,7 +2135,7 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| // Make sure we are not adding the "Aw, snap" view over an existing one.
|
| assert mSadTabView == null;
|
| mSadTabView = SadTabViewFactory.createSadTabView(
|
| - mActivity, suggestionAction, reloadButtonAction);
|
| + mThemedContext, suggestionAction, reloadButtonAction);
|
|
|
| // Show the sad tab inside ContentView.
|
| getContentViewCore().getContainerView().addView(
|
| @@ -2316,7 +2341,7 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| */
|
| @CalledByNative
|
| public boolean loadIfNeeded() {
|
| - if (mActivity == null) {
|
| + if (getActivity() == null) {
|
| Log.e(TAG, "Tab couldn't be loaded because Context was null.");
|
| return false;
|
| }
|
| @@ -2630,7 +2655,7 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| * return null.
|
| */
|
| public SnackbarManager getSnackbarManager() {
|
| - return mActivity.getSnackbarManager();
|
| + return getActivity() != null ? getActivity().getSnackbarManager() : null;
|
| }
|
|
|
| /**
|
| @@ -2646,9 +2671,9 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
| @CalledByNative
|
| public void swapWebContents(
|
| WebContents webContents, boolean didStartLoad, boolean didFinishLoad) {
|
| - ContentViewCore cvc = new ContentViewCore(mActivity);
|
| - ContentView cv = ContentView.createContentView(mActivity, cvc);
|
| - cv.setContentDescription(mActivity.getResources().getString(
|
| + ContentViewCore cvc = new ContentViewCore(mThemedContext);
|
| + ContentView cv = ContentView.createContentView(mThemedContext, cvc);
|
| + cv.setContentDescription(mApplicationContext.getResources().getString(
|
| R.string.accessibility_content_view));
|
| cvc.initialize(cv, cv, webContents, getWindowAndroid());
|
| swapContentViewCore(cvc, false, didStartLoad, didFinishLoad);
|
| @@ -3107,13 +3132,13 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
|
|
|
| // If shouldIgnoreNewTab returns true, the intent is handled by another
|
| // activity. As a result, don't launch a new tab to open the URL.
|
| - if (shouldIgnoreNewTab(url, incognito)) return;
|
| + if (shouldIgnoreNewTab(url, incognito) || getTabModelSelector() == null) return;
|
|
|
| LoadUrlParams loadUrlParams = new LoadUrlParams(url);
|
| loadUrlParams.setVerbatimHeaders(extraHeaders);
|
| loadUrlParams.setPostData(postData);
|
| loadUrlParams.setIsRendererInitiated(isRendererInitiated);
|
| - mActivity.getTabModelSelector().openNewTab(
|
| + getTabModelSelector().openNewTab(
|
| loadUrlParams, tabLaunchType, parentTab, incognito);
|
| }
|
|
|
|
|