From 3231ba01e60ea6489f4d03df774116ae49fb276d Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Mon, 15 Jul 2024 14:19:01 -0400 Subject: [PATCH] Add tests for TaskbarStashController. Test: TaskbarStashControllerTest Bug: 346394503 Flag: TEST_ONLY Change-Id: I930e745826f2512d04434ad689a3e42cac7e9901 --- .../taskbar/TaskbarStashController.java | 50 +- .../TransientBubbleStashController.kt | 7 +- .../taskbar/TaskbarStashControllerTest.kt | 681 ++++++++++++++++++ src/com/android/launcher3/Alarm.java | 11 + 4 files changed, 734 insertions(+), 15 deletions(-) create mode 100644 quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarStashControllerTest.kt diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 9b7d3bfa6e..5f1ad56fcf 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -82,6 +82,8 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba private static final String TAG = "TaskbarStashController"; private static final boolean DEBUG = false; + private static boolean sEnableSoftwareImeForTests = false; + /** * Def. value for @param shouldBubblesFollow in * {@link #updateAndAnimateTransientTaskbar(boolean)} */ @@ -131,19 +133,22 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba * * Use {@link #getStashDuration()} to query duration */ - private static final long TASKBAR_STASH_DURATION = InsetsController.ANIMATION_DURATION_RESIZE; + @VisibleForTesting + static final long TASKBAR_STASH_DURATION = InsetsController.ANIMATION_DURATION_RESIZE; /** * How long to stash/unstash transient taskbar. * * Use {@link #getStashDuration()} to query duration. */ - private static final long TRANSIENT_TASKBAR_STASH_DURATION = 417; + @VisibleForTesting + static final long TRANSIENT_TASKBAR_STASH_DURATION = 417; /** * How long to stash/unstash when keyboard is appearing/disappearing. */ - private static final long TASKBAR_STASH_DURATION_FOR_IME = 80; + @VisibleForTesting + static final long TASKBAR_STASH_DURATION_FOR_IME = 80; /** * The scale TaskbarView animates to when being stashed. @@ -164,7 +169,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba /** * How long the icon/stash handle alpha animation plays. */ - public static final long TASKBAR_STASH_ALPHA_DURATION = 50; + public static final long TRANSIENT_TASKBAR_STASH_ALPHA_DURATION = 50; /** * How long to delay the icon/stash handle alpha for the home to app taskbar animation. @@ -254,7 +259,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba private boolean mEnableBlockingTimeoutDuringTests = false; private Animator mTaskbarBackgroundAlphaAnimator; - private long mTaskbarBackgroundDuration; + private final long mTaskbarBackgroundDuration; private boolean mUserIsNotGoingHome = false; // Evaluate whether the handle should be stashed @@ -801,14 +806,14 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba if (animationType == TRANSITION_HANDLE_FADE) { // When fading, the handle fades in/out at the beginning of the transition with // TASKBAR_STASH_ALPHA_DURATION. - backgroundAndHandleAlphaDuration = TASKBAR_STASH_ALPHA_DURATION; + backgroundAndHandleAlphaDuration = TRANSIENT_TASKBAR_STASH_ALPHA_DURATION; // The iconAlphaDuration must be set to duration for the skippable interpolators // below to work. iconAlphaDuration = duration; } else { iconAlphaStartDelay = TASKBAR_STASH_ALPHA_START_DELAY; - iconAlphaDuration = TASKBAR_STASH_ALPHA_DURATION; - backgroundAndHandleAlphaDuration = TASKBAR_STASH_ALPHA_DURATION; + iconAlphaDuration = TRANSIENT_TASKBAR_STASH_ALPHA_DURATION; + backgroundAndHandleAlphaDuration = TRANSIENT_TASKBAR_STASH_ALPHA_DURATION; if (isStashed) { if (animationType == TRANSITION_HOME_TO_APP) { @@ -1084,7 +1089,8 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba /** * When hiding the IME, delay the unstash animation to align with the end of the transition. */ - private long getTaskbarStashStartDelayForIme() { + @VisibleForTesting + long getTaskbarStashStartDelayForIme() { if (mIsImeShowing) { // Only delay when IME is exiting, not entering. return 0; @@ -1144,13 +1150,13 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba } // Do not stash if pinned taskbar, hardware keyboard is attached and no IME is docked - if (mActivity.isHardwareKeyboard() && DisplayController.isPinnedTaskbar(mActivity) + if (isHardwareKeyboard() && DisplayController.isPinnedTaskbar(mActivity) && !mActivity.isImeDocked()) { return false; } // Do not stash if hardware keyboard is attached, in 3 button nav and desktop windowing mode - if (mActivity.isHardwareKeyboard() + if (isHardwareKeyboard() && mActivity.isThreeButtonNav() && mControllers.taskbarDesktopModeController.getAreDesktopTasksVisible()) { return false; @@ -1164,6 +1170,21 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba return mIsImeShowing || mIsImeSwitcherShowing; } + private boolean isHardwareKeyboard() { + return mActivity.isHardwareKeyboard() && !sEnableSoftwareImeForTests; + } + + /** + * Overrides {@link #isHardwareKeyboard()} to {@code false} for testing, if enabled. + *

+ * Virtual devices are sometimes in hardware keyboard mode, leading to an inconsistent + * testing environment. + */ + @VisibleForTesting + static void enableSoftwareImeForTests(boolean enable) { + sEnableSoftwareImeForTests = enable; + } + /** * Updates the proper flag to indicate whether the task bar should be stashed. * @@ -1289,7 +1310,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba /** * Attempts to start timer to auto hide the taskbar based on time. */ - public void tryStartTaskbarTimeout() { + private void tryStartTaskbarTimeout() { if (!DisplayController.isTransientTaskbar(mActivity) || mIsStashed || mEnableBlockingTimeoutDuringTests) { @@ -1317,6 +1338,11 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba updateAndAnimateTransientTaskbarForTimeout(); } + @VisibleForTesting + Alarm getTimeoutAlarm() { + return mTimeoutAlarm; + } + @Override public void dumpLogs(String prefix, PrintWriter pw) { pw.println(prefix + "TaskbarStashController:"); diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt index 4f0337ddc1..74e3c00c55 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt @@ -32,8 +32,8 @@ import com.android.launcher3.R import com.android.launcher3.anim.AnimatedFloat import com.android.launcher3.anim.SpringAnimationBuilder import com.android.launcher3.taskbar.TaskbarInsetsController -import com.android.launcher3.taskbar.TaskbarStashController.TASKBAR_STASH_ALPHA_DURATION import com.android.launcher3.taskbar.TaskbarStashController.TASKBAR_STASH_ALPHA_START_DELAY +import com.android.launcher3.taskbar.TaskbarStashController.TRANSIENT_TASKBAR_STASH_ALPHA_DURATION import com.android.launcher3.taskbar.bubbles.BubbleBarViewController import com.android.launcher3.taskbar.bubbles.BubbleStashedHandleViewController import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController.Companion.BAR_STASH_DURATION @@ -305,7 +305,8 @@ class TransientBubbleStashController( animatorSet.play( createBackgroundAlphaAnimator(isStashed).apply { - val alphaDuration = if (isStashed) duration else TASKBAR_STASH_ALPHA_DURATION + val alphaDuration = + if (isStashed) duration else TRANSIENT_TASKBAR_STASH_ALPHA_DURATION val alphaDelay = if (isStashed) TASKBAR_STASH_ALPHA_START_DELAY else 0L this.duration = max(0L, alphaDuration - alphaDelay) this.startDelay = alphaDelay @@ -317,7 +318,7 @@ class TransientBubbleStashController( bubbleBarBubbleAlpha .animateToValue(getBarAlphaStart(isStashed), getBarAlphaEnd(isStashed)) .apply { - this.duration = TASKBAR_STASH_ALPHA_DURATION + this.duration = TRANSIENT_TASKBAR_STASH_ALPHA_DURATION this.startDelay = TASKBAR_STASH_ALPHA_START_DELAY this.interpolator = LINEAR } diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarStashControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarStashControllerTest.kt new file mode 100644 index 0000000000..e7364464af --- /dev/null +++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarStashControllerTest.kt @@ -0,0 +1,681 @@ +/* + * 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.animation.AnimatorTestRule +import android.platform.test.annotations.EnableFlags +import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation +import com.android.launcher3.R +import com.android.launcher3.taskbar.StashedHandleViewController.ALPHA_INDEX_STASHED +import com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_EDU_OPEN +import com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP +import com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_OVERVIEW +import com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_STASHED_LAUNCHER_STATE +import com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_DEVICE_LOCKED +import com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IME +import com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_APP_AUTO +import com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_SMALL_SCREEN +import com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_SYSUI +import com.android.launcher3.taskbar.TaskbarStashController.TASKBAR_STASH_DURATION +import com.android.launcher3.taskbar.TaskbarStashController.TASKBAR_STASH_DURATION_FOR_IME +import com.android.launcher3.taskbar.TaskbarStashController.TRANSIENT_TASKBAR_STASH_ALPHA_DURATION +import com.android.launcher3.taskbar.TaskbarStashController.TRANSIENT_TASKBAR_STASH_DURATION +import com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_STASH +import com.android.launcher3.taskbar.bubbles.BubbleControllers +import com.android.launcher3.taskbar.rules.TaskbarModeRule +import com.android.launcher3.taskbar.rules.TaskbarModeRule.Mode.PINNED +import com.android.launcher3.taskbar.rules.TaskbarModeRule.Mode.THREE_BUTTONS +import com.android.launcher3.taskbar.rules.TaskbarModeRule.Mode.TRANSIENT +import com.android.launcher3.taskbar.rules.TaskbarModeRule.TaskbarMode +import com.android.launcher3.taskbar.rules.TaskbarPinningPreferenceRule +import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule +import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule.InjectController +import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule.UserSetupMode +import com.android.launcher3.taskbar.rules.TaskbarWindowSandboxContext +import com.android.launcher3.util.LauncherMultivalentJUnit +import com.android.launcher3.util.LauncherMultivalentJUnit.EmulatedDevices +import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED +import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING +import com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_BAR +import com.google.common.truth.Truth.assertThat +import java.util.Optional +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(LauncherMultivalentJUnit::class) +@EmulatedDevices(["pixelTablet2023"]) +class TaskbarStashControllerTest { + private val context = TaskbarWindowSandboxContext.create(getInstrumentation().targetContext) + + @get:Rule(order = 0) val taskbarModeRule = TaskbarModeRule(context) + @get:Rule(order = 1) val taskbarPinningPreferenceRule = TaskbarPinningPreferenceRule(context) + @get:Rule(order = 2) val animatorTestRule = AnimatorTestRule(this) + @get:Rule(order = 3) val taskbarUnitTestRule = TaskbarUnitTestRule(this, context) + + @InjectController lateinit var stashController: TaskbarStashController + @InjectController lateinit var viewController: TaskbarViewController + @InjectController lateinit var stashedHandleViewController: StashedHandleViewController + @InjectController lateinit var dragLayerController: TaskbarDragLayerController + @InjectController lateinit var autohideSuspendController: TaskbarAutohideSuspendController + @InjectController lateinit var bubbleControllers: Optional + + private val activityContext by taskbarUnitTestRule::activityContext + + // Disable hardware keyboard mode during tests. + @Before fun enableSoftwareIme() = TaskbarStashController.enableSoftwareImeForTests(true) + + @After fun resetIme() = TaskbarStashController.enableSoftwareImeForTests(false) + + @After fun cancelTimeoutIfExists() = stashController.cancelTimeoutIfExists() + + @Test + @TaskbarMode(TRANSIENT) + fun testInit_transientMode_stashedInApp() { + assertThat(stashController.isStashedInApp).isTrue() + } + + @Test + @TaskbarMode(PINNED) + fun testInit_pinnedMode_unstashedInApp() { + assertThat(stashController.isStashedInApp).isFalse() + } + + @Test + @UserSetupMode + @TaskbarMode(PINNED) + fun testInit_userSetupWithPinnedMode_stashedInApp() { + assertThat(stashController.isStashedInApp).isTrue() + } + + @Test + @TaskbarMode(PINNED) + fun testSetSetupUiVisible_true_stashedInApp() { + getInstrumentation().runOnMainSync { stashController.setSetupUIVisible(true) } + assertThat(stashController.isStashedInApp).isTrue() + } + + @Test + @TaskbarMode(PINNED) + fun testSetSetupUiVisible_false_unstashedInApp() { + getInstrumentation().runOnMainSync { stashController.setSetupUIVisible(false) } + assertThat(stashController.isStashedInApp).isFalse() + } + + @Test + fun testRecreateAsTransient_timeoutStarted() { + taskbarPinningPreferenceRule.isPinned = true + activityContext.controllers.sharedState?.taskbarWasPinned = true + + taskbarPinningPreferenceRule.isPinned = false + assertThat(stashController.timeoutAlarm.alarmPending()).isTrue() + } + + @Test + @TaskbarMode(TRANSIENT) + fun testSupportsVisualStashing_transientMode_supported() { + assertThat(stashController.supportsVisualStashing()).isTrue() + } + + @Test + @TaskbarMode(PINNED) + fun testSupportsVisualStashing_pinnedMode_supported() { + assertThat(stashController.supportsVisualStashing()).isTrue() + } + + @Test + @TaskbarMode(THREE_BUTTONS) + fun testSupportsVisualStashing_threeButtonsMode_unsupported() { + assertThat(stashController.supportsVisualStashing()).isFalse() + } + + @Test + @TaskbarMode(TRANSIENT) + fun testGetStashDuration_transientMode() { + assertThat(stashController.stashDuration).isEqualTo(TRANSIENT_TASKBAR_STASH_DURATION) + } + + @Test + @TaskbarMode(PINNED) + fun testGetStashDuration_pinnedMode() { + assertThat(stashController.stashDuration).isEqualTo(TASKBAR_STASH_DURATION) + } + + @Test + @TaskbarMode(PINNED) + fun testIsStashed_pinnedInApp_isUnstashed() { + getInstrumentation().runOnMainSync { + stashController.updateStateForFlag(FLAG_IN_APP, true) + stashController.applyState(0) + } + assertThat(stashController.isStashed).isFalse() + } + + @Test + @TaskbarMode(TRANSIENT) + fun testIsStashed_transientInApp_isStashed() { + getInstrumentation().runOnMainSync { + stashController.updateStateForFlag(FLAG_IN_APP, true) + stashController.applyState(0) + } + assertThat(stashController.isStashed).isTrue() + } + + @Test + @TaskbarMode(TRANSIENT) + fun testIsStashed_transientNotInApp_isUnstashed() { + getInstrumentation().runOnMainSync { + stashController.updateStateForFlag(FLAG_IN_APP, false) + stashController.applyState(0) + } + assertThat(stashController.isStashed).isFalse() + } + + @Test + fun testIsStashed_stashedInLauncherState_isStashed() { + getInstrumentation().runOnMainSync { + stashController.updateStateForFlag(FLAG_IN_APP, false) + stashController.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, true) + stashController.applyState(0) + } + assertThat(stashController.isStashed).isTrue() + } + + @Test + @TaskbarMode(TRANSIENT) + fun testIsStashed_transientInOverview_isUnstashed() { + getInstrumentation().runOnMainSync { + stashController.updateStateForFlag(FLAG_IN_APP, false) + stashController.updateStateForFlag(FLAG_IN_OVERVIEW, true) + stashController.applyState(0) + } + assertThat(stashController.isStashed).isFalse() + } + + @Test + @TaskbarMode(PINNED) + fun testIsStashed_pinnedInOverviewWithIme_isStashed() { + getInstrumentation().runOnMainSync { + stashController.updateStateForFlag(FLAG_IN_APP, false) + stashController.updateStateForFlag(FLAG_IN_OVERVIEW, true) + stashController.updateStateForFlag(FLAG_STASHED_IME, true) + stashController.applyState(0) + } + assertThat(stashController.isStashed).isTrue() + } + + @Test + @TaskbarMode(PINNED) + fun testIsStashed_pinnedTaskbarWithPinnedApp_isStashed() { + getInstrumentation().runOnMainSync { + stashController.updateStateForFlag(FLAG_IN_APP, true) + stashController.updateStateForFlag(FLAG_STASHED_SYSUI, true) // App pinned. + stashController.applyState(0) + } + assertThat(stashController.isStashed).isTrue() + } + + @Test + fun testIsInStashedLauncherState_flagUnset_false() { + stashController.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, false) + assertThat(stashController.isInStashedLauncherState).isFalse() + } + + @Test + @TaskbarMode(THREE_BUTTONS) + fun testIsInStashedLauncherState_flagSetInThreeButtonsMode_false() { + stashController.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, true) + assertThat(stashController.isInStashedLauncherState).isFalse() + } + + @Test + @TaskbarMode(PINNED) + fun testIsInStashedLauncherState_flagSetInPinnedMode_true() { + stashController.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, true) + assertThat(stashController.isInStashedLauncherState).isTrue() + } + + @Test + @TaskbarMode(PINNED) + fun testIsTaskbarVisibleAndNotStashing_pinnedButNotVisible_false() { + getInstrumentation().runOnMainSync { + viewController.taskbarIconAlpha.get(ALPHA_INDEX_STASH).value = 0f + } + assertThat(stashController.isTaskbarVisibleAndNotStashing).isFalse() + } + + @Test + @TaskbarMode(TRANSIENT) + fun testIsTaskbarVisibleAndNotStashing_visibleButStashed_false() { + getInstrumentation().runOnMainSync { + viewController.taskbarIconAlpha.get(ALPHA_INDEX_STASH).value = 1f + } + assertThat(stashController.isTaskbarVisibleAndNotStashing).isFalse() + } + + @Test + @TaskbarMode(PINNED) + fun testIsTaskbarVisibleAndNotStashing_pinnedAndVisible_true() { + getInstrumentation().runOnMainSync { + viewController.taskbarIconAlpha.get(ALPHA_INDEX_STASH).value = 1f + } + assertThat(stashController.isTaskbarVisibleAndNotStashing).isTrue() + } + + @Test + @TaskbarMode(TRANSIENT) + fun testGetTouchableHeight_isStashed_stashedHeight() { + assertThat(stashController.touchableHeight).isEqualTo(stashController.stashedHeight) + } + + @Test + @TaskbarMode(TRANSIENT) + fun testGetTouchableHeight_unstashedTransientMode_heightAndBottomMargin() { + getInstrumentation().runOnMainSync { + stashController.updateStateForFlag(FLAG_STASHED_IN_APP_AUTO, false) + stashController.applyState(0) + } + + val expectedHeight = + activityContext.deviceProfile.run { taskbarHeight + taskbarBottomMargin } + assertThat(stashController.touchableHeight).isEqualTo(expectedHeight) + } + + @Test + @TaskbarMode(PINNED) + fun testGetTouchableHeight_pinnedMode_taskbarHeight() { + assertThat(stashController.touchableHeight) + .isEqualTo(activityContext.deviceProfile.taskbarHeight) + } + + @Test + @TaskbarMode(TRANSIENT) + fun testGetContentHeightToReportToApps_transientMode_stashedHeight() { + assertThat(stashController.contentHeightToReportToApps) + .isEqualTo(stashController.stashedHeight) + } + + @Test + @TaskbarMode(THREE_BUTTONS) + fun testGetContentHeightToReportToApps_threeButtonsMode_taskbarHeight() { + assertThat(stashController.contentHeightToReportToApps) + .isEqualTo(activityContext.deviceProfile.taskbarHeight) + } + + @Test + @TaskbarMode(PINNED) + fun testGetContentHeightToReportToApps_pinnedMode_taskbarHeight() { + assertThat(stashController.contentHeightToReportToApps) + .isEqualTo(activityContext.deviceProfile.taskbarHeight) + } + + @Test + @TaskbarMode(PINNED) + @UserSetupMode + fun testGetContentHeightToReportToApps_pinnedInSetupMode_setupWizardInsets() { + assertThat(stashController.contentHeightToReportToApps) + .isEqualTo(context.resources.getDimensionPixelSize(R.dimen.taskbar_suw_insets)) + } + + @Test + @TaskbarMode(PINNED) + fun testGetContentHeightToReportToApps_pinnedModeButFolded_stashedHeight() { + getInstrumentation().runOnMainSync { + stashedHandleViewController.stashedHandleAlpha.get(ALPHA_INDEX_STASHED).value = 1f + stashController.updateStateForFlag(FLAG_STASHED_SMALL_SCREEN, true) + } + assertThat(stashController.contentHeightToReportToApps) + .isEqualTo(stashController.stashedHeight) + } + + @Test + @TaskbarMode(PINNED) + fun testGetContentHeightToReportToApps_homeDisabledWhenFolded_zeroHeight() { + getInstrumentation().runOnMainSync { + stashedHandleViewController.stashedHandleAlpha.get(ALPHA_INDEX_STASHED).value = 1f + stashedHandleViewController.setIsHomeButtonDisabled(true) + stashController.updateStateForFlag(FLAG_STASHED_SMALL_SCREEN, true) + } + assertThat(stashController.contentHeightToReportToApps).isEqualTo(0) + } + + @Test + @TaskbarMode(TRANSIENT) + fun testGetTappableHeightToReportToApps_transientMode_zeroHeight() { + assertThat(stashController.tappableHeightToReportToApps).isEqualTo(0) + } + + @Test + @TaskbarMode(PINNED) + fun testGetTappableHeightToReportToApps_pinnedMode_taskbarHeight() { + assertThat(stashController.tappableHeightToReportToApps) + .isEqualTo(activityContext.deviceProfile.taskbarHeight) + } + + @Test + @TaskbarMode(TRANSIENT) + fun testUpdateAndAnimateTransientTaskbar_unstashTaskbar_updatesState() { + getInstrumentation().runOnMainSync { + stashController.updateAndAnimateTransientTaskbar(false) + } + assertThat(stashController.isStashed).isFalse() + } + + @Test + @TaskbarMode(TRANSIENT) + fun testUpdateAndAnimateTransientTaskbar_runUnstashAnimation_startsTaskbarTimeout() { + getInstrumentation().runOnMainSync { + stashController.updateAndAnimateTransientTaskbar(false) + animatorTestRule.advanceTimeBy(stashController.stashDuration) + } + assertThat(stashController.timeoutAlarm.alarmPending()).isTrue() + } + + @Test + @TaskbarMode(TRANSIENT) + fun testUpdateAndAnimateTransientTaskbar_finishTaskbarTimeout_taskbarStashes() { + getInstrumentation().runOnMainSync { + stashController.updateAndAnimateTransientTaskbar(false) + animatorTestRule.advanceTimeBy(stashController.stashDuration) + } + assertThat(stashController.timeoutAlarm.alarmPending()).isTrue() + + getInstrumentation().runOnMainSync { + stashController.timeoutAlarm.finishAlarm() + animatorTestRule.advanceTimeBy(stashController.stashDuration) + } + assertThat(stashController.isStashed).isTrue() + } + + @Test + @TaskbarMode(TRANSIENT) + fun testUpdateAndAnimateTransientTaskbar_autoHideSuspendedForEdu_remainsUnstashed() { + getInstrumentation().runOnMainSync { + stashController.updateAndAnimateTransientTaskbar(false) + animatorTestRule.advanceTimeBy(stashController.stashDuration) + } + + getInstrumentation().runOnMainSync { + autohideSuspendController.updateFlag(FLAG_AUTOHIDE_SUSPEND_EDU_OPEN, true) + stashController.updateAndAnimateTransientTaskbar(true) + animatorTestRule.advanceTimeBy(stashController.stashDuration) + } + assertThat(stashController.isStashed).isFalse() + } + + @Test + @EnableFlags(FLAG_ENABLE_BUBBLE_BAR) + @TaskbarMode(TRANSIENT) + fun testUpdateAndAnimateTransientTaskbar_unstashTaskbarWithBubbles_bubbleBarUnstashes() { + getInstrumentation().runOnMainSync { + bubbleControllers.get().bubbleBarViewController.setHiddenForBubbles(false) + bubbleControllers.get().bubbleStashController.stashBubbleBarImmediate() + stashController.updateAndAnimateTransientTaskbar(false, true) + } + assertThat(bubbleControllers.get().bubbleStashController.isStashed).isFalse() + } + + @Test + @EnableFlags(FLAG_ENABLE_BUBBLE_BAR) + @TaskbarMode(TRANSIENT) + fun testUpdateAndAnimateTransientTaskbar_unstashTaskbarWithoutBubbles_bubbleBarStashed() { + getInstrumentation().runOnMainSync { + bubbleControllers.get().bubbleBarViewController.setHiddenForBubbles(false) + bubbleControllers.get().bubbleStashController.stashBubbleBarImmediate() + stashController.updateAndAnimateTransientTaskbar(false, false) + } + assertThat(bubbleControllers.get().bubbleStashController.isStashed).isTrue() + } + + @Test + @EnableFlags(FLAG_ENABLE_BUBBLE_BAR) + @TaskbarMode(TRANSIENT) + fun testUpdateAndAnimateTransientTaskbar_stashTaskbarWithBubbles_bubbleBarStashes() { + getInstrumentation().runOnMainSync { + bubbleControllers.get().bubbleBarViewController.setHiddenForBubbles(false) + bubbleControllers.get().bubbleStashController.showBubbleBarImmediate() + stashController.updateAndAnimateTransientTaskbar(true, true) + } + assertThat(bubbleControllers.get().bubbleStashController.isStashed).isTrue() + } + + @Test + @EnableFlags(FLAG_ENABLE_BUBBLE_BAR) + @TaskbarMode(TRANSIENT) + fun testUpdateAndAnimateTransientTaskbar_stashTaskbarWithoutBubbles_bubbleBarUnstashed() { + getInstrumentation().runOnMainSync { + bubbleControllers.get().bubbleBarViewController.setHiddenForBubbles(false) + bubbleControllers.get().bubbleStashController.showBubbleBarImmediate() + stashController.updateAndAnimateTransientTaskbar(true, false) + } + assertThat(bubbleControllers.get().bubbleStashController.isStashed).isFalse() + } + + @Test + @EnableFlags(FLAG_ENABLE_BUBBLE_BAR) + @TaskbarMode(TRANSIENT) + fun testUpdateAndAnimateTransientTaskbar_bubbleBarExpandedBeforeTimeout_expandedAfterwards() { + getInstrumentation().runOnMainSync { + bubbleControllers.get().bubbleBarViewController.setHiddenForBubbles(false) + bubbleControllers.get().bubbleBarViewController.isExpanded = true + stashController.updateAndAnimateTransientTaskbar(false) + animatorTestRule.advanceTimeBy(stashController.stashDuration) + } + assertThat(stashController.timeoutAlarm.alarmPending()).isTrue() + + getInstrumentation().runOnMainSync { + stashController.timeoutAlarm.finishAlarm() + animatorTestRule.advanceTimeBy(stashController.stashDuration) + } + assertThat(bubbleControllers.get().bubbleBarViewController.isExpanded).isTrue() + } + + @Test + @TaskbarMode(PINNED) + fun testToggleTaskbarStash_pinnedMode_doesNothing() { + getInstrumentation().runOnMainSync { stashController.toggleTaskbarStash() } + assertThat(stashController.isStashed).isFalse() + } + + @Test + @TaskbarMode(TRANSIENT) + fun testToggleTaskbarStash_transientMode_unstashesTaskbar() { + getInstrumentation().runOnMainSync { stashController.toggleTaskbarStash() } + assertThat(stashController.isStashed).isFalse() + } + + @Test + @TaskbarMode(TRANSIENT) + fun testToggleTaskbarStash_twiceInTransientMode_stashesTaskbar() { + getInstrumentation().runOnMainSync { + stashController.toggleTaskbarStash() + stashController.toggleTaskbarStash() + } + assertThat(stashController.isStashed).isTrue() + } + + @Test + @TaskbarMode(TRANSIENT) + fun testToggleTaskbarStash_notInAppWithTransientMode_doesNothing() { + getInstrumentation().runOnMainSync { + stashController.updateStateForFlag(FLAG_IN_APP, false) + stashController.applyState(0) + stashController.toggleTaskbarStash() + } + assertThat(stashController.isStashed).isFalse() + } + + @Test + @TaskbarMode(TRANSIENT) + fun testAnimateTransientTaskbar_bubblesShownInOverview_stashesTaskbar() { + // Start in Overview. Should unstash Taskbar. + getInstrumentation().runOnMainSync { + stashController.updateStateForFlag(FLAG_STASHED_IN_APP_AUTO, false) + stashController.updateStateForFlag(FLAG_IN_APP, false) + stashController.updateStateForFlag(FLAG_IN_OVERVIEW, true) + stashController.applyState(0) + } + assertThat(stashController.isStashed).isFalse() + + // Expand bubbles. Should stash Taskbar. + getInstrumentation().runOnMainSync { + stashController.updateStateForSysuiFlags(SYSUI_STATE_BUBBLES_EXPANDED, false) + animatorTestRule.advanceTimeBy(TASKBAR_STASH_DURATION) + } + assertThat(stashController.isStashed).isTrue() + } + + @Test + @TaskbarMode(PINNED) + fun testAnimatePinnedTaskbar_imeShown_replacesIconsWithHandle() { + getInstrumentation().runOnMainSync { + stashController.updateStateForSysuiFlags(SYSUI_STATE_IME_SHOWING, false) + animatorTestRule.advanceTimeBy(TASKBAR_STASH_DURATION_FOR_IME) + } + assertThat(viewController.areIconsVisible()).isFalse() + assertThat(stashedHandleViewController.isStashedHandleVisible).isTrue() + } + + @Test + @TaskbarMode(PINNED) + fun testAnimatePinnedTaskbar_imeHidden_replacesHandleWithIcons() { + getInstrumentation().runOnMainSync { + stashController.updateStateForSysuiFlags(SYSUI_STATE_IME_SHOWING, true) + animatorTestRule.advanceTimeBy(0) + } + + getInstrumentation().runOnMainSync { + stashController.updateStateForSysuiFlags(0, true) + animatorTestRule.advanceTimeBy(0) + } + assertThat(stashedHandleViewController.isStashedHandleVisible).isFalse() + assertThat(viewController.areIconsVisible()).isTrue() + } + + @Test + @TaskbarMode(PINNED) + fun testAnimatePinnedTaskbar_imeHidden_verifyAnimationDuration() { + // Start with IME shown. + getInstrumentation().runOnMainSync { + stashController.updateStateForSysuiFlags(SYSUI_STATE_IME_SHOWING, true) + animatorTestRule.advanceTimeBy(0) + } + + // Hide IME with animation. + getInstrumentation().runOnMainSync { + stashController.updateStateForSysuiFlags(0, false) + // Fast forward without start delay. + animatorTestRule.advanceTimeBy(TASKBAR_STASH_DURATION_FOR_IME) + } + // Icons should not be visible yet due to start delay. + assertThat(viewController.areIconsVisible()).isFalse() + + // Advance by start delay retroactively. Animation should complete. + getInstrumentation().runOnMainSync { + animatorTestRule.advanceTimeBy(stashController.taskbarStashStartDelayForIme) + } + assertThat(viewController.areIconsVisible()).isTrue() + } + + @Test + @TaskbarMode(THREE_BUTTONS) + fun testAnimateThreeButtonsTaskbar_imeShown_hidesIconsAndBg() { + getInstrumentation().runOnMainSync { + stashController.updateStateForSysuiFlags(SYSUI_STATE_IME_SHOWING, false) + animatorTestRule.advanceTimeBy(TASKBAR_STASH_DURATION_FOR_IME) + } + assertThat(viewController.areIconsVisible()).isFalse() + assertThat(dragLayerController.imeBgTaskbar.value).isEqualTo(0) + } + + @Test + @TaskbarMode(THREE_BUTTONS) + fun testAnimateThreeButtonsTaskbar_imeHidden_showsIconsAndBg() { + getInstrumentation().runOnMainSync { + stashController.updateStateForSysuiFlags(SYSUI_STATE_IME_SHOWING, false) + animatorTestRule.advanceTimeBy(TASKBAR_STASH_DURATION_FOR_IME) + } + + getInstrumentation().runOnMainSync { + stashController.updateStateForSysuiFlags(0, false) + animatorTestRule.advanceTimeBy( + TASKBAR_STASH_DURATION_FOR_IME + stashController.taskbarStashStartDelayForIme + ) + } + assertThat(viewController.areIconsVisible()).isTrue() + assertThat(dragLayerController.imeBgTaskbar.value).isEqualTo(1) + } + + @Test + @TaskbarMode(PINNED) + fun testSetSystemGestureInProgress_whileImeShown_unstashesTaskbar() { + getInstrumentation().runOnMainSync { + stashController.updateStateForSysuiFlags(SYSUI_STATE_IME_SHOWING, true) + animatorTestRule.advanceTimeBy(0) + } + + getInstrumentation().runOnMainSync { + stashController.setSystemGestureInProgress(true) + animatorTestRule.advanceTimeBy( + TASKBAR_STASH_DURATION_FOR_IME + stashController.taskbarStashStartDelayForIme + ) + } + assertThat(stashController.isStashed).isFalse() + } + + @Test + @TaskbarMode(PINNED) + fun testUnlockTransition_pinnedMode_fadesOutHandle() { + getInstrumentation().runOnMainSync { + stashController.updateStateForFlag(FLAG_STASHED_DEVICE_LOCKED, true) + stashController.applyState(0) + } + assertThat(stashedHandleViewController.isStashedHandleVisible).isTrue() + + getInstrumentation().runOnMainSync { + stashController.updateStateForFlag(FLAG_STASHED_DEVICE_LOCKED, false) + stashController.applyState() + animatorTestRule.advanceTimeBy(stashController.stashDuration) + } + assertThat(stashedHandleViewController.isStashedHandleVisible).isFalse() + } + + @Test + @TaskbarMode(TRANSIENT) + fun testUnlockTransition_transientMode_fadesOutHandleEarly() { + getInstrumentation().runOnMainSync { + stashController.updateStateForFlag(FLAG_IN_APP, false) + stashController.updateStateForFlag(FLAG_STASHED_DEVICE_LOCKED, true) + stashController.applyState(0) + } + assertThat(stashedHandleViewController.isStashedHandleVisible).isTrue() + + getInstrumentation().runOnMainSync { + stashController.updateStateForFlag(FLAG_STASHED_DEVICE_LOCKED, false) + stashController.applyState() + // Time it takes for just the handle to hide (full stash animation is longer). + animatorTestRule.advanceTimeBy(TRANSIENT_TASKBAR_STASH_ALPHA_DURATION) + } + assertThat(stashedHandleViewController.isStashedHandleVisible).isFalse() + } +} + +private fun TaskbarStashController.updateStateForFlag(flag: Int, value: Boolean) { + updateStateForFlag(flag.toLong(), value) +} diff --git a/src/com/android/launcher3/Alarm.java b/src/com/android/launcher3/Alarm.java index fb8088c13b..e516ad088b 100644 --- a/src/com/android/launcher3/Alarm.java +++ b/src/com/android/launcher3/Alarm.java @@ -20,6 +20,8 @@ import android.os.Handler; import android.os.Looper; import android.os.SystemClock; +import androidx.annotation.VisibleForTesting; + public class Alarm implements Runnable{ // if we reach this time and the alarm hasn't been cancelled, call the listener private long mAlarmTriggerTime; @@ -96,4 +98,13 @@ public class Alarm implements Runnable{ public long getLastSetTimeout() { return mLastSetTimeout; } + + /** Simulates the alarm firing for tests. */ + @VisibleForTesting + public void finishAlarm() { + if (!mAlarmPending) return; + mAlarmPending = false; + mHandler.removeCallbacks(this); + mAlarmListener.onAlarm(this); + } }