Merge "[Dagger] Make SystemUiProxy provided by DaggerSingletonObject" into main
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index c1d7ffa..cd39c09 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -54,15 +54,16 @@
 
 import androidx.annotation.MainThread;
 import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
 import androidx.annotation.WorkerThread;
 
 import com.android.internal.logging.InstanceId;
 import com.android.internal.util.ScreenshotRequest;
 import com.android.internal.view.AppearanceRegion;
-import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.dagger.ApplicationContext;
+import com.android.launcher3.dagger.LauncherAppSingleton;
+import com.android.launcher3.util.DaggerSingletonObject;
 import com.android.launcher3.util.Preconditions;
-import com.android.launcher3.util.SafeCloseable;
+import com.android.quickstep.dagger.QuickstepBaseAppComponent;
 import com.android.quickstep.util.ActiveGestureProtoLogProxy;
 import com.android.quickstep.util.ContextualSearchInvoker;
 import com.android.quickstep.util.unfold.ProxyUnfoldTransitionProvider;
@@ -109,14 +110,17 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 
+import javax.inject.Inject;
+
 /**
  * Holds the reference to SystemUI.
  */
-public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable {
+@LauncherAppSingleton
+public class SystemUiProxy implements ISystemUiProxy, NavHandle {
     private static final String TAG = "SystemUiProxy";
 
-    public static final MainThreadInitializedObject<SystemUiProxy> INSTANCE =
-            new MainThreadInitializedObject<>(SystemUiProxy::new);
+    public static final DaggerSingletonObject<SystemUiProxy> INSTANCE =
+            new DaggerSingletonObject<>(QuickstepBaseAppComponent::getSystemUiProxy);
 
     private static final int MSG_SET_SHELF_HEIGHT = 1;
     private static final int MSG_SET_LAUNCHER_KEEP_CLEAR_AREA_HEIGHT = 2;
@@ -188,8 +192,8 @@
     @Nullable
     private final ProxyUnfoldTransitionProvider mUnfoldTransitionProvider;
 
-    @VisibleForTesting
-    protected SystemUiProxy(Context context) {
+    @Inject
+    public SystemUiProxy(@ApplicationContext Context context) {
         mContext = context;
         mAsyncHandler = new Handler(UI_HELPER_EXECUTOR.getLooper(), this::handleMessageAsync);
         final Intent baseIntent = new Intent().setPackage(mContext.getPackageName());
@@ -206,9 +210,6 @@
     }
 
     @Override
-    public void close() { }
-
-    @Override
     public void onBackPressed() {
         if (mSystemUiProxy != null) {
             try {
diff --git a/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java b/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java
index 977c036..b2670e8 100644
--- a/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java
+++ b/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java
@@ -19,6 +19,7 @@
 import com.android.launcher3.dagger.LauncherAppComponent;
 import com.android.launcher3.dagger.LauncherBaseAppComponent;
 import com.android.launcher3.model.WellbeingModel;
+import com.android.quickstep.SystemUiProxy;
 import com.android.quickstep.util.AsyncClockEventDelegate;
 
 /**
@@ -34,4 +35,6 @@
     WellbeingModel getWellbeingModel();
 
     AsyncClockEventDelegate getAsyncClockEventDelegate();
+
+    SystemUiProxy getSystemUiProxy();
 }
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarAutohideSuspendControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarAutohideSuspendControllerTest.kt
index 59900b1..46a7733 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarAutohideSuspendControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarAutohideSuspendControllerTest.kt
@@ -24,6 +24,7 @@
 import com.android.launcher3.taskbar.rules.TaskbarModeRule
 import com.android.launcher3.taskbar.rules.TaskbarModeRule.Mode.TRANSIENT
 import com.android.launcher3.taskbar.rules.TaskbarModeRule.TaskbarMode
+import com.android.launcher3.taskbar.rules.TaskbarSandboxComponent
 import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule
 import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule.InjectController
 import com.android.launcher3.taskbar.rules.TaskbarWindowSandboxContext
@@ -33,36 +34,28 @@
 import com.google.common.truth.Truth.assertThat
 import org.junit.Rule
 import org.junit.Test
-import org.junit.rules.TestRule
 import org.junit.runner.RunWith
-import org.junit.runners.model.Statement
 
 @RunWith(LauncherMultivalentJUnit::class)
 @EmulatedDevices(["pixelTablet2023"])
 class TaskbarAutohideSuspendControllerTest {
 
-    @get:Rule(order = 0) val context = TaskbarWindowSandboxContext.create()
-    @get:Rule(order = 1) val animatorTestRule = AnimatorTestRule(this)
-    @get:Rule(order = 2)
-    val systemUiProxyRule = TestRule { base, _ ->
-        object : Statement() {
-            override fun evaluate() {
-                getInstrumentation().runOnMainSync {
-                    context.putObject(
-                        SystemUiProxy.INSTANCE,
-                        object : SystemUiProxy(context) {
-                            override fun notifyTaskbarAutohideSuspend(suspend: Boolean) {
-                                latestSuspendNotification = suspend
-                            }
-                        },
-                    )
+    @get:Rule(order = 0)
+    val context =
+        TaskbarWindowSandboxContext.create {
+            builder: TaskbarSandboxComponent.Builder,
+            sandboxContext: TaskbarWindowSandboxContext ->
+            builder.bindSystemUiProxy(
+                object : SystemUiProxy(sandboxContext) {
+                    override fun notifyTaskbarAutohideSuspend(suspend: Boolean) {
+                        latestSuspendNotification = suspend
+                    }
                 }
-                base.evaluate()
-            }
+            )
         }
-    }
-    @get:Rule(order = 3) val taskbarModeRule = TaskbarModeRule(context)
-    @get:Rule(order = 4) val taskbarUnitTestRule = TaskbarUnitTestRule(this, context)
+    @get:Rule(order = 1) val animatorTestRule = AnimatorTestRule(this)
+    @get:Rule(order = 2) val taskbarModeRule = TaskbarModeRule(context)
+    @get:Rule(order = 3) val taskbarUnitTestRule = TaskbarUnitTestRule(this, context)
 
     @InjectController lateinit var autohideSuspendController: TaskbarAutohideSuspendController
     @InjectController lateinit var stashController: TaskbarStashController
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarScrimViewControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarScrimViewControllerTest.kt
index 12e84b8..b1bb472 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarScrimViewControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarScrimViewControllerTest.kt
@@ -24,6 +24,7 @@
 import com.android.launcher3.taskbar.rules.TaskbarModeRule.Mode.PINNED
 import com.android.launcher3.taskbar.rules.TaskbarModeRule.Mode.TRANSIENT
 import com.android.launcher3.taskbar.rules.TaskbarModeRule.TaskbarMode
+import com.android.launcher3.taskbar.rules.TaskbarSandboxComponent
 import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule
 import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule.InjectController
 import com.android.launcher3.taskbar.rules.TaskbarWindowSandboxContext
@@ -42,7 +43,20 @@
 @RunWith(LauncherMultivalentJUnit::class)
 @EmulatedDevices(["pixelTablet2023"])
 class TaskbarScrimViewControllerTest {
-    @get:Rule(order = 0) val context = TaskbarWindowSandboxContext.create()
+    @get:Rule(order = 0)
+    val context =
+        TaskbarWindowSandboxContext.create {
+            builder: TaskbarSandboxComponent.Builder,
+            sandboxContext: TaskbarWindowSandboxContext ->
+            builder.bindSystemUiProxy(
+                object : SystemUiProxy(sandboxContext) {
+                    override fun onBackPressed() {
+                        super.onBackPressed()
+                        backPressed = true
+                    }
+                }
+            )
+        }
     @get:Rule(order = 1) val taskbarModeRule = TaskbarModeRule(context)
     @get:Rule(order = 2) val animatorTestRule = AnimatorTestRule(this)
     @get:Rule(order = 3) val taskbarUnitTestRule = TaskbarUnitTestRule(this, context)
@@ -53,6 +67,8 @@
     private val animationDuration =
         context.resources.getInteger(android.R.integer.config_mediumAnimTime).toLong()
 
+    private var backPressed = false
+
     @Test
     @TaskbarMode(PINNED)
     fun testOnTaskbarVisibleChanged_onlyTaskbarVisible_noScrim() {
@@ -130,16 +146,6 @@
     @Test
     @TaskbarMode(PINNED)
     fun testOnClick_scrimShown_performsSystemBack() {
-        var backPressed = false
-        context.putObject(
-            SystemUiProxy.INSTANCE,
-            object : SystemUiProxy(context) {
-                override fun onBackPressed() {
-                    backPressed = true
-                }
-            },
-        )
-
         getInstrumentation().runOnMainSync {
             scrimViewController.updateStateForSysuiFlags(SYSUI_STATE_BUBBLES_EXPANDED, true)
             scrimViewController.onTaskbarVisibilityChanged(VISIBLE)
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 2d3bfd6..a331a25 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
@@ -24,8 +24,13 @@
 import androidx.test.core.app.ApplicationProvider
 import com.android.launcher3.FakeLauncherPrefs
 import com.android.launcher3.LauncherPrefs
+import com.android.launcher3.dagger.LauncherAppComponent
+import com.android.launcher3.dagger.LauncherAppSingleton
 import com.android.launcher3.util.MainThreadInitializedObject.ObjectSandbox
 import com.android.launcher3.util.SandboxApplication
+import com.android.quickstep.SystemUiProxy
+import dagger.BindsInstance
+import dagger.Component
 import org.junit.rules.ExternalResource
 import org.junit.rules.RuleChain
 import org.junit.rules.TestRule
@@ -50,7 +55,14 @@
         private const val VIRTUAL_DISPLAY_NAME = "TaskbarSandboxDisplay"
 
         /** Creates a [SandboxApplication] for Taskbar tests. */
-        fun create(): TaskbarWindowSandboxContext {
+        fun create(
+            daggerComponentBinder:
+                ((
+                    builder: TaskbarSandboxComponent.Builder,
+                    sandboxContext: TaskbarWindowSandboxContext,
+                ) -> TaskbarSandboxComponent.Builder)? =
+                null
+        ): TaskbarWindowSandboxContext {
             val base = ApplicationProvider.getApplicationContext<Context>()
             val displayManager = checkNotNull(base.getSystemService(DisplayManager::class.java))
 
@@ -67,10 +79,21 @@
                     )
                 }
 
-            return TaskbarWindowSandboxContext(
-                SandboxApplication(base.createDisplayContext(virtualDisplay.display)),
-                virtualDisplay,
-            )
+            val sandboxApplication =
+                SandboxApplication(base.createDisplayContext(virtualDisplay.display))
+            val taskbarWindowSandboxContext =
+                TaskbarWindowSandboxContext(sandboxApplication, virtualDisplay)
+
+            if (daggerComponentBinder != null) {
+                sandboxApplication.initDaggerComponent(
+                    daggerComponentBinder(
+                        DaggerTaskbarSandboxComponent.builder(),
+                        taskbarWindowSandboxContext,
+                    )
+                )
+            }
+
+            return taskbarWindowSandboxContext
         }
     }
 }
@@ -80,3 +103,14 @@
         override fun after() = virtualDisplay.release()
     }
 }
+
+@LauncherAppSingleton
+@Component
+interface TaskbarSandboxComponent : LauncherAppComponent {
+    @Component.Builder
+    interface Builder : LauncherAppComponent.Builder {
+        @BindsInstance fun bindSystemUiProxy(proxy: SystemUiProxy): Builder
+
+        override fun build(): TaskbarSandboxComponent
+    }
+}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt
index 1f88743..6212b59 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt
@@ -20,6 +20,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.launcher3.R
+import com.android.launcher3.taskbar.rules.DaggerTaskbarSandboxComponent
 import com.android.launcher3.util.LauncherModelHelper
 import com.android.systemui.contextualeducation.GestureType
 import com.android.systemui.shared.system.InputConsumerController
@@ -58,7 +59,9 @@
 
     @Before
     fun setup() {
-        sandboxContext.putObject(SystemUiProxy.INSTANCE, systemUiProxy)
+        sandboxContext.initDaggerComponent(
+            DaggerTaskbarSandboxComponent.builder().bindSystemUiProxy(systemUiProxy)
+        )
         val deviceState = mock(RecentsAnimationDeviceState::class.java)
         whenever(deviceState.rotationTouchHelper).thenReturn(mock(RotationTouchHelper::class.java))
         gestureState = spy(GestureState(OverviewComponentObserver(sandboxContext, deviceState), 0))
@@ -71,7 +74,7 @@
                 gestureState,
                 0,
                 false,
-                inputConsumerController
+                inputConsumerController,
             )
         underTest.onGestureStarted(/* isLikelyToStartNewTask= */ false)
     }
@@ -83,7 +86,7 @@
         verify(systemUiProxy)
             .updateContextualEduStats(
                 /* isTrackpadGesture= */ eq(true),
-                eq(GestureType.HOME.toString())
+                eq(GestureType.HOME.toString()),
             )
     }
 
@@ -93,7 +96,7 @@
         verify(systemUiProxy)
             .updateContextualEduStats(
                 /* isTrackpadGesture= */ eq(false),
-                eq(GestureType.HOME.toString())
+                eq(GestureType.HOME.toString()),
             )
     }
 }