• 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 com.android.cts.documentclient;
18 
19 import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
20 
21 import java.io.ByteArrayOutputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.OutputStream;
25 
26 import com.android.cts.documentclient.MyActivity.Result;
27 
28 import android.app.Activity;
29 import android.content.ContentResolver;
30 import android.content.Intent;
31 import android.content.pm.PackageManager;
32 import android.content.pm.ResolveInfo;
33 import android.content.res.AssetFileDescriptor;
34 import android.content.res.AssetFileDescriptor.AutoCloseInputStream;
35 import android.database.Cursor;
36 import android.net.Uri;
37 import android.support.test.uiautomator.Configurator;
38 import android.support.test.uiautomator.UiDevice;
39 import android.test.InstrumentationTestCase;
40 import android.text.format.DateUtils;
41 import android.util.Log;
42 import android.view.MotionEvent;
43 
44 /**
45  * Base class for DocumentsUI test cases.
46  */
47 abstract class DocumentsClientTestCase extends InstrumentationTestCase {
48     protected static final long TIMEOUT = 30 * DateUtils.SECOND_IN_MILLIS;
49     protected static final int REQUEST_CODE = 42;
50 
51     static final String PROVIDER_PACKAGE = "com.android.cts.documentprovider";
52 
53     private static final String TAG = "DocumentsClientTestCase";
54 
55     protected UiDevice mDevice;
56     protected MyActivity mActivity;
57 
58     private String mDocumentsUiPackageId;
59 
60     private static final String COMPONENT_NAME_DUMMY_IME = "com.android.cts.dummyime/.CtsDummyIme";
61 
62     @Override
setUp()63     public void setUp() throws Exception {
64         if (!supportedHardware()) return;
65         super.setUp();
66 
67         final PackageManager pm = getInstrumentation().getContext().getPackageManager();
68 
69         final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
70         intent.addCategory(Intent.CATEGORY_OPENABLE);
71         intent.setType("*/*");
72         final ResolveInfo ri = pm.resolveActivity(intent, 0);
73         mDocumentsUiPackageId = ri.activityInfo.packageName;
74 
75 
76         // Wake up the device and dismiss the keyguard before the test starts.
77         executeShellCommand("input keyevent KEYCODE_WAKEUP");
78         executeShellCommand("wm dismiss-keyguard");
79 
80         Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_FINGER);
81 
82         // Disable IME's to avoid virtual keyboards from showing up. Occasionally IME draws some UI
83         // controls out of its boundary for some first time setup that obscures the text edit and/or
84         // save/select button. This will constantly fail some of our tests.
85         enableDummyIme();
86 
87         mDevice = UiDevice.getInstance(getInstrumentation());
88         mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
89                 MyActivity.class, null);
90         mDevice.waitForIdle();
91     }
92 
93     @Override
tearDown()94     public void tearDown() throws Exception {
95         if (!supportedHardware()) return;
96         super.tearDown();
97         mActivity.finish();
98 
99         executeShellCommand("ime reset");
100     }
101 
getDocumentsUiPackageId()102     protected String getDocumentsUiPackageId() {
103         return mDocumentsUiPackageId;
104     }
105 
getColumn(Uri uri, String column)106     protected String getColumn(Uri uri, String column) {
107         final ContentResolver resolver = getInstrumentation().getContext().getContentResolver();
108         final Cursor cursor = resolver.query(uri, new String[] { column }, null, null, null);
109         try {
110             assertTrue(cursor.moveToFirst());
111             return cursor.getString(0);
112         } finally {
113             cursor.close();
114         }
115     }
116 
readFully(Uri uri)117     protected byte[] readFully(Uri uri) throws IOException {
118         final InputStream in = getInstrumentation().getContext().getContentResolver()
119                 .openInputStream(uri);
120         return readFully(in);
121     }
122 
readTypedFully(Uri uri, String mimeType)123     protected byte[] readTypedFully(Uri uri, String mimeType) throws IOException {
124         final AssetFileDescriptor descriptor =
125                 getInstrumentation().getContext().getContentResolver()
126                         .openTypedAssetFileDescriptor(uri, mimeType, null, null);
127         try (AutoCloseInputStream in = new AutoCloseInputStream(descriptor)) {
128             return readFully(in);
129         }
130     }
131 
readFully(InputStream in)132     protected byte[] readFully(InputStream in) throws IOException {
133         try {
134             ByteArrayOutputStream bytes = new ByteArrayOutputStream();
135             byte[] buffer = new byte[1024];
136             int count;
137             while ((count = in.read(buffer)) != -1) {
138                 bytes.write(buffer, 0, count);
139             }
140             return bytes.toByteArray();
141         } finally {
142             in.close();
143         }
144     }
145 
writeFully(Uri uri, byte[] data)146     protected void writeFully(Uri uri, byte[] data) throws IOException {
147         OutputStream out = getInstrumentation().getContext().getContentResolver()
148                 .openOutputStream(uri);
149         try {
150             out.write(data);
151         } finally {
152             out.close();
153         }
154     }
155 
supportedHardware()156     protected boolean supportedHardware() {
157         final PackageManager pm = getInstrumentation().getContext().getPackageManager();
158         if (pm.hasSystemFeature("android.hardware.type.television")
159                 || pm.hasSystemFeature("android.hardware.type.watch")
160                 || pm.hasSystemFeature("android.hardware.type.automotive")) {
161             return false;
162         }
163         return true;
164     }
165 
supportedHardwareForScopedDirectoryAccess()166     protected boolean supportedHardwareForScopedDirectoryAccess() {
167         final PackageManager pm = getInstrumentation().getContext().getPackageManager();
168         if (pm.hasSystemFeature("android.hardware.type.television")
169                 || pm.hasSystemFeature("android.hardware.type.watch")
170                 || pm.hasSystemFeature("android.hardware.type.automotive")) {
171             return false;
172         }
173         return true;
174     }
175 
isTelevision()176     protected boolean isTelevision() {
177         final PackageManager pm = getInstrumentation().getContext().getPackageManager();
178         return pm.hasSystemFeature("android.hardware.type.television");
179     }
180 
assertActivityFailed()181     protected void assertActivityFailed() {
182         final Result result = mActivity.getResult();
183         assertEquals(REQUEST_CODE, result.requestCode);
184         assertEquals(Activity.RESULT_CANCELED, result.resultCode);
185         assertNull(result.data);
186     }
187 
assertActivitySucceeded(String prefix)188     protected Intent assertActivitySucceeded(String prefix) {
189         final Result result = mActivity.getResult();
190         assertEquals(prefix + ": invalid request code", REQUEST_CODE, result.requestCode);
191         assertEquals(prefix + ": invalid result code", Activity.RESULT_OK, result.resultCode);
192         assertNotNull(prefix + ": null data on result", result.data);
193         return result.data;
194     }
195 
executeShellCommand(String command)196     protected String executeShellCommand(String command) throws Exception {
197         final String result = runShellCommand(getInstrumentation(), command).trim();
198         Log.d(TAG, "Command '" + command + "' returned '" + result + "'");
199         return result;
200     }
201 
202     /**
203      * Clears the DocumentsUI package data, unless test name ends on {@code DoNotClear}.
204      */
clearDocumentsUi()205     protected void clearDocumentsUi() throws Exception {
206         final String testName = getName();
207         if (testName.endsWith("DoNotClear")) {
208             Log.d(TAG, "Not clearing DocumentsUI due to test name: " + testName);
209             return;
210         }
211         executeShellCommand("pm clear " + getDocumentsUiPackageId());
212     }
213 
enableDummyIme()214     private void enableDummyIme() throws Exception {
215         String enableDummyCommand = "ime enable " + COMPONENT_NAME_DUMMY_IME;
216         executeShellCommand(enableDummyCommand);
217 
218         String setDummyCommand = "ime set " + COMPONENT_NAME_DUMMY_IME;
219         executeShellCommand(setDummyCommand);
220     }
221 }
222