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