Merge "Test M_E_S can readdir anywhere on shared external storage" into rvc-dev
diff --git a/tests/jni/FuseDaemonTest/FilePathAccessTestHelper/src/com/android/tests/fused/FilePathAccessTestHelper.java b/tests/jni/FuseDaemonTest/FilePathAccessTestHelper/src/com/android/tests/fused/FilePathAccessTestHelper.java
index aba6537..e32ee19 100644
--- a/tests/jni/FuseDaemonTest/FilePathAccessTestHelper/src/com/android/tests/fused/FilePathAccessTestHelper.java
+++ b/tests/jni/FuseDaemonTest/FilePathAccessTestHelper/src/com/android/tests/fused/FilePathAccessTestHelper.java
@@ -15,30 +15,28 @@
*/
package com.android.tests.fused;
-import static com.android.tests.fused.lib.ReaddirTestHelper.READDIR_QUERY;
import static com.android.tests.fused.lib.RedactionTestHelper.EXIF_METADATA_QUERY;
import static com.android.tests.fused.lib.RedactionTestHelper.getExifMetadata;
+import static com.android.tests.fused.lib.TestUtils.CAN_READ_WRITE_QUERY;
import static com.android.tests.fused.lib.TestUtils.CREATE_FILE_QUERY;
import static com.android.tests.fused.lib.TestUtils.DELETE_FILE_QUERY;
-import static com.android.tests.fused.lib.TestUtils.CAN_READ_WRITE_QUERY;
import static com.android.tests.fused.lib.TestUtils.INTENT_EXCEPTION;
import static com.android.tests.fused.lib.TestUtils.INTENT_EXTRA_PATH;
import static com.android.tests.fused.lib.TestUtils.OPEN_FILE_FOR_READ_QUERY;
import static com.android.tests.fused.lib.TestUtils.OPEN_FILE_FOR_WRITE_QUERY;
import static com.android.tests.fused.lib.TestUtils.QUERY_TYPE;
+import static com.android.tests.fused.lib.TestUtils.READDIR_QUERY;
import static com.android.tests.fused.lib.TestUtils.canOpen;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
-import android.util.Log;
-
-import com.android.tests.fused.lib.ReaddirTestHelper;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collections;
/**
* App for FilePathAccessTest Functions.
@@ -56,86 +54,91 @@
super.onCreate(savedInstanceState);
String queryType = getIntent().getStringExtra(QUERY_TYPE);
queryType = queryType == null ? "null" : queryType;
- switch (queryType) {
- case READDIR_QUERY:
- sendDirectoryEntries(queryType);
- break;
- case CAN_READ_WRITE_QUERY:
- case CREATE_FILE_QUERY:
- case DELETE_FILE_QUERY:
- case OPEN_FILE_FOR_READ_QUERY:
- case OPEN_FILE_FOR_WRITE_QUERY:
- accessFile(queryType);
- break;
- case EXIF_METADATA_QUERY:
- sendMetadata(queryType);
- break;
- case "null":
- default:
- Log.e(TAG, "Unknown query received from launcher app: " + queryType);
+ Intent returnIntent;
+ try {
+ switch (queryType) {
+ case READDIR_QUERY:
+ returnIntent = sendDirectoryEntries(queryType);
+ break;
+ case CAN_READ_WRITE_QUERY:
+ case CREATE_FILE_QUERY:
+ case DELETE_FILE_QUERY:
+ case OPEN_FILE_FOR_READ_QUERY:
+ case OPEN_FILE_FOR_WRITE_QUERY:
+ returnIntent = accessFile(queryType);
+ break;
+ case EXIF_METADATA_QUERY:
+ returnIntent = sendMetadata(queryType);
+ break;
+ case "null":
+ default:
+ throw new IllegalStateException(
+ "Unknown query received from launcher app: " + queryType);
+ }
+ } catch (Exception e) {
+ returnIntent = new Intent(queryType);
+ returnIntent.putExtra(INTENT_EXCEPTION, e);
}
+ sendBroadcast(returnIntent);
}
- private void sendMetadata(String queryType) {
+ private Intent sendMetadata(String queryType) throws IOException {
final Intent intent = new Intent(queryType);
if (getIntent().hasExtra(INTENT_EXTRA_PATH)) {
final String filePath = getIntent().getStringExtra(INTENT_EXTRA_PATH);
- try {
- if (EXIF_METADATA_QUERY.equals(queryType)) {
- intent.putExtra(queryType, getExifMetadata(new File(filePath)));
- }
- } catch (Exception e) {
- intent.putExtra(INTENT_EXCEPTION, e);
+ if (EXIF_METADATA_QUERY.equals(queryType)) {
+ intent.putExtra(queryType, getExifMetadata(new File(filePath)));
}
} else {
- Log.e(TAG, "File path not set from launcher app");
- intent.putExtra(INTENT_EXCEPTION, new IllegalStateException(
- "File path not set from launcher app"));
+ throw new IllegalStateException(EXIF_METADATA_QUERY
+ + ": File path not set from launcher app");
}
- sendBroadcast(intent);
+ return intent;
}
- private void sendDirectoryEntries(String queryType) {
+ private Intent sendDirectoryEntries(String queryType) throws IOException {
if (getIntent().hasExtra(INTENT_EXTRA_PATH)) {
final String directoryPath = getIntent().getStringExtra(INTENT_EXTRA_PATH);
- ArrayList<String> directoryEntries = new ArrayList<String>();
+ ArrayList<String> directoryEntriesList = new ArrayList<>();
if (queryType.equals(READDIR_QUERY)) {
- directoryEntries = ReaddirTestHelper.readDirectory(directoryPath);
+ final String[] directoryEntries = new File(directoryPath).list();
+ if (directoryEntries == null) {
+ throw new IOException(
+ "I/O exception while listing entries for " + directoryPath);
+ }
+ Collections.addAll(directoryEntriesList, directoryEntries);
}
final Intent intent = new Intent(queryType);
- intent.putStringArrayListExtra(queryType, directoryEntries);
- sendBroadcast(intent);
+ intent.putStringArrayListExtra(queryType, directoryEntriesList);
+ return intent;
} else {
- Log.e(TAG, "Directory path not set from launcher app");
+ throw new IllegalStateException(READDIR_QUERY
+ + ": Directory path not set from launcher app");
}
}
- private void accessFile(String queryType) {
+ private Intent accessFile(String queryType) throws IOException {
if (getIntent().hasExtra(INTENT_EXTRA_PATH)) {
final String filePath = getIntent().getStringExtra(INTENT_EXTRA_PATH);
final File file = new File(filePath);
boolean returnStatus = false;
- try {
- if (queryType.equals(CAN_READ_WRITE_QUERY)) {
+ if (queryType.equals(CAN_READ_WRITE_QUERY)) {
returnStatus = file.exists() && file.canRead() && file.canWrite();
- } else if (queryType.equals(CREATE_FILE_QUERY)) {
- maybeCreateParentDirInAndroid(file);
- returnStatus = file.createNewFile();
- } else if (queryType.equals(DELETE_FILE_QUERY)) {
- returnStatus = file.delete();
- } else if (queryType.equals(OPEN_FILE_FOR_READ_QUERY)) {
- returnStatus = canOpen(file, false /* forWrite */);
- } else if (queryType.equals(OPEN_FILE_FOR_WRITE_QUERY)) {
- returnStatus = canOpen(file, true /* forWrite */);
- }
- } catch(IOException e) {
- Log.e(TAG, "Failed to access file: " + filePath + ". Query type: " + queryType, e);
+ } else if (queryType.equals(CREATE_FILE_QUERY)) {
+ maybeCreateParentDirInAndroid(file);
+ returnStatus = file.createNewFile();
+ } else if (queryType.equals(DELETE_FILE_QUERY)) {
+ returnStatus = file.delete();
+ } else if (queryType.equals(OPEN_FILE_FOR_READ_QUERY)) {
+ returnStatus = canOpen(file, false /* forWrite */);
+ } else if (queryType.equals(OPEN_FILE_FOR_WRITE_QUERY)) {
+ returnStatus = canOpen(file, true /* forWrite */);
}
final Intent intent = new Intent(queryType);
intent.putExtra(queryType, returnStatus);
- sendBroadcast(intent);
+ return intent;
} else {
- Log.e(TAG, "file path not set from launcher app");
+ throw new IllegalStateException(queryType + ": File path not set from launcher app");
}
}
diff --git a/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseDaemonHostTest.java b/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseDaemonHostTest.java
index ef05f13..273f200 100644
--- a/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseDaemonHostTest.java
+++ b/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseDaemonHostTest.java
@@ -252,6 +252,11 @@
}
@Test
+ public void testManageExternalStorageReaddir() throws Exception {
+ runDeviceTest("testManageExternalStorageReaddir");
+ }
+
+ @Test
public void testManageExternalStorageCanRenameOtherAppsContents() throws Exception {
runDeviceTest("testManageExternalStorageCanRenameOtherAppsContents");
}
diff --git a/tests/jni/FuseDaemonTest/legacy/src/com/android/tests/fused/legacy/LegacyFileAccessTest.java b/tests/jni/FuseDaemonTest/legacy/src/com/android/tests/fused/legacy/LegacyFileAccessTest.java
index 2a5c842..18c240d 100644
--- a/tests/jni/FuseDaemonTest/legacy/src/com/android/tests/fused/legacy/LegacyFileAccessTest.java
+++ b/tests/jni/FuseDaemonTest/legacy/src/com/android/tests/fused/legacy/LegacyFileAccessTest.java
@@ -24,6 +24,7 @@
import static com.android.tests.fused.lib.TestUtils.assertCanRenameFile;
import static com.android.tests.fused.lib.TestUtils.assertCanRenameDirectory;
import static com.android.tests.fused.lib.TestUtils.assertCantRenameFile;
+import static com.android.tests.fused.lib.TestUtils.assertDirectoryContains;
import static com.android.tests.fused.lib.TestUtils.assertFileContent;
import static com.android.tests.fused.lib.TestUtils.createFileAs;
import static com.android.tests.fused.lib.TestUtils.deleteFileAsNoThrow;
@@ -61,7 +62,6 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.cts.install.lib.TestApp;
-import com.android.tests.fused.lib.ReaddirTestHelper;
import com.android.tests.fused.lib.TestUtils;
import com.google.common.io.Files;
@@ -413,8 +413,7 @@
try {
assertThat(videoFile.createNewFile()).isTrue();
- assertThat(ReaddirTestHelper.readDirectory(EXTERNAL_STORAGE_DIR))
- .contains(VIDEO_FILE_NAME);
+ assertDirectoryContains(videoFile.getParentFile(), videoFile);
assertThat(getFileRowIdFromDatabase(videoFile)).isNotEqualTo(-1);
// Legacy app can delete its own file.
diff --git a/tests/jni/FuseDaemonTest/libs/FuseDaemonTestLib/src/com/android/tests/fused/lib/ReaddirTestHelper.java b/tests/jni/FuseDaemonTest/libs/FuseDaemonTestLib/src/com/android/tests/fused/lib/ReaddirTestHelper.java
deleted file mode 100644
index 29986bc..0000000
--- a/tests/jni/FuseDaemonTest/libs/FuseDaemonTestLib/src/com/android/tests/fused/lib/ReaddirTestHelper.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tests.fused.lib;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.DirectoryIteratorException;
-import java.nio.file.DirectoryStream;
-import java.nio.file.DirectoryStream.Filter;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import android.util.Log;
-
-/**
- * Helper functions for readdir tests
- */
-public class ReaddirTestHelper {
- private static final String TAG = "ReaddirTestHelper";
-
- public static final String READDIR_QUERY = "com.android.tests.fused.readdir";
-
- /**
- * Returns directory entries for the given {@code directory}
- *
- * @param directory directory that needs to be listed.
- * @return list of directory names and filenames in the given directory.
- */
- public static ArrayList<String> readDirectory(File directory) {
- return readDirectory(directory.toString());
- }
-
- /**
- * Returns directory entries for the given {@code directoryPath}
- *
- * @param directoryPath path of the directory.
- * @return list of directory names and filenames in the given directory.
- */
- public static ArrayList<String> readDirectory(String directoryPath) {
- Filter<Path> filter = new Filter<Path>() {
- public boolean accept(Path file) {
- return true;
- }
- };
- return readDirectory(directoryPath, filter);
- }
-
- /**
- * Returns filtered directory entries for the given {@code directoryPath}
- *
- * @param directoryPath path of the directory.
- * @param filter filter to apply on directory entries.
- * @return list of directory names and filenames in the given directory. Directory entries are
- * filtered by the given filter.
- */
- public static ArrayList<String> readDirectory(String directoryPath, Filter<Path> filter) {
- ArrayList<String> directoryEntries = new ArrayList<String>();
- File dir = new File(directoryPath);
-
- try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(dir.toPath(),
- filter)) {
- for (Path de: directoryStream) {
- directoryEntries.add(de.getFileName().toString());
- }
- } catch (IOException | DirectoryIteratorException x) {
- Log.e(TAG, "IOException occurred while readding directory entries from " +
- directoryPath, x);
- }
- return directoryEntries;
- }
-}
diff --git a/tests/jni/FuseDaemonTest/libs/FuseDaemonTestLib/src/com/android/tests/fused/lib/TestUtils.java b/tests/jni/FuseDaemonTest/libs/FuseDaemonTestLib/src/com/android/tests/fused/lib/TestUtils.java
index 00de011..37a7f67 100644
--- a/tests/jni/FuseDaemonTest/libs/FuseDaemonTestLib/src/com/android/tests/fused/lib/TestUtils.java
+++ b/tests/jni/FuseDaemonTest/libs/FuseDaemonTestLib/src/com/android/tests/fused/lib/TestUtils.java
@@ -18,7 +18,6 @@
import static androidx.test.InstrumentationRegistry.getContext;
-import static com.android.tests.fused.lib.ReaddirTestHelper.READDIR_QUERY;
import static com.android.tests.fused.lib.RedactionTestHelper.EXIF_METADATA_QUERY;
import static com.google.common.truth.Truth.assertThat;
@@ -66,7 +65,9 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -84,6 +85,7 @@
public static final String OPEN_FILE_FOR_READ_QUERY = "com.android.tests.fused.openfile_read";
public static final String OPEN_FILE_FOR_WRITE_QUERY = "com.android.tests.fused.openfile_write";
public static final String CAN_READ_WRITE_QUERY = "com.android.tests.fused.can_read_and_write";
+ public static final String READDIR_QUERY = "com.android.tests.fused.readdir";
public static final String STR_DATA1 = "Just some random text";
public static final String STR_DATA2 = "More arbitrary stuff";
@@ -96,6 +98,8 @@
// Default top-level directories
public static final File ALARMS_DIR = new File(EXTERNAL_STORAGE_DIR,
Environment.DIRECTORY_ALARMS);
+ public static final File ANDROID_DIR = new File(EXTERNAL_STORAGE_DIR,
+ "Android");
public static final File AUDIOBOOKS_DIR = new File(EXTERNAL_STORAGE_DIR,
Environment.DIRECTORY_AUDIOBOOKS);
public static final File DCIM_DIR = new File(EXTERNAL_STORAGE_DIR, Environment.DIRECTORY_DCIM);
@@ -116,8 +120,12 @@
public static final File RINGTONES_DIR = new File(EXTERNAL_STORAGE_DIR,
Environment.DIRECTORY_RINGTONES);
- public static final File ANDROID_DATA_DIR = new File(EXTERNAL_STORAGE_DIR, "Android/data");
- public static final File ANDROID_MEDIA_DIR = new File(EXTERNAL_STORAGE_DIR, "Android/media");
+ public static final File[] DEFAULT_TOP_LEVEL_DIRS = new File [] { ALARMS_DIR, ANDROID_DIR,
+ AUDIOBOOKS_DIR, DCIM_DIR, DOCUMENTS_DIR, DOWNLOAD_DIR, MUSIC_DIR, MOVIES_DIR,
+ NOTIFICATIONS_DIR, PICTURES_DIR, PODCASTS_DIR, RINGTONES_DIR};
+
+ public static final File ANDROID_DATA_DIR = new File(ANDROID_DIR, "data");
+ public static final File ANDROID_MEDIA_DIR = new File(ANDROID_DIR, "media");
private static final long POLLING_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(10);
private static final long POLLING_SLEEP_MILLIS = 100;
@@ -130,9 +138,7 @@
* assumptions about their existence.
*/
public static void setupDefaultDirectories() {
- for (File dir : new File [] { ALARMS_DIR, AUDIOBOOKS_DIR, DCIM_DIR,
- DOCUMENTS_DIR, DOWNLOAD_DIR, MUSIC_DIR, MOVIES_DIR, NOTIFICATIONS_DIR,
- PICTURES_DIR, PODCASTS_DIR, RINGTONES_DIR}) {
+ for (File dir : DEFAULT_TOP_LEVEL_DIRS) {
dir.mkdir();
}
}
@@ -209,9 +215,6 @@
String filePath) throws Exception {
HashMap<String, String> res =
getMetadataFromTestApp(testApp, filePath, EXIF_METADATA_QUERY);
- if (res.containsKey(INTENT_EXCEPTION)) {
- throw new IllegalStateException(res.get(INTENT_EXCEPTION));
- }
return res;
}
@@ -452,13 +455,13 @@
return pfd;
}
- public static <T extends Exception> void assertThrows(Class<T> clazz, Operation<T> r)
+ public static <T extends Exception> void assertThrows(Class<T> clazz, Operation<Exception> r)
throws Exception {
assertThrows(clazz, "", r);
}
public static <T extends Exception> void assertThrows(Class<T> clazz, String errMsg,
- Operation<T> r) throws Exception {
+ Operation<Exception> r) throws Exception {
try {
r.run();
fail("Expected " + clazz + " to be thrown");
@@ -677,12 +680,13 @@
String actionName) throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final HashMap<String, String> appOutputList = new HashMap<>();
+ final Exception[] exception = new Exception[1];
+ exception[0] = null;
final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.hasExtra(INTENT_EXCEPTION)) {
- appOutputList.put(INTENT_EXCEPTION,
- ((Exception)intent.getExtras().get(INTENT_EXCEPTION)).getMessage());
+ exception[0] = (Exception)(intent.getExtras().get(INTENT_EXCEPTION));
} else if(intent.hasExtra(actionName)) {
HashMap<String, String> res =
(HashMap<String, String>) intent.getExtras().get(actionName);
@@ -692,6 +696,7 @@
}
};
sendIntentToTestApp(testApp, dirPath, actionName, broadcastReceiver, latch);
+ if (exception[0] != null) throw exception[0];
return appOutputList;
}
@@ -702,10 +707,14 @@
String actionName) throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final ArrayList<String> appOutputList = new ArrayList<String>();
+ final Exception[] exception = new Exception[1];
+ exception[0] = null;
final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- if(intent.hasExtra(actionName)) {
+ if (intent.hasExtra(INTENT_EXCEPTION)) {
+ exception[0] = (Exception)(intent.getSerializableExtra(INTENT_EXCEPTION));
+ } else if(intent.hasExtra(actionName)) {
appOutputList.addAll(intent.getStringArrayListExtra(actionName));
}
latch.countDown();
@@ -713,6 +722,7 @@
};
sendIntentToTestApp(testApp, dirPath, actionName, broadcastReceiver, latch);
+ if (exception[0] != null) throw exception[0];
return appOutputList;
}
@@ -723,10 +733,14 @@
String actionName) throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final boolean[] appOutput = new boolean[1];
+ final Exception[] exception = new Exception[1];
+ exception[0] = null;
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- if(intent.hasExtra(actionName)) {
+ if (intent.hasExtra(INTENT_EXCEPTION)) {
+ exception[0] = (Exception)(intent.getSerializableExtra(INTENT_EXCEPTION));
+ } else if(intent.hasExtra(actionName)) {
appOutput[0] = intent.getBooleanExtra(actionName, false);
}
latch.countDown();
@@ -734,6 +748,7 @@
};
sendIntentToTestApp(testApp, dirPath, actionName, broadcastReceiver, latch);
+ if (exception[0] != null) throw exception[0];
return appOutput[0];
}
@@ -766,4 +781,15 @@
assertThat(c).isNotNull();
return c;
}
+
+ /**
+ * Asserts that {@code dir} is a directory and that it contains all of {@code expectedContent}
+ */
+ public static void assertDirectoryContains(@NonNull File dir, File... expectedContent) {
+ assertThat(dir.isDirectory()).isTrue();
+ final List<File> actualContent = Arrays.asList(dir.listFiles());
+ for (File f: expectedContent) {
+ assertThat(actualContent).contains(f);
+ }
+ }
}
diff --git a/tests/jni/FuseDaemonTest/src/com/android/tests/fused/FilePathAccessTest.java b/tests/jni/FuseDaemonTest/src/com/android/tests/fused/FilePathAccessTest.java
index 777c78e..36a4fb6 100644
--- a/tests/jni/FuseDaemonTest/src/com/android/tests/fused/FilePathAccessTest.java
+++ b/tests/jni/FuseDaemonTest/src/com/android/tests/fused/FilePathAccessTest.java
@@ -35,19 +35,33 @@
import static com.android.tests.fused.lib.RedactionTestHelper.assertExifMetadataMismatch;
import static com.android.tests.fused.lib.RedactionTestHelper.getExifMetadata;
import static com.android.tests.fused.lib.RedactionTestHelper.getExifMetadataFromRawResource;
+import static com.android.tests.fused.lib.TestUtils.ALARMS_DIR;
+import static com.android.tests.fused.lib.TestUtils.ANDROID_DATA_DIR;
+import static com.android.tests.fused.lib.TestUtils.ANDROID_MEDIA_DIR;
+import static com.android.tests.fused.lib.TestUtils.AUDIOBOOKS_DIR;
import static com.android.tests.fused.lib.TestUtils.BYTES_DATA1;
import static com.android.tests.fused.lib.TestUtils.BYTES_DATA2;
+import static com.android.tests.fused.lib.TestUtils.DCIM_DIR;
+import static com.android.tests.fused.lib.TestUtils.DEFAULT_TOP_LEVEL_DIRS;
+import static com.android.tests.fused.lib.TestUtils.DOCUMENTS_DIR;
+import static com.android.tests.fused.lib.TestUtils.DOWNLOAD_DIR;
+import static com.android.tests.fused.lib.TestUtils.MOVIES_DIR;
+import static com.android.tests.fused.lib.TestUtils.MUSIC_DIR;
+import static com.android.tests.fused.lib.TestUtils.NOTIFICATIONS_DIR;
+import static com.android.tests.fused.lib.TestUtils.PICTURES_DIR;
+import static com.android.tests.fused.lib.TestUtils.PODCASTS_DIR;
+import static com.android.tests.fused.lib.TestUtils.RINGTONES_DIR;
import static com.android.tests.fused.lib.TestUtils.STR_DATA1;
import static com.android.tests.fused.lib.TestUtils.STR_DATA2;
-import static com.android.tests.fused.lib.TestUtils.assertCanRenameFile;
-import static com.android.tests.fused.lib.TestUtils.assertCanRenameDirectory;
import static com.android.tests.fused.lib.TestUtils.allowAppOpsToUid;
+import static com.android.tests.fused.lib.TestUtils.assertCanRenameDirectory;
+import static com.android.tests.fused.lib.TestUtils.assertCanRenameFile;
import static com.android.tests.fused.lib.TestUtils.assertCantRenameDirectory;
import static com.android.tests.fused.lib.TestUtils.assertCantRenameFile;
+import static com.android.tests.fused.lib.TestUtils.assertDirectoryContains;
import static com.android.tests.fused.lib.TestUtils.assertFileContent;
import static com.android.tests.fused.lib.TestUtils.assertThrows;
import static com.android.tests.fused.lib.TestUtils.canOpen;
-import static com.android.tests.fused.lib.TestUtils.canReadAndWriteAs;
import static com.android.tests.fused.lib.TestUtils.createFileAs;
import static com.android.tests.fused.lib.TestUtils.deleteFileAs;
import static com.android.tests.fused.lib.TestUtils.deleteFileAsNoThrow;
@@ -65,6 +79,7 @@
import static com.android.tests.fused.lib.TestUtils.listAs;
import static com.android.tests.fused.lib.TestUtils.openFileAs;
import static com.android.tests.fused.lib.TestUtils.openWithMediaProvider;
+import static com.android.tests.fused.lib.TestUtils.pollForExternalStorageState;
import static com.android.tests.fused.lib.TestUtils.pollForPermission;
import static com.android.tests.fused.lib.TestUtils.readExifMetadataFromTestApp;
import static com.android.tests.fused.lib.TestUtils.revokePermission;
@@ -72,25 +87,9 @@
import static com.android.tests.fused.lib.TestUtils.uninstallApp;
import static com.android.tests.fused.lib.TestUtils.uninstallAppNoThrow;
import static com.android.tests.fused.lib.TestUtils.updateDisplayNameWithMediaProvider;
-import static com.android.tests.fused.lib.TestUtils.pollForExternalStorageState;
-import static com.android.tests.fused.lib.TestUtils.ALARMS_DIR;
-import static com.android.tests.fused.lib.TestUtils.AUDIOBOOKS_DIR;
-import static com.android.tests.fused.lib.TestUtils.DCIM_DIR;
-import static com.android.tests.fused.lib.TestUtils.DOCUMENTS_DIR;
-import static com.android.tests.fused.lib.TestUtils.DOWNLOAD_DIR;
-import static com.android.tests.fused.lib.TestUtils.MUSIC_DIR;
-import static com.android.tests.fused.lib.TestUtils.MOVIES_DIR;
-import static com.android.tests.fused.lib.TestUtils.NOTIFICATIONS_DIR;
-import static com.android.tests.fused.lib.TestUtils.PICTURES_DIR;
-import static com.android.tests.fused.lib.TestUtils.PODCASTS_DIR;
-import static com.android.tests.fused.lib.TestUtils.RINGTONES_DIR;
-import static com.android.tests.fused.lib.TestUtils.ANDROID_DATA_DIR;
-import static com.android.tests.fused.lib.TestUtils.ANDROID_MEDIA_DIR;
import static com.google.common.truth.Truth.assertThat;
-import static junit.framework.Assert.fail;
-
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
@@ -112,12 +111,10 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.cts.install.lib.TestApp;
-import com.android.tests.fused.lib.ReaddirTestHelper;
import com.google.common.io.Files;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -645,7 +642,6 @@
public void testListFilesFromExternalFilesDirectory() throws Exception {
final String packageName = THIS_PACKAGE_NAME;
final File videoFile = new File(EXTERNAL_FILES_DIR, NONMEDIA_FILE_NAME);
- final String videoFileName = videoFile.getName();
try {
// Create a file in app's external files directory
@@ -654,16 +650,14 @@
}
// App should see its directory and directories of shared packages. App should see all
// files and directories in its external directory.
- assertThat(ReaddirTestHelper.readDirectory(videoFile.getParentFile()))
- .containsExactly(videoFileName);
+ assertDirectoryContains(videoFile.getParentFile(), videoFile);
// Install TEST_APP_A with READ_EXTERNAL_STORAGE permission.
// TEST_APP_A should not see other app's external files directory.
installAppWithStoragePermissions(TEST_APP_A);
- // TODO(b/146497700): This is passing because ReaddirTestHelper ignores IOException and
- // returns empty list.
- assertThat(listAs(TEST_APP_A, ANDROID_DATA_DIR.getPath())).doesNotContain(packageName);
- assertThat(listAs(TEST_APP_A, EXTERNAL_FILES_DIR.getPath())).isEmpty();
+
+ assertThrows(IOException.class, () -> listAs(TEST_APP_A, ANDROID_DATA_DIR.getPath()));
+ assertThrows(IOException.class, () -> listAs(TEST_APP_A, EXTERNAL_FILES_DIR.getPath()));
} finally {
videoFile.delete();
uninstallAppNoThrow(TEST_APP_A);
@@ -676,7 +670,6 @@
@Test
public void testListFilesFromExternalMediaDirectory() throws Exception {
final File videoFile = new File(EXTERNAL_MEDIA_DIR, VIDEO_FILE_NAME);
- final String videoFileName = videoFile.getName();
try {
// Create a file in app's external media directory
@@ -686,16 +679,15 @@
// App should see its directory and other app's external media directories with media
// files.
- assertThat(ReaddirTestHelper.readDirectory(EXTERNAL_MEDIA_DIR))
- .containsExactly(videoFileName);
+ assertDirectoryContains(videoFile.getParentFile(), videoFile);
// Install TEST_APP_A with READ_EXTERNAL_STORAGE permission.
// TEST_APP_A with storage permission should see other app's external media directory.
installAppWithStoragePermissions(TEST_APP_A);
// Apps with READ_EXTERNAL_STORAGE can list files in other app's external media directory.
assertThat(listAs(TEST_APP_A, ANDROID_MEDIA_DIR.getPath())).contains(THIS_PACKAGE_NAME);
- // TODO(b/145737191) fails because we don't index these files yet.
- assertThat(listAs(TEST_APP_A, EXTERNAL_MEDIA_DIR.getPath())).containsExactly(videoFileName);
+ assertThat(listAs(TEST_APP_A, EXTERNAL_MEDIA_DIR.getPath()))
+ .containsExactly(videoFile.getName());
} finally {
videoFile.delete();
uninstallAppNoThrow(TEST_APP_A);
@@ -1741,6 +1733,36 @@
}
@Test
+ public void testManageExternalStorageReaddir() throws Exception {
+ final File otherAppPdf = new File(DOWNLOAD_DIR, "other" + NONMEDIA_FILE_NAME);
+ final File otherAppImg = new File(DCIM_DIR, "other" + IMAGE_FILE_NAME);
+ final File otherAppMusic = new File(MUSIC_DIR, "other" + AUDIO_FILE_NAME);
+ final File otherTopLevelFile = new File(EXTERNAL_STORAGE_DIR, "other" + NONMEDIA_FILE_NAME);
+ try {
+ installApp(TEST_APP_A);
+ assertCreateFilesAs(TEST_APP_A, otherAppImg, otherAppMusic, otherAppPdf);
+ executeShellCommand("touch " + otherTopLevelFile);
+
+ allowAppOpsToUid(Process.myUid(), OPSTR_MANAGE_EXTERNAL_STORAGE);
+
+ // We can list other apps' files
+ assertDirectoryContains(otherAppPdf.getParentFile(), otherAppPdf);
+ assertDirectoryContains(otherAppImg.getParentFile(), otherAppImg);
+ assertDirectoryContains(otherAppMusic.getParentFile(), otherAppMusic);
+ // We can list top level files
+ assertDirectoryContains(EXTERNAL_STORAGE_DIR, otherTopLevelFile);
+
+ // We can also list all top level directories
+ assertDirectoryContains(EXTERNAL_STORAGE_DIR, DEFAULT_TOP_LEVEL_DIRS);
+ } finally {
+ denyAppOpsToUid(Process.myUid(), OPSTR_MANAGE_EXTERNAL_STORAGE);
+ executeShellCommand("rm " + otherTopLevelFile);
+ deleteFilesAs(TEST_APP_A, otherAppImg, otherAppMusic, otherAppPdf);
+ uninstallApp(TEST_APP_A);
+ }
+ }
+
+ @Test
public void testManageExternalStorageQueryOtherAppsFile() throws Exception {
final File otherAppPdf = new File(DOWNLOAD_DIR, "other" + NONMEDIA_FILE_NAME);
final File otherAppImg = new File(DCIM_DIR, "other" + IMAGE_FILE_NAME);