Only register RecentTasksChangedListener if flag is enabled
Also unregister it if the feature becomes disabled (currently
this is only done in tests but in the future there will be a
user setting as well).
Added tests to verify getTasks() is not called while both
canShowRunningApps and canShowRecentApps are false.
Bug: 354087794
Test: TaskbarRecentAppsControllerTest
Flag: com.android.launcher3.enable_recents_in_taskbar
Flag: com.android.window.flags.enable_desktop_windowing_taskbar_running_apps
Change-Id: I3123501e7584ad7f877e13294454556501d2dbc8
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
index 2cb950c..49fc0dd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
@@ -50,6 +50,9 @@
@VisibleForTesting
set(isEnabledFromTest) {
field = isEnabledFromTest
+ if (!field && !canShowRecentApps) {
+ recentsModel.unregisterRecentTasksChangedListener()
+ }
}
// TODO(b/343532825): Add a setting to disable Recents even when the flag is on.
@@ -57,6 +60,9 @@
@VisibleForTesting
set(isEnabledFromTest) {
field = isEnabledFromTest
+ if (!field && !canShowRunningApps) {
+ recentsModel.unregisterRecentTasksChangedListener()
+ }
}
// Initialized in init.
@@ -116,8 +122,10 @@
fun init(taskbarControllers: TaskbarControllers) {
controllers = taskbarControllers
- recentsModel.registerRecentTasksChangedListener(recentTasksChangedListener)
- reloadRecentTasksIfNeeded()
+ if (canShowRunningApps || canShowRecentApps) {
+ recentsModel.registerRecentTasksChangedListener(recentTasksChangedListener)
+ reloadRecentTasksIfNeeded()
+ }
}
fun onDestroy() {
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
index 07c4ffc..c0ff189 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
+++ b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
@@ -22,6 +22,7 @@
import android.content.Intent
import android.os.Process
import android.os.UserHandle
+import android.platform.test.rule.TestWatcher
import android.testing.AndroidTestingRunner
import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT
import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION
@@ -40,12 +41,14 @@
import org.junit.Before
import org.junit.Rule
import org.junit.Test
+import org.junit.runner.Description
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Mock
import org.mockito.junit.MockitoJUnit
import org.mockito.kotlin.any
import org.mockito.kotlin.doAnswer
+import org.mockito.kotlin.never
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
@@ -54,6 +57,18 @@
class TaskbarRecentAppsControllerTest : TaskbarBaseTestCase() {
@get:Rule val mockitoRule = MockitoJUnit.rule()
+ @get:Rule
+ val disableControllerForCertainTestsWatcher =
+ object : TestWatcher() {
+ override fun starting(description: Description) {
+ // Update canShowRunningAndRecentAppsAtInit before setUp() is called for each test.
+ canShowRunningAndRecentAppsAtInit =
+ description.methodName !in
+ listOf(
+ "canShowRunningAndRecentAppsAtInitIsFalse_getTasksNeverCalled",
+ )
+ }
+ }
@Mock private lateinit var mockIconCache: TaskIconCache
@Mock private lateinit var mockRecentsModel: RecentsModel
@@ -63,26 +78,39 @@
private var taskListChangeId: Int = 1
private lateinit var recentAppsController: TaskbarRecentAppsController
- private lateinit var recentTasksChangedListener: RecentTasksChangedListener
private lateinit var userHandle: UserHandle
+ private var canShowRunningAndRecentAppsAtInit = true
+ private var recentTasksChangedListener: RecentTasksChangedListener? = null
+
@Before
fun setUp() {
super.setup()
userHandle = Process.myUserHandle()
whenever(mockRecentsModel.iconCache).thenReturn(mockIconCache)
+ whenever(mockRecentsModel.unregisterRecentTasksChangedListener()).then {
+ recentTasksChangedListener = null
+ it
+ }
recentAppsController =
TaskbarRecentAppsController(mockContext, mockRecentsModel) {
mockDesktopVisibilityController
}
+ recentAppsController.canShowRunningApps = canShowRunningAndRecentAppsAtInit
+ recentAppsController.canShowRecentApps = canShowRunningAndRecentAppsAtInit
recentAppsController.init(taskbarControllers)
- recentAppsController.canShowRunningApps = true
- recentAppsController.canShowRecentApps = true
- val listenerCaptor = ArgumentCaptor.forClass(RecentTasksChangedListener::class.java)
- verify(mockRecentsModel).registerRecentTasksChangedListener(listenerCaptor.capture())
- recentTasksChangedListener = listenerCaptor.value
+ recentTasksChangedListener =
+ if (canShowRunningAndRecentAppsAtInit) {
+ val listenerCaptor = ArgumentCaptor.forClass(RecentTasksChangedListener::class.java)
+ verify(mockRecentsModel)
+ .registerRecentTasksChangedListener(listenerCaptor.capture())
+ listenerCaptor.value
+ } else {
+ verify(mockRecentsModel, never()).registerRecentTasksChangedListener(any())
+ null
+ }
// Make sure updateHotseatItemInfos() is called after commitRunningAppsToUI()
whenever(taskbarViewController.commitRunningAppsToUI()).then {
@@ -92,6 +120,32 @@
}
}
+ // See the TestWatcher rule at the top which sets canShowRunningAndRecentAppsAtInit = false.
+ @Test
+ fun canShowRunningAndRecentAppsAtInitIsFalse_getTasksNeverCalled() {
+ prepareHotseatAndRunningAndRecentApps(
+ hotseatPackages = listOf(HOTSEAT_PACKAGE_1, HOTSEAT_PACKAGE_2),
+ runningTasks = listOf(createTask(1, RUNNING_APP_PACKAGE_1)),
+ recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2)
+ )
+ verify(mockRecentsModel, never()).getTasks(any<Consumer<List<GroupTask>>>())
+ }
+
+ @Test
+ fun canShowRunningAndRecentAppsIsFalseAfterInit_getTasksOnlyCalledInInit() {
+ // getTasks() should have been called once from init().
+ verify(mockRecentsModel, times(1)).getTasks(any<Consumer<List<GroupTask>>>())
+ recentAppsController.canShowRunningApps = false
+ recentAppsController.canShowRecentApps = false
+ prepareHotseatAndRunningAndRecentApps(
+ hotseatPackages = listOf(HOTSEAT_PACKAGE_1, HOTSEAT_PACKAGE_2),
+ runningTasks = listOf(createTask(1, RUNNING_APP_PACKAGE_1)),
+ recentTaskPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2)
+ )
+ // Verify that getTasks() was not called again after the init().
+ verify(mockRecentsModel, times(1)).getTasks(any<Consumer<List<GroupTask>>>())
+ }
+
@Test
fun updateHotseatItemInfos_cantShowRunning_inDesktopMode_returnsAllHotseatItems() {
recentAppsController.canShowRunningApps = false
@@ -522,7 +576,7 @@
)
setInDesktopMode(true)
- recentTasksChangedListener.onRecentTasksChanged()
+ recentTasksChangedListener!!.onRecentTasksChanged()
val shownPackages = recentAppsController.shownTasks.flatMap { it.packageNames }
assertThat(shownPackages).containsExactly(RUNNING_APP_PACKAGE_1, RUNNING_APP_PACKAGE_2)
}
@@ -539,7 +593,7 @@
recentTaskPackages = recentTaskPackages
)
setInDesktopMode(false)
- recentTasksChangedListener.onRecentTasksChanged()
+ recentTasksChangedListener!!.onRecentTasksChanged()
val shownPackages = recentAppsController.shownTasks.flatMap { it.packageNames }
// Don't expect RECENT_PACKAGE_3 because it is currently running.
val expectedPackages = listOf(RECENT_PACKAGE_1, RECENT_PACKAGE_2)
@@ -709,7 +763,7 @@
}
.whenever(mockRecentsModel)
.getTasks(any<Consumer<List<GroupTask>>>())
- recentTasksChangedListener.onRecentTasksChanged()
+ recentTasksChangedListener?.onRecentTasksChanged()
}
private fun createHotseatItemsFromPackageNames(packageNames: List<String>): List<ItemInfo> {