• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 android.system.helpers;
18 
19 import android.app.Instrumentation;
20 import android.content.Intent;
21 import android.content.pm.PackageInfo;
22 import android.content.pm.PackageManager;
23 import android.graphics.Point;
24 import android.graphics.Rect;
25 import android.os.SystemClock;
26 import android.support.test.InstrumentationRegistry;
27 import android.support.test.uiautomator.By;
28 import android.support.test.uiautomator.UiDevice;
29 import android.support.test.uiautomator.UiObject2;
30 import android.support.test.uiautomator.UiObjectNotFoundException;
31 import android.support.test.uiautomator.Until;
32 import android.system.helpers.ActivityHelper;
33 import android.util.Log;
34 
35 import org.junit.Assert;
36 
37 import java.io.IOException;
38 import java.util.ArrayList;
39 import java.util.List;
40 
41 /**
42  * Implement common helper methods for Overview.
43  */
44 public class OverviewHelper {
45 
46     private static final String TAG = OverviewHelper.class.getSimpleName();
47     private static final int TIMEOUT = 3000;
48     private static final String RECENTS = "com.android.systemui:id/recents_view";
49 
50     private UiDevice mDevice = null;
51     private Instrumentation mInstrumentation = null;
52     private ActivityHelper mActHelper = null;
53     private final CommandsHelper mCommandsHelper;
54     public static OverviewHelper sInstance = null;
55 
OverviewHelper()56     public OverviewHelper() {
57         mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
58         mInstrumentation = InstrumentationRegistry.getInstrumentation();
59         mActHelper = ActivityHelper.getInstance();
60         mCommandsHelper = CommandsHelper.getInstance(mInstrumentation);
61     }
62 
getInstance()63     public static OverviewHelper getInstance() {
64         if (sInstance == null) {
65             sInstance = new OverviewHelper();
66         }
67         return sInstance;
68     }
69 
70     /**
71      * Navigates to the recents screen
72      * @returns recents object
73      * @throws UiObjectNotFoundException
74      */
navigateToRecents()75     public UiObject2 navigateToRecents() throws Exception {
76         mDevice.pressRecentApps();
77         mDevice.waitForIdle();
78         return mDevice.wait(Until.findObject(By.res(RECENTS)), TIMEOUT);
79     }
80 
81     /**
82      * Populates recents by launching six apps
83      * @throws InterruptedException
84      */
populateRecents()85     public void populateRecents() throws InterruptedException {
86         // We launch six apps, since five is the maximum number
87         // of apps under Recents
88         String[] appPackages = {"com.google.android.gm",
89                 "com.google.android.deskclock", "com.android.settings",
90                 "com.google.android.youtube", "com.google.android.contacts",
91                 "com.google.android.apps.maps"};
92         for (String appPackage : appPackages) {
93             mActHelper.launchPackage(appPackage);
94         }
95     }
96 
populateManyRecentApps()97     public ArrayList<String> populateManyRecentApps() throws IOException {
98         PackageManager pm = mInstrumentation.getContext().getPackageManager();
99         List<PackageInfo> packages = pm.getInstalledPackages(0);
100         ArrayList<String> launchedPackages = new ArrayList<>();
101         for (PackageInfo pkg : packages) {
102             if (pkg.packageName.equals(mInstrumentation.getTargetContext().getPackageName())) {
103                 continue;
104             }
105             Intent intent = pm.getLaunchIntentForPackage(pkg.packageName);
106             if (intent == null) {
107                 continue;
108             }
109             intent.addCategory(Intent.CATEGORY_LAUNCHER);
110             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
111             try {
112                 mInstrumentation.getTargetContext().startActivity(intent);
113             } catch (SecurityException e) {
114                 Log.i(TAG, "Failed to start package " + pkg.packageName + ", exception: " + e);
115             }
116 
117             // Don't overload the system
118             SystemClock.sleep(500);
119             launchedPackages.add(pkg.packageName);
120         }
121 
122         // Give the apps some time to finish starting. Some apps start another activity while
123         // starting, and we don't want to happen when we are testing stuff.
124         SystemClock.sleep(3000);
125 
126         // Close any crash dialogs
127         while (mDevice.hasObject(By.textContains("has stopped"))) {
128             UiObject2 crashDialog = mDevice.findObject(By.text("Close"));
129             if (crashDialog != null) {
130                 crashDialog.clickAndWait(Until.newWindow(), 2000);
131             }
132         }
133         return launchedPackages;
134     }
135 
forceStopPackages(ArrayList<String> packages)136     public void forceStopPackages(ArrayList<String> packages) {
137         for (String pkg : packages) {
138             mCommandsHelper.executeShellCommand("am force-stop " + pkg);
139         }
140     }
141 
142     /**
143     * Scrolls through given recents object to the top
144     * @param recents Recents object
145     */
scrollToTopOfRecents(UiObject2 recents)146     public void scrollToTopOfRecents(UiObject2 recents) {
147         Rect r = recents.getVisibleBounds();
148         // decide the top & bottom edges for scroll gesture
149         int top = r.top + r.height() / 4; // top edge = top + 25% height
150         int bottom = r.bottom - 200; // bottom edge = bottom & shift up 200px
151         mDevice.swipe(r.width() / 2, top, r.width() / 2, bottom, 5);
152         mDevice.waitForIdle();
153     }
154 
155     /**
156      * Docks an app to the top half of the multiwindow screen
157      * @param appPackageName name of app package
158      * @param appName Name of app to verify on screen
159      * @throws UiObjectNotFoundException, InterruptedException
160      */
dockAppToTopMultiwindowSlot(String appPackageName, String appName)161     public void dockAppToTopMultiwindowSlot(String appPackageName, String appName)
162             throws Exception {
163         mDevice.pressRecentApps();
164         mDevice.waitForIdle();
165         UiObject2 recentsView = mDevice.wait(Until.findObject
166                 (By.res("com.android.systemui:id/recents_view")),TIMEOUT);
167         // Check if recents isn't already empty, if not, clear it.
168         if (!mDevice.wait(Until.hasObject(By.text("No recent items")),TIMEOUT)) {
169             scrollToTopOfRecents(recentsView);
170             // click clear all
171             UiObject2 clearAll = mDevice.wait(Until.findObject(By.text("CLEAR ALL")),TIMEOUT);
172             if (!clearAll.equals(null)) {
173                 clearAll.click();
174             }
175             Thread.sleep(TIMEOUT);
176         }
177         // Open app
178         mActHelper.launchPackage(appPackageName);
179         // Go to overview
180         mDevice.pressRecentApps();
181         mDevice.waitForIdle();
182         // Long press on app
183         UiObject2 appObject = mDevice.wait(Until.findObject
184                 (By.desc(appName)),TIMEOUT);
185         int yCoordinate = mDevice.getDisplayHeight() / 12;
186         int xCoordinate = mDevice.getDisplayWidth() / 2;
187         // Drag and drop the app object to the multiwindow area
188         appObject.drag(new Point(xCoordinate, yCoordinate), 1000);
189         // Adding a sleep to allow the drag and drop animation to finish.
190         Thread.sleep(TIMEOUT);
191         mDevice.click(mDevice.getDisplayHeight() / 4, mDevice.getDisplayWidth() / 2);
192         Assert.assertTrue("App not correctly docked to top multiwindow slot",
193                 mDevice.wait(Until.hasObject(By.pkg(appPackageName)
194                         .res("android:id/content")), TIMEOUT));
195     }
196 
197     /**
198      * Docks two apps, one to the each half of the multiwindow screen
199      * @param topAppPackageName name of app package for top half
200      * @param topAppName Name of top app to verify on screen
201      * @param bottomAppPackageName name of app package for bottom half
202      * @throws UiObjectNotFoundException, InterruptedException
203      */
dockAppsToBothMultiwindowAreas(String topAppPackageName, String topAppName, String bottomAppPackageName)204     public void dockAppsToBothMultiwindowAreas(String topAppPackageName,
205             String topAppName, String bottomAppPackageName) throws Exception {
206         dockAppToTopMultiwindowSlot(topAppPackageName, topAppName);
207         mDevice.pressHome();
208         mDevice.waitForIdle();
209         // After docking the top app, simply launching another app
210         // will launch it in the bottom half in docked mode. This
211         // results in two apps being docked to multiwindow.
212         mActHelper.launchPackage(bottomAppPackageName);
213     }
214 
215     /**
216      * Undocks apps from multiwindow. Only the package for the upper app is needed.
217      * @param topAppPackageName name of app package for top half
218      * @throws UiObjectNotFoundException, InterruptedException
219      */
undockAppFromMultiwindow(String topAppPackageName)220     public void undockAppFromMultiwindow(String topAppPackageName) throws Exception {
221         mDevice.click(mDevice.getDisplayHeight() / 4, mDevice.getDisplayWidth() / 2);
222         UiObject2 appArea = mDevice.wait(Until.findObject(By.pkg(topAppPackageName)
223                 .res("android:id/content")), TIMEOUT);
224         Rect appBounds = appArea.getVisibleBounds();
225         int xCoordinate = mDevice.getDisplayWidth() / 2;
226         mDevice.drag(xCoordinate, appBounds.bottom, xCoordinate,
227                 mDevice.getDisplayHeight() - 120, 4);
228         // Adding a sleep to allow the drag and drop animation to finish.
229         Thread.sleep(TIMEOUT);
230     }
231 }