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