1 /* 2 * Copyright (C) 2015 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.appsecurity.cts; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNotNull; 22 import static org.junit.Assert.assertNull; 23 import static org.junit.Assert.assertTrue; 24 25 import android.platform.test.annotations.Presubmit; 26 27 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; 28 import com.android.ddmlib.Log; 29 import com.android.tradefed.device.DeviceNotAvailableException; 30 import com.android.tradefed.device.ITestDevice; 31 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; 32 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; 33 import com.android.tradefed.util.AbiUtils; 34 import com.android.tradefed.util.RunUtil; 35 36 import org.junit.After; 37 import org.junit.Assume; 38 import org.junit.Before; 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 42 import java.io.File; 43 import java.io.FileNotFoundException; 44 import java.util.ArrayList; 45 import java.util.List; 46 47 /** 48 * Set of tests that verify behavior of external storage devices. 49 */ 50 @Presubmit 51 @RunWith(DeviceJUnit4ClassRunner.class) 52 public class ExternalStorageHostTest extends BaseHostJUnit4Test { 53 private static final String TAG = "ExternalStorageHostTest"; 54 55 private static class Config { 56 public final String apk; 57 public final String pkg; 58 public final String clazz; 59 Config(String apk, String pkg, String clazz)60 public Config(String apk, String pkg, String clazz) { 61 this.apk = apk; 62 this.pkg = pkg; 63 this.clazz = clazz; 64 } 65 } 66 67 private static final String COMMON_CLASS = 68 "com.android.cts.externalstorageapp.CommonExternalStorageTest"; 69 70 private static final String NONE_APK = "CtsExternalStorageApp.apk"; 71 private static final String NONE_PKG = "com.android.cts.externalstorageapp"; 72 private static final String NONE_CLASS = NONE_PKG + ".ExternalStorageTest"; 73 private static final String READ_APK = "CtsReadExternalStorageApp.apk"; 74 private static final String READ_PKG = "com.android.cts.readexternalstorageapp"; 75 private static final String READ_CLASS = READ_PKG + ".ReadExternalStorageTest"; 76 private static final String WRITE_APK = "CtsWriteExternalStorageApp.apk"; 77 private static final String WRITE_PKG = "com.android.cts.writeexternalstorageapp"; 78 private static final String WRITE_CLASS = WRITE_PKG + ".WriteExternalStorageTest"; 79 private static final String WRITE_APK_2 = "CtsWriteExternalStorageApp2.apk"; 80 private static final String WRITE_PKG_2 = "com.android.cts.writeexternalstorageapp2"; 81 private static final String MULTIUSER_APK = "CtsMultiUserStorageApp.apk"; 82 private static final String MULTIUSER_PKG = "com.android.cts.multiuserstorageapp"; 83 private static final String MULTIUSER_CLASS = MULTIUSER_PKG + ".MultiUserStorageTest"; 84 85 private static final String MEDIA_CLAZZ = "com.android.cts.mediastorageapp.MediaStorageTest"; 86 87 private static final Config MEDIA = new Config("CtsMediaStorageApp.apk", 88 "com.android.cts.mediastorageapp", MEDIA_CLAZZ); 89 private static final Config MEDIA_28 = new Config("CtsMediaStorageApp28.apk", 90 "com.android.cts.mediastorageapp28", MEDIA_CLAZZ); 91 private static final Config MEDIA_29 = new Config("CtsMediaStorageApp29.apk", 92 "com.android.cts.mediastorageapp29", MEDIA_CLAZZ); 93 private static final Config MEDIA_31 = new Config("CtsMediaStorageApp31.apk", 94 "com.android.cts.mediastorageapp31", MEDIA_CLAZZ); 95 96 private static final String PERM_ACCESS_MEDIA_LOCATION = 97 "android.permission.ACCESS_MEDIA_LOCATION"; 98 private static final String PERM_READ_EXTERNAL_STORAGE = 99 "android.permission.READ_EXTERNAL_STORAGE"; 100 private static final String PERM_READ_MEDIA_IMAGES = 101 "android.permission.READ_MEDIA_IMAGES"; 102 private static final String PERM_READ_MEDIA_AUDIO = 103 "android.permission.READ_MEDIA_AUDIO"; 104 private static final String PERM_READ_MEDIA_VIDEO = 105 "android.permission.READ_MEDIA_VIDEO"; 106 private static final String PERM_READ_MEDIA_VISUAL_USER_SELECTED = 107 "android.permission.READ_MEDIA_VISUAL_USER_SELECTED"; 108 private static final String PERM_WRITE_EXTERNAL_STORAGE = 109 "android.permission.WRITE_EXTERNAL_STORAGE"; 110 111 private static final String APP_OPS_MANAGE_EXTERNAL_STORAGE = "android:manage_external_storage"; 112 private static final String APP_OPS_MANAGE_MEDIA = "android:manage_media"; 113 114 /** Copied from PackageManager*/ 115 private static final String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive"; 116 private static final String FEATURE_EMBEDDED = "android.hardware.type.embedded"; 117 private static final String FEATURE_LEANBACK_ONLY = "android.software.leanback_only"; 118 private static final String FEATURE_WATCH = "android.hardware.type.watch"; 119 120 private int[] mUsers; 121 private boolean mAdbWasRoot; 122 getTestAppFile(String fileName)123 private File getTestAppFile(String fileName) throws FileNotFoundException { 124 CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild()); 125 return buildHelper.getTestFile(fileName); 126 } 127 128 @Before setUp()129 public void setUp() throws Exception { 130 mUsers = Utils.prepareMultipleUsers(getDevice()); 131 assertNotNull(getAbi()); 132 assertNotNull(getBuild()); 133 134 ITestDevice device = getDevice(); 135 mAdbWasRoot = device.isAdbRoot(); 136 if (mAdbWasRoot) { 137 // This test assumes that the test is not run with root privileges. But this test runs 138 // as a part of appsecurity test suite which contains a lot of other tests. Some of 139 // which may enable adb root, make sure that this test is run without root access. 140 device.disableAdbRoot(); 141 assertFalse("adb root is enabled", device.isAdbRoot()); 142 } 143 } 144 145 @Before 146 @After cleanUp()147 public void cleanUp() throws DeviceNotAvailableException { 148 getDevice().uninstallPackage(NONE_PKG); 149 getDevice().uninstallPackage(READ_PKG); 150 getDevice().uninstallPackage(WRITE_PKG); 151 getDevice().uninstallPackage(MULTIUSER_PKG); 152 153 wipePrimaryExternalStorage(); 154 } 155 156 @After tearDown()157 public void tearDown() throws DeviceNotAvailableException { 158 ITestDevice device = getDevice(); 159 if (mAdbWasRoot) { 160 device.enableAdbRoot(); 161 } else { 162 device.disableAdbRoot(); 163 } 164 } 165 166 @Test testExternalStorageRename()167 public void testExternalStorageRename() throws Exception { 168 try { 169 wipePrimaryExternalStorage(); 170 171 getDevice().uninstallPackage(WRITE_PKG); 172 installPackage(WRITE_APK); 173 174 // Make sure user initialization is complete before testing 175 waitForBroadcastIdle(); 176 177 for (int user : mUsers) { 178 runDeviceTests(WRITE_PKG, WRITE_CLASS, "testExternalStorageRename", user); 179 } 180 } finally { 181 getDevice().uninstallPackage(WRITE_PKG); 182 } 183 } 184 185 /** 186 * Verify that app with no external storage permissions works correctly. 187 */ 188 @Test testExternalStorageNone29()189 public void testExternalStorageNone29() throws Exception { 190 try { 191 wipePrimaryExternalStorage(); 192 193 getDevice().uninstallPackage(NONE_PKG); 194 String[] options = {AbiUtils.createAbiFlag(getAbi().getName())}; 195 assertNull(getDevice().installPackage(getTestAppFile(NONE_APK), false, options)); 196 197 for (int user : mUsers) { 198 runDeviceTests(NONE_PKG, COMMON_CLASS, user); 199 runDeviceTests(NONE_PKG, NONE_CLASS, user); 200 } 201 } finally { 202 getDevice().uninstallPackage(NONE_PKG); 203 } 204 } 205 206 /** 207 * Verify that app with 208 * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} works 209 * correctly. 210 */ 211 @Test testExternalStorageRead29()212 public void testExternalStorageRead29() throws Exception { 213 try { 214 wipePrimaryExternalStorage(); 215 216 getDevice().uninstallPackage(READ_PKG); 217 String[] options = {AbiUtils.createAbiFlag(getAbi().getName())}; 218 assertNull(getDevice().installPackage(getTestAppFile(READ_APK), false, options)); 219 220 for (int user : mUsers) { 221 runDeviceTests(READ_PKG, COMMON_CLASS, user); 222 runDeviceTests(READ_PKG, READ_CLASS, user); 223 } 224 } finally { 225 getDevice().uninstallPackage(READ_PKG); 226 } 227 } 228 229 /** 230 * Verify that app with 231 * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} works 232 * correctly. 233 */ 234 @Test testExternalStorageWrite()235 public void testExternalStorageWrite() throws Exception { 236 try { 237 wipePrimaryExternalStorage(); 238 239 getDevice().uninstallPackage(WRITE_PKG); 240 String[] options = {AbiUtils.createAbiFlag(getAbi().getName())}; 241 assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK), false, options)); 242 243 for (int user : mUsers) { 244 runDeviceTests(WRITE_PKG, COMMON_CLASS, user); 245 runDeviceTests(WRITE_PKG, WRITE_CLASS, user); 246 } 247 } finally { 248 getDevice().uninstallPackage(WRITE_PKG); 249 } 250 } 251 252 /** 253 * Verify that apps can't leave gifts in package specific external storage 254 * directories belonging to other apps. Apps can only create files in their 255 * external storage directories. 256 */ 257 @Test testExternalStorageNoGifts()258 public void testExternalStorageNoGifts() throws Exception { 259 try { 260 wipePrimaryExternalStorage(); 261 262 getDevice().uninstallPackage(NONE_PKG); 263 getDevice().uninstallPackage(READ_PKG); 264 getDevice().uninstallPackage(WRITE_PKG); 265 final String[] options = {AbiUtils.createAbiFlag(getAbi().getName())}; 266 267 assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK), false, options)); 268 assertNull(getDevice().installPackage(getTestAppFile(NONE_APK), false, options)); 269 assertNull(getDevice().installPackage(getTestAppFile(READ_APK), false, options)); 270 for (int user : mUsers) { 271 runDeviceTests(NONE_PKG, NONE_PKG + ".GiftTest", "testStageNonGifts", user); 272 runDeviceTests(READ_PKG, READ_PKG + ".ReadGiftTest", "testStageNonGifts", user); 273 runDeviceTests(WRITE_PKG, WRITE_PKG + ".WriteGiftTest", "testStageNonGifts", user); 274 275 runDeviceTests(NONE_PKG, NONE_PKG + ".GiftTest", "testNoGifts", user); 276 runDeviceTests(READ_PKG, READ_PKG + ".ReadGiftTest", "testNoGifts", user); 277 runDeviceTests(WRITE_PKG, WRITE_PKG + ".WriteGiftTest", "testNoGifts", user); 278 } 279 } finally { 280 getDevice().uninstallPackage(NONE_PKG); 281 getDevice().uninstallPackage(READ_PKG); 282 getDevice().uninstallPackage(WRITE_PKG); 283 } 284 } 285 286 /** 287 * Verify that app with REQUEST_INSTALL_PACKAGES can leave gifts in obb 288 * directories belonging to other apps, and those apps can read. 289 */ 290 @Test testCanAccessOtherObbDirs()291 public void testCanAccessOtherObbDirs() throws Exception { 292 try { 293 wipePrimaryExternalStorage(); 294 295 getDevice().uninstallPackage(WRITE_PKG_2); 296 getDevice().uninstallPackage(NONE_PKG); 297 final String[] options = {AbiUtils.createAbiFlag(getAbi().getName())}; 298 299 // We purposefully delay the installation of the reading apps to 300 // verify that the daemon correctly invalidates any caches. 301 assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK_2), false, options)); 302 for (int user : mUsers) { 303 updateAppOp(WRITE_PKG_2, user, "android:request_install_packages", true); 304 updatePermissions(WRITE_PKG_2, user, new String[] { 305 PERM_READ_MEDIA_IMAGES, 306 PERM_READ_MEDIA_VIDEO, 307 PERM_READ_MEDIA_AUDIO, 308 PERM_READ_EXTERNAL_STORAGE, 309 PERM_WRITE_EXTERNAL_STORAGE, 310 }, true); 311 } 312 313 for (int user : mUsers) { 314 runDeviceTests(WRITE_PKG_2, WRITE_PKG + ".WriteGiftTest", "testObbGifts", user); 315 } 316 317 assertNull(getDevice().installPackage(getTestAppFile(NONE_APK), false, options)); 318 for (int user : mUsers) { 319 runDeviceTests(NONE_PKG, NONE_PKG + ".GiftTest", "testObbGifts", user); 320 } 321 322 for (int user : mUsers) { 323 runDeviceTests(WRITE_PKG_2, WRITE_PKG + ".WriteGiftTest", 324 "testAccessObbGifts", user); 325 updateAppOp(WRITE_PKG_2, user, "android:request_install_packages", false); 326 runDeviceTests(WRITE_PKG_2, WRITE_PKG + ".WriteGiftTest", 327 "testCantAccessObbGifts", user); 328 } 329 } finally { 330 getDevice().uninstallPackage(WRITE_PKG_2); 331 getDevice().uninstallPackage(NONE_PKG); 332 } 333 } 334 335 @Test testExternalStorageUnsharedObb()336 public void testExternalStorageUnsharedObb() throws Exception { 337 final int numUsers = mUsers.length; 338 Assume.assumeTrue(numUsers > 1); 339 340 try { 341 wipePrimaryExternalStorage(); 342 343 getDevice().uninstallPackage(NONE_PKG); 344 getDevice().uninstallPackage(WRITE_PKG); 345 final String[] options = {AbiUtils.createAbiFlag(getAbi().getName())}; 346 347 // We purposefully delay the installation of the reading apps to 348 // verify that the daemon correctly invalidates any caches. 349 assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK), false, options)); 350 updateAppOp(WRITE_PKG, mUsers[0], "android:request_install_packages", true); 351 runDeviceTests(WRITE_PKG, WRITE_PKG + ".WriteGiftTest", "testObbGifts", mUsers[0]); 352 353 // Create a file in one user and verify that file is not accessible to other users. 354 assertNull(getDevice().installPackage(getTestAppFile(NONE_APK), false, options)); 355 for (int i = 1; i < numUsers; ++i) { 356 runDeviceTests(NONE_PKG, NONE_PKG + ".GiftTest", "testNoObbGifts", mUsers[i]); 357 updateAppOp(WRITE_PKG, mUsers[i], "android:request_install_packages", true); 358 runDeviceTests(WRITE_PKG, WRITE_PKG + ".WriteGiftTest", "testObbGifts", mUsers[i]); 359 } 360 361 // Delete a file in one user and verify that it doesn't affect files accessible to 362 // other users. 363 runDeviceTests(NONE_PKG, NONE_PKG + ".GiftTest", "testRemoveObbGifts", mUsers[0]); 364 for (int i = 1; i < numUsers; ++i) { 365 runDeviceTests(NONE_PKG, NONE_PKG + ".GiftTest", "testObbGifts", mUsers[i]); 366 } 367 368 } finally { 369 getDevice().uninstallPackage(NONE_PKG); 370 getDevice().uninstallPackage(WRITE_PKG); 371 } 372 } 373 374 /** 375 * Test multi-user emulated storage environment, ensuring that each user has 376 * isolated storage. 377 */ 378 @Test testMultiUserStorageIsolated()379 public void testMultiUserStorageIsolated() throws Exception { 380 try { 381 if (mUsers.length == 1) { 382 Log.d(TAG, "Single user device; skipping isolated storage tests"); 383 return; 384 } 385 386 final int owner = mUsers[0]; 387 final int secondary = mUsers[1]; 388 389 // Install our test app 390 getDevice().uninstallPackage(MULTIUSER_PKG); 391 String[] options = {AbiUtils.createAbiFlag(getAbi().getName())}; 392 final String installResult = getDevice() 393 .installPackage(getTestAppFile(MULTIUSER_APK), false, options); 394 assertNull("Failed to install: " + installResult, installResult); 395 396 // Clear data from previous tests 397 runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testCleanIsolatedStorage", owner); 398 runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testCleanIsolatedStorage", secondary); 399 400 // Have both users try writing into isolated storage 401 runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testWriteIsolatedStorage", owner); 402 runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testWriteIsolatedStorage", secondary); 403 404 // Verify they both have isolated view of storage 405 runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testReadIsolatedStorage", owner); 406 runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testReadIsolatedStorage", secondary); 407 408 // Verify they can't poke at each other 409 runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testUserIsolation", owner); 410 runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testUserIsolation", secondary); 411 412 // Verify they can't access other users' content using media provider 413 runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testMediaProviderUserIsolation", owner); 414 runDeviceTests( 415 MULTIUSER_PKG, MULTIUSER_CLASS, "testMediaProviderUserIsolation", secondary); 416 } finally { 417 getDevice().uninstallPackage(MULTIUSER_PKG); 418 } 419 } 420 421 /** 422 * Test that apps with read permissions see the appropriate permissions. 423 */ 424 @Test testMultiViewMoveConsistency()425 public void testMultiViewMoveConsistency() throws Exception { 426 try { 427 wipePrimaryExternalStorage(); 428 429 getDevice().uninstallPackage(NONE_PKG); 430 getDevice().uninstallPackage(READ_PKG); 431 final String[] options = {AbiUtils.createAbiFlag(getAbi().getName())}; 432 433 assertNull(getDevice().installPackage(getTestAppFile(READ_APK), false, options)); 434 435 for (int user : mUsers) { 436 runDeviceTests(READ_PKG, READ_PKG + ".ReadMultiViewTest", "testFolderSetup", user); 437 } 438 for (int user : mUsers) { 439 runDeviceTests(READ_PKG, READ_PKG + ".ReadMultiViewTest", "testRWAccess", user); 440 } 441 442 // for fuse file system 443 RunUtil.getDefault().sleep(10000); 444 for (int user : mUsers) { 445 runDeviceTests(READ_PKG, READ_PKG + ".ReadMultiViewTest", "testRWAccess", user); 446 } 447 } finally { 448 getDevice().uninstallPackage(NONE_PKG); 449 getDevice().uninstallPackage(READ_PKG); 450 } 451 } 452 453 /** Verify that app without READ_EXTERNAL can play default URIs in external storage. */ 454 @Test testExternalStorageReadDefaultUris()455 public void testExternalStorageReadDefaultUris() throws Exception { 456 Throwable existingException = null; 457 try { 458 wipePrimaryExternalStorage(); 459 460 getDevice().uninstallPackage(NONE_PKG); 461 getDevice().uninstallPackage(WRITE_PKG); 462 final String[] options = {AbiUtils.createAbiFlag(getAbi().getName())}; 463 464 assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK), false, options)); 465 assertNull(getDevice().installPackage(getTestAppFile(NONE_APK), false, options)); 466 467 for (int user : mUsers) { 468 updateAppOp(WRITE_PKG, user, "android:write_settings", true); 469 runDeviceTests( 470 WRITE_PKG, WRITE_PKG + ".ChangeDefaultUris", "testChangeDefaultUris", user); 471 472 runDeviceTests( 473 NONE_PKG, NONE_PKG + ".ReadDefaultUris", "testPlayDefaultUris", user); 474 } 475 } catch (Throwable t) { 476 Log.e(TAG, "Test exception: " + t); 477 // Don't rethrow if there is already an exception. 478 if (existingException == null) { 479 existingException = t; 480 throw t; 481 } 482 } finally { 483 try { 484 // Make sure the provider and uris are reset on failure. 485 for (int user : mUsers) { 486 runDeviceTests( 487 WRITE_PKG, WRITE_PKG + ".ChangeDefaultUris", "testResetDefaultUris", 488 user); 489 } 490 getDevice().uninstallPackage(NONE_PKG); 491 getDevice().uninstallPackage(WRITE_PKG); 492 } catch (Throwable t) { 493 Log.e(TAG, "Cleanup exception: " + t); 494 // Don't rethrow if there is already an exception. 495 if (existingException == null) { 496 existingException = t; 497 throw t; 498 } 499 } 500 } 501 } 502 503 /** 504 * For security reasons, the shell user cannot access the shared storage of 505 * secondary users. Instead, developers should use the {@code content} shell 506 * tool to read/write files in those locations. 507 */ 508 @Test testSecondaryUsersInaccessible()509 public void testSecondaryUsersInaccessible() throws Exception { 510 List<String> mounts = new ArrayList<>(); 511 for (String line : getDevice().executeShellCommand("cat /proc/mounts").split("\n")) { 512 String[] split = line.split(" "); 513 if (split[1].startsWith("/storage/") || split[1].startsWith("/mnt/")) { 514 mounts.add(split[1]); 515 } 516 } 517 518 for (int user : mUsers) { 519 String probe = "/sdcard/../" + user; 520 if (user == Utils.USER_SYSTEM) { 521 // Primary user should always be visible. Skip checking raw 522 // mount points, since we'd get false-positives for physical 523 // devices that aren't multi-user aware. 524 assertTrue(probe, access(probe)); 525 } else { 526 // Secondary user should never be visible. 527 assertFalse(probe, access(probe)); 528 for (String mount : mounts) { 529 probe = mount + "/" + user; 530 assertFalse(probe, access(probe)); 531 } 532 } 533 } 534 } 535 536 @Test testMediaLegacy28()537 public void testMediaLegacy28() throws Exception { 538 doMediaLegacy(MEDIA_28); 539 } 540 @Test testMediaLegacy29()541 public void testMediaLegacy29() throws Exception { 542 doMediaLegacy(MEDIA_29); 543 } 544 doMediaLegacy(Config config)545 private void doMediaLegacy(Config config) throws Exception { 546 installPackage(config.apk); 547 installPackage(MEDIA_29.apk); 548 // Make sure user initialization is complete before updating permission 549 waitForBroadcastIdle(); 550 for (int user : mUsers) { 551 updatePermissions(config.pkg, user, new String[] { 552 PERM_READ_MEDIA_IMAGES, 553 PERM_READ_MEDIA_VIDEO, 554 PERM_READ_MEDIA_AUDIO, 555 PERM_READ_EXTERNAL_STORAGE, 556 PERM_WRITE_EXTERNAL_STORAGE, 557 }, true); 558 updatePermissions(MEDIA_29.pkg, user, new String[] { 559 PERM_READ_EXTERNAL_STORAGE, 560 PERM_WRITE_EXTERNAL_STORAGE, 561 }, true); 562 563 // Create the files needed for the test from MEDIA_29 pkg since shell 564 // can't access secondary user's storage. 565 runDeviceTests(MEDIA_29.pkg, MEDIA_29.clazz, "testStageFiles", user); 566 runDeviceTests(config.pkg, config.clazz, "testLegacy", user); 567 runDeviceTests(MEDIA_29.pkg, MEDIA_29.clazz, "testClearFiles", user); 568 } 569 } 570 571 /** 572 * b/197302116. The apps can't be granted prefix UriPermissions to the uri, when the query 573 * result of the uri is 1. 574 */ 575 @Test testOwningOneFileNotGrantPrefixUriPermission()576 public void testOwningOneFileNotGrantPrefixUriPermission() throws Exception { 577 installPackage(MEDIA.apk); 578 579 int user = getDevice().getCurrentUser(); 580 581 // revoke permissions 582 updatePermissions(MEDIA.pkg, user, new String[] { 583 PERM_READ_MEDIA_IMAGES, 584 PERM_READ_MEDIA_VIDEO, 585 PERM_READ_MEDIA_AUDIO, 586 PERM_READ_EXTERNAL_STORAGE, 587 PERM_WRITE_EXTERNAL_STORAGE, 588 }, false); 589 590 591 // revoke the app ops permission 592 updateAppOp(MEDIA.pkg, user, APP_OPS_MANAGE_EXTERNAL_STORAGE, false); 593 594 runDeviceTests(MEDIA.pkg, MEDIA.clazz, 595 "testOwningOneFileNotGrantPrefixUriPermission", user); 596 } 597 598 /** 599 * If the app grants read UriPermission to the uri without id (E.g. 600 * MediaStore.Audio.Media.EXTERNAL_CONTENT_URI), the query result of the uri should be the same 601 * without granting permission. 602 */ 603 @Test testReadUriPermissionOnUriWithoutId_sameQueryResult()604 public void testReadUriPermissionOnUriWithoutId_sameQueryResult() throws Exception { 605 installPackage(MEDIA.apk); 606 607 int user = getDevice().getCurrentUser(); 608 609 // revoke permissions 610 updatePermissions(MEDIA.pkg, user, new String[] { 611 PERM_READ_MEDIA_IMAGES, 612 PERM_READ_MEDIA_VIDEO, 613 PERM_READ_MEDIA_AUDIO, 614 PERM_READ_EXTERNAL_STORAGE, 615 PERM_WRITE_EXTERNAL_STORAGE, 616 }, false); 617 618 619 // revoke the app ops permission 620 updateAppOp(MEDIA.pkg, user, APP_OPS_MANAGE_EXTERNAL_STORAGE, false); 621 622 runDeviceTests(MEDIA.pkg, MEDIA.clazz, 623 "testReadUriPermissionOnUriWithoutId_sameQueryResult", user); 624 } 625 626 @Test testGrantUriPermission()627 public void testGrantUriPermission() throws Exception { 628 doGrantUriPermission(MEDIA, "testGrantUriPermission", new String[]{}); 629 doGrantUriPermission(MEDIA, "testGrantUriPermission", 630 new String[]{PERM_READ_MEDIA_IMAGES, PERM_READ_MEDIA_VIDEO, 631 PERM_READ_MEDIA_AUDIO, PERM_READ_EXTERNAL_STORAGE}); 632 doGrantUriPermission(MEDIA, "testGrantUriPermission", 633 new String[]{PERM_READ_EXTERNAL_STORAGE, PERM_READ_MEDIA_IMAGES, 634 PERM_READ_MEDIA_VIDEO, PERM_READ_MEDIA_AUDIO, PERM_WRITE_EXTERNAL_STORAGE}); 635 } 636 637 @Test testGrantUriPermission29()638 public void testGrantUriPermission29() throws Exception { 639 doGrantUriPermission(MEDIA_29, "testGrantUriPermission", new String[]{}); 640 doGrantUriPermission(MEDIA_29, "testGrantUriPermission", 641 new String[]{PERM_READ_EXTERNAL_STORAGE}); 642 doGrantUriPermission(MEDIA_29, "testGrantUriPermission", 643 new String[]{PERM_READ_EXTERNAL_STORAGE, PERM_WRITE_EXTERNAL_STORAGE}); 644 } 645 doGrantUriPermission(Config config, String method, String[] grantPermissions)646 private void doGrantUriPermission(Config config, String method, String[] grantPermissions) 647 throws Exception { 648 uninstallPackage(config.apk); 649 installPackage(config.apk); 650 for (int user : mUsers) { 651 // Over revoke all permissions and grant necessary permissions later. 652 updatePermissions(config.pkg, user, new String[] { 653 PERM_READ_MEDIA_IMAGES, 654 PERM_READ_MEDIA_VIDEO, 655 PERM_READ_MEDIA_AUDIO, 656 PERM_READ_EXTERNAL_STORAGE, 657 PERM_WRITE_EXTERNAL_STORAGE, 658 }, false); 659 updatePermissions(config.pkg, user, grantPermissions, true); 660 runDeviceTests(config.pkg, config.clazz, method, user); 661 } 662 } 663 664 @Test testMediaNone()665 public void testMediaNone() throws Exception { 666 doMediaNone(MEDIA); 667 } 668 @Test testMediaNone28()669 public void testMediaNone28() throws Exception { 670 doMediaNone(MEDIA_28); 671 } 672 @Test testMediaNone29()673 public void testMediaNone29() throws Exception { 674 doMediaNone(MEDIA_29); 675 } 676 doMediaNone(Config config)677 private void doMediaNone(Config config) throws Exception { 678 installPackage(config.apk); 679 for (int user : mUsers) { 680 updatePermissions(config.pkg, user, new String[] { 681 PERM_READ_MEDIA_IMAGES, 682 PERM_READ_MEDIA_VIDEO, 683 PERM_READ_MEDIA_AUDIO, 684 PERM_READ_EXTERNAL_STORAGE, 685 PERM_WRITE_EXTERNAL_STORAGE, 686 }, false); 687 688 runDeviceTests(config.pkg, config.clazz, "testMediaNone", user); 689 } 690 } 691 692 @Test testMediaRead()693 public void testMediaRead() throws Exception { 694 doMediaRead(MEDIA); 695 } 696 @Test testMediaRead28()697 public void testMediaRead28() throws Exception { 698 doMediaRead(MEDIA_28); 699 } 700 @Test testMediaRead29()701 public void testMediaRead29() throws Exception { 702 doMediaRead(MEDIA_29); 703 } 704 doMediaRead(Config config)705 private void doMediaRead(Config config) throws Exception { 706 installPackage(config.apk); 707 for (int user : mUsers) { 708 updatePermissions(config.pkg, user, new String[] { 709 PERM_READ_MEDIA_IMAGES, 710 PERM_READ_MEDIA_VIDEO, 711 PERM_READ_MEDIA_AUDIO, 712 PERM_READ_EXTERNAL_STORAGE, 713 }, true); 714 updatePermissions(config.pkg, user, new String[] { 715 PERM_WRITE_EXTERNAL_STORAGE, 716 }, false); 717 718 runDeviceTests(config.pkg, config.clazz, "testMediaRead", user); 719 } 720 } 721 722 @Test testMediaWrite()723 public void testMediaWrite() throws Exception { 724 doMediaWrite(MEDIA); 725 } 726 @Test testMediaWrite28()727 public void testMediaWrite28() throws Exception { 728 doMediaWrite(MEDIA_28); 729 } 730 @Test testMediaWrite29()731 public void testMediaWrite29() throws Exception { 732 doMediaWrite(MEDIA_29); 733 } 734 doMediaWrite(Config config)735 private void doMediaWrite(Config config) throws Exception { 736 installPackage(config.apk); 737 for (int user : mUsers) { 738 updatePermissions(config.pkg, user, new String[] { 739 PERM_READ_MEDIA_IMAGES, 740 PERM_READ_MEDIA_VIDEO, 741 PERM_READ_MEDIA_AUDIO, 742 PERM_READ_EXTERNAL_STORAGE, 743 PERM_WRITE_EXTERNAL_STORAGE, 744 }, true); 745 746 runDeviceTests(config.pkg, config.clazz, "testMediaWrite", user); 747 } 748 } 749 750 @Test testMediaEscalation_RequestWriteFilePathSupport()751 public void testMediaEscalation_RequestWriteFilePathSupport() throws Exception { 752 // Not adding tests for MEDIA_28 and MEDIA_29 as they need W_E_S for write access via file 753 // path for shared files, and will always have access as they have W_E_S. 754 installPackage(MEDIA.apk); 755 756 int user = getDevice().getCurrentUser(); 757 // revoke all permissions 758 updatePermissions(MEDIA.pkg, user, new String[] { 759 PERM_ACCESS_MEDIA_LOCATION, 760 PERM_READ_MEDIA_IMAGES, 761 PERM_READ_MEDIA_VIDEO, 762 PERM_READ_MEDIA_AUDIO, 763 PERM_READ_EXTERNAL_STORAGE, 764 PERM_WRITE_EXTERNAL_STORAGE, 765 }, false); 766 767 // revoke the app ops permission 768 updateAppOp(MEDIA.pkg, user, APP_OPS_MANAGE_MEDIA, false); 769 updateAppOp(MEDIA.pkg, user, APP_OPS_MANAGE_EXTERNAL_STORAGE, false); 770 771 runDeviceTests(MEDIA.pkg, MEDIA.clazz, "testMediaEscalation_RequestWriteFilePathSupport", 772 user); 773 } 774 775 @Test testMediaEscalation()776 public void testMediaEscalation() throws Exception { 777 doMediaEscalation(MEDIA); 778 } 779 @Test testMediaEscalation28()780 public void testMediaEscalation28() throws Exception { 781 doMediaEscalation(MEDIA_28); 782 } 783 @Test testMediaEscalation29()784 public void testMediaEscalation29() throws Exception { 785 doMediaEscalation(MEDIA_29); 786 } 787 doMediaEscalation(Config config)788 private void doMediaEscalation(Config config) throws Exception { 789 installPackage(config.apk); 790 791 // TODO: extend test to exercise secondary users 792 int user = getDevice().getCurrentUser(); 793 updatePermissions(config.pkg, user, new String[] { 794 PERM_READ_MEDIA_IMAGES, 795 PERM_READ_MEDIA_VIDEO, 796 PERM_READ_MEDIA_AUDIO, 797 PERM_READ_EXTERNAL_STORAGE, 798 }, true); 799 updatePermissions(config.pkg, user, new String[] { 800 PERM_WRITE_EXTERNAL_STORAGE, 801 }, false); 802 803 runDeviceTests(config.pkg, config.clazz, "testMediaEscalation_Open", user); 804 runDeviceTests(config.pkg, config.clazz, "testMediaEscalation_Update", user); 805 runDeviceTests(config.pkg, config.clazz, "testMediaEscalation_Delete", user); 806 807 runDeviceTests(config.pkg, config.clazz, "testMediaEscalation_RequestWrite", user); 808 runDeviceTests(config.pkg, config.clazz, "testMediaEscalation_RequestTrash", user); 809 runDeviceTests(config.pkg, config.clazz, "testMediaEscalation_RequestFavorite", user); 810 runDeviceTests(config.pkg, config.clazz, "testMediaEscalation_RequestDelete", user); 811 } 812 813 @Test testExternalStorageClearing()814 public void testExternalStorageClearing() throws Exception { 815 String[] options = {AbiUtils.createAbiFlag(getAbi().getName())}; 816 817 try { 818 getDevice().uninstallPackage(WRITE_PKG); 819 assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK), false, options)); 820 for (int user : mUsers) { 821 runDeviceTests(WRITE_PKG, WRITE_PKG + ".WriteGiftTest", "testClearingWrite", user); 822 } 823 824 // Uninstall and reinstall means all storage should be cleared 825 getDevice().uninstallPackage(WRITE_PKG); 826 assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK), false, options)); 827 for (int user : mUsers) { 828 runDeviceTests(WRITE_PKG, WRITE_PKG + ".WriteGiftTest", "testClearingRead", user); 829 } 830 } finally { 831 getDevice().uninstallPackage(WRITE_PKG); 832 } 833 } 834 835 @Test testIsExternalStorageLegacy()836 public void testIsExternalStorageLegacy() throws Exception { 837 String[] options = {AbiUtils.createAbiFlag(getAbi().getName())}; 838 839 try { 840 getDevice().uninstallPackage(WRITE_PKG); 841 getDevice().uninstallPackage(WRITE_PKG_2); 842 assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK), false, options)); 843 assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK_2), false, options)); 844 for (int user : mUsers) { 845 runDeviceTests(WRITE_PKG, WRITE_PKG + ".WriteGiftTest", 846 "testIsExternalStorageLegacy", user); 847 updatePermissions(WRITE_PKG, user, new String[] { 848 PERM_READ_EXTERNAL_STORAGE, 849 PERM_WRITE_EXTERNAL_STORAGE, 850 }, false); 851 runDeviceTests(WRITE_PKG, WRITE_PKG + ".WriteGiftTest", 852 "testIsExternalStorageLegacy", user); 853 854 runDeviceTests(WRITE_PKG_2, WRITE_PKG + ".WriteGiftTest", 855 "testNotIsExternalStorageLegacy", user); 856 } 857 } finally { 858 getDevice().uninstallPackage(WRITE_PKG); 859 getDevice().uninstallPackage(WRITE_PKG_2); 860 } 861 } 862 863 /** 864 * Check the behavior when the app calls MediaStore#createTrashRequest, 865 * MediaStore#createDeleteRequest or MediaStore#createWriteRequest, the user 866 * click the deny button on confirmation dialog. 867 * 868 * @throws Exception 869 */ 870 @Test testCreateRequest_userDenied()871 public void testCreateRequest_userDenied() throws Exception { 872 installPackage(MEDIA.apk); 873 874 int user = getDevice().getCurrentUser(); 875 876 runDeviceTests(MEDIA.pkg, MEDIA.clazz, 877 "testMediaEscalationWithDenied_RequestWrite", user); 878 runDeviceTests(MEDIA.pkg, MEDIA.clazz, 879 "testMediaEscalationWithDenied_RequestDelete", user); 880 runDeviceTests(MEDIA.pkg, MEDIA.clazz, 881 "testMediaEscalationWithDenied_RequestTrash", user); 882 runDeviceTests(MEDIA.pkg, MEDIA.clazz, 883 "testMediaEscalationWithDenied_RequestUnTrash", user); 884 } 885 886 /** 887 * If the app is NOT granted {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} 888 * and {@link android.Manifest.permission#MANAGE_EXTERNAL_STORAGE} 889 * when it calls MediaStore#createTrashRequest, 890 * MediaStore#createDeleteRequest, or MediaStore#createWriteRequest, 891 * the system will show the user confirmation dialog. 892 * 893 * @throws Exception 894 */ 895 @Test testCreateRequest_noRESAndMES_showConfirmDialog()896 public void testCreateRequest_noRESAndMES_showConfirmDialog() throws Exception { 897 installPackage(MEDIA.apk); 898 899 int user = getDevice().getCurrentUser(); 900 901 // grant permissions 902 updatePermissions(MEDIA.pkg, user, new String[] { 903 PERM_ACCESS_MEDIA_LOCATION, 904 }, true); 905 // revoke permissions 906 updatePermissions(MEDIA.pkg, user, new String[] { 907 PERM_READ_MEDIA_IMAGES, 908 PERM_READ_MEDIA_VIDEO, 909 PERM_READ_MEDIA_AUDIO, 910 PERM_READ_EXTERNAL_STORAGE, 911 PERM_WRITE_EXTERNAL_STORAGE, 912 }, false); 913 914 915 // revoke the app ops permission 916 updateAppOp(MEDIA.pkg, user, APP_OPS_MANAGE_EXTERNAL_STORAGE, false); 917 918 // grant the app ops permission 919 updateAppOp(MEDIA.pkg, user, APP_OPS_MANAGE_MEDIA, true); 920 921 runDeviceTests(MEDIA.pkg, MEDIA.clazz, 922 "testMediaEscalation_RequestWrite_showConfirmDialog", user); 923 } 924 925 /** 926 * If the app is NOT granted {@link android.Manifest.permission#MANAGE_MEDIA}, 927 * when it calls MediaStore#createTrashRequest, 928 * MediaStore#createDeleteRequest, or MediaStore#createWriteRequest, 929 * the system will show the user confirmation dialog. 930 * 931 * @throws Exception 932 */ 933 @Test testCreateRequest_noMANAGEMEDIA_showConfirmDialog()934 public void testCreateRequest_noMANAGEMEDIA_showConfirmDialog() throws Exception { 935 installPackage(MEDIA.apk); 936 937 int user = getDevice().getCurrentUser(); 938 // grant permissions 939 updatePermissions(MEDIA.pkg, user, new String[] { 940 PERM_READ_MEDIA_IMAGES, 941 PERM_READ_MEDIA_VIDEO, 942 PERM_READ_MEDIA_AUDIO, 943 PERM_READ_EXTERNAL_STORAGE, 944 PERM_ACCESS_MEDIA_LOCATION, 945 }, true); 946 947 // revoke the app ops permission 948 updateAppOp(MEDIA.pkg, user, APP_OPS_MANAGE_MEDIA, false); 949 950 runDeviceTests(MEDIA.pkg, MEDIA.clazz, 951 "testMediaEscalation_RequestWrite_showConfirmDialog", user); 952 runDeviceTests(MEDIA.pkg, MEDIA.clazz, 953 "testMediaEscalation_RequestTrash_showConfirmDialog", user); 954 runDeviceTests(MEDIA.pkg, MEDIA.clazz, 955 "testMediaEscalation_RequestDelete_showConfirmDialog", user); 956 } 957 958 /** 959 * If the app is granted {@link android.Manifest.permission#MANAGE_MEDIA}, 960 * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}, without 961 * {@link android.Manifest.permission#ACCESS_MEDIA_LOCATION}, 962 * when it calls MediaStore#createTrashRequest or 963 * MediaStore#createDeleteRequest, The system will NOT show the user 964 * confirmation dialog. When it calls MediaStore#createWriteRequest, the 965 * system will show the user confirmation dialog. 966 * 967 * @throws Exception 968 */ 969 @Test testCreateRequest_withNoAML_showConfirmDialog()970 public void testCreateRequest_withNoAML_showConfirmDialog() throws Exception { 971 installPackage(MEDIA.apk); 972 973 int user = getDevice().getCurrentUser(); 974 // grant permissions 975 updatePermissions(MEDIA.pkg, user, new String[] { 976 PERM_READ_MEDIA_IMAGES, 977 PERM_READ_MEDIA_VIDEO, 978 PERM_READ_MEDIA_AUDIO, 979 PERM_READ_EXTERNAL_STORAGE, 980 }, true); 981 // revoke permission 982 updatePermissions(MEDIA.pkg, user, new String[] { 983 PERM_ACCESS_MEDIA_LOCATION, 984 }, false); 985 986 // grant the app ops permission 987 updateAppOp(MEDIA.pkg, user, APP_OPS_MANAGE_MEDIA, true); 988 989 // show confirm dialog in requestWrite 990 runDeviceTests(MEDIA.pkg, MEDIA.clazz, 991 "testMediaEscalation_RequestWrite_showConfirmDialog", user); 992 993 // not show confirm dialog in requestTrash and requestDelete 994 runDeviceTests(MEDIA.pkg, MEDIA.clazz, 995 "testMediaEscalation_RequestTrash_notShowConfirmDialog", user); 996 runDeviceTests(MEDIA.pkg, MEDIA.clazz, 997 "testMediaEscalation_RequestDelete_notShowConfirmDialog", user); 998 } 999 1000 /** 1001 * If the app is granted {@link android.Manifest.permission#MANAGE_MEDIA}, {@link 1002 * android.Manifest.permission#READ_EXTERNAL_STORAGE}, without {@link 1003 * android.Manifest.permission#ACCESS_MEDIA_LOCATION}, when it calls 1004 * MediaStore#createTrashRequest or MediaStore#createDeleteRequest, The system will NOT show the 1005 * user confirmation dialog. When it calls MediaStore#createWriteRequest, the system will show 1006 * the user confirmation dialog. This tests pre-SDK level 33 behavior. 1007 * 1008 * @throws Exception 1009 */ 1010 @Test testCreateRequest_withNoAML_showConfirmDialog31()1011 public void testCreateRequest_withNoAML_showConfirmDialog31() throws Exception { 1012 installPackage(MEDIA_31.apk); 1013 1014 int user = getDevice().getCurrentUser(); 1015 // grant permissions 1016 updatePermissions(MEDIA_31.pkg, user, new String[] { 1017 PERM_READ_MEDIA_IMAGES, 1018 PERM_READ_MEDIA_VIDEO, 1019 PERM_READ_MEDIA_AUDIO, 1020 PERM_READ_EXTERNAL_STORAGE, 1021 }, true); 1022 // revoke permission 1023 updatePermissions(MEDIA_31.pkg, user, new String[] { 1024 PERM_ACCESS_MEDIA_LOCATION, 1025 }, false); 1026 1027 // grant the app ops permission 1028 updateAppOp(MEDIA_31.pkg, user, APP_OPS_MANAGE_MEDIA, true); 1029 1030 // show confirm dialog in requestWrite 1031 runDeviceTests(MEDIA_31.pkg, MEDIA_31.clazz, 1032 "testMediaEscalation_RequestWrite_showConfirmDialog", user); 1033 1034 // not show confirm dialog in requestTrash and requestDelete 1035 runDeviceTests(MEDIA_31.pkg, MEDIA_31.clazz, 1036 "testMediaEscalation_RequestTrash_notShowConfirmDialog", user); 1037 runDeviceTests(MEDIA_31.pkg, MEDIA_31.clazz, 1038 "testMediaEscalation_RequestDelete_notShowConfirmDialog", user); 1039 } 1040 1041 /** 1042 * If the app is granted {@link android.Manifest.permission#MANAGE_MEDIA}, 1043 * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}, and 1044 * {@link android.Manifest.permission#ACCESS_MEDIA_LOCATION}, 1045 * when it calls MediaStore#createWriteRequest, MediaStore#createTrashRequest or 1046 * MediaStore#createDeleteRequest, the system will NOT show the user confirmation dialog. 1047 * 1048 * @throws Exception 1049 */ 1050 @Test testCreateRequest_withPermission_notShowConfirmDialog()1051 public void testCreateRequest_withPermission_notShowConfirmDialog() throws Exception { 1052 installPackage(MEDIA.apk); 1053 1054 int user = getDevice().getCurrentUser(); 1055 // grant permissions 1056 updatePermissions(MEDIA.pkg, user, new String[] { 1057 PERM_READ_MEDIA_IMAGES, 1058 PERM_READ_MEDIA_VIDEO, 1059 PERM_READ_MEDIA_AUDIO, 1060 PERM_READ_EXTERNAL_STORAGE, 1061 PERM_ACCESS_MEDIA_LOCATION, 1062 PERM_READ_MEDIA_VISUAL_USER_SELECTED, 1063 }, true); 1064 1065 // revoke the app ops permission 1066 updateAppOp(MEDIA.pkg, user, APP_OPS_MANAGE_MEDIA, true); 1067 1068 runDeviceTests(MEDIA.pkg, MEDIA.clazz, 1069 "testMediaEscalation_RequestWrite_notShowConfirmDialog", user); 1070 runDeviceTests(MEDIA.pkg, MEDIA.clazz, 1071 "testMediaEscalation_RequestTrash_notShowConfirmDialog", user); 1072 runDeviceTests(MEDIA.pkg, MEDIA.clazz, 1073 "testMediaEscalation_RequestDelete_notShowConfirmDialog", user); 1074 } 1075 1076 /** 1077 * Bypasses the calling test case if ANY of the given features is available in the device. 1078 */ bypassTestForFeatures(String... features)1079 private void bypassTestForFeatures(String... features) throws DeviceNotAvailableException { 1080 final String featureList = getDevice().executeShellCommand("pm list features"); 1081 for (String feature : features) { 1082 Assume.assumeFalse(featureList.contains(feature)); 1083 } 1084 } 1085 1086 @Test testSystemGalleryExists()1087 public void testSystemGalleryExists() throws Exception { 1088 // Watches, TVs and IoT devices are not obligated to have a system gallery 1089 bypassTestForFeatures(FEATURE_AUTOMOTIVE, FEATURE_EMBEDDED, FEATURE_LEANBACK_ONLY, 1090 FEATURE_WATCH); 1091 1092 for (int user : mUsers) { 1093 final String[] roleHolders = getDevice().executeShellCommand( 1094 "cmd role get-role-holders --user " + user 1095 + " android.app.role.SYSTEM_GALLERY").trim().split(";"); 1096 assertEquals("Expected 1 SYSTEM_GALLERY for user " + user, 1, roleHolders.length); 1097 } 1098 } 1099 access(String path)1100 private boolean access(String path) throws DeviceNotAvailableException { 1101 final long nonce = System.nanoTime(); 1102 return getDevice().executeShellCommand("ls -la " + path + " && echo " + nonce) 1103 .contains(Long.toString(nonce)); 1104 } 1105 updatePermissions(String packageName, int userId, String[] permissions, boolean grant)1106 private void updatePermissions(String packageName, int userId, String[] permissions, 1107 boolean grant) throws Exception { 1108 final String verb = grant ? "grant" : "revoke"; 1109 for (String permission : permissions) { 1110 getDevice().executeShellCommand( 1111 "cmd package " + verb + " --user " + userId + " --uid " + packageName + " " 1112 + permission); 1113 } 1114 } 1115 1116 /** Wait until all broadcast queues are idle. */ waitForBroadcastIdle()1117 private void waitForBroadcastIdle() throws Exception{ 1118 getDevice().executeShellCommand("am wait-for-broadcast-idle"); 1119 } 1120 updateAppOp(String packageName, int userId, String appOp, boolean allow)1121 private void updateAppOp(String packageName, int userId, String appOp, boolean allow) 1122 throws Exception { 1123 updateAppOp(packageName, false, userId, appOp, allow); 1124 } 1125 updateAppOp(String packageName, boolean targetsUid, int userId, String appOp, boolean allow)1126 private void updateAppOp(String packageName, boolean targetsUid, int userId, 1127 String appOp, boolean allow) 1128 throws Exception { 1129 final String verb = allow ? "allow" : "default"; 1130 getDevice().executeShellCommand( 1131 "cmd appops set --user " + userId + (targetsUid ? " --uid " : " ") + packageName 1132 + " " + appOp + " " + verb); 1133 } 1134 wipePrimaryExternalStorage()1135 private void wipePrimaryExternalStorage() throws DeviceNotAvailableException { 1136 // Can't delete everything under /sdcard as that's going to remove the mounts. 1137 getDevice().executeShellCommand("find /sdcard -type f -delete"); 1138 getDevice().executeShellCommand("rm -rf /sdcard/DCIM/*"); 1139 getDevice().executeShellCommand("rm -rf /sdcard/MUST_*"); 1140 } 1141 runDeviceTests(String packageName, String testClassName, int userId)1142 private void runDeviceTests(String packageName, String testClassName, int userId) 1143 throws DeviceNotAvailableException { 1144 runDeviceTests(getDevice(), packageName, testClassName, null, userId, null); 1145 } 1146 runDeviceTests(String packageName, String testClassName, String testMethodName, int userId)1147 private void runDeviceTests(String packageName, String testClassName, String testMethodName, 1148 int userId) throws DeviceNotAvailableException { 1149 runDeviceTests(getDevice(), packageName, testClassName, testMethodName, userId, null); 1150 } 1151 } 1152