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