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.documentsui; 18 19 import android.app.Activity; 20 import android.app.UiAutomation; 21 import android.app.UiModeManager; 22 import android.content.ContentProviderClient; 23 import android.content.ContentResolver; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.content.res.Configuration; 27 import android.os.Bundle; 28 import android.os.RemoteException; 29 import android.provider.DocumentsContract; 30 import android.provider.DocumentsContract.Document; 31 import android.support.test.uiautomator.Configurator; 32 import android.support.test.uiautomator.UiDevice; 33 import android.support.test.uiautomator.UiObjectNotFoundException; 34 import android.test.ActivityInstrumentationTestCase2; 35 import android.view.KeyEvent; 36 import android.view.MotionEvent; 37 38 import com.android.documentsui.base.Features; 39 import com.android.documentsui.base.RootInfo; 40 import com.android.documentsui.base.UserId; 41 import com.android.documentsui.bots.Bots; 42 import com.android.documentsui.files.FilesActivity; 43 44 import javax.annotation.Nullable; 45 46 /** 47 * Provides basic test environment for UI tests: 48 * - Launches activity 49 * - Creates and gives access to test root directories and test files 50 * - Cleans up the test environment 51 */ 52 public abstract class ActivityTest<T extends Activity> extends ActivityInstrumentationTestCase2<T> { 53 54 static final int TIMEOUT = 5000; 55 static final int NIGHT_MODE_CHANGE_WAIT_TIME = 1000; 56 57 // Testing files. For custom ones, override initTestFiles(). 58 public static final String dirName1 = "Dir1"; 59 public static final String childDir1 = "ChildDir1"; 60 public static final String fileName1 = "file1.log"; 61 public static final String fileName2 = "file12.png"; 62 public static final String fileName3 = "anotherFile0.log"; 63 public static final String fileName4 = "poodles.text"; 64 public static final String fileNameNoRename = "NO_RENAMEfile.txt"; 65 66 public Bots bots; 67 public UiDevice device; 68 public Context context; 69 public UserId userId; 70 public UiAutomation automation; 71 72 public Features features; 73 public RootInfo rootDir0; 74 public RootInfo rootDir1; 75 protected ContentResolver mResolver; 76 protected DocumentsProviderHelper mDocsHelper; 77 protected ContentProviderClient mClient; 78 protected UiModeManager mUiModeManager; 79 ActivityTest(Class<T> activityClass)80 public ActivityTest(Class<T> activityClass) { 81 super(activityClass); 82 } 83 84 /* 85 * Returns the root that will be opened within the activity. 86 * By default tests are started with one of the test roots. 87 * Override the method if you want to open different root on start. 88 * @return Root that will be opened. Return null if you want to open activity's default root. 89 */ getInitialRoot()90 protected @Nullable RootInfo getInitialRoot() { 91 return rootDir0; 92 } 93 94 /** 95 * Returns the authority of the testing provider begin used. 96 * By default it's StubProvider's authority. 97 * @return Authority of the provider. 98 */ getTestingProviderAuthority()99 protected String getTestingProviderAuthority() { 100 return StubProvider.DEFAULT_AUTHORITY; 101 } 102 103 /** 104 * Resolves testing roots. 105 */ setupTestingRoots()106 protected void setupTestingRoots() throws RemoteException { 107 rootDir0 = mDocsHelper.getRoot(StubProvider.ROOT_0_ID); 108 rootDir1 = mDocsHelper.getRoot(StubProvider.ROOT_1_ID); 109 } 110 111 @Override setUp()112 public void setUp() throws Exception { 113 device = UiDevice.getInstance(getInstrumentation()); 114 // NOTE: Must be the "target" context, else security checks in content provider will fail. 115 context = getInstrumentation().getTargetContext(); 116 userId = UserId.DEFAULT_USER; 117 automation = getInstrumentation().getUiAutomation(); 118 features = new Features.RuntimeFeatures(context.getResources(), null); 119 120 bots = new Bots(device, automation, context, TIMEOUT); 121 122 Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_MOUSE); 123 124 mResolver = context.getContentResolver(); 125 mDocsHelper = new DocumentsProviderHelper(userId, getTestingProviderAuthority(), context, 126 getTestingProviderAuthority()); 127 128 device.setOrientationNatural(); 129 device.pressKeyCode(KeyEvent.KEYCODE_WAKEUP); 130 device.pressKeyCode(KeyEvent.KEYCODE_MENU); 131 setupTestingRoots(); 132 133 launchActivity(); 134 resetStorage(); 135 136 // Since at the launch of activity, ROOT_0 and ROOT_1 have no files, drawer will 137 // automatically open for phone devices. Espresso register click() as (x, y) MotionEvents, 138 // so if a drawer is on top of a file we want to select, it will actually click the drawer. 139 // Thus to start a clean state, we always try to close first. 140 bots.roots.closeDrawer(); 141 142 // Configure the provider back to default. 143 mDocsHelper.configure(null, Bundle.EMPTY); 144 } 145 146 @Override tearDown()147 public void tearDown() throws Exception { 148 device.unfreezeRotation(); 149 mDocsHelper.cleanUp(); 150 super.tearDown(); 151 } 152 launchActivity()153 protected void launchActivity() { 154 final Intent intent = new Intent(context, FilesActivity.class); 155 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); 156 if (getInitialRoot() != null) { 157 intent.setAction(Intent.ACTION_VIEW); 158 intent.setDataAndType(getInitialRoot().getUri(), DocumentsContract.Root.MIME_TYPE_ITEM); 159 } 160 setActivityIntent(intent); 161 getActivity(); // Launch the activity. 162 } 163 resetStorage()164 protected void resetStorage() throws RemoteException { 165 mDocsHelper.clear(null, null); 166 device.waitForIdle(); 167 } 168 initTestFiles()169 protected void initTestFiles() throws RemoteException { 170 mDocsHelper.createFolder(rootDir0, dirName1); 171 mDocsHelper.createDocument(rootDir0, "text/plain", fileName1); 172 mDocsHelper.createDocument(rootDir0, "image/png", fileName2); 173 mDocsHelper.createDocumentWithFlags(rootDir0.documentId, "text/plain", fileNameNoRename, 174 Document.FLAG_SUPPORTS_WRITE); 175 176 mDocsHelper.createDocument(rootDir1, "text/plain", fileName3); 177 mDocsHelper.createDocument(rootDir1, "text/plain", fileName4); 178 } 179 assertDefaultContentOfTestDir0()180 void assertDefaultContentOfTestDir0() throws UiObjectNotFoundException { 181 bots.directory.waitForDocument(fileName1); 182 bots.directory.waitForDocument(fileName2); 183 bots.directory.waitForDocument(dirName1); 184 bots.directory.waitForDocument(fileNameNoRename); 185 bots.directory.assertDocumentsCount(4); 186 } 187 assertDefaultContentOfTestDir1()188 void assertDefaultContentOfTestDir1() throws UiObjectNotFoundException { 189 bots.directory.waitForDocument(fileName3); 190 bots.directory.waitForDocument(fileName4); 191 bots.directory.assertDocumentsCount(2); 192 } 193 194 /** 195 * Setup test Activity UI Mode YES or not(AUTO/YES/NO) before start to testing 196 * @param uiModeNight Constant for {@link #setNightMode(int)} 197 * 0 - MODE_NIGHT_AUTO 198 * 1 - MODE_NIGHT_NO 199 * 2 - MODE_NIGHT_YES 200 */ setSystemUiModeNight(int uiModeNight)201 protected void setSystemUiModeNight(int uiModeNight) { 202 int systemUiMode = getActivity().getResources().getConfiguration().uiMode 203 & Configuration.UI_MODE_NIGHT_MASK; 204 if(uiModeNight != systemUiMode) { 205 /* TODO since ag/4947691 enable config_lockDayNightMode to block app setNightMode() 206 create b/115315612 to handle the UiModeManager permission deny problem */ 207 mUiModeManager = (UiModeManager) getActivity() 208 .getSystemService(Context.UI_MODE_SERVICE); 209 mUiModeManager.setNightMode(uiModeNight); 210 device.waitForIdle(NIGHT_MODE_CHANGE_WAIT_TIME); 211 } 212 } 213 } 214