• 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 static com.android.launcher3.tapl.OverviewTask.TASK_START_EVENT;
22 import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL;
23 
24 import android.graphics.Point;
25 import android.os.SystemClock;
26 import android.view.MotionEvent;
27 
28 import androidx.annotation.NonNull;
29 import androidx.test.uiautomator.UiObject2;
30 
31 import com.android.launcher3.testing.TestProtocol;
32 
33 import java.util.regex.Pattern;
34 
35 /**
36  * Indicates the base state with a UI other than Overview running as foreground. It can also
37  * indicate Launcher as long as Launcher is not in Overview state.
38  */
39 public class Background extends LauncherInstrumentation.VisibleContainer {
40     private static final int ZERO_BUTTON_SWIPE_UP_GESTURE_DURATION = 500;
41     private static final Pattern SQUARE_BUTTON_EVENT = Pattern.compile("onOverviewToggle");
42 
Background(LauncherInstrumentation launcher)43     Background(LauncherInstrumentation launcher) {
44         super(launcher);
45     }
46 
47     @Override
getContainerType()48     protected LauncherInstrumentation.ContainerType getContainerType() {
49         return LauncherInstrumentation.ContainerType.BACKGROUND;
50     }
51 
52     /**
53      * Swipes up or presses the square button to switch to Overview.
54      * Returns the base overview, which can be either in Launcher or the fallback recents.
55      *
56      * @return the Overview panel object.
57      */
58     @NonNull
switchToOverview()59     public BaseOverview switchToOverview() {
60         try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
61              LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
62                      "want to switch from background to overview")) {
63             verifyActiveContainer();
64             goToOverviewUnchecked();
65             return mLauncher.isFallbackOverview() ?
66                     new BaseOverview(mLauncher) : new Overview(mLauncher);
67         }
68     }
69 
zeroButtonToOverviewGestureStartsInLauncher()70     protected boolean zeroButtonToOverviewGestureStartsInLauncher() {
71         return false;
72     }
73 
goToOverviewUnchecked()74     protected void goToOverviewUnchecked() {
75         switch (mLauncher.getNavigationModel()) {
76             case ZERO_BUTTON: {
77                 final int centerX = mLauncher.getDevice().getDisplayWidth() / 2;
78                 final int startY = getSwipeStartY();
79                 final int swipeHeight = mLauncher.getTestInfo(getSwipeHeightRequestName()).
80                         getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
81                 final Point start = new Point(centerX, startY);
82                 final Point end =
83                         new Point(centerX, startY - swipeHeight - mLauncher.getTouchSlop());
84 
85                 final long downTime = SystemClock.uptimeMillis();
86                 final LauncherInstrumentation.GestureScope gestureScope =
87                         zeroButtonToOverviewGestureStartsInLauncher()
88                                 ? LauncherInstrumentation.GestureScope.INSIDE_TO_OUTSIDE
89                                 : LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER;
90 
91                 mLauncher.sendPointer(
92                         downTime, downTime, MotionEvent.ACTION_DOWN, start, gestureScope);
93                 mLauncher.executeAndWaitForLauncherEvent(
94                         () -> mLauncher.movePointer(
95                                 downTime,
96                                 downTime,
97                                 ZERO_BUTTON_SWIPE_UP_GESTURE_DURATION,
98                                 start,
99                                 end,
100                                 gestureScope),
101                         event -> TestProtocol.PAUSE_DETECTED_MESSAGE.equals(event.getClassName()),
102                         () -> "Pause wasn't detected", "swiping and holding");
103                 mLauncher.runToState(
104                         () -> mLauncher.sendPointer(
105                                 downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, end,
106                                 gestureScope),
107                         OVERVIEW_STATE_ORDINAL, "sending UP event");
108                 break;
109             }
110 
111             case TWO_BUTTON: {
112                 final int startX;
113                 final int startY;
114                 final int endX;
115                 final int endY;
116                 final int swipeLength = mLauncher.getTestInfo(getSwipeHeightRequestName()).
117                         getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD) + mLauncher.getTouchSlop();
118 
119                 if (mLauncher.getDevice().isNaturalOrientation()) {
120                     startX = endX = mLauncher.getDevice().getDisplayWidth() / 2;
121                     startY = getSwipeStartY();
122                     endY = startY - swipeLength;
123                 } else {
124                     startX = getSwipeStartX();
125                     // TODO(b/184059820) make horizontal swipe use swipe width not height, for the
126                     // moment just double the swipe length.
127                     endX = startX - swipeLength * 2;
128                     startY = endY = mLauncher.getDevice().getDisplayHeight() / 2;
129                 }
130 
131                 mLauncher.swipeToState(startX, startY, endX, endY, 10, OVERVIEW_STATE_ORDINAL,
132                         LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER);
133                 break;
134             }
135 
136             case THREE_BUTTON:
137                 mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SQUARE_BUTTON_EVENT);
138                 mLauncher.runToState(
139                         () -> mLauncher.waitForSystemUiObject("recent_apps").click(),
140                         OVERVIEW_STATE_ORDINAL, "clicking Recents button");
141                 break;
142         }
143         expectSwitchToOverviewEvents();
144     }
145 
expectSwitchToOverviewEvents()146     private void expectSwitchToOverviewEvents() {
147     }
148 
149     @NonNull
quickSwitchToPreviousApp()150     public Background quickSwitchToPreviousApp() {
151         boolean toRight = true;
152         quickSwitch(toRight);
153         return new Background(mLauncher);
154     }
155 
156     @NonNull
quickSwitchToPreviousAppSwipeLeft()157     public Background quickSwitchToPreviousAppSwipeLeft() {
158         boolean toRight = false;
159         quickSwitch(toRight);
160         return new Background(mLauncher);
161     }
162 
163     @NonNull
quickSwitch(boolean toRight)164     private void quickSwitch(boolean toRight) {
165         try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
166              LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
167                      "want to quick switch to the previous app")) {
168             verifyActiveContainer();
169             final boolean launcherWasVisible = mLauncher.isLauncherVisible();
170             boolean transposeInLandscape = false;
171             switch (mLauncher.getNavigationModel()) {
172                 case TWO_BUTTON:
173                     transposeInLandscape = true;
174                     // Fall through, zero button and two button modes behave the same.
175                 case ZERO_BUTTON: {
176                     final int startX;
177                     final int startY;
178                     final int endX;
179                     final int endY;
180                     final int cornerRadius = (int) Math.ceil(mLauncher.getWindowCornerRadius());
181                     if (toRight) {
182                         if (mLauncher.getDevice().isNaturalOrientation() || !transposeInLandscape) {
183                             // Swipe from the bottom left to the bottom right of the screen.
184                             startX = cornerRadius;
185                             startY = getSwipeStartY();
186                             endX = mLauncher.getDevice().getDisplayWidth() - cornerRadius;
187                             endY = startY;
188                         } else {
189                             // Swipe from the bottom right to the top right of the screen.
190                             startX = getSwipeStartX();
191                             startY = mLauncher.getRealDisplaySize().y - 1 - cornerRadius;
192                             endX = startX;
193                             endY = cornerRadius;
194                         }
195                     } else {
196                         if (mLauncher.getDevice().isNaturalOrientation() || !transposeInLandscape) {
197                             // Swipe from the bottom right to the bottom left of the screen.
198                             startX = mLauncher.getDevice().getDisplayWidth() - cornerRadius;
199                             startY = getSwipeStartY();
200                             endX = cornerRadius;
201                             endY = startY;
202                         } else {
203                             // Swipe from the bottom left to the top left of the screen.
204                             startX = getSwipeStartX();
205                             startY = cornerRadius;
206                             endX = startX;
207                             endY = mLauncher.getRealDisplaySize().y - 1 - cornerRadius;
208                         }
209                     }
210 
211                     final boolean isZeroButton = mLauncher.getNavigationModel()
212                             == LauncherInstrumentation.NavigationModel.ZERO_BUTTON;
213                     LauncherInstrumentation.GestureScope gestureScope =
214                             launcherWasVisible && isZeroButton
215                                     ? LauncherInstrumentation.GestureScope.INSIDE_TO_OUTSIDE
216                                     : LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER;
217                     mLauncher.executeAndWaitForEvent(
218                             () -> mLauncher.linearGesture(
219                                     startX, startY, endX, endY, 20, false, gestureScope),
220                             event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
221                             () -> "Quick switch gesture didn't change window state", "swiping");
222                     break;
223                 }
224 
225                 case THREE_BUTTON:
226                     // Double press the recents button.
227                     UiObject2 recentsButton = mLauncher.waitForSystemUiObject("recent_apps");
228                     mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SQUARE_BUTTON_EVENT);
229                     mLauncher.runToState(() -> recentsButton.click(), OVERVIEW_STATE_ORDINAL,
230                             "clicking Recents button for the first time");
231                     mLauncher.getOverview();
232                     mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SQUARE_BUTTON_EVENT);
233                     mLauncher.executeAndWaitForEvent(
234                             () -> recentsButton.click(),
235                             event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
236                             () -> "Pressing recents button didn't change window state",
237                             "clicking Recents button for the second time");
238                     break;
239             }
240             mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, TASK_START_EVENT);
241             return;
242         }
243     }
244 
getSwipeHeightRequestName()245     protected String getSwipeHeightRequestName() {
246         return TestProtocol.REQUEST_BACKGROUND_TO_OVERVIEW_SWIPE_HEIGHT;
247     }
248 
getSwipeStartX()249     protected int getSwipeStartX() {
250         return mLauncher.getRealDisplaySize().x - 1;
251     }
252 
getSwipeStartY()253     protected int getSwipeStartY() {
254         return mLauncher.getRealDisplaySize().y - 1;
255     }
256 }
257