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 com.android.launcher3.tapl.LauncherInstrumentation.WAIT_TIME_MS;
20 
21 import android.graphics.Point;
22 import android.graphics.Rect;
23 
24 import androidx.test.uiautomator.By;
25 import androidx.test.uiautomator.BySelector;
26 import androidx.test.uiautomator.Direction;
27 import androidx.test.uiautomator.UiObject2;
28 import androidx.test.uiautomator.Until;
29 
30 import com.android.launcher3.tapl.LauncherInstrumentation.GestureScope;
31 
32 import java.util.Collection;
33 
34 /**
35  * All widgets container.
36  */
37 public final class Widgets extends LauncherInstrumentation.VisibleContainer {
38     private static final int FLING_STEPS = 10;
39 
Widgets(LauncherInstrumentation launcher)40     Widgets(LauncherInstrumentation launcher) {
41         super(launcher);
42         verifyActiveContainer();
43     }
44 
45     /**
46      * Flings forward (down) and waits the fling's end.
47      */
flingForward()48     public void flingForward() {
49         try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
50              LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
51                      "want to fling forward in widgets")) {
52             LauncherInstrumentation.log("Widgets.flingForward enter");
53             final UiObject2 widgetsContainer = verifyActiveContainer();
54             mLauncher.scroll(
55                     widgetsContainer,
56                     Direction.DOWN,
57                     new Rect(0, 0, 0,
58                             mLauncher.getBottomGestureMarginInContainer(widgetsContainer) + 1),
59                     FLING_STEPS, false);
60             try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("flung forward")) {
61                 verifyActiveContainer();
62             }
63             LauncherInstrumentation.log("Widgets.flingForward exit");
64         }
65     }
66 
67     /**
68      * Flings backward (up) and waits the fling's end.
69      */
flingBackward()70     public void flingBackward() {
71         try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
72              LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
73                      "want to fling backwards in widgets")) {
74             LauncherInstrumentation.log("Widgets.flingBackward enter");
75             final UiObject2 widgetsContainer = verifyActiveContainer();
76             mLauncher.scroll(
77                     widgetsContainer,
78                     Direction.UP,
79                     new Rect(0, 0, mLauncher.getVisibleBounds(widgetsContainer).width(), 0),
80                     FLING_STEPS, false);
81             try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("flung back")) {
82                 verifyActiveContainer();
83             }
84             LauncherInstrumentation.log("Widgets.flingBackward exit");
85         }
86     }
87 
88     @Override
getContainerType()89     protected LauncherInstrumentation.ContainerType getContainerType() {
90         return LauncherInstrumentation.ContainerType.WIDGETS;
91     }
92 
getWidget(String labelText)93     public Widget getWidget(String labelText) {
94         try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
95              LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
96                      "getting widget " + labelText + " in widgets list")) {
97             final UiObject2 widgetsContainer = verifyActiveContainer();
98             mLauncher.assertTrue("Widgets container didn't become scrollable",
99                     widgetsContainer.wait(Until.scrollable(true), WAIT_TIME_MS));
100             final Point displaySize = mLauncher.getRealDisplaySize();
101             final BySelector labelSelector = By.clazz("android.widget.TextView").text(labelText);
102 
103             int i = 0;
104             for (; ; ) {
105                 final Collection<UiObject2> cells = mLauncher.getObjectsInContainer(
106                         widgetsContainer, "widgets_scroll_container");
107                 mLauncher.assertTrue("Widgets doesn't have 2 rows", cells.size() >= 2);
108                 for (UiObject2 cell : cells) {
109                     final UiObject2 label = cell.findObject(labelSelector);
110                     if (label == null) continue;
111 
112                     final UiObject2 widget = label.getParent().getParent();
113                     mLauncher.assertEquals(
114                             "View is not WidgetCell",
115                             "com.android.launcher3.widget.WidgetCell",
116                             widget.getClassName());
117 
118                     int maxWidth = 0;
119                     for (UiObject2 sibling : widget.getParent().getChildren()) {
120                         maxWidth = Math.max(mLauncher.getVisibleBounds(sibling).width(), maxWidth);
121                     }
122 
123                     if (mLauncher.getVisibleBounds(widget).bottom
124                             <= displaySize.y - mLauncher.getBottomGestureSize()) {
125                         int visibleDelta = maxWidth - mLauncher.getVisibleBounds(widget).width();
126                         if (visibleDelta > 0) {
127                             Rect parentBounds = mLauncher.getVisibleBounds(cell);
128                             mLauncher.linearGesture(parentBounds.centerX() + visibleDelta
129                                             + mLauncher.getTouchSlop(),
130                                     parentBounds.centerY(), parentBounds.centerX(),
131                                     parentBounds.centerY(), 10, true, GestureScope.INSIDE);
132                         }
133 
134                         return new Widget(mLauncher, widget);
135                     }
136                 }
137 
138                 mLauncher.assertTrue("Too many attempts", ++i <= 40);
139                 mLauncher.scrollToLastVisibleRow(widgetsContainer, cells, 0);
140             }
141         }
142     }
143 }
144