c0a8f7ea99
Flag: com.android.window.flags.enable_taskbar_recents_layout_transition Fix: 402683858 Test: go/testedequals Change-Id: Icc4a3a61b6c0997564a4dcdd8eb7768459d5f2ef
176 lines
6.7 KiB
Kotlin
176 lines
6.7 KiB
Kotlin
/*
|
|
* 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.taskbar
|
|
|
|
import android.animation.AnimatorTestRule
|
|
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
|
|
import com.android.launcher3.BubbleTextView
|
|
import com.android.launcher3.BubbleTextView.RunningAppState
|
|
import com.android.launcher3.BubbleTextView.RunningAppState.MINIMIZED
|
|
import com.android.launcher3.BubbleTextView.RunningAppState.NOT_RUNNING
|
|
import com.android.launcher3.BubbleTextView.RunningAppState.RUNNING
|
|
import com.android.launcher3.model.data.TaskItemInfo
|
|
import com.android.launcher3.taskbar.TaskbarControllerTestUtil.runOnMainSync
|
|
import com.android.launcher3.taskbar.TaskbarRunningAppStateAnimationController.Companion.LINE_ANIM_DURATION
|
|
import com.android.launcher3.taskbar.TaskbarRunningAppStateAnimationController.Companion.UNPINNED_APP_LINE_ANIM_DELAY
|
|
import com.android.launcher3.util.ActivityContextWrapper
|
|
import com.android.launcher3.util.LauncherMultivalentJUnit
|
|
import com.android.launcher3.util.MultiTranslateDelegate.INDEX_TASKBAR_APP_RUNNING_STATE_ANIM
|
|
import com.google.common.truth.Truth.assertThat
|
|
import org.junit.Rule
|
|
import org.junit.Test
|
|
import org.junit.runner.RunWith
|
|
|
|
private const val FRAME_TIME_MS = 16L // Simulates 60 Hz.
|
|
private val PINNED_APP = TaskItemInfo(0, TaskbarViewTestUtil.createHotseatWorkspaceItem(0))
|
|
private val UNPINNED_APP = TaskbarViewTestUtil.createRecentTask(1)
|
|
|
|
@RunWith(LauncherMultivalentJUnit::class)
|
|
class TaskbarRunningAppStateAnimationControllerTest {
|
|
|
|
@get:Rule val animatorTestRule = AnimatorTestRule(this)
|
|
|
|
private val context = ActivityContextWrapper(getInstrumentation().targetContext)
|
|
private val btv = BubbleTextView(context)
|
|
private val controller = TaskbarRunningAppStateAnimationController(context)
|
|
|
|
@Test
|
|
fun updateRunningState_minimizeApp_verifySpringEndState() {
|
|
startStateChange(start = RUNNING, end = MINIMIZED)
|
|
verifySpringAnimationEnd(MINIMIZED)
|
|
}
|
|
|
|
@Test
|
|
fun updateRunningState_minimizeApp_verifyCancelEndState() {
|
|
startStateChange(start = RUNNING, end = MINIMIZED)
|
|
runOnMainSync { controller.onDestroy() }
|
|
verifyStateSettled(state = MINIMIZED)
|
|
}
|
|
|
|
@Test
|
|
fun updateRunningState_restoreApp_verifySpringEndState() {
|
|
startStateChange(start = MINIMIZED, end = RUNNING)
|
|
verifySpringAnimationEnd(RUNNING)
|
|
}
|
|
|
|
@Test
|
|
fun updateRunningState_openPinnedApp_verifySpringEndState() {
|
|
btv.tag = PINNED_APP
|
|
startStateChange(start = NOT_RUNNING, end = RUNNING)
|
|
verifySpringAnimationEnd(RUNNING)
|
|
}
|
|
|
|
@Test
|
|
fun updateRunningState_openUnpinnedApp_verifyStartDelay() {
|
|
btv.tag = UNPINNED_APP
|
|
startStateChange(start = NOT_RUNNING, end = RUNNING)
|
|
runOnMainSync { animatorTestRule.advanceTimeBy(UNPINNED_APP_LINE_ANIM_DELAY) }
|
|
verifyLineIndicator(state = NOT_RUNNING)
|
|
}
|
|
|
|
@Test
|
|
fun updateRunningState_openUnpinnedApp_verifyEndState() {
|
|
btv.tag = UNPINNED_APP
|
|
startStateChange(start = NOT_RUNNING, end = RUNNING)
|
|
runOnMainSync {
|
|
animatorTestRule.advanceTimeBy(UNPINNED_APP_LINE_ANIM_DELAY + LINE_ANIM_DURATION)
|
|
}
|
|
|
|
verifyStateSettled(state = RUNNING)
|
|
}
|
|
|
|
@Test
|
|
fun updateRunningState_openUnpinnedApp_verifyCancelEndState() {
|
|
btv.tag = UNPINNED_APP
|
|
startStateChange(start = NOT_RUNNING, end = RUNNING)
|
|
runOnMainSync { controller.onDestroy() }
|
|
verifyStateSettled(state = RUNNING)
|
|
}
|
|
|
|
@Test
|
|
fun updateRunningState_closeApp_verifyEndState() {
|
|
startStateChange(start = RUNNING, end = NOT_RUNNING)
|
|
runOnMainSync { animatorTestRule.advanceTimeBy(LINE_ANIM_DURATION) }
|
|
verifyStateSettled(state = NOT_RUNNING)
|
|
}
|
|
|
|
@Test
|
|
fun updateRunningState_repeatUpdateDuringAnimation_animationNotCanceled() {
|
|
startStateChange(start = MINIMIZED, end = RUNNING)
|
|
runOnMainSync {
|
|
animatorTestRule.advanceTimeBy(FRAME_TIME_MS)
|
|
controller.updateRunningState(btv, RUNNING, animate = false)
|
|
}
|
|
assertThat(controller.isAnimationRunning(btv)).isTrue()
|
|
}
|
|
|
|
@Test
|
|
fun updateRunningState_minimizedDuringOpen_verifyMinimizedEndState() {
|
|
startStateChange(start = NOT_RUNNING, end = RUNNING)
|
|
runOnMainSync { controller.updateRunningState(btv, MINIMIZED, animate = true) }
|
|
verifySpringAnimationEnd(MINIMIZED)
|
|
}
|
|
|
|
@Test
|
|
fun onDestroy_multipleAnimations_cancelsAll() {
|
|
startStateChange(start = RUNNING, end = MINIMIZED)
|
|
val btv2 = BubbleTextView(context)
|
|
startStateChange(btv = btv2, start = RUNNING, end = MINIMIZED)
|
|
|
|
runOnMainSync { controller.onDestroy() }
|
|
verifyStateSettled(state = MINIMIZED)
|
|
verifyStateSettled(btv = btv2, state = MINIMIZED)
|
|
}
|
|
|
|
private fun startStateChange(
|
|
btv: BubbleTextView = this.btv,
|
|
start: RunningAppState,
|
|
end: RunningAppState,
|
|
) {
|
|
runOnMainSync {
|
|
controller.updateRunningState(btv, start, animate = false)
|
|
controller.updateRunningState(btv, end, animate = true)
|
|
}
|
|
verifyLineIndicator(btv, start)
|
|
assertThat(controller.isAnimationRunning(btv)).isTrue()
|
|
}
|
|
|
|
/** Verifies [btv] spring animation ends at [state]. */
|
|
private fun verifySpringAnimationEnd(state: RunningAppState) {
|
|
while (controller.isAnimationRunning(btv)) {
|
|
runOnMainSync { animatorTestRule.advanceTimeBy(FRAME_TIME_MS) }
|
|
}
|
|
verifyStateSettled(state = state)
|
|
}
|
|
|
|
private fun verifyStateSettled(btv: BubbleTextView = this.btv, state: RunningAppState) {
|
|
assertThat(controller.isAnimationRunning(btv)).isFalse()
|
|
verifyLineIndicator(btv, state)
|
|
|
|
val translateYProp =
|
|
btv.translateDelegate.getTranslationY(INDEX_TASKBAR_APP_RUNNING_STATE_ANIM)
|
|
assertThat(translateYProp.value).isZero()
|
|
}
|
|
|
|
private fun verifyLineIndicator(btv: BubbleTextView = this.btv, state: RunningAppState) {
|
|
controller.run {
|
|
assertThat(btv.lineIndicatorWidth).isEqualTo(state.lineWidth)
|
|
assertThat(btv.lineIndicatorColor).isEqualTo(state.lineColor)
|
|
}
|
|
}
|
|
}
|