Background.java 12 KB

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