1 /*
2  * Copyright (C) 2014 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.support.test.aupt;
18 
19 import android.accounts.Account;
20 import android.accounts.AccountManager;
21 import android.content.Intent;
22 import android.content.pm.PackageInfo;
23 import android.content.pm.PackageManager;
24 import android.content.pm.PackageManager.NameNotFoundException;
25 import android.os.Bundle;
26 import android.os.SystemClock;
27 import android.test.InstrumentationTestCase;
28 import android.test.InstrumentationTestRunner;
29 import android.util.Log;
30 
31 import androidx.test.uiautomator.By;
32 import androidx.test.uiautomator.UiDevice;
33 import androidx.test.uiautomator.UiWatcher;
34 
35 import junit.framework.Assert;
36 
37 import java.util.List;
38 
39 /**
40  * Base class for AuptTests.
41  */
42 public class AuptTestCase extends InstrumentationTestCase {
43     /* Constants */
44     static final int STEPS_BACK = 10;
45     static final int RECOVERY_SLEEP = 2000;
46     static final long DEFAULT_SHORT_SLEEP = 5 * 1000;
47     static final long DEFAULT_LONG_SLEEP = 30 * 1000;
48     static final String TAG = AuptTestCase.class.getSimpleName();
49 
50     /* State */
51     private UiWatchers mWatchers;
52     private UiDevice mDevice;
53 
54     /* *******************  InstrumentationTestCase Hooks ******************* */
55 
56     /**
57      * {@inheritDoc}
58      */
59     @Override
setUp()60     protected void setUp() throws Exception {
61         super.setUp();
62 
63         mDevice = UiDevice.getInstance(getInstrumentation());
64         mWatchers = new UiWatchers();
65         mWatchers.registerAnrAndCrashWatchers(getInstrumentation());
66 
67         mDevice.registerWatcher("LockScreenWatcher", new LockScreenWatcher());
68         mDevice.setOrientationNatural();
69     }
70 
71     /**
72      * {@inheritDoc}
73      */
74     @Override
tearDown()75     protected void tearDown() throws Exception {
76         mDevice.removeWatcher("LockScreenWatcher");
77         mDevice.unfreezeRotation();
78 
79         super.tearDown();
80     }
81 
82     /* *******************  Device Methods ******************* */
83 
84     /**
85      * @deprecated you should be using an AppHelper library to do this.
86      */
87     @Deprecated
getUiDevice()88     protected UiDevice getUiDevice() {
89         return mDevice;
90     }
91 
92     /**
93      * @deprecated you should be using an AppHelper library to do this.
94      */
95     @Deprecated
launchIntent(Intent intent)96     public void launchIntent(Intent intent) {
97         getInstrumentation().getContext().startActivity(intent);
98     }
99 
100     /**
101      * Press back button repeatedly in order to attempt to bring the app back to home screen.
102      * This is intended so that an app can recover if the previous session left an app in a weird
103      * state.
104      *
105      * @deprecated you should be using an AppHelper library to do this.
106      */
107     @Deprecated
navigateToHome()108     public void navigateToHome() {
109         int iterations = 0;
110         String launcherPkg = mDevice.getLauncherPackageName();
111         while (!launcherPkg.equals(mDevice.getCurrentPackageName())
112                 && iterations < STEPS_BACK) {
113             mDevice.pressBack();
114             SystemClock.sleep(RECOVERY_SLEEP);
115             iterations++;
116         }
117     }
118 
119     /* *******************  Parameter Accessors ******************* */
120 
getParams()121     protected Bundle getParams() {
122         return ((InstrumentationTestRunner)getInstrumentation()).getArguments();
123     }
124 
125     /**
126      * Looks up a parameter or returns a default value if parameter is not
127      * present.
128      * @param key
129      * @param defaultValue
130      * @return passed in parameter or default value if parameter is not found.
131      */
getLongParam(String key, long defaultValue)132     public long getLongParam(String key, long defaultValue) throws NumberFormatException {
133         if (getParams().containsKey(key)) {
134             return Long.parseLong(getParams().getString(key));
135         } else {
136             return defaultValue;
137         }
138     }
139 
140     /**
141      * Returns the timeout for short sleep. Can be set with shortSleep command
142      * line option. Default is 5 seconds.
143      * @return time in milliseconds
144      */
getShortSleep()145     public long getShortSleep() {
146         return getLongParam("shortSleep", DEFAULT_SHORT_SLEEP);
147     }
148 
149     /**
150      * Returns the timeout for long sleep. Can be set with longSleep command
151      * line option. Default is 30 seconds
152      * @return time in milliseconds.
153      */
getLongSleep()154     public long getLongSleep() {
155         return getLongParam("longSleep", DEFAULT_LONG_SLEEP);
156     }
157 
158     /**
159      * @return the jar-file arguments of this AUPT test run
160      */
getDexedJarPaths()161     public List<String> getDexedJarPaths() {
162         return DexTestRunner.parseDexedJarPaths(getParams().getString("jars", ""));
163     }
164 
165     /**
166      * @return the version corresponding to a given package name
167      *
168      * @deprecated you should be using an AppHelper library to do this.
169      */
170     @Deprecated
getPackageVersion(String packageName)171     public String getPackageVersion(String packageName) throws NameNotFoundException {
172         if (null == packageName || packageName.isEmpty()) {
173               throw new RuntimeException("Package name can't be null or empty");
174         }
175         PackageManager pm = getInstrumentation().getContext().getPackageManager();
176         PackageInfo pInfo = pm.getPackageInfo(packageName, 0);
177         String version = pInfo.versionName;
178         if (null == version || version.isEmpty()) {
179               throw new RuntimeException(
180                       String.format("Version isn't found for package = %s", packageName));
181         }
182 
183         return version;
184     }
185 
186     /**
187      * Get registered accounts
188      * Ensures there is at least one account registered
189      * returns the google account name
190      *
191      * @deprecated you should be using an AppHelper library to do this.
192      */
193     @Deprecated
getRegisteredEmailAccount()194     public String getRegisteredEmailAccount() {
195         Account[] accounts = AccountManager.get(getInstrumentation().getContext()).getAccounts();
196         Assert.assertTrue("Device doesn't have any account registered", accounts.length >= 1);
197         for(int i =0; i < accounts.length; ++i) {
198             if(accounts[i].type.equals("com.google")) {
199                 return accounts[i].name;
200             }
201         }
202 
203         throw new RuntimeException("The device is not registered with a google account");
204     }
205 
206     /* *******************  Logging ******************* */
207 
dumpMemInfo(String notes)208     protected void dumpMemInfo(String notes) {
209         FilesystemUtil.dumpMeminfo(getInstrumentation(), notes);
210     }
211 
212     /* *******************  Utilities ******************* */
213 
214     private class LockScreenWatcher implements UiWatcher {
215         @Override
checkForCondition()216         public boolean checkForCondition() {
217             if (mDevice.hasObject(By.desc("Slide area."))) {
218                 mDevice.pressMenu();
219                 Log.v(TAG, "Lock screen dismissed.");
220                 return true;
221             }
222             return false;
223         }
224     }
225 }
226