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.test.uiautomator.UiObject2;
24 
25 import com.android.launcher3.testing.TestProtocol;
26 
27 import java.util.List;
28 import java.util.regex.Pattern;
29 import java.util.stream.Collectors;
30 
31 /**
32  * A recent task in the overview panel carousel.
33  */
34 public final class OverviewTask {
35     static final Pattern TASK_START_EVENT =
36             Pattern.compile("startActivityFromRecentsAsync");
37     private final LauncherInstrumentation mLauncher;
38     private final UiObject2 mTask;
39     private final BaseOverview mOverview;
40 
OverviewTask(LauncherInstrumentation launcher, UiObject2 task, BaseOverview overview)41     OverviewTask(LauncherInstrumentation launcher, UiObject2 task, BaseOverview overview) {
42         mLauncher = launcher;
43         mTask = task;
44         mOverview = overview;
45         verifyActiveContainer();
46     }
47 
verifyActiveContainer()48     private void verifyActiveContainer() {
49         mOverview.verifyActiveContainer();
50     }
51 
getVisibleHeight()52     int getVisibleHeight() {
53         return mTask.getVisibleBounds().height();
54     }
55 
getVisibleWidth()56     int getVisibleWidth() {
57         return mTask.getVisibleBounds().width();
58     }
59 
getTaskCenterX()60     int getTaskCenterX() {
61         return mTask.getVisibleCenter().x;
62     }
63 
64     /**
65      * Dismisses the task by swiping up.
66      */
dismiss()67     public void dismiss() {
68         try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
69              LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
70                      "want to dismiss an overview task")) {
71             verifyActiveContainer();
72             int taskCountBeforeDismiss = mOverview.getTaskCount();
73             mLauncher.assertNotEquals("Unable to find a task", 0, taskCountBeforeDismiss);
74             if (taskCountBeforeDismiss == 1) {
75                 dismissBySwipingUp();
76                 return;
77             }
78 
79             boolean taskWasFocused = mLauncher.isTablet() && getVisibleHeight() == mLauncher
80                     .getFocusedTaskHeightForTablet();
81             List<Integer> originalTasksCenterX = getCurrentTasksCenterXList();
82             boolean isClearAllVisibleBeforeDismiss = mOverview.isClearAllVisible();
83 
84             dismissBySwipingUp();
85 
86             try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("dismissed")) {
87                 if (taskWasFocused) {
88                     mLauncher.assertNotNull("No task became focused",
89                             mOverview.getFocusedTaskForTablet());
90                 }
91                 if (!isClearAllVisibleBeforeDismiss) {
92                     List<Integer> currentTasksCenterX = getCurrentTasksCenterXList();
93                     if (originalTasksCenterX.size() == currentTasksCenterX.size()) {
94                         // Check for the same number of visible tasks before and after to
95                         // avoid asserting on cases of shifting all tasks to close the distance
96                         // between clear all and tasks at the end of the grid.
97                         mLauncher.assertTrue("Task centers not aligned",
98                                 originalTasksCenterX.equals(currentTasksCenterX));
99                     }
100                 }
101             }
102         }
103     }
104 
dismissBySwipingUp()105     private void dismissBySwipingUp() {
106         verifyActiveContainer();
107         // Dismiss the task via flinging it up.
108         final Rect taskBounds = mLauncher.getVisibleBounds(mTask);
109         final int centerX = taskBounds.centerX();
110         final int centerY = taskBounds.centerY();
111         mLauncher.executeAndWaitForLauncherEvent(
112                 () -> mLauncher.linearGesture(centerX, centerY, centerX, 0, 10, false,
113                         LauncherInstrumentation.GestureScope.INSIDE),
114                 event -> TestProtocol.DISMISS_ANIMATION_ENDS_MESSAGE.equals(event.getClassName()),
115                 () -> "Didn't receive a dismiss animation ends message: " + centerX + ", "
116                         + centerY, "swiping to dismiss");
117     }
118 
getCurrentTasksCenterXList()119     private List<Integer> getCurrentTasksCenterXList() {
120         return mLauncher.isTablet()
121                 ? mOverview.getCurrentTasksForTablet().stream()
122                     .map(OverviewTask::getTaskCenterX)
123                     .collect(Collectors.toList())
124                 : List.of(mOverview.getCurrentTask().getTaskCenterX());
125     }
126 
127     /**
128      * Clicks at the task.
129      */
open()130     public Background open() {
131         try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
132             verifyActiveContainer();
133             mLauncher.executeAndWaitForEvent(
134                     () -> mLauncher.clickLauncherObject(mTask),
135                     event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
136                     () -> "Launching task didn't open a new window: "
137                             + mTask.getParent().getContentDescription(),
138                     "clicking an overview task");
139             mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, TASK_START_EVENT);
140             return new Background(mLauncher);
141         }
142     }
143 }
144