Commit 24eca4b9 authored by Brandon Wylie's avatar Brandon Wylie Committed by Commit Bot

Reparent the current Tab when the theme is changed

* Creating a class which handles reparenting the current tab when the
  theme is swapped.
* Hooking that class into ChromeActivity.
* Adding plumbing to a few ReparentingTask/TabReparentingParams to
  facilitate the process.

Bug: 944302
Change-Id: I2801eba979b3acafa02856a9053bc474bf2f581c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1931763Reviewed-by: default avatarYusuf Ozuysal <yusufo@chromium.org>
Commit-Queue: Brandon Wylie <wylieb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#726136}
parent de225e17
...@@ -941,6 +941,7 @@ chrome_java_sources = [ ...@@ -941,6 +941,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java", "java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java",
"java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolder.java", "java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolder.java",
"java/src/org/chromium/chrome/browser/night_mode/NightModeMetrics.java", "java/src/org/chromium/chrome/browser/night_mode/NightModeMetrics.java",
"java/src/org/chromium/chrome/browser/night_mode/NightModeReparentingController.java",
"java/src/org/chromium/chrome/browser/night_mode/NightModeStateProvider.java", "java/src/org/chromium/chrome/browser/night_mode/NightModeStateProvider.java",
"java/src/org/chromium/chrome/browser/night_mode/NightModeUtils.java", "java/src/org/chromium/chrome/browser/night_mode/NightModeUtils.java",
"java/src/org/chromium/chrome/browser/night_mode/PowerSavingModeMonitor.java", "java/src/org/chromium/chrome/browser/night_mode/PowerSavingModeMonitor.java",
...@@ -1624,6 +1625,7 @@ chrome_java_sources = [ ...@@ -1624,6 +1625,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/tab/TabWebContentsUserData.java", "java/src/org/chromium/chrome/browser/tab/TabWebContentsUserData.java",
"java/src/org/chromium/chrome/browser/tab/TrustedCdn.java", "java/src/org/chromium/chrome/browser/tab/TrustedCdn.java",
"java/src/org/chromium/chrome/browser/tab_activity_glue/ActivityTabWebContentsDelegateAndroid.java", "java/src/org/chromium/chrome/browser/tab_activity_glue/ActivityTabWebContentsDelegateAndroid.java",
"java/src/org/chromium/chrome/browser/tab_activity_glue/ReparentingDelegateFactory.java",
"java/src/org/chromium/chrome/browser/tab_activity_glue/ReparentingTask.java", "java/src/org/chromium/chrome/browser/tab_activity_glue/ReparentingTask.java",
"java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java", "java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java",
"java/src/org/chromium/chrome/browser/tabbed_mode/TabbedNavigationBarColorController.java", "java/src/org/chromium/chrome/browser/tabbed_mode/TabbedNavigationBarColorController.java",
......
...@@ -87,6 +87,7 @@ import org.chromium.chrome.browser.firstrun.ForcedSigninProcessor; ...@@ -87,6 +87,7 @@ import org.chromium.chrome.browser.firstrun.ForcedSigninProcessor;
import org.chromium.chrome.browser.flags.ActivityType; import org.chromium.chrome.browser.flags.ActivityType;
import org.chromium.chrome.browser.flags.FeatureUtilities; import org.chromium.chrome.browser.flags.FeatureUtilities;
import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
import org.chromium.chrome.browser.fullscreen.ComposedBrowserControlsVisibilityDelegate;
import org.chromium.chrome.browser.gsa.ContextReporter; import org.chromium.chrome.browser.gsa.ContextReporter;
import org.chromium.chrome.browser.gsa.GSAAccountChangeListener; import org.chromium.chrome.browser.gsa.GSAAccountChangeListener;
import org.chromium.chrome.browser.gsa.GSAState; import org.chromium.chrome.browser.gsa.GSAState;
...@@ -105,6 +106,7 @@ import org.chromium.chrome.browser.metrics.LaunchMetrics; ...@@ -105,6 +106,7 @@ import org.chromium.chrome.browser.metrics.LaunchMetrics;
import org.chromium.chrome.browser.metrics.UmaSessionStats; import org.chromium.chrome.browser.metrics.UmaSessionStats;
import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
import org.chromium.chrome.browser.nfc.BeamController; import org.chromium.chrome.browser.nfc.BeamController;
import org.chromium.chrome.browser.night_mode.NightModeReparentingController;
import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.ntp.NewTabPage;
import org.chromium.chrome.browser.ntp.NewTabPageUma; import org.chromium.chrome.browser.ntp.NewTabPageUma;
import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.chrome.browser.offlinepages.OfflinePageUtils;
...@@ -129,11 +131,13 @@ import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarManageable; ...@@ -129,11 +131,13 @@ import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarManageable;
import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.chrome.browser.sync.ProfileSyncService;
import org.chromium.chrome.browser.sync.SyncController; import org.chromium.chrome.browser.sync.SyncController;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabDelegateFactory;
import org.chromium.chrome.browser.tab.TabHidingType; import org.chromium.chrome.browser.tab.TabHidingType;
import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabImpl;
import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabLaunchType;
import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tab.TabSelectionType;
import org.chromium.chrome.browser.tab.TabState; import org.chromium.chrome.browser.tab.TabState;
import org.chromium.chrome.browser.tab_activity_glue.ReparentingDelegateFactory;
import org.chromium.chrome.browser.tabmodel.AsyncTabParamsManager; import org.chromium.chrome.browser.tabmodel.AsyncTabParamsManager;
import org.chromium.chrome.browser.tabmodel.EmptyTabModel; import org.chromium.chrome.browser.tabmodel.EmptyTabModel;
import org.chromium.chrome.browser.tabmodel.TabCreatorManager; import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
...@@ -320,6 +324,9 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -320,6 +324,9 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
private List<MenuOrKeyboardActionController.MenuOrKeyboardActionHandler> mMenuActionHandlers = private List<MenuOrKeyboardActionController.MenuOrKeyboardActionHandler> mMenuActionHandlers =
new ArrayList<>(); new ArrayList<>();
/** Controls tab reparenting for night mode. */
NightModeReparentingController mNightModeReparentingController;
@Override @Override
protected ActivityWindowAndroid createWindowAndroid() { protected ActivityWindowAndroid createWindowAndroid() {
return new ChromeWindow(this); return new ChromeWindow(this);
...@@ -356,6 +363,11 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -356,6 +363,11 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
} }
getWindow().setBackgroundDrawable(getBackgroundDrawable()); getWindow().setBackgroundDrawable(getBackgroundDrawable());
mNightModeReparentingController = new NightModeReparentingController(
ReparentingDelegateFactory.createNightModeReparentingControllerDelegate(this),
ReparentingDelegateFactory.createReparentingTaskDelegate(this));
getLifecycleDispatcher().register(mNightModeReparentingController);
} }
protected RootUiCoordinator createRootUiCoordinator() { protected RootUiCoordinator createRootUiCoordinator() {
...@@ -1545,6 +1557,11 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -1545,6 +1557,11 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
return mActivityTabProvider; return mActivityTabProvider;
} }
public TabDelegateFactory getTabDelegateFactory() {
return new TabbedModeTabDelegateFactory(
this, new ComposedBrowserControlsVisibilityDelegate(), getShareDelegateSupplier());
}
/** /**
* Returns the {@link InsetObserverView} that has the current system window * Returns the {@link InsetObserverView} that has the current system window
* insets information. * insets information.
...@@ -2404,4 +2421,16 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -2404,4 +2421,16 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
public RootUiCoordinator getRootUiCoordinatorForTesting() { public RootUiCoordinator getRootUiCoordinatorForTesting() {
return mRootUiCoordinator; return mRootUiCoordinator;
} }
// NightModeStateProvider.Observer implementation.
@Override
public void onNightModeStateChanged() {
// Note: order matters here because the call to super will recreate the activity.
// Note: it's possible for this method to be called before mNightModeReparentingController
// is constructed.
if (mNightModeReparentingController != null) {
mNightModeReparentingController.onNightModeStateChanged();
}
super.onNightModeStateChanged();
}
} }
...@@ -127,7 +127,7 @@ public class HiddenTabHolder { ...@@ -127,7 +127,7 @@ public class HiddenTabHolder {
int width = bounds.right - bounds.left; int width = bounds.right - bounds.left;
int height = bounds.bottom - bounds.top; int height = bounds.bottom - bounds.top;
tab.getWebContents().setSize(width, height); tab.getWebContents().setSize(width, height);
ReparentingTask.detach(tab); ReparentingTask.from(tab).detach();
return tab; return tab;
} }
......
...@@ -46,6 +46,7 @@ import org.chromium.chrome.browser.tab.Tab; ...@@ -46,6 +46,7 @@ import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabAssociatedApp; import org.chromium.chrome.browser.tab.TabAssociatedApp;
import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabLaunchType;
import org.chromium.chrome.browser.tab.TabRedirectHandler; import org.chromium.chrome.browser.tab.TabRedirectHandler;
import org.chromium.chrome.browser.tab_activity_glue.ReparentingDelegateFactory;
import org.chromium.chrome.browser.tabmodel.AsyncTabParams; import org.chromium.chrome.browser.tabmodel.AsyncTabParams;
import org.chromium.chrome.browser.tabmodel.AsyncTabParamsManager; import org.chromium.chrome.browser.tabmodel.AsyncTabParamsManager;
import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModel;
...@@ -316,7 +317,8 @@ public class CustomTabActivityTabController ...@@ -316,7 +317,8 @@ public class CustomTabActivityTabController
if (mode == TabCreationMode.HIDDEN) { if (mode == TabCreationMode.HIDDEN) {
TabReparentingParams params = TabReparentingParams params =
(TabReparentingParams) AsyncTabParamsManager.remove(tab.getId()); (TabReparentingParams) AsyncTabParamsManager.remove(tab.getId());
mReparentingTaskProvider.get(tab).finish(mActivity, mCustomTabDelegateFactory.get(), mReparentingTaskProvider.get(tab).finish(
ReparentingDelegateFactory.createReparentingTaskDelegate(mActivity),
(params == null ? null : params.getFinalizeCallback())); (params == null ? null : params.getFinalizeCallback()));
} }
......
// Copyright 2019 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.night_mode;
import android.util.SparseArray;
import androidx.annotation.NonNull;
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.lifecycle.StartStopWithNativeObserver;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabLaunchType;
import org.chromium.chrome.browser.tab_activity_glue.ReparentingTask;
import org.chromium.chrome.browser.tabmodel.AsyncTabParams;
import org.chromium.chrome.browser.tabmodel.AsyncTabParamsManager;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabReparentingParams;
// TODO(wylieb): Write unittests for this class.
/** Controls the reparenting of tabs when the theme is swapped. */
public class NightModeReparentingController
implements StartStopWithNativeObserver, NightModeStateProvider.Observer {
/** Provides data to {@link NightModeReparentingController} facilitate reparenting tabs. */
public interface Delegate {
/** The current ActivityTabProvider which is used to get the current Tab. */
ActivityTabProvider getActivityTabProvider();
/** Gets a {@link TabModelSelector} which is used to add the tab. */
TabModelSelector getTabModelSelector();
}
private Delegate mDelegate;
private ReparentingTask.Delegate mReparentingDelegate;
/** Constructs a {@link NightModeReparentingController} with the given delegate. */
public NightModeReparentingController(
@NonNull Delegate delegate, @NonNull ReparentingTask.Delegate reparentingDelegate) {
mDelegate = delegate;
mReparentingDelegate = reparentingDelegate;
}
@Override
public void onStartWithNative() {
// Note: for now only the current tab is added to the AsyncTabParamsManager when the theme
// is changed. In the future these will be added in tab index order and read at reverse
// tab index order.
final SparseArray<AsyncTabParams> paramsArray = AsyncTabParamsManager.getAsyncTabParams();
for (int i = 0; i < paramsArray.size(); i++) {
final int tabId = paramsArray.keyAt(i);
AsyncTabParams params = paramsArray.get(tabId);
if (!(params instanceof TabReparentingParams)) continue;
if (params == null) continue;
final TabReparentingParams reparentingParams = (TabReparentingParams) params;
if (!reparentingParams.isFromNightModeReparenting()) continue;
if (!reparentingParams.hasTabToReparent()) continue;
if (!reparentingParams.hasTabIndex()) continue;
final ReparentingTask reparentingTask =
ReparentingTask.get(reparentingParams.getTabToReparent());
if (reparentingTask == null) continue;
reparentingTask.finish(mReparentingDelegate, () -> {
mDelegate.getTabModelSelector().getCurrentModel().addTab(
reparentingParams.getTabToReparent(), reparentingParams.getTabIndex(),
TabLaunchType.FROM_REPARENTING);
AsyncTabParamsManager.remove(tabId);
});
}
}
@Override
public void onStopWithNative() {}
@Override
public void onNightModeStateChanged() {
// TODO(crbug.com/1031332): Reparent all tabs in the current tab model.
Tab tabToDetach = mDelegate.getActivityTabProvider().get();
TabModel currentTabModel = mDelegate.getTabModelSelector().getCurrentModel();
TabReparentingParams params = new TabReparentingParams(tabToDetach, null, null);
params.setTabIndex(currentTabModel.indexOf(tabToDetach));
params.setFromNightModeReparenting(true);
AsyncTabParamsManager.add(tabToDetach.getId(), params);
currentTabModel.removeTab(tabToDetach);
ReparentingTask.from(tabToDetach).detach();
}
}
// Copyright 2019 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.tab_activity_glue;
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.compositor.CompositorViewHolder;
import org.chromium.chrome.browser.night_mode.NightModeReparentingController;
import org.chromium.chrome.browser.tab.TabDelegateFactory;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.ui.base.WindowAndroid;
/** Constructs delegates needed for reparenting tabs. */
public class ReparentingDelegateFactory {
/**
* @return Creates an implementation of {@link ReparentingTask.Delegate} that supplies
* dependencies for {@link ReparentingTask} to reparent a Tab.
*/
public static ReparentingTask.Delegate createReparentingTaskDelegate(
final ChromeActivity chromeActivity) {
return new ReparentingTask.Delegate() {
@Override
public CompositorViewHolder getCompositorViewHolder() {
return chromeActivity.getCompositorViewHolder();
}
@Override
public WindowAndroid getWindowAndroid() {
return chromeActivity.getWindowAndroid();
}
@Override
public TabDelegateFactory getTabDelegateFactory() {
return chromeActivity.getTabDelegateFactory();
}
};
}
/**
* @return Creates an implementation of {@link NightModeReparentingController.Delegate} that
* supplies dependencies to {@link NightModeReparentingController}.
*/
public static NightModeReparentingController.Delegate
createNightModeReparentingControllerDelegate(final ChromeActivity chromeActivity) {
return new NightModeReparentingController.Delegate() {
@Override
public ActivityTabProvider getActivityTabProvider() {
return chromeActivity.getActivityTabProvider();
}
@Override
public TabModelSelector getTabModelSelector() {
return chromeActivity.getTabModelSelector();
}
};
}
}
...@@ -12,19 +12,21 @@ import android.os.Bundle; ...@@ -12,19 +12,21 @@ import android.os.Bundle;
import android.provider.Browser; import android.provider.Browser;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.chromium.base.ContextUtils; import org.chromium.base.ContextUtils;
import org.chromium.base.UserData; import org.chromium.base.UserData;
import org.chromium.base.annotations.NativeMethods; import org.chromium.base.annotations.NativeMethods;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.IntentHandler;
import org.chromium.chrome.browser.compositor.CompositorViewHolder;
import org.chromium.chrome.browser.document.ChromeLauncherActivity; import org.chromium.chrome.browser.document.ChromeLauncherActivity;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabDelegateFactory; import org.chromium.chrome.browser.tab.TabDelegateFactory;
import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabImpl;
import org.chromium.chrome.browser.tabmodel.AsyncTabParamsManager; import org.chromium.chrome.browser.tabmodel.AsyncTabParamsManager;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabReparentingParams; import org.chromium.chrome.browser.tabmodel.TabReparentingParams;
import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContents;
import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.base.WindowAndroid;
...@@ -33,6 +35,27 @@ import org.chromium.ui.base.WindowAndroid; ...@@ -33,6 +35,27 @@ import org.chromium.ui.base.WindowAndroid;
* Takes care of reparenting a Tab object from one Activity to another. * Takes care of reparenting a Tab object from one Activity to another.
*/ */
public class ReparentingTask implements UserData { public class ReparentingTask implements UserData {
/** Provides data to {@link ReparentingTask} facilitate reparenting tabs. */
public interface Delegate {
/**
* Gets a {@link CompositorViewHolder} which is passed on to {@link ReparentingTask}, used
* in the reparenting process.
*/
CompositorViewHolder getCompositorViewHolder();
/**
* Gets a {@link WindowAndroid} which is passed on to {@link ReparentingTask}, used in the
* reparenting process.
*/
WindowAndroid getWindowAndroid();
/**
* Gets a {@link TabDelegateFactory} which is passed on to {@link ReparentingTask}, used in
* the reparenting process.
*/
TabDelegateFactory getTabDelegateFactory();
}
private static final Class<ReparentingTask> USER_DATA_KEY = ReparentingTask.class; private static final Class<ReparentingTask> USER_DATA_KEY = ReparentingTask.class;
private final Tab mTab; private final Tab mTab;
...@@ -52,7 +75,7 @@ public class ReparentingTask implements UserData { ...@@ -52,7 +75,7 @@ public class ReparentingTask implements UserData {
} }
@Nullable @Nullable
private static ReparentingTask get(Tab tab) { public static ReparentingTask get(Tab tab) {
return tab.getUserDataHost().getUserData(USER_DATA_KEY); return tab.getUserDataHost().getUserData(USER_DATA_KEY);
} }
...@@ -96,7 +119,7 @@ public class ReparentingTask implements UserData { ...@@ -96,7 +119,7 @@ public class ReparentingTask implements UserData {
AsyncTabParamsManager.add( AsyncTabParamsManager.add(
mTab.getId(), new TabReparentingParams(mTab, intent, finalizeCallback)); mTab.getId(), new TabReparentingParams(mTab, intent, finalizeCallback));
detach(mTab); detach();
} }
context.startActivity(intent, startActivityOptions); context.startActivity(intent, startActivityOptions);
...@@ -110,16 +133,16 @@ public class ReparentingTask implements UserData { ...@@ -110,16 +133,16 @@ public class ReparentingTask implements UserData {
* - Removes the tab from its current {@link TabModelSelector}, effectively severing * - Removes the tab from its current {@link TabModelSelector}, effectively severing
* the {@link Activity} to {@link Tab} link. * the {@link Activity} to {@link Tab} link.
*/ */
public static void detach(Tab tab) { public void detach() {
// TODO(yusufo): We can't call tab.updateWindowAndroid that sets |mWindowAndroid| to null // TODO(yusufo): We can't call tab.updateWindowAndroid that sets |mWindowAndroid| to null
// because many code paths (including navigation) expect the tab to always be associated // because many code paths (including navigation) expect the tab to always be associated
// with an activity, and will crash. crbug.com/657007 // with an activity, and will crash. crbug.com/657007
WebContents webContents = tab.getWebContents(); WebContents webContents = mTab.getWebContents();
if (webContents != null) webContents.setTopLevelNativeWindow(null); if (webContents != null) webContents.setTopLevelNativeWindow(null);
// TabModelSelector of this Tab, if present, gets notified to remove the tab from // TabModelSelector of this Tab, if present, gets notified to remove the tab from
// the TabModel it belonged to. // the TabModel it belonged to.
tab.updateAttachment(null, null); mTab.updateAttachment(null, null);
} }
/** /**
...@@ -127,14 +150,12 @@ public class ReparentingTask implements UserData { ...@@ -127,14 +150,12 @@ public class ReparentingTask implements UserData {
* the tab and related objects to reference it. This updates many delegates inside the tab * the tab and related objects to reference it. This updates many delegates inside the tab
* and {@link WebContents} both on java and native sides. * and {@link WebContents} both on java and native sides.
* *
* @param activity A new {@link ChromeActivity} to attach this Tab instance to. * @param delegate A delegate that provides dependencies.
* @param tabDelegateFactory The new delegate factory this tab should be using.
* @param finalizeCallback A Callback to be called after the Tab has been reparented. * @param finalizeCallback A Callback to be called after the Tab has been reparented.
*/ */
public void finish(ChromeActivity activity, TabDelegateFactory tabDelegateFactory, public void finish(@NonNull Delegate delegate, @Nullable Runnable finalizeCallback) {
@Nullable Runnable finalizeCallback) { delegate.getCompositorViewHolder().prepareForTabReparenting();
activity.getCompositorViewHolder().prepareForTabReparenting(); attach(delegate.getWindowAndroid(), delegate.getTabDelegateFactory());
attach(activity.getWindowAndroid(), tabDelegateFactory);
((TabImpl) mTab).setIsTabStateDirty(true); ((TabImpl) mTab).setIsTabStateDirty(true);
if (finalizeCallback != null) finalizeCallback.run(); if (finalizeCallback != null) finalizeCallback.run();
} }
......
...@@ -25,6 +25,7 @@ import org.chromium.chrome.browser.tab.TabLaunchType; ...@@ -25,6 +25,7 @@ import org.chromium.chrome.browser.tab.TabLaunchType;
import org.chromium.chrome.browser.tab.TabParentIntent; import org.chromium.chrome.browser.tab.TabParentIntent;
import org.chromium.chrome.browser.tab.TabRedirectHandler; import org.chromium.chrome.browser.tab.TabRedirectHandler;
import org.chromium.chrome.browser.tab.TabState; import org.chromium.chrome.browser.tab.TabState;
import org.chromium.chrome.browser.tab_activity_glue.ReparentingDelegateFactory;
import org.chromium.chrome.browser.tab_activity_glue.ReparentingTask; import org.chromium.chrome.browser.tab_activity_glue.ReparentingTask;
import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.chrome.browser.util.IntentUtils;
import org.chromium.components.url_formatter.UrlFormatter; import org.chromium.components.url_formatter.UrlFormatter;
...@@ -128,7 +129,8 @@ public class ChromeTabCreator extends TabCreatorManager.TabCreator { ...@@ -128,7 +129,8 @@ public class ChromeTabCreator extends TabCreatorManager.TabCreator {
TabReparentingParams params = (TabReparentingParams) asyncParams; TabReparentingParams params = (TabReparentingParams) asyncParams;
tab = params.getTabToReparent(); tab = params.getTabToReparent();
ReparentingTask.from(tab).finish( ReparentingTask.from(tab).finish(
mActivity, createDefaultTabDelegateFactory(), params.getFinalizeCallback()); ReparentingDelegateFactory.createReparentingTaskDelegate(mActivity),
params.getFinalizeCallback());
} else if (asyncParams != null && asyncParams.getWebContents() != null) { } else if (asyncParams != null && asyncParams.getWebContents() != null) {
openInForeground = true; openInForeground = true;
WebContents webContents = asyncParams.getWebContents(); WebContents webContents = asyncParams.getWebContents();
......
...@@ -17,10 +17,15 @@ import org.chromium.content_public.browser.WebContents; ...@@ -17,10 +17,15 @@ import org.chromium.content_public.browser.WebContents;
* Class for handling tab reparenting operations across multiple activities. * Class for handling tab reparenting operations across multiple activities.
*/ */
public class TabReparentingParams implements AsyncTabParams { public class TabReparentingParams implements AsyncTabParams {
private static final int TAB_INDEX_NOT_SET = -1;
private final Tab mTabToReparent; private final Tab mTabToReparent;
private final Intent mOriginalIntent; private final Intent mOriginalIntent;
private final Runnable mFinalizeCallback; private final Runnable mFinalizeCallback;
private int mTabIndex = TAB_INDEX_NOT_SET;
private boolean mIsFromNightModeReparenting;
/** /**
* Basic constructor for {@link TabReparentingParams}. * Basic constructor for {@link TabReparentingParams}.
*/ */
...@@ -61,6 +66,10 @@ public class TabReparentingParams implements AsyncTabParams { ...@@ -61,6 +66,10 @@ public class TabReparentingParams implements AsyncTabParams {
return mTabToReparent; return mTabToReparent;
} }
public boolean hasTabToReparent() {
return mTabToReparent != null;
}
/** /**
* Returns the callback to be used once Tab reparenting has finished, if any. * Returns the callback to be used once Tab reparenting has finished, if any.
*/ */
...@@ -72,4 +81,31 @@ public class TabReparentingParams implements AsyncTabParams { ...@@ -72,4 +81,31 @@ public class TabReparentingParams implements AsyncTabParams {
public void destroy() { public void destroy() {
if (mTabToReparent != null) mTabToReparent.destroy(); if (mTabToReparent != null) mTabToReparent.destroy();
} }
// Night mode reparenting implementation.
/** Set the tab index for later retrieval. */
public void setTabIndex(int tabIndex) {
mTabIndex = tabIndex;
}
/** @return Index of the stored tab. */
public int getTabIndex() {
return mTabIndex;
}
/** @return Whether this holds a tab index. */
public boolean hasTabIndex() {
return mTabIndex != TAB_INDEX_NOT_SET;
}
/** Set whether these params are from night mode reparenting. */
public void setFromNightModeReparenting(boolean fromNightModeReparenting) {
mIsFromNightModeReparenting = fromNightModeReparenting;
}
/** @return Whether these params are from night mode reparenting. */
public boolean isFromNightModeReparenting() {
return mIsFromNightModeReparenting;
}
} }
...@@ -126,7 +126,7 @@ public class CustomTabActivityTabControllerTest { ...@@ -126,7 +126,7 @@ public class CustomTabActivityTabControllerTest {
public void finishesReparentingHiddenTab() { public void finishesReparentingHiddenTab() {
Tab hiddenTab = env.prepareHiddenTab(); Tab hiddenTab = env.prepareHiddenTab();
env.reachNativeInit(mTabController); env.reachNativeInit(mTabController);
verify(env.reparentingTaskProvider.get(hiddenTab)).finish(any(), any(), any()); verify(env.reparentingTaskProvider.get(hiddenTab)).finish(any(), any());
} }
@Test @Test
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment