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.functional.externalstoragetests; 18 19 import android.app.UiAutomation; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.provider.Settings; 23 import android.support.test.uiautomator.By; 24 import android.support.test.uiautomator.UiDevice; 25 import android.support.test.uiautomator.UiObject2; 26 import android.support.test.uiautomator.Until; 27 import android.test.InstrumentationTestCase; 28 import android.test.suitebuilder.annotation.LargeTest; 29 import java.util.regex.Matcher; 30 import java.util.regex.Pattern; 31 import junit.framework.Assert; 32 33 public class PortableStorageTests extends InstrumentationTestCase { 34 private UiDevice mDevice = null; 35 private Context mContext = null; 36 private UiAutomation mUiAutomation = null; 37 private ExternalStorageHelper storageHelper; 38 39 @Override setUp()40 protected void setUp() throws Exception { 41 super.setUp(); 42 mDevice = UiDevice.getInstance(getInstrumentation()); 43 mContext = getInstrumentation().getContext(); 44 mUiAutomation = getInstrumentation().getUiAutomation(); 45 storageHelper = ExternalStorageHelper.getInstance(mDevice, mContext, mUiAutomation, 46 getInstrumentation()); 47 mDevice.setOrientationNatural(); 48 } 49 50 /** 51 * Test to ensure sd card can be adopted as portable storage 52 */ 53 @LargeTest testAdoptAsPortableViaUI()54 public void testAdoptAsPortableViaUI() throws InterruptedException { 55 // ensure notification 56 storageHelper.executeShellCommand(String.format( 57 "sm partition %s %s", storageHelper.getAdoptionDisk(), "public")); 58 Thread.sleep(storageHelper.TIMEOUT); 59 storageHelper.setupAsPortableUiFlow(); 60 storageHelper.executeShellCommand(String.format("sm forget all")); 61 Thread.sleep(storageHelper.TIMEOUT); 62 } 63 64 /** 65 * tests to ensure copy option is visible for items on portable storage 66 */ 67 @LargeTest testCopyFromPortable()68 public void testCopyFromPortable() throws InterruptedException { 69 ensureHasPortable(); 70 storageHelper.createFiles(2, 71 String.format("/storage/%s", storageHelper.getAdoptionVolumeUuid("public"))); 72 storageHelper.openSDCard(); 73 mDevice.wait(Until.findObject(By.res("android:id/title").text("Test_0")), 74 storageHelper.TIMEOUT).click(storageHelper.TIMEOUT); 75 mDevice.wait(Until.findObject(By.desc(Pattern.compile("More options", 76 Pattern.CASE_INSENSITIVE))), storageHelper.TIMEOUT).click(); 77 assertNotNull(mDevice.wait(Until.findObject(By.res("android:id/title").text("Copy to…")), 78 2 * storageHelper.TIMEOUT)); 79 mDevice.wait(Until.findObject(By.res("android:id/title").text("Copy to…")), 80 storageHelper.TIMEOUT).clickAndWait(Until.newWindow(), storageHelper.TIMEOUT); 81 mDevice.pressBack(); 82 } 83 84 /** 85 * tests to ensure that resources on portable storage can be deleted via UI 86 */ 87 @LargeTest testDeleteFromPortable()88 public void testDeleteFromPortable() throws InterruptedException { 89 ensureHasPortable(); 90 storageHelper.createFiles(2, 91 String.format("/storage/%s", storageHelper.getAdoptionVolumeUuid("public"))); 92 storageHelper.openSDCard(); 93 mDevice.wait(Until.findObject(By.res("android:id/title").text("Test_0")), 94 storageHelper.TIMEOUT).click(storageHelper.TIMEOUT); 95 mDevice.wait(Until.findObject(By.res("com.android.documentsui:id/menu_sort")), 96 storageHelper.TIMEOUT).clickAndWait(Until.newWindow(), storageHelper.TIMEOUT); 97 assertNull(mDevice.wait(Until.findObject(By.res("android:id/title").text("Test_0")), 98 2 * storageHelper.TIMEOUT)); 99 } 100 101 /** 102 * tests to ensure that external storage is explorable via UI 103 */ 104 @LargeTest testExplorePortable()105 public void testExplorePortable() throws InterruptedException { 106 ensureHasPortable(); 107 // Create 2 random files on SDCard 108 storageHelper.createFiles(2, 109 String.format("/storage/%s", storageHelper.getAdoptionVolumeUuid("public"))); 110 Intent intent = new Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS); 111 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 112 mContext.startActivity(intent); 113 Thread.sleep(storageHelper.TIMEOUT * 2); 114 mDevice.wait(Until.findObject(By.textContains("SD card")), storageHelper.TIMEOUT) 115 .clickAndWait(Until.newWindow(), storageHelper.TIMEOUT); 116 for (int i = 0; i < 2; ++i) { 117 Assert.assertTrue(mDevice.wait(Until.hasObject(By.res("android:id/title") 118 .text(String.format("Test_%d", i))), storageHelper.TIMEOUT)); 119 } 120 } 121 122 /** 123 * tests to ensure that resources on portable storage can be shared via UI 124 */ 125 @LargeTest testShareableFromPortable()126 public void testShareableFromPortable() throws InterruptedException { 127 ensureHasPortable(); 128 storageHelper.createFiles(2, 129 String.format("/storage/%s", storageHelper.getAdoptionVolumeUuid("public"))); 130 storageHelper.openSDCard(); 131 mDevice.wait(Until.findObject(By.res("android:id/title").text("Test_0")), 132 storageHelper.TIMEOUT).click(storageHelper.TIMEOUT); 133 mDevice.wait(Until.findObject(By.res("com.android.documentsui:id/menu_list")), 134 storageHelper.TIMEOUT).click(); 135 assertNotNull(mDevice.wait(Until.findObject(By.res("android:id/resolver_list")), 136 storageHelper.TIMEOUT)); 137 // click and ensure intent is sent to share? or actual share? 138 mDevice.pressBack(); 139 } 140 141 /** 142 * tests to ensure that portable overflow menu contain all setting options 143 */ 144 @LargeTest testPortableOverflowSettings()145 public void testPortableOverflowSettings() throws InterruptedException { 146 ensureHasPortable(); 147 storageHelper.createFiles(2, 148 String.format("/storage/%s", storageHelper.getAdoptionVolumeUuid("public"))); 149 storageHelper.openSDCard(); 150 mDevice.wait(Until.findObject(By.res("android:id/title").text("Test_0")), 151 storageHelper.TIMEOUT).click(storageHelper.TIMEOUT); 152 assertTrue(mDevice.wait(Until.hasObject(By.res(storageHelper.DOCUMENTS_PKG, "menu_search")), 153 storageHelper.TIMEOUT)); 154 assertTrue(mDevice.wait(Until.hasObject(By.res(storageHelper.DOCUMENTS_PKG, "menu_sort")), 155 storageHelper.TIMEOUT)); 156 assertTrue(mDevice.wait(Until.hasObject(By.text("1 selected")), storageHelper.TIMEOUT)); 157 } 158 159 /** 160 * tests to ensure that portable storage has setting options format, format as internal, eject 161 */ 162 @LargeTest testPortableSettings()163 public void testPortableSettings() throws InterruptedException { 164 ensureHasPortable(); 165 storageHelper.openSDCard(); 166 Pattern pattern = Pattern.compile("More options", Pattern.CASE_INSENSITIVE); 167 mDevice.wait(Until.findObject(By.desc(pattern)), storageHelper.TIMEOUT).click(); 168 pattern = Pattern.compile("Storage settings", Pattern.CASE_INSENSITIVE); 169 mDevice.wait(Until.findObject(By.text(pattern)), storageHelper.TIMEOUT) 170 .clickAndWait( 171 Until.newWindow(), storageHelper.TIMEOUT); 172 pattern = Pattern.compile("Eject", Pattern.CASE_INSENSITIVE); 173 assertTrue(mDevice.wait(Until.hasObject(By.text(pattern)), storageHelper.TIMEOUT)); 174 pattern = Pattern.compile("Format", Pattern.CASE_INSENSITIVE); 175 assertTrue(mDevice.wait(Until.hasObject(By.text(pattern)), storageHelper.TIMEOUT)); 176 pattern = Pattern.compile("Format as internal", Pattern.CASE_INSENSITIVE); 177 assertTrue(mDevice.wait(Until.hasObject(By.text(pattern)), 178 storageHelper.TIMEOUT)); 179 } 180 181 /** 182 * tests to ensure that portable storage can be ejected from settings 183 */ 184 @LargeTest testEjectPortable()185 public void testEjectPortable() throws InterruptedException { 186 ensureHasPortable(); 187 storageHelper.openStorageSettings(); 188 mDevice.wait(Until.findObject(By.res(storageHelper.SETTINGS_PKG, "unmount")), 189 storageHelper.TIMEOUT).click(); 190 assertTrue(mDevice.wait(Until.hasObject(By.res("android:id/summary").text("Ejected")), 191 4 * storageHelper.TIMEOUT)); 192 mDevice.wait(Until.findObject(By.textContains("SD card")), 2 * storageHelper.TIMEOUT) 193 .click(); 194 Pattern pattern = Pattern.compile("Mount", Pattern.CASE_INSENSITIVE); 195 mDevice.wait(Until.findObject(By.res("android:id/button1").text(pattern)), 196 2 * storageHelper.TIMEOUT).clickAndWait(Until.newWindow(), storageHelper.TIMEOUT); 197 ; 198 } 199 200 /** 201 * tests to ensure that portable storage can be erased and formated from settings 202 */ 203 @LargeTest testFormatPortable()204 public void testFormatPortable() throws InterruptedException { 205 ensureHasPortable(); 206 storageHelper.openSDCard(); 207 Pattern pattern = Pattern.compile("More options", Pattern.CASE_INSENSITIVE); 208 mDevice.wait(Until.findObject(By.desc(pattern)), storageHelper.TIMEOUT).click(); 209 pattern = Pattern.compile("Storage settings", Pattern.CASE_INSENSITIVE); 210 mDevice.wait(Until.findObject(By.text(pattern)), storageHelper.TIMEOUT) 211 .clickAndWait( 212 Until.newWindow(), storageHelper.TIMEOUT); 213 UiObject2 format = mDevice.wait(Until.findObject(By.text("Format")), storageHelper.TIMEOUT); 214 format.clickAndWait(Until.newWindow(), storageHelper.TIMEOUT); 215 pattern = Pattern.compile("Erase & Format", Pattern.CASE_INSENSITIVE); 216 mDevice.wait(Until.findObject(By.text(pattern)), storageHelper.TIMEOUT).click(); 217 pattern = Pattern.compile("Done", Pattern.CASE_INSENSITIVE); 218 mDevice.wait(Until.findObject(By.text(pattern)), 20 * storageHelper.TIMEOUT).click(); 219 } 220 221 /** 222 * tests to ensure that portable storage can be erased and formated as internal from settings 223 */ 224 @LargeTest testFormatPortableAsAdoptable()225 public void testFormatPortableAsAdoptable() throws InterruptedException { 226 try { 227 ensureHasPortable(); 228 storageHelper.openSDCard(); 229 Pattern pattern = Pattern.compile("More options", Pattern.CASE_INSENSITIVE); 230 mDevice.wait(Until.findObject(By.desc(pattern)), storageHelper.TIMEOUT).click(); 231 pattern = Pattern.compile("Storage settings", Pattern.CASE_INSENSITIVE); 232 mDevice.wait(Until.findObject(By.text(pattern)), storageHelper.TIMEOUT) 233 .clickAndWait( 234 Until.newWindow(), storageHelper.TIMEOUT); 235 pattern = Pattern.compile("Format", Pattern.CASE_INSENSITIVE); 236 assertTrue(mDevice.wait(Until.hasObject(By.text(pattern)), storageHelper.TIMEOUT)); 237 pattern = Pattern.compile("Format as internal", Pattern.CASE_INSENSITIVE); 238 assertTrue(mDevice.wait(Until.hasObject(By.text(pattern)), 239 storageHelper.TIMEOUT)); 240 // Next flow is same as adoption, so no need to test 241 } finally { 242 storageHelper.partitionDisk("public"); 243 } 244 } 245 ensureHasPortable()246 private void ensureHasPortable() throws InterruptedException { 247 storageHelper.partitionDisk("public"); 248 storageHelper.settingsUiCleanUp(); 249 } 250 251 @Override tearDown()252 protected void tearDown() throws Exception { 253 mDevice.unfreezeRotation(); 254 mDevice.pressBack(); 255 mDevice.pressHome(); 256 super.tearDown(); 257 } 258 } 259