Assert that all external storage is isolated.

Any storage devices exposed through APIs need to be fully isolated
across user boundaries.

Bug: 11221486
Change-Id: I3e82d970f3a1b0c00c02e71f4eacbad81d452096
diff --git a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
index 5d3bdb6..f38236b 100644
--- a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
@@ -122,6 +122,14 @@
         return paths;
     }
 
+    public static List<File> getAllPackageSpecificPathsExceptObb(Context context) {
+        final List<File> paths = new ArrayList<File>();
+        Collections.addAll(paths, context.getExternalCacheDirs());
+        Collections.addAll(paths, context.getExternalFilesDirs(null));
+        Collections.addAll(paths, context.getExternalFilesDirs(Environment.DIRECTORY_PICTURES));
+        return paths;
+    }
+
     public static List<File> getPrimaryPackageSpecificPaths(Context context) {
         final List<File> paths = new ArrayList<File>();
         Collections.addAll(paths, context.getExternalCacheDir());
diff --git a/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/Android.mk b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/Android.mk
index 8781e8b..48f88b8 100644
--- a/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/Android.mk
@@ -17,9 +17,11 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := 16
+LOCAL_SDK_VERSION := current
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+    ../ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
+
 LOCAL_PACKAGE_NAME := CtsMultiUserStorageApp
 
 LOCAL_DEX_PREOPT := false
diff --git a/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/src/com/android/cts/multiuserstorageapp/MultiUserStorageTest.java b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/src/com/android/cts/multiuserstorageapp/MultiUserStorageTest.java
index 267bf11..2a80c75 100644
--- a/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/src/com/android/cts/multiuserstorageapp/MultiUserStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/src/com/android/cts/multiuserstorageapp/MultiUserStorageTest.java
@@ -16,16 +16,15 @@
 
 package com.android.cts.multiuserstorageapp;
 
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getAllPackageSpecificPathsExceptObb;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.readInt;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.writeInt;
+
 import android.os.Environment;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
 
 /**
  * Test multi-user emulated storage environment, ensuring that each user has
@@ -59,22 +58,44 @@
     }
 
     public void writeIsolatedStorage() throws Exception {
-        writeInt(buildApiPath(FILE_SINGLETON), android.os.Process.myUid());
-        writeInt(buildApiPath(FILE_MY_UID), android.os.Process.myUid());
+        final int uid = android.os.Process.myUid();
+
+        writeInt(buildApiPath(FILE_SINGLETON), uid);
+        writeInt(buildApiPath(FILE_MY_UID), uid);
+
+        // Write to every external path we think we have access to
+        for (File path : getAllPackageSpecificPathsExceptObb(getContext())) {
+            assertNotNull("Valid media must be inserted during CTS", path);
+            assertEquals("Valid media must be inserted during CTS", Environment.MEDIA_MOUNTED,
+                    Environment.getStorageState(path));
+
+            writeInt(new File(path, FILE_SINGLETON), uid);
+        }
     }
 
     public void readIsolatedStorage() throws Exception {
+        final int uid = android.os.Process.myUid();
+
         // Expect that the value we wrote earlier is still valid and wasn't
         // overwritten by us running as another user.
-        assertEquals("Failed to read singleton file from API path", android.os.Process.myUid(),
+        assertEquals("Failed to read singleton file from API path", uid,
                 readInt(buildApiPath(FILE_SINGLETON)));
-        assertEquals("Failed to read singleton file from env path", android.os.Process.myUid(),
+        assertEquals("Failed to read singleton file from env path", uid,
                 readInt(buildEnvPath(FILE_SINGLETON)));
-        assertEquals("Failed to read singleton file from raw path", android.os.Process.myUid(),
+        assertEquals("Failed to read singleton file from raw path", uid,
                 readInt(buildRawPath(FILE_SINGLETON)));
 
-        assertEquals("Failed to read UID file from API path", android.os.Process.myUid(),
+        assertEquals("Failed to read UID file from API path", uid,
                 readInt(buildApiPath(FILE_MY_UID)));
+
+        for (File path : getAllPackageSpecificPathsExceptObb(getContext())) {
+            assertNotNull("Valid media must be inserted during CTS", path);
+            assertEquals("Valid media must be inserted during CTS", Environment.MEDIA_MOUNTED,
+                    Environment.getStorageState(path));
+
+            assertEquals("Unexpected value in singleton file at " + path, uid,
+                    readInt(new File(path, FILE_SINGLETON)));
+        }
     }
 
     public void cleanObbStorage() throws Exception {
@@ -119,22 +140,4 @@
     private static File buildRawPath(String file) {
         return new File("/sdcard/", file);
     }
-
-    private static void writeInt(File file, int value) throws IOException {
-        final DataOutputStream os = new DataOutputStream(new FileOutputStream(file));
-        try {
-            os.writeInt(value);
-        } finally {
-            os.close();
-        }
-    }
-
-    private static int readInt(File file) throws IOException {
-        final DataInputStream is = new DataInputStream(new FileInputStream(file));
-        try {
-            return is.readInt();
-        } finally {
-            is.close();
-        }
-    }
 }