1 /* 2 * Copyright (C) 2012 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.cts.multiuserstorageapp; 18 19 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirNoAccess; 20 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getAllPackageSpecificPathsExceptObb; 21 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.readInt; 22 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.writeInt; 23 24 import android.os.Environment; 25 import android.test.AndroidTestCase; 26 import android.util.Log; 27 28 import java.io.File; 29 30 /** 31 * Test multi-user emulated storage environment, ensuring that each user has 32 * isolated storage minus shared OBB directory. 33 */ 34 public class MultiUserStorageTest extends AndroidTestCase { 35 private static final String TAG = "MultiUserStorageTest"; 36 37 private static final String FILE_PREFIX = "MUST_"; 38 39 private final String FILE_SINGLETON = FILE_PREFIX + "singleton"; 40 private final String FILE_OBB_SINGLETON = FILE_PREFIX + "obb_singleton"; 41 private final String FILE_OBB_API_SINGLETON = FILE_PREFIX + "obb_api_singleton"; 42 private final String FILE_MY_UID = FILE_PREFIX + android.os.Process.myUid(); 43 44 private static final int OBB_API_VALUE = 0xcafe; 45 private static final int OBB_VALUE = 0xf00d; 46 wipeTestFiles(File dir)47 private void wipeTestFiles(File dir) { 48 dir.mkdirs(); 49 final File[] files = dir.listFiles(); 50 if (files == null) return; 51 for (File file : files) { 52 if (file.getName().startsWith(FILE_PREFIX)) { 53 Log.d(TAG, "Wiping " + file); 54 file.delete(); 55 } 56 } 57 } 58 testCleanIsolatedStorage()59 public void testCleanIsolatedStorage() throws Exception { 60 wipeTestFiles(Environment.getExternalStorageDirectory()); 61 } 62 testWriteIsolatedStorage()63 public void testWriteIsolatedStorage() throws Exception { 64 final int uid = android.os.Process.myUid(); 65 66 writeInt(buildApiPath(FILE_SINGLETON), uid); 67 writeInt(buildApiPath(FILE_MY_UID), uid); 68 69 // Write to every external path we think we have access to 70 for (File path : getAllPackageSpecificPathsExceptObb(getContext())) { 71 assertNotNull("Valid media must be inserted during CTS", path); 72 assertEquals("Valid media must be inserted during CTS", Environment.MEDIA_MOUNTED, 73 Environment.getExternalStorageState(path)); 74 75 writeInt(new File(path, FILE_SINGLETON), uid); 76 } 77 } 78 testReadIsolatedStorage()79 public void testReadIsolatedStorage() throws Exception { 80 final int uid = android.os.Process.myUid(); 81 82 // Expect that the value we wrote earlier is still valid and wasn't 83 // overwritten by us running as another user. 84 assertEquals("Failed to read singleton file from API path", uid, 85 readInt(buildApiPath(FILE_SINGLETON))); 86 assertEquals("Failed to read singleton file from env path", uid, 87 readInt(buildEnvPath(FILE_SINGLETON))); 88 assertEquals("Failed to read singleton file from raw path", uid, 89 readInt(buildRawPath(FILE_SINGLETON))); 90 91 assertEquals("Failed to read UID file from API path", uid, 92 readInt(buildApiPath(FILE_MY_UID))); 93 94 for (File path : getAllPackageSpecificPathsExceptObb(getContext())) { 95 assertNotNull("Valid media must be inserted during CTS", path); 96 assertEquals("Valid media must be inserted during CTS", Environment.MEDIA_MOUNTED, 97 Environment.getExternalStorageState(path)); 98 99 assertEquals("Unexpected value in singleton file at " + path, uid, 100 readInt(new File(path, FILE_SINGLETON))); 101 } 102 } 103 testCleanObbStorage()104 public void testCleanObbStorage() throws Exception { 105 wipeTestFiles(getContext().getObbDir()); 106 } 107 testWriteObbStorage()108 public void testWriteObbStorage() throws Exception { 109 writeInt(buildApiObbPath(FILE_OBB_API_SINGLETON), OBB_API_VALUE); 110 writeInt(buildEnvObbPath(FILE_OBB_SINGLETON), OBB_VALUE); 111 } 112 testReadObbStorage()113 public void testReadObbStorage() throws Exception { 114 assertEquals("Failed to read OBB file from API path", OBB_API_VALUE, 115 readInt(buildApiObbPath(FILE_OBB_API_SINGLETON))); 116 117 assertEquals("Failed to read OBB file from env path", OBB_VALUE, 118 readInt(buildEnvObbPath(FILE_OBB_SINGLETON))); 119 assertEquals("Failed to read OBB file from raw path", OBB_VALUE, 120 readInt(buildRawObbPath(FILE_OBB_SINGLETON))); 121 } 122 123 /** 124 * Verify that we can't poke at storage of other users. 125 */ testUserIsolation()126 public void testUserIsolation() throws Exception { 127 final File myPath = Environment.getExternalStorageDirectory(); 128 final int myId = android.os.Process.myUid() / 100000; 129 assertEquals(String.valueOf(myId), myPath.getName()); 130 131 Log.d(TAG, "My path is " + myPath); 132 final File basePath = myPath.getParentFile(); 133 for (int i = 0; i < 128; i++) { 134 if (i == myId) continue; 135 136 final File otherPath = new File(basePath, String.valueOf(i)); 137 assertDirNoAccess(otherPath); 138 } 139 } 140 buildApiObbPath(String file)141 private File buildApiObbPath(String file) { 142 return new File(getContext().getObbDir(), file); 143 } 144 buildEnvObbPath(String file)145 private File buildEnvObbPath(String file) { 146 return new File(new File(System.getenv("EXTERNAL_STORAGE"), "Android/obb"), file); 147 } 148 buildRawObbPath(String file)149 private File buildRawObbPath(String file) { 150 return new File("/sdcard/Android/obb/", file); 151 } 152 buildApiPath(String file)153 private static File buildApiPath(String file) { 154 return new File(Environment.getExternalStorageDirectory(), file); 155 } 156 buildEnvPath(String file)157 private static File buildEnvPath(String file) { 158 return new File(System.getenv("EXTERNAL_STORAGE"), file); 159 } 160 buildRawPath(String file)161 private static File buildRawPath(String file) { 162 return new File("/sdcard/", file); 163 } 164 } 165