• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 
17 package com.android.launcher3.tapl;
18 
19 import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
20 
21 import android.graphics.Rect;
22 
23 import androidx.annotation.NonNull;
24 import androidx.test.uiautomator.By;
25 import androidx.test.uiautomator.BySelector;
26 import androidx.test.uiautomator.UiObject2;
27 
28 import com.android.launcher3.testing.shared.TestProtocol;
29 
30 import java.util.List;
31 import java.util.regex.Pattern;
32 import java.util.stream.Collectors;
33 
34 /**
35  * A recent task in the overview panel carousel.
36  */
37 public final class OverviewTask {
38     private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
39 
40     static final Pattern TASK_START_EVENT = Pattern.compile("startActivityFromRecentsAsync");
41     static final Pattern SPLIT_SELECT_EVENT = Pattern.compile("enterSplitSelect");
42     static final Pattern SPLIT_START_EVENT = Pattern.compile("launchSplitTasks");
43     private final LauncherInstrumentation mLauncher;
44     private final UiObject2 mTask;
45     private final BaseOverview mOverview;
46 
OverviewTask(LauncherInstrumentation launcher, UiObject2 task, BaseOverview overview)47     OverviewTask(LauncherInstrumentation launcher, UiObject2 task, BaseOverview overview) {
48         mLauncher = launcher;
49         mTask = task;
50         mOverview = overview;
51         verifyActiveContainer();
52     }
53 
verifyActiveContainer()54     private void verifyActiveContainer() {
55         mOverview.verifyActiveContainer();
56     }
57 
getVisibleHeight()58     int getVisibleHeight() {
59         return mTask.getVisibleBounds().height();
60     }
61 
getVisibleWidth()62     int getVisibleWidth() {
63         return mTask.getVisibleBounds().width();
64     }
65 
getTaskCenterX()66     int getTaskCenterX() {
67         return mTask.getVisibleCenter().x;
68     }
69 
getExactCenterX()70     float getExactCenterX() {
71         return mTask.getVisibleBounds().exactCenterX();
72     }
73 
getUiObject()74     UiObject2 getUiObject() {
75         return mTask;
76     }
77 
78     /**
79      * Dismisses the task by swiping up.
80      */
dismiss()81     public void dismiss() {
82         try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
83              LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
84                      "want to dismiss an overview task")) {
85             verifyActiveContainer();
86             int taskCountBeforeDismiss = mOverview.getTaskCount();
87             mLauncher.assertNotEquals("Unable to find a task", 0, taskCountBeforeDismiss);
88             if (taskCountBeforeDismiss == 1) {
89                 dismissBySwipingUp();
90                 return;
91             }
92 
93             boolean taskWasFocused = mLauncher.isTablet() && getVisibleHeight() == mLauncher
94                     .getFocusedTaskHeightForTablet();
95             List<Integer> originalTasksCenterX = getCurrentTasksCenterXList();
96             boolean isClearAllVisibleBeforeDismiss = mOverview.isClearAllVisible();
97 
98             dismissBySwipingUp();
99 
100             try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("dismissed")) {
101                 if (taskWasFocused) {
102                     mLauncher.assertNotNull("No task became focused",
103                             mOverview.getFocusedTaskForTablet());
104                 }
105                 if (!isClearAllVisibleBeforeDismiss) {
106                     List<Integer> currentTasksCenterX = getCurrentTasksCenterXList();
107                     if (originalTasksCenterX.size() == currentTasksCenterX.size()) {
108                         // Check for the same number of visible tasks before and after to
109                         // avoid asserting on cases of shifting all tasks to close the distance
110                         // between clear all and tasks at the end of the grid.
111                         mLauncher.assertTrue("Task centers not aligned",
112                                 originalTasksCenterX.equals(currentTasksCenterX));
113                     }
114                 }
115             }
116         }
117     }
118 
dismissBySwipingUp()119     private void dismissBySwipingUp() {
120         verifyActiveContainer();
121         // Dismiss the task via flinging it up.
122         final Rect taskBounds = mLauncher.getVisibleBounds(mTask);
123         final int centerX = taskBounds.centerX();
124         final int centerY = taskBounds.centerY();
125         mLauncher.executeAndWaitForLauncherEvent(
126                 () -> mLauncher.linearGesture(centerX, centerY, centerX, 0, 10, false,
127                         LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER),
128                 event -> TestProtocol.DISMISS_ANIMATION_ENDS_MESSAGE.equals(event.getClassName()),
129                 () -> "Didn't receive a dismiss animation ends message: " + centerX + ", "
130                         + centerY, "swiping to dismiss");
131     }
132 
getCurrentTasksCenterXList()133     private List<Integer> getCurrentTasksCenterXList() {
134         return mLauncher.isTablet()
135                 ? mOverview.getCurrentTasksForTablet().stream()
136                     .map(OverviewTask::getTaskCenterX)
137                     .collect(Collectors.toList())
138                 : List.of(mOverview.getCurrentTask().getTaskCenterX());
139     }
140 
141     /**
142      * Clicks the task.
143      */
open()144     public LaunchedAppState open() {
145         try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
146             verifyActiveContainer();
147             mLauncher.executeAndWaitForEvent(
148                     () -> mLauncher.clickLauncherObject(mTask),
149                     event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
150                     () -> "Launching task didn't open a new window: "
151                             + mTask.getParent().getContentDescription(),
152                     "clicking an overview task");
153             if (mOverview.getContainerType()
154                     == LauncherInstrumentation.ContainerType.SPLIT_SCREEN_SELECT) {
155                 mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SPLIT_START_EVENT);
156 
157                 try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
158                         "launched splitscreen")) {
159 
160                     BySelector divider = By.res(SYSTEMUI_PACKAGE, "docked_divider_handle");
161                     mLauncher.waitForSystemUiObject(divider);
162                     return new LaunchedAppState(mLauncher);
163                 }
164             } else {
165                 mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, TASK_START_EVENT);
166                 return new LaunchedAppState(mLauncher);
167             }
168         }
169     }
170 
171     /** Taps the task menu. */
172     @NonNull
tapMenu()173     public OverviewTaskMenu tapMenu() {
174         try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
175              LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
176                      "want to tap the task menu")) {
177             mLauncher.clickLauncherObject(
178                     mLauncher.waitForObjectInContainer(mTask.getParent(), "icon"));
179 
180             try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
181                     "tapped the task menu")) {
182                 return new OverviewTaskMenu(mLauncher);
183             }
184         }
185     }
186 
isTaskSplit()187     boolean isTaskSplit() {
188         return mLauncher.findObjectInContainer(mTask.getParent(), "bottomright_snapshot") != null;
189     }
190 }
191