Setup view-binder entry points for NotifIconContainer

Bug: 290787599
Test: make
Change-Id: I33e247b67233feae8ddeee62e58ffa691d26b0f6
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
index 63cd20b..26dfe3e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
@@ -50,6 +50,10 @@
 import com.android.systemui.statusbar.notification.collection.ListEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerShelfViewModel
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerStatusBarViewModel
+import com.android.systemui.statusbar.notification.shelf.ui.viewbinder.NotificationShelfViewBinderWrapperControllerImpl
 import com.android.systemui.statusbar.phone.DozeParameters
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.phone.NotificationIconAreaController
@@ -60,6 +64,7 @@
 import java.util.Optional
 import java.util.function.Function
 import javax.inject.Inject
+import kotlinx.coroutines.DisposableHandle
 
 /**
  * Controller class for [NotificationIconContainer]. This implementation serves as a temporary
@@ -86,6 +91,9 @@
     featureFlags: FeatureFlags,
     private val statusBarWindowController: StatusBarWindowController,
     private val screenOffAnimationController: ScreenOffAnimationController,
+    private val shelfIconsViewModel: NotificationIconContainerShelfViewModel,
+    private val statusBarIconsViewModel: NotificationIconContainerStatusBarViewModel,
+    private val aodIconsViewModel: NotificationIconContainerAlwaysOnDisplayViewModel,
 ) :
     NotificationIconAreaController,
     DarkIconDispatcher.DarkReceiver,
@@ -106,6 +114,7 @@
     private var notificationIcons: NotificationIconContainer? = null
     private var shelfIcons: NotificationIconContainer? = null
     private var aodIcons: NotificationIconContainer? = null
+    private var aodBindJob: DisposableHandle? = null
     private var aodIconAppearTranslation = 0
     private var animationsEnabled = false
     private var aodIconTint = 0
@@ -142,9 +151,11 @@
         if (changed) {
             this.aodIcons!!.setAnimationsEnabled(false)
             this.aodIcons!!.removeAllViews()
+            aodBindJob?.dispose()
         }
         this.aodIcons = aodIcons
         this.aodIcons!!.setOnLockScreen(true)
+        aodBindJob = NotificationIconContainerViewBinder.bind(aodIcons, aodIconsViewModel)
         updateAodIconsVisibility(animate = false, forceUpdate = changed)
         updateAnimations()
         if (changed) {
@@ -153,13 +164,12 @@
         updateIconLayoutParams(context)
     }
 
-    override fun setupShelf(notificationShelfController: NotificationShelfController) {
-        shelfRefactor.assertDisabled()
-        shelfIcons = notificationShelfController.shelfIcons
-    }
+    override fun setupShelf(notificationShelfController: NotificationShelfController) =
+        NotificationShelfViewBinderWrapperControllerImpl.unsupported
 
     override fun setShelfIcons(icons: NotificationIconContainer) {
         if (shelfRefactor.expectEnabled()) {
+            NotificationIconContainerViewBinder.bind(icons, shelfIconsViewModel)
             shelfIcons = icons
         }
     }
@@ -329,6 +339,7 @@
         val layoutInflater = LayoutInflater.from(context)
         notificationIconArea = inflateIconArea(layoutInflater)
         notificationIcons = notificationIconArea?.findViewById(R.id.notificationIcons)
+        NotificationIconContainerViewBinder.bind(notificationIcons!!, statusBarIconsViewModel)
     }
 
     private fun updateIconLayoutParams(context: Context) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
index d06ff34..8293bb3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
@@ -20,13 +20,14 @@
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel
 import com.android.systemui.statusbar.phone.NotificationIconContainer
+import kotlinx.coroutines.DisposableHandle
 
 /** Binds a [NotificationIconContainer] to its [view model][NotificationIconContainerViewModel]. */
 object NotificationIconContainerViewBinder {
     fun bind(
         view: NotificationIconContainer,
         viewModel: NotificationIconContainerViewModel,
-    ) {
-        view.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) {} }
+    ): DisposableHandle {
+        return view.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) {} }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt
new file mode 100644
index 0000000..f68b0ef
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.systemui.statusbar.notification.icon.ui.viewmodel
+
+import javax.inject.Inject
+
+/** View-model for the row of notification icons displayed on the always-on display. */
+class NotificationIconContainerAlwaysOnDisplayViewModel @Inject constructor() :
+    NotificationIconContainerViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt
new file mode 100644
index 0000000..933c76f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.systemui.statusbar.notification.icon.ui.viewmodel
+
+import javax.inject.Inject
+
+/** View-model for the overflow row of notification icons displayed in the notification shade. */
+class NotificationIconContainerShelfViewModel @Inject constructor() :
+    NotificationIconContainerViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
new file mode 100644
index 0000000..2217646
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.systemui.statusbar.notification.icon.ui.viewmodel
+
+import javax.inject.Inject
+
+/** View-model for the row of notification icons displayed in the status bar, */
+class NotificationIconContainerStatusBarViewModel @Inject constructor() :
+    NotificationIconContainerViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt
index 22a87a7..b92c51f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt
@@ -64,8 +64,10 @@
 
     override fun setOnClickListener(listener: View.OnClickListener) = unsupported
 
