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