diff options
Diffstat (limited to 'hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java')
-rw-r--r-- | hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java index 30683328b35..a04b86fed22 100644 --- a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java +++ b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java @@ -16,6 +16,7 @@ package android.scopedstorage.cts.lib; +import static android.provider.MediaStore.VOLUME_EXTERNAL; import static android.scopedstorage.cts.lib.RedactionTestHelper.EXIF_METADATA_QUERY; import static androidx.test.InstrumentationRegistry.getContext; @@ -98,6 +99,7 @@ public class TestUtils { public static final String CREATE_IMAGE_ENTRY_QUERY = "android.scopedstorage.cts.createimageentry"; public static final String DELETE_FILE_QUERY = "android.scopedstorage.cts.deletefile"; + public static final String DELETE_RECURSIVE_QUERY = "android.scopedstorage.cts.deleteRecursive"; public static final String CAN_OPEN_FILE_FOR_READ_QUERY = "android.scopedstorage.cts.can_openfile_read"; public static final String CAN_OPEN_FILE_FOR_WRITE_QUERY = @@ -295,6 +297,17 @@ public class TestUtils { } /** + * Makes the given {@code testApp} delete a file or directory. + * If the file is a directory, then deletes all of its children (file or directories) + * recursively. + * + * <p>This method drops shell permission identity. + */ + public static boolean deleteRecursivelyAs(TestApp testApp, String path) throws Exception { + return getResultFromTestApp(testApp, path, DELETE_RECURSIVE_QUERY); + } + + /** * Makes the given {@code testApp} delete a file. Doesn't throw in case of failure. */ public static boolean deleteFileAsNoThrow(TestApp testApp, String path) { @@ -950,6 +963,111 @@ public class TestUtils { } /** + * Assert that app cannot insert files in other app's private directories + * + * @param fileName name of the file + * @param throwsExceptionForDataValue Apps like System Gallery for which Data column is not + * respected, will not throw an Exception as the Data value is ignored. + * @param otherApp Other test app in whose external private directory we will attempt to insert + * @param callingPackageName Calling package name + */ + public static void assertCantInsertToOtherPrivateAppDirectories(String fileName, + boolean throwsExceptionForDataValue, TestApp otherApp, String callingPackageName) + throws Exception { + // Create directory in which the device test will try to insert file to + final File otherAppExternalDataDir = new File(getExternalFilesDir().getPath().replace( + callingPackageName, otherApp.getPackageName())); + final File file = new File(otherAppExternalDataDir, fileName); + try { + assertThat(createFileAs(otherApp, file.getPath())).isTrue(); + + final ContentValues valuesWithData = new ContentValues(); + valuesWithData.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath()); + try { + Uri uri = getContentResolver().insert( + MediaStore.Files.getContentUri(VOLUME_EXTERNAL), + valuesWithData); + + if (throwsExceptionForDataValue) { + fail("File insert expected to fail: " + file); + } else { + try (Cursor c = getContentResolver().query(uri, new String[]{ + MediaStore.MediaColumns.DATA}, null, null)) { + assertThat(c.moveToFirst()).isTrue(); + assertThat(c.getString(0)).isNotEqualTo(file.getAbsolutePath()); + } + } + } catch (IllegalArgumentException expected) { + } + + final ContentValues valuesWithRelativePath = new ContentValues(); + final String path = file.getAbsolutePath(); + valuesWithRelativePath.put(MediaStore.MediaColumns.RELATIVE_PATH, + path.substring(path.indexOf("Android"))); + valuesWithRelativePath.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName); + try { + getContentResolver().insert(MediaStore.Files.getContentUri(VOLUME_EXTERNAL), + valuesWithRelativePath); + fail("File insert expected to fail: " + file); + } catch (IllegalArgumentException expected) { + } + } finally { + deleteFileAsNoThrow(otherApp, file.getPath()); + } + } + + /** + * Assert that app cannot update files in other app's private directories + * + * @param fileName name of the file + * @param throwsExceptionForDataValue Apps like non-legacy System Gallery/MES for which + * Data column is not respected, will not throw an Exception as the Data value is ignored. + * @param otherApp Other test app in whose external private directory we will attempt to insert + * @param callingPackageName Calling package name + */ + public static void assertCantUpdateToOtherPrivateAppDirectories(String fileName, + boolean throwsExceptionForDataValue, TestApp otherApp, String callingPackageName) + throws Exception { + // Create priv-app file and add to the database that we will try to update + final File otherAppExternalDataDir = new File(getExternalFilesDir().getPath().replace( + callingPackageName, otherApp.getPackageName())); + final File file = new File(otherAppExternalDataDir, fileName); + try { + assertThat(createFileAs(otherApp, file.getPath())).isTrue(); + MediaStore.scanFile(getContentResolver(), file); + + final ContentValues valuesWithData = new ContentValues(); + valuesWithData.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath()); + try { + int res = getContentResolver().update( + MediaStore.Files.getContentUri(VOLUME_EXTERNAL), + valuesWithData, Bundle.EMPTY); + + if (throwsExceptionForDataValue) { + fail("File update expected to fail: " + file); + } else { + assertThat(res).isEqualTo(0); + } + } catch (IllegalArgumentException expected) { + } + + final ContentValues valuesWithRelativePath = new ContentValues(); + final String path = file.getAbsolutePath(); + valuesWithRelativePath.put(MediaStore.MediaColumns.RELATIVE_PATH, + path.substring(path.indexOf("Android"))); + valuesWithRelativePath.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName); + try { + getContentResolver().update(MediaStore.Files.getContentUri(VOLUME_EXTERNAL), + valuesWithRelativePath, Bundle.EMPTY); + fail("File update expected to fail: " + file); + } catch (IllegalArgumentException expected) { + } + } finally { + deleteFileAsNoThrow(otherApp, file.getPath()); + } + } + + /** * Asserts can rename directory. */ public static void assertCanRenameDirectory(File oldDirectory, File newDirectory, |