Files
Lawnchair/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarViewWithLayoutTransitionTest.kt
T
Jon Miranda a19e4e2063 Switch taskbar overflow flag to lse_desktop_experience
Both flags are in Nextfood, so there will be no change to
user experience.

Bug: 368119679
Bug: 375627272
Test: TaskbarOverflowTest
Flag: com.android.window.flags.enable_taskbar_overflow
Change-Id: Ie3ef3bd49e078f5657bd069bc92c5a48a136e7cb
2025-04-23 15:20:04 -07:00

353 lines
14 KiB
Kotlin

/*
* 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.launcher3.taskbar
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import android.view.View
import com.android.launcher3.R
import com.android.launcher3.statehandlers.DesktopVisibilityController
import com.android.launcher3.taskbar.TaskbarControllerTestUtil.runOnMainSync
import com.android.launcher3.taskbar.TaskbarIconType.ALL_APPS
import com.android.launcher3.taskbar.TaskbarIconType.DIVIDER
import com.android.launcher3.taskbar.TaskbarIconType.HOTSEAT
import com.android.launcher3.taskbar.TaskbarIconType.OVERFLOW
import com.android.launcher3.taskbar.TaskbarIconType.RECENT
import com.android.launcher3.taskbar.TaskbarViewTestUtil.assertThat
import com.android.launcher3.taskbar.TaskbarViewTestUtil.createHotseatItems
import com.android.launcher3.taskbar.TaskbarViewTestUtil.createRecents
import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule
import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule.ForceRtl
import com.android.launcher3.taskbar.rules.TaskbarWindowSandboxContext
import com.android.launcher3.util.LauncherMultivalentJUnit
import com.android.launcher3.util.LauncherMultivalentJUnit.EmulatedDevices
import com.android.window.flags.Flags.FLAG_ENABLE_TASKBAR_OVERFLOW
import com.android.window.flags.Flags.FLAG_ENABLE_TASKBAR_RECENTS_LAYOUT_TRANSITION
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.whenever
@RunWith(LauncherMultivalentJUnit::class)
@EmulatedDevices(["pixelFoldable2023", "pixelTablet2023"])
@EnableFlags(FLAG_ENABLE_TASKBAR_OVERFLOW, FLAG_ENABLE_TASKBAR_RECENTS_LAYOUT_TRANSITION)
class TaskbarViewWithLayoutTransitionTest {
@get:Rule(order = 0) val setFlagsRule = SetFlagsRule()
@get:Rule(order = 1) val context = TaskbarWindowSandboxContext.create()
@get:Rule(order = 2) val taskbarUnitTestRule = TaskbarUnitTestRule(this, context)
private lateinit var taskbarView: TaskbarView
private val iconViews: Array<View>
get() = taskbarView.iconViews
private val desktopVisibilityController: DesktopVisibilityController
get() = DesktopVisibilityController.INSTANCE[context]
private val maxShownRecents: Int
get() = taskbarView.maxNumIconViews - 2 // Account for All Apps and Divider.
@Before
fun obtainView() {
taskbarView = taskbarUnitTestRule.activityContext.dragLayer.findViewById(R.id.taskbar_view)
}
@Test
@ForceRtl
fun testUpdateItems_rtl_hotseatItems_hasDividerBetweenHotseatAndAllApps() {
runOnMainSync { taskbarView.updateItems(createHotseatItems(2), emptyList()) }
assertThat(taskbarView).hasIconTypes(*HOTSEAT * 2, DIVIDER, ALL_APPS)
}
@Test
@ForceRtl
fun testUpdateItems_rtl_recentsItems_hasDividerBetweenRecentsAndAllApps() {
runOnMainSync { taskbarView.updateItems(emptyArray(), createRecents(4)) }
assertThat(taskbarView).hasIconTypes(*RECENT * 4, DIVIDER, ALL_APPS)
}
@Test
@ForceRtl
fun testUpdateItems_rtl_recentsItems_recentsAreReversed() {
runOnMainSync { taskbarView.updateItems(emptyArray(), createRecents(4)) }
assertThat(taskbarView).hasRecentsOrder(startIndex = 0, expectedIds = listOf(3, 2, 1, 0))
}
@Test
@ForceRtl
fun testUpdateItems_rtl_hotseatItemsAndRecents_hasDividerBetweenRecentsAndHotseat() {
runOnMainSync { taskbarView.updateItems(createHotseatItems(3), createRecents(2)) }
assertThat(taskbarView).hasIconTypes(*RECENT * 2, DIVIDER, *HOTSEAT * 3, ALL_APPS)
}
@Test
@ForceRtl
fun testUpdateItems_rtl_addHotseatItemWithoutRecents_updatesHotseat() {
runOnMainSync {
taskbarView.updateItems(createHotseatItems(1), emptyList())
taskbarView.updateItems(createHotseatItems(2), emptyList())
}
assertThat(taskbarView).hasIconTypes(*HOTSEAT * 2, DIVIDER, ALL_APPS)
}
@Test
@ForceRtl
fun testUpdateItems_rtl_addHotseatItemWithRecents_updatesHotseat() {
runOnMainSync {
taskbarView.updateItems(createHotseatItems(1), createRecents(1))
taskbarView.updateItems(createHotseatItems(2), createRecents(1))
}
assertThat(taskbarView).hasIconTypes(RECENT, DIVIDER, *HOTSEAT * 2, ALL_APPS)
}
@Test
@ForceRtl
fun testUpdateItems_rtl_removeHotseatItem_updatesHotseat() {
runOnMainSync {
taskbarView.updateItems(createHotseatItems(2), createRecents(1))
taskbarView.updateItems(createHotseatItems(1), createRecents(1))
}
assertThat(taskbarView).hasIconTypes(RECENT, DIVIDER, HOTSEAT, ALL_APPS)
}
@Test
@ForceRtl
fun testUpdateItems_rtl_addRecentsItem_updatesRecents() {
runOnMainSync {
taskbarView.updateItems(createHotseatItems(1), createRecents(1))
taskbarView.updateItems(createHotseatItems(1), createRecents(2))
}
assertThat(taskbarView).hasIconTypes(*RECENT * 2, DIVIDER, HOTSEAT, ALL_APPS)
}
@Test
@ForceRtl
fun testUpdateItems_rtl_removeRecentsItem_updatesRecents() {
runOnMainSync {
taskbarView.updateItems(createHotseatItems(1), createRecents(2))
taskbarView.updateItems(createHotseatItems(1), createRecents(1))
}
assertThat(taskbarView).hasIconTypes(RECENT, DIVIDER, HOTSEAT, ALL_APPS)
}
@Test
fun testUpdateItems_addRecentsItem_viewAddedOnRight() {
runOnMainSync {
taskbarView.updateItems(emptyArray(), createRecents(1))
val prevIconViews = iconViews
val newRecents = createRecents(2)
taskbarView.updateItems(emptyArray(), newRecents)
assertThat(taskbarView).hasRecentsOrder(startIndex = 2, expectedIds = listOf(0, 1))
assertThat(iconViews[2]).isSameInstanceAs(prevIconViews[2])
assertThat(iconViews.last() in prevIconViews).isFalse()
}
}
@Test
@ForceRtl
fun testUpdateItems_rtl_addRecentsItem_viewAddedOnLeft() {
runOnMainSync {
taskbarView.updateItems(emptyArray(), createRecents(1))
val prevIconViews = iconViews
val newRecents = createRecents(2)
taskbarView.updateItems(emptyArray(), newRecents)
assertThat(taskbarView).hasRecentsOrder(startIndex = 0, expectedIds = listOf(1, 0))
assertThat(iconViews[1]).isSameInstanceAs(prevIconViews.first())
assertThat(iconViews.first() in prevIconViews).isFalse()
}
}
@Test
fun testUpdateItems_removeFirstRecentsItem_correspondingViewRemoved() {
runOnMainSync {
val recents = createRecents(2)
taskbarView.updateItems(emptyArray(), recents)
val expectedViewToRemove = iconViews[2]
assertThat(expectedViewToRemove.tag).isEqualTo(recents.first())
taskbarView.updateItems(emptyArray(), listOf(recents.last()))
assertThat(expectedViewToRemove in iconViews).isFalse()
}
}
@Test
fun testUpdateItems_removeLastRecentsItem_correspondingViewRemoved() {
runOnMainSync {
val recents = createRecents(2)
taskbarView.updateItems(emptyArray(), recents)
val expectedViewToRemove = iconViews[3]
assertThat(expectedViewToRemove.tag).isEqualTo(recents.last())
taskbarView.updateItems(emptyArray(), listOf(recents.first()))
assertThat(expectedViewToRemove in iconViews).isFalse()
}
}
@Test
@ForceRtl
fun testUpdateItems_rtl_removeFirstRecentsItem_correspondingViewRemoved() {
runOnMainSync {
val recents = createRecents(2)
taskbarView.updateItems(emptyArray(), recents)
val expectedViewToRemove = iconViews[1]
assertThat(expectedViewToRemove.tag).isEqualTo(recents.first())
taskbarView.updateItems(emptyArray(), listOf(recents.last()))
assertThat(expectedViewToRemove in iconViews).isFalse()
}
}
@Test
@ForceRtl
fun testUpdateItems_rtl_removeLastRecentsItem_correspondingViewRemoved() {
runOnMainSync {
val recents = createRecents(2)
taskbarView.updateItems(emptyArray(), recents)
val expectedViewToRemove = iconViews[0]
assertThat(expectedViewToRemove.tag).isEqualTo(recents.last())
taskbarView.updateItems(emptyArray(), listOf(recents.first()))
assertThat(expectedViewToRemove in iconViews).isFalse()
}
}
@Test
fun testUpdateItems_desktopMode_hotseatItem_noDivider() {
whenever(desktopVisibilityController.isInDesktopMode(context.displayId)).thenReturn(true)
runOnMainSync { taskbarView.updateItems(createHotseatItems(1), emptyList()) }
assertThat(taskbarView).hasIconTypes(ALL_APPS, HOTSEAT)
}
@Test
@ForceRtl
fun testUpdateItems_rtlAndDesktopMode_hotseatItem_noDivider() {
whenever(desktopVisibilityController.isInDesktopMode(context.displayId)).thenReturn(true)
runOnMainSync { taskbarView.updateItems(createHotseatItems(1), emptyList()) }
assertThat(taskbarView).hasIconTypes(HOTSEAT, ALL_APPS)
}
@Test
fun testUpdateItems_desktopMode_recentItem_hasDivider() {
whenever(desktopVisibilityController.isInDesktopMode(context.displayId)).thenReturn(true)
runOnMainSync { taskbarView.updateItems(emptyArray(), createRecents(1)) }
assertThat(taskbarView).hasIconTypes(ALL_APPS, DIVIDER, RECENT)
}
@Test
@ForceRtl
fun testUpdateItems_rtlAndDesktopMode_recentItem_hasDivider() {
whenever(desktopVisibilityController.isInDesktopMode(context.displayId)).thenReturn(true)
runOnMainSync { taskbarView.updateItems(emptyArray(), createRecents(1)) }
assertThat(taskbarView).hasIconTypes(RECENT, DIVIDER, ALL_APPS)
}
@Test
fun testUpdateItems_maxRecents_noOverflow() {
runOnMainSync { taskbarView.updateItems(emptyArray(), createRecents(maxShownRecents)) }
assertThat(taskbarView).hasIconTypes(ALL_APPS, DIVIDER, *RECENT * maxShownRecents)
}
@Test
fun testUpdateItems_moreThanMaxRecents_overflowShownBeforeRecents() {
val recentsSize = maxShownRecents + 2
runOnMainSync { taskbarView.updateItems(emptyArray(), createRecents(recentsSize)) }
val expectedNumRecents = RECENT * getExpectedNumRecentsWithOverflow()
assertThat(taskbarView).hasIconTypes(ALL_APPS, DIVIDER, OVERFLOW, *expectedNumRecents)
}
@Test
@ForceRtl
fun testUpdateItems_rtl_moreThanMaxRecents_overflowShownAfterRecents() {
val recentsSize = maxShownRecents + 2
runOnMainSync { taskbarView.updateItems(emptyArray(), createRecents(recentsSize)) }
val expectedRecents = RECENT * getExpectedNumRecentsWithOverflow()
assertThat(taskbarView).hasIconTypes(*expectedRecents, OVERFLOW, DIVIDER, ALL_APPS)
}
@Test
fun testUpdateItems_moreThanMaxRecentsWithHotseat_fewerRecentsShown() {
val hotseatSize = 4
val recentsSize = maxShownRecents + 2
runOnMainSync {
taskbarView.updateItems(createHotseatItems(hotseatSize), createRecents(recentsSize))
}
val expectedRecents = RECENT * getExpectedNumRecentsWithOverflow(hotseatSize)
assertThat(taskbarView)
.hasIconTypes(ALL_APPS, *HOTSEAT * hotseatSize, DIVIDER, OVERFLOW, *expectedRecents)
}
@Test
@ForceRtl
fun testUpdateItems_rtl_moreThanMaxRecentsWithHotseat_fewerRecentsShown() {
val hotseatSize = 4
val recentsSize = maxShownRecents + 2
runOnMainSync {
taskbarView.updateItems(createHotseatItems(hotseatSize), createRecents(recentsSize))
}
val expectedRecents = RECENT * getExpectedNumRecentsWithOverflow(hotseatSize)
assertThat(taskbarView)
.hasIconTypes(*expectedRecents, OVERFLOW, DIVIDER, *HOTSEAT * hotseatSize, ALL_APPS)
}
@Test
fun testUpdateItems_moreThanMaxRecents_verifyShownRecentsOrder() {
val recentsSize = maxShownRecents + 2
runOnMainSync { taskbarView.updateItems(emptyArray(), createRecents(recentsSize)) }
val expectedNumRecents = getExpectedNumRecentsWithOverflow()
assertThat(taskbarView)
.hasRecentsOrder(
startIndex = iconViews.size - expectedNumRecents,
expectedIds = ((recentsSize - expectedNumRecents)..<recentsSize).toList(),
)
}
@Test
@ForceRtl
fun testUpdateItems_rtl_moreThanMaxRecents_verifyShownRecentsReversed() {
val recentsSize = maxShownRecents + 2
runOnMainSync { taskbarView.updateItems(emptyArray(), createRecents(recentsSize)) }
val expectedNumRecents = getExpectedNumRecentsWithOverflow()
assertThat(taskbarView)
.hasRecentsOrder(
startIndex = 0,
expectedIds = ((recentsSize - expectedNumRecents)..<recentsSize).toList().reversed(),
)
}
/** Returns the number of expected recents outside of the overflow based on [hotseatSize]. */
private fun getExpectedNumRecentsWithOverflow(hotseatSize: Int = 0): Int {
return maxShownRecents - hotseatSize - 1 // Account for overflow.
}
}