-    private val unsupported: Nothing
-        get() = error("Code path not supported when NOTIFICATION_SHELF_REFACTOR is disabled")
+    companion object {
+        val unsupported: Nothing
+            get() = error("Code path not supported when NOTIFICATION_SHELF_REFACTOR is disabled")
+    }
 }
 
 /** Binds a [NotificationShelf] to its [view model][NotificationShelfViewModel]. */
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImplTest.kt
index d6f685d..b8792a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImplTest.kt
@@ -27,6 +27,9 @@
 import com.android.systemui.statusbar.NotificationMediaManager
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
 import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerShelfViewModel
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerStatusBarViewModel
 import com.android.systemui.statusbar.phone.DozeParameters
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.phone.NotificationIconContainer
@@ -35,7 +38,8 @@
 import com.android.systemui.util.mockito.whenever
 import com.android.wm.shell.bubbles.Bubbles
 import java.util.Optional
-import org.junit.Assert
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -45,7 +49,7 @@
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
-@RunWithLooper
+@RunWithLooper(setAsMainLooper = true)
 class NotificationIconAreaControllerViewBinderWrapperImplTest : SysuiTestCase() {
     @Mock private lateinit var notifListener: NotificationListener
     @Mock private lateinit var statusBarStateController: StatusBarStateController
@@ -62,6 +66,10 @@
     @Mock private lateinit var aodIcons: NotificationIconContainer
     @Mock private lateinit var featureFlags: FeatureFlags
 
+    private val shelfViewModel = NotificationIconContainerShelfViewModel()
+    private val statusBarViewModel = NotificationIconContainerStatusBarViewModel()
+    private val aodViewModel = NotificationIconContainerAlwaysOnDisplayViewModel()
+
     private lateinit var underTest: NotificationIconAreaControllerViewBinderWrapperImpl
 
     @Before
@@ -82,20 +90,23 @@
                 darkIconDispatcher,
                 featureFlags,
                 statusBarWindowController,
-                screenOffAnimController
+                screenOffAnimController,
+                shelfViewModel,
+                statusBarViewModel,
+                aodViewModel,
             )
     }
 
     @Test
     fun testNotificationIcons_settingHideIcons() {
         underTest.settingsListener.onStatusBarIconsBehaviorChanged(true)
-        Assert.assertFalse(underTest.shouldShowLowPriorityIcons())
+        assertFalse(underTest.shouldShowLowPriorityIcons())
     }
 
     @Test
     fun testNotificationIcons_settingShowIcons() {
         underTest.settingsListener.onStatusBarIconsBehaviorChanged(false)
-        Assert.assertTrue(underTest.shouldShowLowPriorityIcons())
+        assertTrue(underTest.shouldShowLowPriorityIcons())
     }
 
     @Test