diff options
author | 2025-01-13 15:56:26 -0800 | |
---|---|---|
committer | 2025-01-14 11:40:35 -0800 | |
commit | 55dc2d1c31f598b8a23022881f556f8b33c72caa (patch) | |
tree | 3299e5f046a316131871c91062688b564432a74c | |
parent | 8fa43b3bb19fb406a544d9de525d789665b5ab84 (diff) |
Moving DisplayController to dagger
Separating various overrides to individual modules so that they can be reused in tests
Removing ContextualEduStatsManager and directly using SysUiProxy as all the usescases
are only in quickstep/
This avoids additional Module definition and delegation
Bug: 361850561
Test: Presubmit
Flag: EXEMPT dagger
Change-Id: I096459d638553991ed01766002b874589c6b976e
27 files changed, 271 insertions, 280 deletions
diff --git a/quickstep/src/com/android/launcher3/dagger/Modules.kt b/quickstep/src/com/android/launcher3/dagger/Modules.kt new file mode 100644 index 0000000000..04c1d5e461 --- /dev/null +++ b/quickstep/src/com/android/launcher3/dagger/Modules.kt @@ -0,0 +1,44 @@ +/* + * 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 com.android.launcher3.uioverrides.SystemApiWrapper +import com.android.launcher3.uioverrides.plugins.PluginManagerWrapperImpl +import com.android.launcher3.util.ApiWrapper +import com.android.launcher3.util.PluginManagerWrapper +import com.android.launcher3.util.window.WindowManagerProxy +import com.android.quickstep.util.SystemWindowManagerProxy +import dagger.Binds +import dagger.Module + +private object Modules {} + +@Module +abstract class WindowManagerProxyModule { + @Binds abstract fun bindWindowManagerProxy(proxy: SystemWindowManagerProxy): WindowManagerProxy +} + +@Module +abstract class ApiWrapperModule { + @Binds abstract fun bindApiWrapper(systemApiWrapper: SystemApiWrapper): ApiWrapper +} + +@Module +abstract class PluginManagerWrapperModule { + @Binds + abstract fun bindPluginManagerWrapper(impl: PluginManagerWrapperImpl): PluginManagerWrapper +} diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java index 3fa0e8e426..7c6c7ac121 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java @@ -61,7 +61,6 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.anim.AnimatorPlaybackController; -import com.android.launcher3.contextualeducation.ContextualEduStatsManager; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarNavButtonCallbacks; import com.android.launcher3.taskbar.unfold.NonDestroyableScopedUnfoldTransitionProgressProvider; @@ -270,7 +269,6 @@ public class TaskbarManager { context, navCallbacks, SystemUiProxy.INSTANCE.get(mWindowContext), - ContextualEduStatsManager.INSTANCE.get(mWindowContext), new Handler(), new ContextualSearchInvoker(mWindowContext)); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java index d1f9be0b91..1adb2e909e 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java @@ -51,7 +51,6 @@ import androidx.annotation.Nullable; import androidx.annotation.StringRes; import com.android.launcher3.R; -import com.android.launcher3.contextualeducation.ContextualEduStatsManager; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.shared.TestProtocol; @@ -120,7 +119,6 @@ public class TaskbarNavButtonController implements TaskbarControllers.LoggableTa private final Context mContext; private final TaskbarNavButtonCallbacks mCallbacks; private final SystemUiProxy mSystemUiProxy; - private final ContextualEduStatsManager mContextualEduStatsManager; private final Handler mHandler; private final ContextualSearchInvoker mContextualSearchInvoker; @Nullable private StatsLogManager mStatsLogManager; @@ -131,13 +129,11 @@ public class TaskbarNavButtonController implements TaskbarControllers.LoggableTa Context context, TaskbarNavButtonCallbacks callbacks, SystemUiProxy systemUiProxy, - ContextualEduStatsManager contextualEduStatsManager, Handler handler, ContextualSearchInvoker contextualSearchInvoker) { mContext = context; mCallbacks = callbacks; mSystemUiProxy = systemUiProxy; - mContextualEduStatsManager = contextualEduStatsManager; mHandler = handler; mContextualSearchInvoker = contextualSearchInvoker; } @@ -159,13 +155,13 @@ public class TaskbarNavButtonController implements TaskbarControllers.LoggableTa break; case BUTTON_HOME: logEvent(LAUNCHER_TASKBAR_HOME_BUTTON_TAP); - mContextualEduStatsManager.updateEduStats(/* isTrackpadGesture= */ false, + mSystemUiProxy.updateContextualEduStats(/* isTrackpadGesture= */ false, GestureType.HOME); navigateHome(); break; case BUTTON_RECENTS: logEvent(LAUNCHER_TASKBAR_OVERVIEW_BUTTON_TAP); - mContextualEduStatsManager.updateEduStats(/* isTrackpadGesture= */ false, + mSystemUiProxy.updateContextualEduStats(/* isTrackpadGesture= */ false, GestureType.OVERVIEW); navigateToOverview(); break; @@ -364,7 +360,7 @@ public class TaskbarNavButtonController implements TaskbarControllers.LoggableTa private void executeBack(@Nullable KeyEvent keyEvent) { if (keyEvent == null || (keyEvent.getAction() == ACTION_UP && !keyEvent.isCanceled())) { logEvent(LAUNCHER_TASKBAR_BACK_BUTTON_TAP); - mContextualEduStatsManager.updateEduStats(/* isTrackpadGesture= */ false, + mSystemUiProxy.updateContextualEduStats(/* isTrackpadGesture= */ false, GestureType.BACK); } mSystemUiProxy.onBackEvent(keyEvent); diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java index 1d9e49201d..3f0839da92 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java @@ -45,11 +45,11 @@ import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.config.FeatureFlags; -import com.android.launcher3.contextualeducation.ContextualEduStatsManager; import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.touch.SingleAxisSwipeDetector; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.TouchController; +import com.android.quickstep.SystemUiProxy; import com.android.quickstep.TaskUtils; import com.android.quickstep.util.AnimatorControllerWithResistance; import com.android.quickstep.util.OverviewToHomeAnim; @@ -221,7 +221,7 @@ public class NavBarToHomeTouchController implements TouchController, } if (mStartState != mEndState) { logHomeGesture(); - ContextualEduStatsManager.INSTANCE.get(mLauncher).updateEduStats( + SystemUiProxy.INSTANCE.get(mLauncher).updateContextualEduStats( mSwipeDetector.isTrackpadGesture(), GestureType.HOME); } AbstractFloatingView topOpenView = AbstractFloatingView.getTopOpenView(mLauncher); diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java index b562838091..a74b350a64 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java @@ -37,6 +37,7 @@ import com.android.launcher3.uioverrides.states.OverviewState; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.util.LayoutUtils; import com.android.quickstep.views.RecentsView; +import com.android.systemui.contextualeducation.GestureType; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; /** @@ -163,8 +164,19 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr @Override protected void onSwipeInteractionCompleted(LauncherState targetState) { super.onSwipeInteractionCompleted(targetState); + SystemUiProxy sysUIProxy = SystemUiProxy.INSTANCE.get(mLauncher); if (mStartState == NORMAL && targetState == OVERVIEW) { - SystemUiProxy.INSTANCE.get(mLauncher).onOverviewShown(true, TAG); + sysUIProxy.onOverviewShown(true, TAG); + } + + if (targetState == OVERVIEW) { + sysUIProxy.updateContextualEduStats( + mDetector.isTrackpadGesture(), GestureType.OVERVIEW); + } else if (targetState == ALL_APPS && !mDetector.isTrackpadGesture()) { + // Only update if it is touch gesture as trackpad gesture is not relevant for all apps + // which only provides keyboard education. + sysUIProxy.updateContextualEduStats( + /* isTrackpadGesture= */ false, GestureType.ALL_APPS); } } diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index e27b6079df..0042c8ac72 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -118,7 +118,6 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.compat.AccessibilityManagerCompat; -import com.android.launcher3.contextualeducation.ContextualEduStatsManager; import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.logging.StatsLogManager.StatsLogger; @@ -174,6 +173,8 @@ import com.android.wm.shell.shared.startingsurface.SplashScreenExitAnimationUtil import com.google.android.msdl.data.model.MSDLToken; +import kotlin.Unit; + import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -183,8 +184,6 @@ import java.util.Optional; import java.util.OptionalInt; import java.util.function.Consumer; -import kotlin.Unit; - /** * Handles the navigation gestures when Launcher is the default home activity. */ @@ -1413,7 +1412,7 @@ public abstract class AbsSwipeUpHandler< duration = mContainer != null && mContainer.getDeviceProfile().isTaskbarPresent ? QuickstepTransitionManager.getTaskbarToHomeDuration(isPinnedTaskbar) : StaggeredWorkspaceAnim.DURATION_MS; - ContextualEduStatsManager.INSTANCE.get(mContext).updateEduStats( + SystemUiProxy.INSTANCE.get(mContext).updateContextualEduStats( mGestureState.isTrackpadGesture(), GestureType.HOME); } else if (endTarget == RECENTS) { if (mRecentsView != null) { @@ -1439,7 +1438,7 @@ public abstract class AbsSwipeUpHandler< if (!mGestureState.isHandlingAtomicEvent() || isScrolling) { duration = Math.max(duration, mRecentsView.getScroller().getDuration()); } - ContextualEduStatsManager.INSTANCE.get(mContext).updateEduStats( + SystemUiProxy.INSTANCE.get(mContext).updateContextualEduStats( mGestureState.isTrackpadGesture(), GestureType.OVERVIEW); } } else if (endTarget == LAST_TASK && mRecentsView != null diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.kt b/quickstep/src/com/android/quickstep/SystemUiProxy.kt index a7405a0bae..f2cedbaa71 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.kt +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.kt @@ -63,6 +63,7 @@ import com.android.launcher3.util.SplitConfigurationOptions.StagePosition import com.android.quickstep.util.ActiveGestureProtoLogProxy import com.android.quickstep.util.ContextualSearchInvoker import com.android.quickstep.util.unfold.ProxyUnfoldTransitionProvider +import com.android.systemui.contextualeducation.GestureType import com.android.systemui.shared.recents.ISystemUiProxy import com.android.systemui.shared.recents.model.ThumbnailData.Companion.wrap import com.android.systemui.shared.system.QuickStepContract @@ -216,9 +217,9 @@ class SystemUiProxy @Inject constructor(@ApplicationContext private val context: systemUiProxy?.onImeSwitcherLongPress() } - fun updateContextualEduStats(isTrackpadGesture: Boolean, gestureType: String) = + fun updateContextualEduStats(isTrackpadGesture: Boolean, gestureType: GestureType) = executeWithErrorLog({ "Failed call updateContextualEduStats" }) { - systemUiProxy?.updateContextualEduStats(isTrackpadGesture, gestureType) + systemUiProxy?.updateContextualEduStats(isTrackpadGesture, gestureType.name) } fun setHomeRotationEnabled(enabled: Boolean) = diff --git a/quickstep/src/com/android/quickstep/contextualeducation/SystemContextualEduStatsManager.java b/quickstep/src/com/android/quickstep/contextualeducation/SystemContextualEduStatsManager.java deleted file mode 100644 index 6a725370ba..0000000000 --- a/quickstep/src/com/android/quickstep/contextualeducation/SystemContextualEduStatsManager.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2024 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.quickstep.contextualeducation; - -import com.android.launcher3.contextualeducation.ContextualEduStatsManager; -import com.android.launcher3.dagger.LauncherAppSingleton; -import com.android.quickstep.SystemUiProxy; -import com.android.systemui.contextualeducation.GestureType; - -import javax.inject.Inject; - -/** - * A class to update contextual education data via {@link SystemUiProxy} - */ -@LauncherAppSingleton -public class SystemContextualEduStatsManager extends ContextualEduStatsManager { - private final SystemUiProxy mSystemUiProxy; - - @Inject - public SystemContextualEduStatsManager(SystemUiProxy systemUiProxy) { - mSystemUiProxy = systemUiProxy; - } - - @Override - public void updateEduStats(boolean isTrackpadGesture, GestureType gestureType) { - mSystemUiProxy.updateContextualEduStats(isTrackpadGesture, - gestureType.name()); - } -} diff --git a/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java b/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java deleted file mode 100644 index a6feff0652..0000000000 --- a/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2024 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.quickstep.dagger; - -import com.android.launcher3.contextualeducation.ContextualEduStatsManager; -import com.android.launcher3.uioverrides.SystemApiWrapper; -import com.android.launcher3.uioverrides.plugins.PluginManagerWrapperImpl; -import com.android.launcher3.util.ApiWrapper; -import com.android.launcher3.util.PluginManagerWrapper; -import com.android.launcher3.util.window.WindowManagerProxy; -import com.android.quickstep.contextualeducation.SystemContextualEduStatsManager; -import com.android.quickstep.util.SystemWindowManagerProxy; - -import dagger.Binds; -import dagger.Module; - -@Module -public abstract class QuickStepModule { - - @Binds abstract PluginManagerWrapper bindPluginManagerWrapper(PluginManagerWrapperImpl impl); - @Binds abstract ApiWrapper bindApiWrapper(SystemApiWrapper systemApiWrapper); - @Binds abstract ContextualEduStatsManager bindContextualEduStatsManager( - SystemContextualEduStatsManager manager); - @Binds abstract WindowManagerProxy bindWindowManagerProxy(SystemWindowManagerProxy proxy); -} diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java index c68299035d..a8f3500a72 100644 --- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java +++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java @@ -40,7 +40,6 @@ import android.view.inputmethod.Flags; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; -import com.android.launcher3.contextualeducation.ContextualEduStatsManager; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarNavButtonCallbacks; import com.android.quickstep.SystemUiProxy; @@ -65,9 +64,6 @@ public class TaskbarNavButtonControllerTest { SystemUiProxy mockSystemUiProxy; @Mock - ContextualEduStatsManager mockContextualEduStatsManager; - - @Mock TouchInteractionService mockService; @Mock Handler mockHandler; @@ -118,7 +114,6 @@ public class TaskbarNavButtonControllerTest { mockService, mCallbacks, mockSystemUiProxy, - mockContextualEduStatsManager, mockHandler, mockContextualSearchInvoker); } @@ -132,8 +127,8 @@ public class TaskbarNavButtonControllerTest { @Test public void testPressBack_updateContextualEduData() { mNavButtonController.onButtonClick(BUTTON_BACK, mockView); - verify(mockContextualEduStatsManager, times(1)) - .updateEduStats(/* isTrackpad= */ eq(false), eq(GestureType.BACK)); + verify(mockSystemUiProxy, times(1)) + .updateContextualEduStats(/* isTrackpad= */ eq(false), eq(GestureType.BACK)); } @Test @@ -223,8 +218,8 @@ public class TaskbarNavButtonControllerTest { @Test public void testPressHome_updateContextualEduData() { mNavButtonController.onButtonClick(BUTTON_HOME, mockView); - verify(mockContextualEduStatsManager, times(1)) - .updateEduStats(/* isTrackpad= */ eq(false), eq(GestureType.HOME)); + verify(mockSystemUiProxy, times(1)) + .updateContextualEduStats(/* isTrackpad= */ eq(false), eq(GestureType.HOME)); } @Test @@ -236,8 +231,8 @@ public class TaskbarNavButtonControllerTest { @Test public void testPressRecents_updateContextualEduData() { mNavButtonController.onButtonClick(BUTTON_RECENTS, mockView); - verify(mockContextualEduStatsManager, times(1)) - .updateEduStats(/* isTrackpad= */ eq(false), eq(GestureType.OVERVIEW)); + verify(mockSystemUiProxy, times(1)) + .updateContextualEduStats(/* isTrackpad= */ eq(false), eq(GestureType.OVERVIEW)); } @Test diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarModeRule.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarModeRule.kt index 74b154a53d..3cf912c8e3 100644 --- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarModeRule.kt +++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarModeRule.kt @@ -61,11 +61,10 @@ class TaskbarModeRule(private val context: TaskbarWindowSandboxContext) : TestRu val mode = taskbarMode.mode getInstrumentation().runOnMainSync { - context.putObject( - DisplayController.INSTANCE, - object : DisplayController(context) { - override fun getInfo(): Info { - return spy(super.getInfo()) { + DisplayController.INSTANCE[context].let { + if (it is DisplayControllerSpy) { + it.infoModifier = { info -> + spy(info) { on { isTransientTaskbar } doReturn (mode == Mode.TRANSIENT) on { isPinnedTaskbar } doReturn (mode == Mode.PINNED) on { navigationMode } doReturn @@ -76,8 +75,8 @@ class TaskbarModeRule(private val context: TaskbarWindowSandboxContext) : TestRu } } } - }, - ) + } + } } base.evaluate() diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarWindowSandboxContext.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarWindowSandboxContext.kt index 31c5a4c950..e6dc2a209e 100644 --- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarWindowSandboxContext.kt +++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarWindowSandboxContext.kt @@ -22,17 +22,25 @@ import android.hardware.display.DisplayManager import android.hardware.display.VirtualDisplay import android.view.Display.DEFAULT_DISPLAY import androidx.test.core.app.ApplicationProvider -import com.android.launcher3.FakeLauncherPrefs +import com.android.launcher3.LauncherPrefs +import com.android.launcher3.dagger.ApplicationContext import com.android.launcher3.dagger.LauncherAppComponent -import com.android.launcher3.dagger.LauncherAppModule import com.android.launcher3.dagger.LauncherAppSingleton +import com.android.launcher3.util.AllModulesForTest +import com.android.launcher3.util.DaggerSingletonTracker +import com.android.launcher3.util.DisplayController +import com.android.launcher3.util.FakePrefsModule import com.android.launcher3.util.MainThreadInitializedObject.ObjectSandbox import com.android.launcher3.util.SandboxApplication import com.android.launcher3.util.SettingsCache import com.android.launcher3.util.SettingsCacheSandbox +import com.android.launcher3.util.window.WindowManagerProxy import com.android.quickstep.SystemUiProxy +import dagger.Binds import dagger.BindsInstance import dagger.Component +import dagger.Module +import javax.inject.Inject import org.junit.rules.ExternalResource import org.junit.rules.RuleChain import org.junit.rules.TestRule @@ -113,11 +121,32 @@ private constructor( } } +/** A wrapper over display controller which allows modifying the underlying info */ @LauncherAppSingleton -@Component(modules = [LauncherAppModule::class]) -interface TaskbarSandboxComponent : LauncherAppComponent { +class DisplayControllerSpy +@Inject +constructor( + @ApplicationContext context: Context, + wmProxy: WindowManagerProxy, + prefs: LauncherPrefs, + lifecycle: DaggerSingletonTracker, +) : DisplayController(context, wmProxy, prefs, lifecycle) { + + var infoModifier: ((Info) -> Info)? = null + + override fun getInfo(): Info = infoModifier?.invoke(super.getInfo()) ?: super.getInfo() +} + +@Module +abstract class DisplayControllerModule { + @Binds abstract fun bindDisplayController(controller: DisplayControllerSpy): DisplayController +} - override fun getLauncherPrefs(): FakeLauncherPrefs +@LauncherAppSingleton +@Component( + modules = [AllModulesForTest::class, FakePrefsModule::class, DisplayControllerModule::class] +) +interface TaskbarSandboxComponent : LauncherAppComponent { @Component.Builder interface Builder : LauncherAppComponent.Builder { diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt index 073833665f..4541fdb3ed 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt @@ -97,7 +97,7 @@ class LauncherSwipeHandlerV2Test { verify(systemUiProxy) .updateContextualEduStats( /* isTrackpadGesture= */ eq(true), - eq(GestureType.HOME.toString()), + eq(GestureType.HOME), ) } @@ -107,7 +107,7 @@ class LauncherSwipeHandlerV2Test { verify(systemUiProxy) .updateContextualEduStats( /* isTrackpadGesture= */ eq(false), - eq(GestureType.HOME.toString()), + eq(GestureType.HOME), ) } } diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsWindowSwipeHandlerTestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsWindowSwipeHandlerTestCase.java index dcb45e5ef0..c1be1cee9b 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsWindowSwipeHandlerTestCase.java +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsWindowSwipeHandlerTestCase.java @@ -21,8 +21,8 @@ import androidx.test.filters.SmallTest; import com.android.launcher3.dagger.LauncherAppComponent; import com.android.launcher3.dagger.LauncherAppSingleton; +import com.android.launcher3.util.AllModulesForTest; import com.android.launcher3.util.LauncherMultivalentJUnit; -import com.android.quickstep.dagger.QuickStepModule; import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.fallback.RecentsState; import com.android.quickstep.fallback.window.RecentsDisplayModel; @@ -30,13 +30,13 @@ import com.android.quickstep.fallback.window.RecentsWindowManager; import com.android.quickstep.fallback.window.RecentsWindowSwipeHandler; import com.android.quickstep.views.RecentsViewContainer; +import dagger.BindsInstance; +import dagger.Component; + import org.junit.Before; import org.junit.runner.RunWith; import org.mockito.Mock; -import dagger.BindsInstance; -import dagger.Component; - @SmallTest @RunWith(LauncherMultivalentJUnit.class) public class RecentsWindowSwipeHandlerTestCase extends AbsSwipeUpHandlerTestCase< @@ -83,7 +83,7 @@ public class RecentsWindowSwipeHandlerTestCase extends AbsSwipeUpHandlerTestCase } @LauncherAppSingleton - @Component(modules = { QuickStepModule.class }) + @Component(modules = {AllModulesForTest.class}) interface TestComponent extends LauncherAppComponent { @Component.Builder interface Builder extends LauncherAppComponent.Builder { diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumerTest.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumerTest.java index 8879a0103d..7776351517 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumerTest.java +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumerTest.java @@ -46,8 +46,8 @@ import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import com.android.launcher3.dagger.LauncherAppComponent; -import com.android.launcher3.dagger.LauncherAppModule; import com.android.launcher3.dagger.LauncherAppSingleton; +import com.android.launcher3.util.AllModulesForTest; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.MainThreadInitializedObject.SandboxContext; import com.android.quickstep.DeviceConfigWrapper; @@ -461,12 +461,11 @@ public class NavHandleLongPressInputConsumerTest { } @LauncherAppSingleton - @Component(modules = LauncherAppModule.class) + @Component(modules = AllModulesForTest.class) public interface TopTaskTrackerComponent extends LauncherAppComponent { @Component.Builder interface Builder extends LauncherAppComponent.Builder { - @BindsInstance - Builder bindTopTaskTracker(TopTaskTracker topTaskTracker); + @BindsInstance Builder bindTopTaskTracker(TopTaskTracker topTaskTracker); @Override TopTaskTrackerComponent build(); diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskViewSimulatorTest.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskViewSimulatorTest.java index fa81680cb8..be76f9e86d 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskViewSimulatorTest.java +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskViewSimulatorTest.java @@ -35,6 +35,9 @@ import androidx.test.filters.SmallTest; import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; +import com.android.launcher3.dagger.LauncherAppComponent; +import com.android.launcher3.dagger.LauncherAppSingleton; +import com.android.launcher3.util.AllModulesMinusWMProxy; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.Info; import com.android.launcher3.util.LauncherModelHelper; @@ -46,6 +49,9 @@ import com.android.launcher3.util.window.WindowManagerProxy; import com.android.quickstep.FallbackActivityInterface; import com.android.quickstep.util.SurfaceTransaction.MockProperties; +import dagger.BindsInstance; +import dagger.Component; + import org.hamcrest.Description; import org.hamcrest.TypeSafeMatcher; import org.junit.Assert; @@ -159,6 +165,11 @@ public class TaskViewSimulatorTest { void verifyNoTransforms() { LauncherModelHelper helper = new LauncherModelHelper(); try { + DisplayController mockController = mock(DisplayController.class); + + helper.sandboxContext.initDaggerComponent( + DaggerTaskViewSimulatorTest_TaskViewSimulatorTestComponent.builder() + .bindDisplayController(mockController)); int rotation = mDisplaySize.x > mDisplaySize.y ? Surface.ROTATION_90 : Surface.ROTATION_0; CachedDisplayInfo cdi = new CachedDisplayInfo(mDisplaySize, rotation); @@ -192,10 +203,7 @@ public class TaskViewSimulatorTest { DisplayController.Info info = new Info( configurationContext, wmProxy, perDisplayBoundsCache); - - DisplayController mockController = mock(DisplayController.class); when(mockController.getInfo()).thenReturn(info); - helper.sandboxContext.putObject(DisplayController.INSTANCE, mockController); mDeviceProfile = InvariantDeviceProfile.INSTANCE.get(helper.sandboxContext) .getBestMatch(mAppBounds.width(), mAppBounds.height(), rotation); @@ -271,4 +279,18 @@ public class TaskViewSimulatorTest { description.appendValue(mExpected); } } + + @LauncherAppSingleton + @Component(modules = {AllModulesMinusWMProxy.class}) + interface TaskViewSimulatorTestComponent extends LauncherAppComponent { + + @Component.Builder + interface Builder extends LauncherAppComponent.Builder { + + @BindsInstance + Builder bindDisplayController(DisplayController controller); + + TaskViewSimulatorTestComponent build(); + } + } } diff --git a/src/com/android/launcher3/contextualeducation/ContextualEduStatsManager.java b/src/com/android/launcher3/contextualeducation/ContextualEduStatsManager.java deleted file mode 100644 index 5664174014..0000000000 --- a/src/com/android/launcher3/contextualeducation/ContextualEduStatsManager.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2024 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.contextualeducation; - -import com.android.launcher3.dagger.LauncherAppSingleton; -import com.android.launcher3.dagger.LauncherBaseAppComponent; -import com.android.launcher3.util.DaggerSingletonObject; -import com.android.systemui.contextualeducation.GestureType; - -import javax.inject.Inject; - -/** - * A class to update contextual education data. It is a no-op implementation and could be - * overridden through dagger modules to provide a real implementation. - */ -@LauncherAppSingleton -public class ContextualEduStatsManager { - public static final DaggerSingletonObject<ContextualEduStatsManager> INSTANCE = - new DaggerSingletonObject<>(LauncherBaseAppComponent::getContextualEduStatsManager); - - @Inject - public ContextualEduStatsManager() { } - - - /** - * Updates contextual education stats when a gesture is triggered - * @param isTrackpadGesture indicates if the gesture is triggered by trackpad - * @param gestureType type of gesture triggered - */ - public void updateEduStats(boolean isTrackpadGesture, GestureType gestureType) { - } -} diff --git a/quickstep/dagger/com/android/launcher3/dagger/LauncherAppModule.java b/src/com/android/launcher3/dagger/LauncherAppModule.java index 1711fc13e5..ef136d07b9 100644 --- a/quickstep/dagger/com/android/launcher3/dagger/LauncherAppModule.java +++ b/src/com/android/launcher3/dagger/LauncherAppModule.java @@ -16,9 +16,12 @@ package com.android.launcher3.dagger; -import com.android.quickstep.dagger.QuickStepModule; - import dagger.Module; -@Module(includes = QuickStepModule.class) -public class LauncherAppModule {} +@Module(includes = { + WindowManagerProxyModule.class, + ApiWrapperModule.class, + PluginManagerWrapperModule.class +}) +public class LauncherAppModule { +} diff --git a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java index 4b43d490e9..5883a88a51 100644 --- a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java +++ b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java @@ -19,13 +19,13 @@ package com.android.launcher3.dagger; import android.content.Context; import com.android.launcher3.LauncherPrefs; -import com.android.launcher3.contextualeducation.ContextualEduStatsManager; import com.android.launcher3.graphics.IconShape; import com.android.launcher3.graphics.ThemeManager; import com.android.launcher3.model.ItemInstallQueue; import com.android.launcher3.pm.InstallSessionHelper; import com.android.launcher3.util.ApiWrapper; import com.android.launcher3.util.DaggerSingletonTracker; +import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DynamicResource; import com.android.launcher3.util.MSDLPlayerWrapper; import com.android.launcher3.util.PackageManagerHelper; @@ -50,7 +50,6 @@ import dagger.BindsInstance; public interface LauncherBaseAppComponent { DaggerSingletonTracker getDaggerSingletonTracker(); ApiWrapper getApiWrapper(); - ContextualEduStatsManager getContextualEduStatsManager(); CustomWidgetManager getCustomWidgetManager(); DynamicResource getDynamicResource(); IconShape getIconShape(); @@ -66,6 +65,7 @@ public interface LauncherBaseAppComponent { WindowManagerProxy getWmProxy(); LauncherPrefs getLauncherPrefs(); ThemeManager getThemeManager(); + DisplayController getDisplayController(); /** Builder for LauncherBaseAppComponent. */ interface Builder { diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java index 74a09669a7..3817563b0b 100644 --- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java +++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java @@ -40,13 +40,11 @@ import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.LauncherState; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorPlaybackController; -import com.android.launcher3.contextualeducation.ContextualEduStatsManager; import com.android.launcher3.logger.LauncherAtom; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.util.FlingBlockCheck; import com.android.launcher3.util.TouchController; -import com.android.systemui.contextualeducation.GestureType; /** * TouchController for handling state changes @@ -390,7 +388,6 @@ public abstract class AbstractStateChangeTouchController } else { logReachedState(mToState); } - updateContextualEduStats(targetState); } protected void goToTargetState(LauncherState targetState) { @@ -406,18 +403,6 @@ public abstract class AbstractStateChangeTouchController .setDuration(0).start(); } - private void updateContextualEduStats(LauncherState targetState) { - if (targetState == OVERVIEW) { - ContextualEduStatsManager.INSTANCE.get( - mLauncher).updateEduStats(mDetector.isTrackpadGesture(), GestureType.OVERVIEW); - } else if (targetState == ALL_APPS && !mDetector.isTrackpadGesture()) { - // Only update if it is touch gesture as trackpad gesture is not relevant for all apps - // which only provides keyboard education. - ContextualEduStatsManager.INSTANCE.get( - mLauncher).updateEduStats(/* isTrackpadGesture= */ false, GestureType.ALL_APPS); - } - } - private void logReachedState(LauncherState targetState) { if (mStartState == targetState) { return; diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java index d8a2a3d2ec..9472f5fa43 100644 --- a/src/com/android/launcher3/util/DisplayController.java +++ b/src/com/android/launcher3/util/DisplayController.java @@ -53,6 +53,9 @@ import com.android.launcher3.InvariantDeviceProfile.DeviceType; import com.android.launcher3.LauncherPrefChangeListener; import com.android.launcher3.LauncherPrefs; import com.android.launcher3.Utilities; +import com.android.launcher3.dagger.ApplicationContext; +import com.android.launcher3.dagger.LauncherAppComponent; +import com.android.launcher3.dagger.LauncherAppSingleton; import com.android.launcher3.logging.FileLog; import com.android.launcher3.util.window.CachedDisplayInfo; import com.android.launcher3.util.window.WindowManagerProxy; @@ -67,11 +70,14 @@ import java.util.Objects; import java.util.Set; import java.util.StringJoiner; +import javax.inject.Inject; + /** * Utility class to cache properties of default display to avoid a system RPC on every call. */ @SuppressLint("NewApi") -public class DisplayController implements ComponentCallbacks, SafeCloseable, +@LauncherAppSingleton +public class DisplayController implements ComponentCallbacks, DesktopVisibilityListener { private static final String TAG = "DisplayController"; @@ -82,8 +88,8 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable, // TODO(b/254119092) remove all logs with this tag public static final String TASKBAR_NOT_DESTROYED_TAG = "b/254119092"; - public static final MainThreadInitializedObject<DisplayController> INSTANCE = - new MainThreadInitializedObject<>(DisplayController::new); + public static final DaggerSingletonObject<DisplayController> INSTANCE = + new DaggerSingletonObject<>(LauncherAppComponent::getDisplayController); public static final int CHANGE_ACTIVE_SCREEN = 1 << 0; public static final int CHANGE_ROTATION = 1 << 1; @@ -101,6 +107,7 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable, private static final String TARGET_OVERLAY_PACKAGE = "android"; private final Context mContext; + private final WindowManagerProxy mWMProxy; // Null for SDK < S private final Context mWindowContext; @@ -117,13 +124,31 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable, private Info mInfo; private boolean mDestroyed = false; - private LauncherPrefChangeListener mTaskbarPinningPreferenceChangeListener; - - @VisibleForTesting - protected DisplayController(Context context) { + @Inject + protected DisplayController(@ApplicationContext Context context, + WindowManagerProxy wmProxy, + LauncherPrefs prefs, + DaggerSingletonTracker lifecycle) { mContext = context; + mWMProxy = wmProxy; + if (enableTaskbarPinning()) { - attachTaskbarPinningSharedPreferenceChangeListener(mContext); + LauncherPrefChangeListener prefListener = key -> { + boolean isTaskbarPinningChanged = TASKBAR_PINNING_KEY.equals(key) + && mInfo.mIsTaskbarPinned != prefs.get(TASKBAR_PINNING); + boolean isTaskbarPinningDesktopModeChanged = + TASKBAR_PINNING_DESKTOP_MODE_KEY.equals(key) + && mInfo.mIsTaskbarPinnedInDesktopMode != prefs.get( + TASKBAR_PINNING_IN_DESKTOP_MODE); + if (isTaskbarPinningChanged || isTaskbarPinningDesktopModeChanged) { + notifyConfigChange(); + } + }; + + prefs.addListener(prefListener, TASKBAR_PINNING); + prefs.addListener(prefListener, TASKBAR_PINNING_IN_DESKTOP_MODE); + lifecycle.addCloseable(() -> prefs.removeListener( + prefListener, TASKBAR_PINNING, TASKBAR_PINNING_IN_DESKTOP_MODE)); } Display display = context.getSystemService(DisplayManager.class) @@ -134,31 +159,17 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable, // Initialize navigation mode change listener mReceiver.registerPkgActions(mContext, TARGET_OVERLAY_PACKAGE, ACTION_OVERLAY_CHANGED); - WindowManagerProxy wmProxy = WindowManagerProxy.INSTANCE.get(context); mInfo = new Info(mWindowContext, wmProxy, wmProxy.estimateInternalDisplayBounds(mWindowContext)); wmProxy.registerDesktopVisibilityListener(this); FileLog.i(TAG, "(CTOR) perDisplayBounds: " + mInfo.mPerDisplayBounds); - } - private void attachTaskbarPinningSharedPreferenceChangeListener(Context context) { - mTaskbarPinningPreferenceChangeListener = key -> { - LauncherPrefs prefs = LauncherPrefs.get(mContext); - boolean isTaskbarPinningChanged = TASKBAR_PINNING_KEY.equals(key) - && mInfo.mIsTaskbarPinned != prefs.get(TASKBAR_PINNING); - boolean isTaskbarPinningDesktopModeChanged = - TASKBAR_PINNING_DESKTOP_MODE_KEY.equals(key) - && mInfo.mIsTaskbarPinnedInDesktopMode != prefs.get( - TASKBAR_PINNING_IN_DESKTOP_MODE); - if (isTaskbarPinningChanged || isTaskbarPinningDesktopModeChanged) { - notifyConfigChange(); - } - }; - - LauncherPrefs.get(context).addListener( - mTaskbarPinningPreferenceChangeListener, TASKBAR_PINNING); - LauncherPrefs.get(context).addListener( - mTaskbarPinningPreferenceChangeListener, TASKBAR_PINNING_IN_DESKTOP_MODE); + lifecycle.addCloseable(() -> { + mDestroyed = true; + mWindowContext.unregisterComponentCallbacks(this); + mReceiver.unregisterReceiverSafely(mContext); + wmProxy.unregisterDesktopVisibilityListener(this); + }); } /** @@ -208,20 +219,6 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable, } @Override - public void close() { - mDestroyed = true; - if (enableTaskbarPinning()) { - LauncherPrefs.get(mContext).removeListener( - mTaskbarPinningPreferenceChangeListener, TASKBAR_PINNING); - LauncherPrefs.get(mContext).removeListener( - mTaskbarPinningPreferenceChangeListener, TASKBAR_PINNING_IN_DESKTOP_MODE); - } - mWindowContext.unregisterComponentCallbacks(this); - mReceiver.unregisterReceiverSafely(mContext); - WindowManagerProxy.INSTANCE.get(mContext).unregisterDesktopVisibilityListener(this); - } - - @Override public void onDesktopVisibilityChanged(boolean visible) { notifyConfigChange(); } @@ -259,7 +256,7 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable, || !mInfo.mScreenSizeDp.equals( new PortraitSize(config.screenHeightDp, config.screenWidthDp)) || mWindowContext.getDisplay().getRotation() != mInfo.rotation - || WindowManagerProxy.INSTANCE.get(mContext).showLockedTaskbarOnHome(mWindowContext) + || mWMProxy.showLockedTaskbarOnHome(mWindowContext) != mInfo.showLockedTaskbarOnHome()) { notifyConfigChange(); } @@ -286,17 +283,16 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable, @AnyThread public void notifyConfigChange() { - WindowManagerProxy wmProxy = WindowManagerProxy.INSTANCE.get(mContext); Info oldInfo = mInfo; Context displayInfoContext = mWindowContext; - Info newInfo = new Info(displayInfoContext, wmProxy, oldInfo.mPerDisplayBounds); + Info newInfo = new Info(displayInfoContext, mWMProxy, oldInfo.mPerDisplayBounds); if (newInfo.densityDpi != oldInfo.densityDpi || newInfo.fontScale != oldInfo.fontScale || newInfo.getNavigationMode() != oldInfo.getNavigationMode()) { // Cache may not be valid anymore, recreate without cache - newInfo = new Info(displayInfoContext, wmProxy, - wmProxy.estimateInternalDisplayBounds(displayInfoContext)); + newInfo = new Info(displayInfoContext, mWMProxy, + mWMProxy.estimateInternalDisplayBounds(displayInfoContext)); } int change = 0; diff --git a/src_no_quickstep/com/android/launcher3/dagger/LauncherAppModule.java b/src_no_quickstep/com/android/launcher3/dagger/Modules.kt index f7b8489f62..dab33a04ee 100644 --- a/src_no_quickstep/com/android/launcher3/dagger/LauncherAppModule.java +++ b/src_no_quickstep/com/android/launcher3/dagger/Modules.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * 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. @@ -14,9 +14,14 @@ * limitations under the License. */ -package com.android.launcher3.dagger; +package com.android.launcher3.dagger -import dagger.Module; +import dagger.Module -@Module -public class LauncherAppModule { } +private object Modules {} + +@Module abstract class WindowManagerProxyModule {} + +@Module abstract class ApiWrapperModule {} + +@Module abstract class PluginManagerWrapperModule {} diff --git a/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt b/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt index 6676766632..9c64ec9704 100644 --- a/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt @@ -29,9 +29,9 @@ import android.view.Surface import androidx.test.core.app.ApplicationProvider.getApplicationContext import androidx.test.platform.app.InstrumentationRegistry import com.android.launcher3.dagger.LauncherAppComponent -import com.android.launcher3.dagger.LauncherAppModule import com.android.launcher3.dagger.LauncherAppSingleton import com.android.launcher3.testing.shared.ResourceUtils +import com.android.launcher3.util.AllModulesMinusWMProxy import com.android.launcher3.util.DisplayController import com.android.launcher3.util.MainThreadInitializedObject.SandboxContext import com.android.launcher3.util.NavigationMode @@ -69,7 +69,7 @@ abstract class AbstractDeviceProfileTest { protected lateinit var context: SandboxContext protected open val runningContext: Context = getApplicationContext() private val displayController: DisplayController = mock() - private val windowManagerProxy: MyWmProxy = mock() + private val windowManagerProxy: WindowManagerProxy = mock() private val launcherPrefs: LauncherPrefs = mock() @get:Rule val setFlagsRule = SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT) @@ -312,8 +312,8 @@ abstract class AbstractDeviceProfileTest { DaggerAbsDPTestSandboxComponent.builder() .bindWMProxy(windowManagerProxy) .bindLauncherPrefs(launcherPrefs) + .bindDisplayController(displayController) ) - context.putObject(DisplayController.INSTANCE, displayController) whenever(launcherPrefs.get(LauncherPrefs.TASKBAR_PINNING)).thenReturn(false) whenever(launcherPrefs.get(LauncherPrefs.TASKBAR_PINNING_IN_DESKTOP_MODE)).thenReturn(true) @@ -364,20 +364,18 @@ abstract class AbstractDeviceProfileTest { } } -class MyWmProxy : WindowManagerProxy() - @LauncherAppSingleton -@Component(modules = [LauncherAppModule::class]) +@Component(modules = [AllModulesMinusWMProxy::class]) interface AbsDPTestSandboxComponent : LauncherAppComponent { - override fun getWmProxy(): MyWmProxy - @Component.Builder interface Builder : LauncherAppComponent.Builder { - @BindsInstance fun bindWMProxy(proxy: MyWmProxy): Builder + @BindsInstance fun bindWMProxy(proxy: WindowManagerProxy): Builder @BindsInstance fun bindLauncherPrefs(prefs: LauncherPrefs): Builder + @BindsInstance fun bindDisplayController(displayController: DisplayController): Builder + override fun build(): AbsDPTestSandboxComponent } } diff --git a/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt b/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt index fcbb94be9c..97ecafeeab 100644 --- a/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt @@ -42,10 +42,10 @@ import com.android.launcher3.LauncherSettings.Favorites.SPANX import com.android.launcher3.LauncherSettings.Favorites.SPANY import com.android.launcher3.LauncherSettings.Favorites._ID import com.android.launcher3.dagger.LauncherAppComponent -import com.android.launcher3.dagger.LauncherAppModule import com.android.launcher3.dagger.LauncherAppSingleton import com.android.launcher3.model.data.AppInfo import com.android.launcher3.pm.UserCache +import com.android.launcher3.util.AllModulesMinusApiWrapper import com.android.launcher3.util.ApiWrapper import com.android.launcher3.util.Executors import com.android.launcher3.util.LauncherLayoutBuilder @@ -224,17 +224,15 @@ class AutoInstallsLayoutTest { } } -class MyApiWrapper : ApiWrapper(null) {} +class MyApiWrapper : ApiWrapper(null) @LauncherAppSingleton -@Component(modules = [LauncherAppModule::class]) +@Component(modules = [AllModulesMinusApiWrapper::class]) interface AutoInstallsLayoutTestComponent : LauncherAppComponent { - override fun getApiWrapper(): MyApiWrapper - @Component.Builder interface Builder : LauncherAppComponent.Builder { - @BindsInstance fun bindApiWrapper(wrapper: MyApiWrapper): Builder + @BindsInstance fun bindApiWrapper(wrapper: ApiWrapper): Builder override fun build(): AutoInstallsLayoutTestComponent } diff --git a/tests/multivalentTests/src/com/android/launcher3/graphics/ThemeManagerTest.kt b/tests/multivalentTests/src/com/android/launcher3/graphics/ThemeManagerTest.kt index 43bbad9e68..43b7b68d57 100644 --- a/tests/multivalentTests/src/com/android/launcher3/graphics/ThemeManagerTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/graphics/ThemeManagerTest.kt @@ -20,9 +20,10 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.launcher3.FakeLauncherPrefs import com.android.launcher3.dagger.LauncherAppComponent -import com.android.launcher3.dagger.LauncherAppModule import com.android.launcher3.dagger.LauncherAppSingleton +import com.android.launcher3.util.AllModulesForTest import com.android.launcher3.util.Executors.MAIN_EXECUTOR +import com.android.launcher3.util.FakePrefsModule import com.android.launcher3.util.SandboxApplication import com.android.launcher3.util.TestUtil import dagger.Component @@ -91,7 +92,7 @@ class ThemeManagerTest { } @LauncherAppSingleton -@Component(modules = [LauncherAppModule::class]) +@Component(modules = [AllModulesForTest::class, FakePrefsModule::class]) interface ThemeManagerComponent : LauncherAppComponent { override fun getLauncherPrefs(): FakeLauncherPrefs diff --git a/tests/multivalentTests/src/com/android/launcher3/util/DaggerGraphs.kt b/tests/multivalentTests/src/com/android/launcher3/util/DaggerGraphs.kt new file mode 100644 index 0000000000..68da9ff4d6 --- /dev/null +++ b/tests/multivalentTests/src/com/android/launcher3/util/DaggerGraphs.kt @@ -0,0 +1,41 @@ +/* + * 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.util + +import com.android.launcher3.FakeLauncherPrefs +import com.android.launcher3.LauncherPrefs +import com.android.launcher3.dagger.ApiWrapperModule +import com.android.launcher3.dagger.WindowManagerProxyModule +import dagger.Binds +import dagger.Module + +private class DaggerGraphs {} + +@Module +abstract class FakePrefsModule { + @Binds abstract fun bindLauncherPrefs(prefs: FakeLauncherPrefs): LauncherPrefs +} + +/** All modules. We also exclude the plugin module from tests */ +@Module(includes = [ApiWrapperModule::class, WindowManagerProxyModule::class]) +class AllModulesForTest + +/** All modules except the WMProxy */ +@Module(includes = [ApiWrapperModule::class]) class AllModulesMinusWMProxy + +/** All modules except the ApiWrapper */ +@Module(includes = [WindowManagerProxyModule::class]) class AllModulesMinusApiWrapper diff --git a/tests/multivalentTests/src/com/android/launcher3/util/DisplayControllerTest.kt b/tests/multivalentTests/src/com/android/launcher3/util/DisplayControllerTest.kt index e6e156fb1e..7e76e1965c 100644 --- a/tests/multivalentTests/src/com/android/launcher3/util/DisplayControllerTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/util/DisplayControllerTest.kt @@ -30,7 +30,6 @@ import com.android.launcher3.LauncherPrefs import com.android.launcher3.LauncherPrefs.Companion.TASKBAR_PINNING import com.android.launcher3.LauncherPrefs.Companion.TASKBAR_PINNING_IN_DESKTOP_MODE import com.android.launcher3.dagger.LauncherAppComponent -import com.android.launcher3.dagger.LauncherAppModule import com.android.launcher3.dagger.LauncherAppSingleton import com.android.launcher3.util.DisplayController.CHANGE_DENSITY import com.android.launcher3.util.DisplayController.CHANGE_ROTATION @@ -43,6 +42,7 @@ import dagger.BindsInstance import dagger.Component import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue +import kotlin.math.min import org.junit.After import org.junit.Before import org.junit.Test @@ -57,7 +57,6 @@ import org.mockito.kotlin.spy import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.mockito.stubbing.Answer -import kotlin.math.min /** Unit tests for {@link DisplayController} */ @SmallTest @@ -139,7 +138,7 @@ class DisplayControllerTest { whenever(context.resources).thenReturn(resources) // Initialize DisplayController - displayController = DisplayController(context) + displayController = DisplayController.INSTANCE.get(context) displayController.addChangeListener(displayInfoChangeListener) } @@ -235,14 +234,12 @@ class DisplayControllerTest { class MyWmProxy : WindowManagerProxy() @LauncherAppSingleton -@Component(modules = [LauncherAppModule::class]) +@Component(modules = [AllModulesMinusWMProxy::class]) interface DisplayControllerTestComponent : LauncherAppComponent { - override fun getWmProxy(): MyWmProxy - @Component.Builder interface Builder : LauncherAppComponent.Builder { - @BindsInstance fun bindWMProxy(proxy: MyWmProxy): Builder + @BindsInstance fun bindWMProxy(proxy: WindowManagerProxy): Builder @BindsInstance fun bindLauncherPrefs(prefs: LauncherPrefs): Builder |