1 /* <lambda>null2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.quickstep 17 18 import android.platform.test.rule.AllowedDevices 19 import android.platform.test.rule.DeviceProduct 20 import android.platform.test.rule.IgnoreLimit 21 import androidx.test.uiautomator.By 22 import androidx.test.uiautomator.Until 23 import com.android.launcher3.BuildConfig 24 import com.android.launcher3.tapl.LaunchedAppState 25 import com.android.launcher3.tapl.OverviewTask 26 import com.android.launcher3.ui.AbstractLauncherUiTest 27 import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape 28 import com.android.launcher3.uioverrides.QuickstepLauncher 29 import com.android.launcher3.util.TestUtil 30 import com.google.common.truth.Truth.assertWithMessage 31 import org.junit.Before 32 import org.junit.Test 33 34 /** Test Desktop windowing in Overview. */ 35 @AllowedDevices(allowed = [DeviceProduct.CF_TABLET, DeviceProduct.TANGORPRO]) 36 @IgnoreLimit(ignoreLimit = BuildConfig.IS_STUDIO_BUILD) 37 class TaplTestsOverviewDesktop : AbstractLauncherUiTest<QuickstepLauncher?>() { 38 @Before 39 fun setup() { 40 val overview = mLauncher.goHome().switchToOverview() 41 if (overview.hasTasks()) { 42 overview.dismissAllTasks() 43 } 44 startTestAppsWithCheck() 45 mLauncher.goHome() 46 } 47 48 @Test 49 @PortraitLandscape 50 fun enterDesktopViaOverviewMenu() { 51 mLauncher.workspace.switchToOverview() 52 moveTaskToDesktop(TEST_ACTIVITY_2) // Move last launched TEST_ACTIVITY_2 into Desktop 53 54 // Scroll back to TEST_ACTIVITY_1, then move it into Desktop 55 mLauncher 56 .goHome() 57 .switchToOverview() 58 .apply { flingForward() } 59 .also { moveTaskToDesktop(TEST_ACTIVITY_1) } 60 TEST_ACTIVITIES.forEach { assertTestAppLaunched(it) } 61 62 // Launch static DesktopTaskView without live tile in Overview 63 val desktopTask = 64 mLauncher.goHome().switchToOverview().getTestActivityTask(TEST_ACTIVITIES).open() 65 TEST_ACTIVITIES.forEach { assertTestAppLaunched(it) } 66 67 // Launch live-tile DesktopTaskView 68 desktopTask.switchToOverview().getTestActivityTask(TEST_ACTIVITIES).open() 69 TEST_ACTIVITIES.forEach { assertTestAppLaunched(it) } 70 71 // Launch static DesktopTaskView with live tile in Overview 72 mLauncher.goHome() 73 startTestActivity(TEST_ACTIVITY_EXTRA) 74 mLauncher.launchedAppState 75 .switchToOverview() 76 .apply { flingBackward() } 77 .getTestActivityTask(TEST_ACTIVITIES) 78 .open() 79 TEST_ACTIVITIES.forEach { assertTestAppLaunched(it) } 80 } 81 82 @Test 83 @PortraitLandscape 84 fun dismissFocusedTasks_thenDesktopIsCentered() { 85 // Create DesktopTaskView 86 mLauncher.goHome().switchToOverview() 87 moveTaskToDesktop(TEST_ACTIVITY_2) 88 89 // Create a new task activity to be the focused task 90 mLauncher.goHome() 91 startTestActivity(TEST_ACTIVITY_EXTRA) 92 93 val overview = mLauncher.goHome().switchToOverview() 94 95 // Dismiss focused task 96 val focusedTask1 = overview.currentTask 97 assertTaskContentDescription(focusedTask1, TEST_ACTIVITY_EXTRA) 98 focusedTask1.dismiss() 99 100 // Dismiss new focused task 101 val focusedTask2 = overview.currentTask 102 assertTaskContentDescription(focusedTask2, TEST_ACTIVITY_1) 103 focusedTask2.dismiss() 104 105 // Dismiss DesktopTaskView 106 val desktopTask = overview.currentTask 107 assertWithMessage("The current task is not a Desktop.").that(desktopTask.isDesktop).isTrue() 108 desktopTask.dismiss() 109 110 assertWithMessage("Still have tasks after dismissing all the tasks") 111 .that(mLauncher.workspace.switchToOverview().hasTasks()) 112 .isFalse() 113 } 114 115 @Test 116 @PortraitLandscape 117 fun dismissTasks_whenDesktopTask_IsInTheCenter() { 118 // Create extra activity to be DesktopTaskView 119 startTestActivity(TEST_ACTIVITY_EXTRA) 120 mLauncher.goHome().switchToOverview() 121 122 val desktop = moveTaskToDesktop(TEST_ACTIVITY_EXTRA) 123 var overview = desktop.switchToOverview() 124 125 // Open first fullscreen task and go back to Overview to validate whether it has adjacent 126 // tasks in its both sides (grid task on left and desktop tasks at its right side) 127 val firstFullscreenTaskOpened = overview.getTestActivityTask(TEST_ACTIVITY_2).open() 128 129 // Fling to desktop task and dismiss the first fullscreen task to check repositioning of 130 // grid tasks. 131 overview = firstFullscreenTaskOpened.switchToOverview().apply { flingBackward() } 132 val desktopTask = overview.currentTask 133 assertWithMessage("The current task is not a Desktop.").that(desktopTask.isDesktop).isTrue() 134 135 // Get first fullscreen task (previously opened task) then dismiss this task 136 val firstFullscreenTaskInOverview = overview.getTestActivityTask(TEST_ACTIVITY_2) 137 assertTaskContentDescription(firstFullscreenTaskInOverview, TEST_ACTIVITY_2) 138 firstFullscreenTaskInOverview.dismiss() 139 140 // Dismiss DesktopTask to validate whether the new task will take its position 141 desktopTask.dismiss() 142 143 // Dismiss last fullscreen task 144 val lastFocusedTask = overview.currentTask 145 assertTaskContentDescription(lastFocusedTask, TEST_ACTIVITY_1) 146 lastFocusedTask.dismiss() 147 148 assertWithMessage("Still have tasks after dismissing all the tasks") 149 .that(mLauncher.workspace.switchToOverview().hasTasks()) 150 .isFalse() 151 } 152 153 private fun assertTaskContentDescription(task: OverviewTask, activityIndex: Int) { 154 assertWithMessage("The current task content description is not TestActivity$activityIndex.") 155 .that(task.containsContentDescription("TestActivity$activityIndex")) 156 .isTrue() 157 } 158 159 private fun moveTaskToDesktop(activityIndex: Int): LaunchedAppState { 160 return mLauncher.overview 161 .getTestActivityTask(activityIndex) 162 .tapMenu() 163 .tapDesktopMenuItem() 164 .also { assertTestAppLaunched(activityIndex) } 165 } 166 167 private fun startTestAppsWithCheck() { 168 TEST_ACTIVITIES.forEach { 169 startTestActivity(it) 170 executeOnLauncher { launcher -> 171 assertWithMessage( 172 "Launcher activity is the top activity; expecting TestActivity$it" 173 ) 174 .that(isInLaunchedApp(launcher)) 175 .isTrue() 176 } 177 } 178 } 179 180 private fun assertTestAppLaunched(index: Int) { 181 assertWithMessage("TestActivity$index not opened in Desktop") 182 .that( 183 mDevice.wait( 184 Until.hasObject(By.pkg(getAppPackageName()).text("TestActivity$index")), 185 TestUtil.DEFAULT_UI_TIMEOUT, 186 ) 187 ) 188 .isTrue() 189 } 190 191 companion object { 192 const val TEST_ACTIVITY_1 = 2 193 const val TEST_ACTIVITY_2 = 3 194 const val TEST_ACTIVITY_EXTRA = 4 195 val TEST_ACTIVITIES = listOf(TEST_ACTIVITY_1, TEST_ACTIVITY_2) 196 } 197 } 198