From b4c610492594556be6e400fda2d8190287babb42 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Mon, 14 Apr 2025 15:32:45 +0100 Subject: [PATCH] Injrect WindowContext into RecentsWindowManager - Also inject SystemUiProxy and RecentsModel - Also creates a DesktopRecentsTransitionController to avoid crashing when launching desktop tasks - Minor clean-up to use this instead of injected context in RecentsWindowManager Bug: 408988616 Test: manual Flag: com.android.launcher3.enable_fallback_overview_in_window Flag: com.android.launcher3.enable_launcher_overview_in_window Change-Id: I0691d5266f3eae1376ffadd6b29e3ec635b0354b --- .../launcher3/dagger/PerDisplayModule.kt | 34 +++++++++++++++++++ .../fallback/window/RecentsWindowManager.kt | 34 ++++++++++++------- .../quickstep/LauncherSwipeHandlerV2Test.kt | 10 ++++-- .../launcher3/dagger/WindowContext.java | 32 +++++++++++++++++ 4 files changed, 95 insertions(+), 15 deletions(-) create mode 100644 src/com/android/launcher3/dagger/WindowContext.java diff --git a/quickstep/src/com/android/launcher3/dagger/PerDisplayModule.kt b/quickstep/src/com/android/launcher3/dagger/PerDisplayModule.kt index 05f19ed56e..51db1c6648 100644 --- a/quickstep/src/com/android/launcher3/dagger/PerDisplayModule.kt +++ b/quickstep/src/com/android/launcher3/dagger/PerDisplayModule.kt @@ -21,6 +21,7 @@ import android.hardware.display.DisplayManager import android.os.Handler import android.util.Log import android.view.Display.DEFAULT_DISPLAY +import android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY import com.android.app.displaylib.DefaultDisplayOnlyInstanceRepositoryImpl import com.android.app.displaylib.DisplayLibBackground import com.android.app.displaylib.DisplayLibComponent @@ -178,6 +179,39 @@ object PerDisplayRepositoriesModule { ) } } + + @Provides + @LauncherAppSingleton + @WindowContext + fun provideWindowContext( + repositoryFactory: PerDisplayInstanceRepositoryImpl.Factory, + displayRepository: DisplayRepository, + @ApplicationContext context: Context, + ): PerDisplayRepository { + return if (enableOverviewOnConnectedDisplays()) { + repositoryFactory.create( + "DisplayContextRepo", + { displayId -> + displayRepository.getDisplay(displayId)?.let { + context.createWindowContext( + it, + TYPE_APPLICATION_OVERLAY, + /* options=*/ null, + ) + } + }, + ) + } else { + SingleInstanceRepositoryImpl( + "DisplayContextRepo", + context.createWindowContext( + displayRepository.getDisplay(DEFAULT_DISPLAY)!!, + TYPE_APPLICATION_OVERLAY, + /* options=*/ null, + ), + ) + } + } } /** diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt index 91ab561b47..6250384245 100644 --- a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt +++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt @@ -31,7 +31,6 @@ import android.view.RemoteAnimationTarget import android.view.SurfaceControl import android.view.View import android.view.WindowManager -import android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY import android.window.RemoteTransition import com.android.app.displaylib.PerDisplayInstanceProviderWithTeardown import com.android.app.displaylib.PerDisplayRepository @@ -42,8 +41,9 @@ import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory import com.android.launcher3.LauncherState import com.android.launcher3.R import com.android.launcher3.compat.AccessibilityManagerCompat -import com.android.launcher3.dagger.DisplayContext import com.android.launcher3.dagger.LauncherAppSingleton +import com.android.launcher3.dagger.WindowContext +import com.android.launcher3.desktop.DesktopRecentsTransitionController import com.android.launcher3.statemanager.StateManager import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory import com.android.launcher3.statemanager.StatefulContainer @@ -104,8 +104,13 @@ import javax.inject.Inject */ class RecentsWindowManager @AssistedInject -constructor(@Assisted context: Context, wallpaperColorHints: WallpaperColorHints) : - RecentsWindowContext(context, wallpaperColorHints.hints), +constructor( + @Assisted windowContext: Context, + wallpaperColorHints: WallpaperColorHints, + private val systemUiProxy: SystemUiProxy, + private val recentsModel: RecentsModel, +) : + RecentsWindowContext(windowContext, wallpaperColorHints.hints), RecentsViewContainer, StatefulContainer { @@ -132,9 +137,7 @@ constructor(@Assisted context: Context, wallpaperColorHints: WallpaperColorHints } protected var recentsView: FallbackRecentsView? = null - private val windowContext: Context = createWindowContext(TYPE_APPLICATION_OVERLAY, null) - private val windowManager: WindowManager = - windowContext.getSystemService(WindowManager::class.java)!! + private val windowManager: WindowManager = getSystemService(WindowManager::class.java)!! private var layoutInflater: LayoutInflater = LayoutInflater.from(this).cloneInContext(this) private var stateManager: StateManager = StateManager(this, RecentsState.BG_LAUNCHER) @@ -262,11 +265,16 @@ constructor(@Assisted context: Context, wallpaperColorHints: WallpaperColorHints stateManager, /* depthController= */ null, statsLogManager, - SystemUiProxy.INSTANCE[this@RecentsWindowManager], - RecentsModel.INSTANCE[this@RecentsWindowManager], + systemUiProxy, + recentsModel, /* activityBackCallback= */ null, ), - /* desktopRecentsTransitionController= */ null, + DesktopRecentsTransitionController( + stateManager, + systemUiProxy, + iApplicationThread, + /* depthController= */ null, + ), ) } actionsView?.apply { @@ -498,7 +506,7 @@ constructor(@Assisted context: Context, wallpaperColorHints: WallpaperColorHints @AssistedFactory interface Factory { /** Creates a new instance of [RecentsWindowManager] for a given [context]. */ - fun create(@DisplayContext context: Context): RecentsWindowManager + fun create(@WindowContext context: Context): RecentsWindowManager } } @@ -507,10 +515,10 @@ class RecentsWindowManagerInstanceProvider @Inject constructor( private val factory: RecentsWindowManager.Factory, - @DisplayContext private val displayContextRepository: PerDisplayRepository, + @WindowContext private val windowContextRepository: PerDisplayRepository, ) : PerDisplayInstanceProviderWithTeardown { override fun createInstance(displayId: Int) = - displayContextRepository[displayId]?.let { factory.create(it) } + windowContextRepository[displayId]?.let { factory.create(it) } override fun destroyInstance(instance: RecentsWindowManager) { instance.destroy() diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt index c596847089..8a7361f325 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt @@ -60,6 +60,8 @@ class LauncherSwipeHandlerV2Test { @Mock(answer = RETURNS_DEEP_STUBS) private lateinit var systemUiProxy: SystemUiProxy + @Mock(answer = RETURNS_DEEP_STUBS) private lateinit var recentsModel: RecentsModel + @Mock private lateinit var msdlPlayerWrapper: MSDLPlayerWrapper @Mock private lateinit var rotationTouchHelper: RotationTouchHelper @@ -88,7 +90,9 @@ class LauncherSwipeHandlerV2Test { whenever(displayManager.displays).thenReturn(arrayOf(display)) sandboxContext.initDaggerComponent( - DaggerTestComponent.builder().bindSystemUiProxy(systemUiProxy) + DaggerTestComponent.builder() + .bindSystemUiProxy(systemUiProxy) + .bindRecentsModel(recentsModel) ) gestureState = spy( @@ -135,7 +139,9 @@ class LauncherSwipeHandlerV2Test { interface TestComponent : LauncherAppComponent { @Component.Builder interface Builder : LauncherAppComponent.Builder { - @BindsInstance fun bindSystemUiProxy(proxy: SystemUiProxy): Builder + @BindsInstance fun bindSystemUiProxy(systemUiProxy: SystemUiProxy): Builder + + @BindsInstance fun bindRecentsModel(recentsModel: RecentsModel): Builder override fun build(): TestComponent } diff --git a/src/com/android/launcher3/dagger/WindowContext.java b/src/com/android/launcher3/dagger/WindowContext.java new file mode 100644 index 0000000000..74f6997f68 --- /dev/null +++ b/src/com/android/launcher3/dagger/WindowContext.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.dagger; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.inject.Qualifier; + +/** + * Qualifier for per window context created using [createWindowContext]. + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Qualifier +public @interface WindowContext { +}