From 807d0f9ecf387fc2d37dd6e39ca3116ca27847e0 Mon Sep 17 00:00:00 2001 From: Will Osborn Date: Wed, 30 Apr 2025 12:57:34 +0000 Subject: [PATCH] Better null handling for OverviewComponentObserver.getContainerInterface Bug: 413634484 Test: local + unit tests Flag: EXEMPT bugfix Change-Id: I249cd1925ac416e9861be9d0c3c451e2b6cdff43 --- .../launcher3/dagger/PerDisplayModule.kt | 13 ++---- .../launcher3/taskbar/TaskbarManagerImpl.java | 13 +++--- .../uioverrides/QuickstepLauncher.java | 8 +++- .../states/BackgroundAppState.java | 2 +- .../NoButtonQuickSwitchTouchController.java | 2 +- .../PortraitStatesTouchController.java | 2 +- .../quickstep/FallbackWindowInterface.java | 33 ++++++++------- .../android/quickstep/InputConsumerUtils.kt | 18 ++++---- .../quickstep/OverviewCommandHelper.kt | 14 +++---- .../quickstep/OverviewComponentObserver.java | 1 + .../QuickstepTestInformationHandler.java | 11 ++++- .../android/quickstep/RecentsActivity.java | 5 +++ .../com/android/quickstep/TaskViewUtils.java | 4 +- .../quickstep/TouchInteractionService.java | 20 +++++---- .../fallback/FallbackRecentsView.java | 8 ---- .../fallback/window/RecentsWindowManager.kt | 21 +++++++++- .../quickstep/util/ActivityPreloadUtil.kt | 2 +- .../quickstep/util/RecentsOrientedState.java | 2 +- .../SplitWithKeyboardShortcutController.java | 8 +++- .../quickstep/views/LauncherRecentsView.java | 11 +---- .../android/quickstep/views/RecentsView.java | 41 ++++++++----------- .../quickstep/views/RecentsViewContainer.java | 6 +++ .../quickstep/views/RecentsViewUtils.kt | 2 +- .../com/android/quickstep/views/TaskView.kt | 2 +- 24 files changed, 137 insertions(+), 112 deletions(-) diff --git a/quickstep/src/com/android/launcher3/dagger/PerDisplayModule.kt b/quickstep/src/com/android/launcher3/dagger/PerDisplayModule.kt index 19fa1a8ca0..dbb01cf162 100644 --- a/quickstep/src/com/android/launcher3/dagger/PerDisplayModule.kt +++ b/quickstep/src/com/android/launcher3/dagger/PerDisplayModule.kt @@ -123,22 +123,15 @@ object PerDisplayRepositoriesModule { @Provides @LauncherAppSingleton fun provideFallbackWindowInterfaceRepo( - repositoryFactory: PerDisplayInstanceRepositoryImpl.Factory, - instanceFactory: FallbackWindowInterface.Factory, - recentsWindowManagerRepository: PerDisplayRepository, + repositoryFactory: PerDisplayInstanceRepositoryImpl.Factory ): PerDisplayRepository { return if (enableOverviewOnConnectedDisplays()) { repositoryFactory.create( "FallbackWindowInterfaceRepo", - { displayId -> - recentsWindowManagerRepository[displayId]?.let { instanceFactory.create(it) } - }, + { _ -> FallbackWindowInterface() }, ) } else { - SingleInstanceRepositoryImpl( - "FallbackWindowInterfaceRepo", - instanceFactory.create(recentsWindowManagerRepository[DEFAULT_DISPLAY]), - ) + SingleInstanceRepositoryImpl("FallbackWindowInterfaceRepo", FallbackWindowInterface()) } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManagerImpl.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManagerImpl.java index 8fd94fad91..202e9e8996 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManagerImpl.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManagerImpl.java @@ -91,6 +91,7 @@ import com.android.launcher3.util.LooperExecutor; import com.android.launcher3.util.SettingsCache; import com.android.launcher3.util.SimpleBroadcastReceiver; import com.android.quickstep.AllAppsActionManager; +import com.android.quickstep.BaseContainerInterface; import com.android.quickstep.OverviewComponentObserver; import com.android.quickstep.RecentsActivity; import com.android.quickstep.SystemDecorationChangeObserver; @@ -727,12 +728,14 @@ public class TaskbarManagerImpl implements DisplayDecorationListener { /** Creates a {@link TaskbarUIController} to use with non default displays. */ private TaskbarUIController createTaskbarUIControllerForNonDefaultDisplay(int displayId) { debugTaskbarManager("createTaskbarUIControllerForNonDefaultDisplay", displayId); - RecentsViewContainer rvc = OverviewComponentObserver.INSTANCE.get( - mBaseContext).getContainerInterface(displayId).getCreatedContainer(); - if (rvc instanceof RecentsWindowManager) { - return createTaskbarUIControllerForRecentsViewContainer(rvc, displayId); + BaseContainerInterface containerInterface = OverviewComponentObserver.INSTANCE.get( + mBaseContext).getContainerInterface(displayId); + if (containerInterface != null) { + RecentsViewContainer container = containerInterface.getCreatedContainer(); + if (container instanceof RecentsWindowManager) { + return createTaskbarUIControllerForRecentsViewContainer(container, displayId); + } } - return new TaskbarUIController(); } diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 7fb1a80734..6a07c5b2fc 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -175,6 +175,7 @@ import com.android.launcher3.util.StableViewInfo; import com.android.launcher3.util.StartActivityParams; import com.android.launcher3.util.TouchController; import com.android.launcher3.views.FloatingIconView; +import com.android.quickstep.LauncherActivityInterface; import com.android.quickstep.OverviewCommandHelper; import com.android.quickstep.OverviewComponentObserver; import com.android.quickstep.OverviewComponentObserver.OverviewChangeListener; @@ -306,7 +307,7 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer, super.setupViews(); mActionsView = findViewById(R.id.overview_actions_view); - RecentsView overviewPanel = getOverviewPanel(); + RecentsView overviewPanel = getOverviewPanel(); SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.get(this); mSplitSelectStateController = new SplitSelectStateController(this, getStateManager(), @@ -1589,4 +1590,9 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer, return isOverviewBackgroundBlurEnabled() ? R.style.OverviewBlurStyle : R.style.OverviewBlurFallbackStyle; } + + @Override + public LauncherActivityInterface getContainerInterface() { + return LauncherActivityInterface.INSTANCE; + } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java index 542c9d8839..9550933c40 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java @@ -54,7 +54,7 @@ public class BackgroundAppState extends OverviewState { launcher, launcher.getDeviceProfile(), recentsView.getPagedOrientationHandler(), - recentsView.getSizeStrategy()); + recentsView.getContainerInterface()); AllAppsTransitionController controller = launcher.getAllAppsController(); float scrollRange = Math.max(controller.getShiftRange(), 1); float progressDelta = (transitionLength / scrollRange); diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java index 4c452a27c3..b3c424f3f0 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java @@ -135,7 +135,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController, mLauncher, mLauncher.getDeviceProfile(), mRecentsView.getPagedOrientationHandler(), - mRecentsView.getSizeStrategy()); + mRecentsView.getContainerInterface()); mMaxYProgress = mLauncher.getDeviceProfile().heightPx / mYRange; mMotionPauseDetector = new MotionPauseDetector(mLauncher); mMotionPauseMinDisplacement = mLauncher.getResources().getDimension( diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java index 01abc0f196..22055821fa 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java @@ -149,7 +149,7 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr mLauncher, mLauncher.getDeviceProfile(), recentsView.getPagedOrientationHandler(), - recentsView.getSizeStrategy()); + recentsView.getContainerInterface()); } else { mCurrentAnimation = mLauncher.getStateManager() .createAnimationToNewWorkspace(mToState, config); diff --git a/quickstep/src/com/android/quickstep/FallbackWindowInterface.java b/quickstep/src/com/android/quickstep/FallbackWindowInterface.java index e7beaad9f2..a60605fddd 100644 --- a/quickstep/src/com/android/quickstep/FallbackWindowInterface.java +++ b/quickstep/src/com/android/quickstep/FallbackWindowInterface.java @@ -44,8 +44,6 @@ import com.android.quickstep.util.AnimatorControllerWithResistance; import com.android.quickstep.util.ContextInitListener; import com.android.quickstep.views.RecentsView; -import dagger.assisted.Assisted; -import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; import java.util.function.Consumer; @@ -56,17 +54,20 @@ import java.util.function.Predicate; * currently running one and apps should interact with the {@link RecentsWindowManager} as opposed * to the in-launcher one. */ -public final class FallbackWindowInterface extends BaseWindowInterface{ +public final class FallbackWindowInterface extends BaseWindowInterface { public static final DaggerSingletonObject> REPOSITORY_INSTANCE = new DaggerSingletonObject<>( QuickstepBaseAppComponent::getFallbackWindowInterfaceRepository); - private final RecentsWindowManager mRecentsWindowManager; + @Nullable private RecentsWindowManager mRecentsWindowManager = null; @AssistedInject - public FallbackWindowInterface(@Assisted RecentsWindowManager recentsWindowManager) { + public FallbackWindowInterface() { super(DEFAULT, BACKGROUND_APP); + } + + public void setRecentsWindowManager(@Nullable RecentsWindowManager recentsWindowManager) { mRecentsWindowManager = recentsWindowManager; } @@ -131,8 +132,8 @@ public final class FallbackWindowInterface extends BaseWindowInterface{ @Override public > T getVisibleRecentsView() { RecentsWindowManager manager = getCreatedContainer(); - if(manager.isStarted() || isInLiveTileMode()){ - return getCreatedContainer().getOverviewPanel(); + if (manager != null && (manager.isStarted() || isInLiveTileMode())) { + return manager.getOverviewPanel(); } return null; } @@ -160,9 +161,10 @@ public final class FallbackWindowInterface extends BaseWindowInterface{ @Override public void onExitOverview(Runnable exitRunnable) { + RecentsWindowManager windowManager = getCreatedContainer(); final StateManager stateManager = - getCreatedContainer().getStateManager(); - if (stateManager.getState() == HOME) { + windowManager != null ? windowManager.getStateManager() : null; + if (stateManager == null || stateManager.getState() == HOME) { exitRunnable.run(); notifyRecentsOfOrientation(); return; @@ -215,8 +217,11 @@ public final class FallbackWindowInterface extends BaseWindowInterface{ } private void notifyRecentsOfOrientation() { - // reset layout on swipe to home - ((RecentsView) getCreatedContainer().getOverviewPanel()).reapplyActiveRotation(); + RecentsWindowManager recentsWindowManager = getCreatedContainer(); + if (recentsWindowManager != null) { + // reset layout on swipe to home + ((RecentsView) recentsWindowManager.getOverviewPanel()).reapplyActiveRotation(); + } } @Override @@ -240,10 +245,4 @@ public final class FallbackWindowInterface extends BaseWindowInterface{ animatorSet.playTogether(superAnimator, taskbarAnimator); return animatorSet; } - - @AssistedFactory - public interface Factory { - /** Creates a new instance of [FallbackWindowInterface] for a [RecentsWindowManager]. */ - FallbackWindowInterface create(RecentsWindowManager recentsWindowManager); - } } diff --git a/quickstep/src/com/android/quickstep/InputConsumerUtils.kt b/quickstep/src/com/android/quickstep/InputConsumerUtils.kt index 272faf2831..549fffdfa5 100644 --- a/quickstep/src/com/android/quickstep/InputConsumerUtils.kt +++ b/quickstep/src/com/android/quickstep/InputConsumerUtils.kt @@ -526,10 +526,12 @@ object InputConsumerUtils { reasonString.append("%skeyguard is not showing occluded", SUBSTRING_PREFIX) val runningTask = gestureState.runningTask - val container = gestureState.getContainerInterface() + val containerInterface = gestureState.getContainerInterface() // Use overview input consumer for sharesheets on top of home. val forceOverviewInputConsumer = - container.isStarted() && runningTask != null && runningTask.isRootChooseActivity + containerInterface.isStarted() && + runningTask != null && + runningTask.isRootChooseActivity if (!Flags.enableShellTopTaskTracking()) { // In the case where we are in an excluded, translucent overlay, ignore it and treat the @@ -551,7 +553,7 @@ object InputConsumerUtils { // explicitly check against recents animation too. // Home is always running and isn't resumed when home shows behind desktop. val launcherResumedThroughShellTransition = - container.isResumed() && + containerInterface.isResumed() && !previousGestureState.isRecentsAnimationRunning && !DesktopState.fromContext(context).shouldShowHomeBehindDesktop @@ -561,9 +563,9 @@ object InputConsumerUtils { runningTask.isHomeTask && !previousGestureState.isRecentsAnimationRunning && overviewComponentObserver.isHomeAndOverviewSame && - container.isLauncherOverlayShowing + containerInterface.isLauncherOverlayShowing - return if (container.isInLiveTileMode()) { + return if (containerInterface.isInLiveTileMode()) { createOverviewInputConsumer( userUnlocked, taskAnimationManager, @@ -702,8 +704,9 @@ object InputConsumerUtils { event: MotionEvent, reasonString: CompoundString, ): InputConsumer where T : RecentsViewContainer, T : StatefulContainer { + val containerInterface = gestureState.getContainerInterface()!! val container: T = - gestureState.getContainerInterface().getCreatedContainer() + containerInterface.getCreatedContainer() ?: return getDefaultInputConsumer( gestureState.displayId, userUnlocked, @@ -720,8 +723,7 @@ object InputConsumerUtils { val isPreviousGestureAnimatingToLauncher = (previousGestureState.isRunningAnimationToLauncher || deviceState.isPredictiveBackToHomeInProgress) - val isInLiveTileMode: Boolean = - gestureState.getContainerInterface().isInLiveTileMode() + val isInLiveTileMode: Boolean = containerInterface.isInLiveTileMode() reasonString.append( if (hasWindowFocus) "%sactivity has window focus" diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt index b7f07b7e49..b78af148da 100644 --- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt +++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt @@ -24,7 +24,6 @@ import android.os.Trace import android.util.Log import android.view.Display.DEFAULT_DISPLAY import android.view.View -import android.window.DesktopExperienceFlags import android.window.TransitionInfo import androidx.annotation.BinderThread import androidx.annotation.UiThread @@ -101,7 +100,7 @@ constructor( overviewComponentObserver.getContainerInterface(displayId) private fun getVisibleRecentsView(displayId: Int) = - getContainerInterface(displayId).getVisibleRecentsView>() + getContainerInterface(displayId)?.getVisibleRecentsView>() /** * Adds a command to be executed next, after all pending tasks are completed. Max commands that @@ -338,11 +337,12 @@ constructor( } } + // Returns false if callbacks should be awaited, true otherwise. private fun executeWhenRecentsIsNotVisible( command: CommandInfo, onCallbackResult: () -> Unit, ): Boolean { - val containerInterface = getContainerInterface(command.displayId) + val containerInterface = getContainerInterface(command.displayId) ?: return true val recentsViewContainer = containerInterface.getCreatedContainer() val recentsView: RecentsView<*, *>? = recentsViewContainer?.getOverviewPanel() val deviceProfile = recentsViewContainer?.getDeviceProfile() @@ -361,9 +361,7 @@ constructor( val taskAnimationManager = taskAnimationManagerRepository[command.displayId] if (taskAnimationManager == null) { Log.e(TAG, "No TaskAnimationManager found for display ${command.displayId}") - ActiveGestureProtoLogProxy.logOnTaskAnimationManagerNotAvailable( - command.displayId - ) + ActiveGestureProtoLogProxy.logOnTaskAnimationManagerNotAvailable(command.displayId) return false } @@ -468,7 +466,7 @@ constructor( // Can happen e.g. when a display is disconnected, so try to handle gracefully. Log.d(TAG, "AbsSwipeUpHandler not available for displayId=${command.displayId})") ActiveGestureProtoLogProxy.logOnAbsSwipeUpHandlerNotAvailable(command.displayId) - return false + return true } interactionHandler.setGestureEndCallback { onTransitionComplete(command, interactionHandler, onCallbackResult) @@ -633,7 +631,7 @@ constructor( } private fun logShowOverviewFrom(command: CommandInfo) { - val containerInterface = getContainerInterface(command.displayId) + val containerInterface = getContainerInterface(command.displayId) ?: return val container = containerInterface.getCreatedContainer() ?: return val event = when (command.type) { diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java index 37d6bff681..ce029722fe 100644 --- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java +++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java @@ -324,6 +324,7 @@ public final class OverviewComponentObserver { * @param displayId The display id * @return the control helper for the given display */ + @Nullable public BaseContainerInterface getContainerInterface(int displayId) { return (enableOverviewOnConnectedDisplays() && displayId != DEFAULT_DISPLAY) ? mFallbackWindowInterfaceRepository.get(displayId) diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java index f808b1f722..72a073acb7 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -239,10 +239,17 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { return insets == null ? super.getWindowInsets() : insets; } + @Nullable private RecentsViewContainer getRecentsViewContainer() { // TODO (b/400647896): support per-display container in e2e tests - return OverviewComponentObserver.INSTANCE.get(mContext) - .getContainerInterface(DEFAULT_DISPLAY).getCreatedContainer(); + BaseContainerInterface containerInterface = OverviewComponentObserver.INSTANCE.get( + mContext) + .getContainerInterface(DEFAULT_DISPLAY); + if (containerInterface != null) { + return containerInterface.getCreatedContainer(); + } else { + return null; + } } @Override diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java index 69075dce92..fd1bd27a80 100644 --- a/quickstep/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/src/com/android/quickstep/RecentsActivity.java @@ -237,6 +237,11 @@ public final class RecentsActivity extends StatefulActivity implem return mScrimView; } + @Override + public FallbackActivityInterface getContainerInterface() { + return FallbackActivityInterface.INSTANCE; + } + @Override public FallbackRecentsView getOverviewPanel() { return mFallbackRecentsView; diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java index 4264163c5d..2d5d1c2e90 100644 --- a/quickstep/src/com/android/quickstep/TaskViewUtils.java +++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java @@ -199,7 +199,7 @@ public final class TaskViewUtils { } else { boolean forDesktop = taskView instanceof DesktopTaskView; RemoteTargetGluer gluer = new RemoteTargetGluer(taskView.getContext(), - recentsView.getSizeStrategy(), targets, forDesktop); + recentsView.getContainerInterface(), targets, forDesktop); if (forDesktop) { remoteTargetHandles = gluer.assignTargetsForDesktop(targets, transitionInfo); if (enableDesktopExplodedView()) { @@ -686,7 +686,7 @@ public final class TaskViewUtils { // We may have notified launcher is not visible so that taskbar can // stash immediately. Now that the animation is over, we can update // that launcher is still visible. - TaskbarUIController controller = recentsView.getSizeStrategy() + TaskbarUIController controller = recentsView.getContainerInterface() .getTaskbarController(); // If we're launching the desktop tile in Overview, no need to change // the launcher visibility and taskbar visibility below. diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 65dfe0523a..1298ad0a5f 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -327,10 +327,13 @@ public class TouchInteractionService extends Service { @Override public void enterStageSplitFromRunningApp(int displayId, boolean leftOrTop) { executeForTouchInteractionService(tis -> { - RecentsViewContainer container = tis.mOverviewComponentObserver - .getContainerInterface(displayId).getCreatedContainer(); - if (container != null) { - container.enterStageSplitFromRunningApp(leftOrTop, displayId); + BaseContainerInterface containerInterface = tis.mOverviewComponentObserver + .getContainerInterface(displayId); + if (containerInterface != null) { + RecentsViewContainer container = containerInterface.getCreatedContainer(); + if (container != null) { + container.enterStageSplitFromRunningApp(leftOrTop, displayId); + } } }); } @@ -1288,12 +1291,13 @@ public class TouchInteractionService extends Service { if (deviceState != null) { deviceState.dump(pw); } - RecentsViewContainer createdOverviewContainer = + BaseContainerInterface containerInterface = mOverviewComponentObserver == null ? null : mOverviewComponentObserver.getContainerInterface( - displayId).getCreatedContainer(); - boolean resumed = mOverviewComponentObserver != null - && mOverviewComponentObserver.getContainerInterface(displayId).isResumed(); + displayId); + RecentsViewContainer createdOverviewContainer = containerInterface == null ? null : + containerInterface.getCreatedContainer(); + boolean resumed = containerInterface != null && containerInterface.isResumed(); pw.println("\tcreatedOverviewActivity=" + createdOverviewContainer); pw.println("\tresumed=" + resumed); if (createdOverviewContainer != null) { diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java index d5c187fbbc..02cc5344a9 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -41,9 +41,7 @@ import com.android.launcher3.statemanager.StateManager.StateListener; import com.android.launcher3.statemanager.StatefulContainer; import com.android.launcher3.util.SplitConfigurationOptions; import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource; -import com.android.quickstep.BaseContainerInterface; import com.android.quickstep.GestureState; -import com.android.quickstep.OverviewComponentObserver; import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle; import com.android.quickstep.fallback.window.RecentsWindowManager; import com.android.quickstep.util.GroupTask; @@ -79,12 +77,6 @@ public class FallbackRecentsView getContainerInterface(int displayId) { - return (BaseContainerInterface) OverviewComponentObserver.INSTANCE.get( - mContext).getContainerInterface(displayId); - } - @Override public void init(OverviewActionsView actionsView, SplitSelectStateController splitController, @Nullable DesktopRecentsTransitionController desktopRecentsTransitionController) { diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt index 1e322133ec..b3169e1eb3 100644 --- a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt +++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt @@ -59,6 +59,8 @@ import com.android.launcher3.util.SystemUiController import com.android.launcher3.util.WallpaperColorHints import com.android.launcher3.views.BaseDragLayer import com.android.launcher3.views.ScrimView +import com.android.quickstep.BaseContainerInterface +import com.android.quickstep.FallbackWindowInterface import com.android.quickstep.HomeVisibilityState import com.android.quickstep.OverviewComponentObserver import com.android.quickstep.RecentsAnimationCallbacks @@ -105,6 +107,7 @@ class RecentsWindowManager @AssistedInject constructor( @Assisted windowContext: Context, + @Assisted private val fallbackWindowInterface: FallbackWindowInterface, wallpaperColorHints: WallpaperColorHints, private val systemUiProxy: SystemUiProxy, private val recentsModel: RecentsModel, @@ -220,6 +223,7 @@ constructor( } init { + fallbackWindowInterface.setRecentsWindowManager(this) homeVisibilityState.addListener(homeVisibilityListener) } @@ -235,6 +239,7 @@ constructor( override fun destroy() { super.destroy() + fallbackWindowInterface.setRecentsWindowManager(null) Executors.MAIN_EXECUTOR.execute { tisBindHelper.onDestroy() onViewDestroyed() @@ -416,6 +421,10 @@ constructor( return scrimView } + override fun ?> getContainerInterface(): T { + return fallbackWindowInterface as T + } + override fun getOverviewPanel(): T { return recentsView as T } @@ -512,7 +521,10 @@ constructor( @AssistedFactory interface Factory { /** Creates a new instance of [RecentsWindowManager] for a given [context]. */ - fun create(@WindowContext context: Context): RecentsWindowManager + fun create( + @WindowContext context: Context, + fallbackWindowInterface: FallbackWindowInterface, + ): RecentsWindowManager } } @@ -522,9 +534,14 @@ class RecentsWindowManagerInstanceProvider constructor( private val factory: RecentsWindowManager.Factory, @WindowContext private val windowContextRepository: PerDisplayRepository, + private val fallbackWindowInterfaceRepository: PerDisplayRepository, ) : PerDisplayInstanceProviderWithTeardown { override fun createInstance(displayId: Int) = - windowContextRepository[displayId]?.let { factory.create(it) } + windowContextRepository[displayId]?.let { windowContext -> + fallbackWindowInterfaceRepository[displayId]?.let { fallbackWindowInterface -> + factory.create(windowContext, fallbackWindowInterface) + } + } override fun destroyInstance(instance: RecentsWindowManager) { instance.destroy() diff --git a/quickstep/src/com/android/quickstep/util/ActivityPreloadUtil.kt b/quickstep/src/com/android/quickstep/util/ActivityPreloadUtil.kt index 3c7ac40a7a..8110f27da6 100644 --- a/quickstep/src/com/android/quickstep/util/ActivityPreloadUtil.kt +++ b/quickstep/src/com/android/quickstep/util/ActivityPreloadUtil.kt @@ -63,7 +63,7 @@ object ActivityPreloadUtil { // have the latest state. if ( fromInit && - overviewCompObserver.getContainerInterface(DEFAULT_DISPLAY).createdContainer != + overviewCompObserver.getContainerInterface(DEFAULT_DISPLAY)?.createdContainer != null ) return diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java index 454ff3b258..079478ccf1 100644 --- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java +++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java @@ -147,7 +147,7 @@ public class RecentsOrientedState implements LauncherPrefChangeListener { IntConsumer rotationChangeListener) { mContext = context; mContainerInterface = containerInterface; - mOrientationListener = new OrientationEventListener(context) { + mOrientationListener = new OrientationEventListener(mContext) { @Override public void onOrientationChanged(int degrees) { int newRotation = getRotationForUserDegreesRotated(degrees, mPreviousRotation); diff --git a/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java b/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java index b4cb730de3..e3fc56178e 100644 --- a/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java +++ b/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java @@ -37,6 +37,7 @@ import com.android.launcher3.R; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.taskbar.LauncherTaskbarUIController; import com.android.launcher3.uioverrides.QuickstepLauncher; +import com.android.quickstep.BaseContainerInterface; import com.android.quickstep.OverviewComponentObserver; import com.android.quickstep.RecentsAnimationCallbacks; import com.android.quickstep.RecentsAnimationController; @@ -77,8 +78,13 @@ public class SplitWithKeyboardShortcutController { // Do not enter stage split from keyboard shortcuts if the user is already in split return; } + BaseContainerInterface containerInterface = + mOverviewComponentObserver.getContainerInterface(displayId); + if (containerInterface == null) { + return; + } RecentsAnimationCallbacks callbacks = new RecentsAnimationCallbacks( - mOverviewComponentObserver.getContainerInterface(displayId).getCreatedContainer()); + containerInterface.getCreatedContainer()); SplitWithKeyboardShortcutRecentsAnimationListener listener = new SplitWithKeyboardShortcutRecentsAnimationListener(leftOrTop); diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java index 6bfcf64f19..81d7294deb 100644 --- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java +++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java @@ -18,14 +18,14 @@ package com.android.quickstep.views; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY; -import static com.android.launcher3.util.OverviewReleaseFlags.enableGridOnlyOverview; -import static com.android.launcher3.LauncherState.CLEAR_ALL_BUTTON; import static com.android.launcher3.LauncherState.ADD_DESK_BUTTON; +import static com.android.launcher3.LauncherState.CLEAR_ALL_BUTTON; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK; import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SPLIT_SELECTION_EXIT_HOME; +import static com.android.launcher3.util.OverviewReleaseFlags.enableGridOnlyOverview; import android.annotation.TargetApi; import android.content.Context; @@ -48,9 +48,7 @@ import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.launcher3.util.PendingSplitSelectInfo; import com.android.launcher3.util.SplitConfigurationOptions; import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource; -import com.android.quickstep.BaseContainerInterface; import com.android.quickstep.GestureState; -import com.android.quickstep.LauncherActivityInterface; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.util.AnimUtils; import com.android.quickstep.util.SplitSelectStateController; @@ -239,11 +237,6 @@ public class LauncherRecentsView extends RecentsView getContainerInterface(int displayId) { - return LauncherActivityInterface.INSTANCE; - } - @Override protected void onDismissAnimationEnds() { super.onDismissAnimationEnds(); diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index b4a8900909..90ecfd9456 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -518,7 +518,7 @@ public abstract class RecentsView< private static final float FOREGROUND_SCRIM_TINT = 0.32f; protected final RecentsOrientedState mOrientationState; - protected final BaseContainerInterface mSizeStrategy; + protected final BaseContainerInterface mContainerInterface; @Nullable protected RecentsAnimationController mRecentsAnimationController; @Nullable @@ -891,10 +891,9 @@ public abstract class RecentsView< setEnableFreeScroll(true); mContainer = RecentsViewContainer.containerFromContext(context); - mSizeStrategy = getContainerInterface(mContainer.getDisplayId()); - + mContainerInterface = mContainer.getContainerInterface(); mOrientationState = new RecentsOrientedState( - context, mSizeStrategy, this::animateRecentsRotationInPlace); + context, mContainerInterface, this::animateRecentsRotationInPlace); final int rotation = mContainer.getDisplay().getRotation(); mOrientationState.setRecentsRotation(rotation); @@ -2385,8 +2384,8 @@ public abstract class RecentsView< dp.widthPx - mInsets.right - mLastComputedTaskSize.right, dp.heightPx - mInsets.bottom - mLastComputedTaskSize.bottom); - mSizeStrategy.calculateGridSize(dp, mContainer, mLastComputedGridSize); - mSizeStrategy.calculateGridTaskSize(mContainer, dp, mLastComputedGridTaskSize, + mContainerInterface.calculateGridSize(dp, mContainer, mLastComputedGridSize); + mContainerInterface.calculateGridTaskSize(mContainer, dp, mLastComputedGridTaskSize, getPagedOrientationHandler()); mTaskGridVerticalDiff = mLastComputedGridTaskSize.top - mLastComputedTaskSize.top; @@ -2429,7 +2428,7 @@ public abstract class RecentsView< } public void getTaskSize(Rect outRect) { - mSizeStrategy.calculateTaskSize(mContainer, mContainer.getDeviceProfile(), outRect, + mContainerInterface.calculateTaskSize(mContainer, mContainer.getDeviceProfile(), outRect, getPagedOrientationHandler()); } @@ -2496,8 +2495,8 @@ public abstract class RecentsView< /** Gets the task size for modal state. */ public void getModalTaskSize(Rect outRect) { - mSizeStrategy.calculateModalTaskSize(mContainer, mContainer.getDeviceProfile(), outRect, - getPagedOrientationHandler()); + mContainerInterface.calculateModalTaskSize(mContainer, mContainer.getDeviceProfile(), + outRect, getPagedOrientationHandler()); } @Override @@ -5955,13 +5954,13 @@ public abstract class RecentsView< RemoteTargetGluer gluer; if (recentsAnimationTargets.hasDesktopTasks(mContext)) { - gluer = new RemoteTargetGluer(getContext(), getSizeStrategy(), recentsAnimationTargets, - true /* forDesktop */); + gluer = new RemoteTargetGluer(getContext(), getContainerInterface(), + recentsAnimationTargets, true /* forDesktop */); mRemoteTargetHandles = gluer.assignTargetsForDesktop( recentsAnimationTargets, /* transitionInfo= */ null); } else { - gluer = new RemoteTargetGluer(getContext(), getSizeStrategy(), recentsAnimationTargets, - false); + gluer = new RemoteTargetGluer(getContext(), getContainerInterface(), + recentsAnimationTargets, false); mRemoteTargetHandles = gluer.assignTargetsForSplitScreen(recentsAnimationTargets); } mSplitBoundsConfig = gluer.getSplitBounds(); @@ -6641,16 +6640,10 @@ public abstract class RecentsView< return mTaskOverlayFactory; } - public BaseContainerInterface getSizeStrategy() { - return mSizeStrategy; + public BaseContainerInterface getContainerInterface() { + return mContainerInterface; } - - /** - * Returns the container interface - */ - protected abstract BaseContainerInterface getContainerInterface(int displayId); - /** * Set all the task views to color tint scrim mode, dimming or tinting them all. Allows the * tasks to be dimmed while other elements in the recents view are left alone. @@ -6697,7 +6690,7 @@ public abstract class RecentsView< /** Returns {@code true} if the overview tasks are displayed as a grid. */ public boolean showAsGrid() { return mOverviewGridEnabled || (mCurrentGestureEndTarget != null - && mSizeStrategy.stateFromGestureEndTarget(mCurrentGestureEndTarget) + && mContainerInterface.stateFromGestureEndTarget(mCurrentGestureEndTarget) .displayOverviewTasksAsGrid(mContainer.getDeviceProfile())); } @@ -6909,12 +6902,12 @@ public abstract class RecentsView< public void onExpandPip() { MAIN_EXECUTOR.execute(() -> { if (mRecentsView == null - || mRecentsView.mSizeStrategy.getTaskbarController() == null) { + || mRecentsView.mContainerInterface.getTaskbarController() == null) { return; } // Hide the task bar when leaving PiP to prevent it from flickering once // the app settles in full-screen mode. - mRecentsView.mSizeStrategy.getTaskbarController().onExpandPip(); + mRecentsView.mContainerInterface.getTaskbarController().onExpandPip(); }); } diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java index 5ba31bebbf..706247af7c 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java +++ b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java @@ -32,6 +32,7 @@ import com.android.launcher3.logger.LauncherAtom; import com.android.launcher3.taskbar.TaskbarUIController; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.ScrimView; +import com.android.quickstep.BaseContainerInterface; /** * Interface to be implemented by the parent view of RecentsView @@ -57,6 +58,11 @@ public interface RecentsViewContainer extends ActivityContext { */ ScrimView getScrimView(); + /** + * Returns the BaseContainerInterface to interact with RecentsViewContainer. + */ + > T getContainerInterface(); + /** * Returns the Overview Panel as a View */ diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt b/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt index 4292daf291..6fe6ecd94b 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt +++ b/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt @@ -605,7 +605,7 @@ class RecentsViewUtils(private val recentsView: RecentsView<*, *>) : DesktopVisi with(recentsView) { Log.d(TAG, "onPrepareGestureEndAnimation - endTarget: $endTarget") mCurrentGestureEndTarget = endTarget - val endState: BaseState<*> = mSizeStrategy.stateFromGestureEndTarget(endTarget) + val endState: BaseState<*> = mContainerInterface.stateFromGestureEndTarget(endTarget) // Starting the desk exploded animation when the gesture from an app is released. if (enableDesktopExplodedView()) { diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt index d52fd23326..b1303c3f1a 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.kt +++ b/quickstep/src/com/android/quickstep/views/TaskView.kt @@ -1508,7 +1508,7 @@ constructor( // checking whether to handle resume, but that can come in before // startHome() changes the state, so force-refresh here to ensure the // taskbar is updated - it.mSizeStrategy.taskbarController?.refreshResumedState() + it.mContainerInterface.taskbarController?.refreshResumedState() } } }