1 /* 2 * Copyright (C) 2011 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.os.storage.cts; 18 19 import com.android.cts.stub.R; 20 21 import android.content.Context; 22 import android.content.res.Resources; 23 import android.content.res.Resources.NotFoundException; 24 import android.os.cts.FileUtils; 25 import android.os.storage.OnObbStateChangeListener; 26 import android.os.storage.StorageManager; 27 import android.test.AndroidTestCase; 28 import android.test.ComparisonFailure; 29 import android.util.Log; 30 31 import java.io.File; 32 import java.io.InputStream; 33 34 public class StorageManagerTest extends AndroidTestCase { 35 36 private static final String TAG = StorageManager.class.getSimpleName(); 37 38 private static final long MAX_WAIT_TIME = 25*1000; 39 private static final long WAIT_TIME_INCR = 5*1000; 40 41 private static final String OBB_MOUNT_PREFIX = "/mnt/obb/"; 42 43 private StorageManager mStorageManager; 44 45 @Override 46 protected void setUp() throws Exception { 47 super.setUp(); 48 mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE); 49 } 50 51 public void testMountAndUnmountObbNormal() { 52 final File outFile = getFilePath("test1.obb"); 53 54 final String canonPath = mountObb(R.raw.test1, outFile, OnObbStateChangeListener.MOUNTED); 55 56 mountObb(R.raw.test1, outFile, OnObbStateChangeListener.ERROR_ALREADY_MOUNTED); 57 58 final String mountPath = checkMountedPath(canonPath); 59 final File mountDir = new File(mountPath); 60 61 assertTrue("OBB mounted path should be a directory", mountDir.isDirectory()); 62 63 unmountObb(outFile, OnObbStateChangeListener.UNMOUNTED); 64 } 65 66 public void testAttemptMountNonObb() { 67 final File outFile = getFilePath("test1_nosig.obb"); 68 69 mountObb(R.raw.test1_nosig, outFile, OnObbStateChangeListener.ERROR_INTERNAL); 70 71 assertFalse("OBB should not be mounted", 72 mStorageManager.isObbMounted(outFile.getPath())); 73 74 assertNull("OBB's mounted path should be null", 75 mStorageManager.getMountedObbPath(outFile.getPath())); 76 } 77 78 public void testAttemptMountObbWrongPackage() { 79 final File outFile = getFilePath("test1_wrongpackage.obb"); 80 81 mountObb(R.raw.test1_wrongpackage, outFile, 82 OnObbStateChangeListener.ERROR_PERMISSION_DENIED); 83 84 assertFalse("OBB should not be mounted", 85 mStorageManager.isObbMounted(outFile.getPath())); 86 87 assertNull("OBB's mounted path should be null", 88 mStorageManager.getMountedObbPath(outFile.getPath())); 89 } 90 91 public void testMountAndUnmountTwoObbs() { 92 final File file1 = getFilePath("test1.obb"); 93 final File file2 = getFilePath("test2.obb"); 94 95 ObbObserver oo1 = mountObbWithoutWait(R.raw.test1, file1); 96 ObbObserver oo2 = mountObbWithoutWait(R.raw.test1, file2); 97 98 Log.d(TAG, "Waiting for OBB #1 to complete mount"); 99 waitForObbActionCompletion(file1, oo1, OnObbStateChangeListener.MOUNTED); 100 Log.d(TAG, "Waiting for OBB #2 to complete mount"); 101 waitForObbActionCompletion(file2, oo2, OnObbStateChangeListener.MOUNTED); 102 103 final String mountPath1 = checkMountedPath(oo1.getPath()); 104 final File mountDir1 = new File(mountPath1); 105 assertTrue("OBB mounted path should be a directory", mountDir1.isDirectory()); 106 107 final String mountPath2 = checkMountedPath(oo2.getPath()); 108 final File mountDir2 = new File(mountPath2); 109 assertTrue("OBB mounted path should be a directory", mountDir2.isDirectory()); 110 111 unmountObb(file1, OnObbStateChangeListener.UNMOUNTED); 112 unmountObb(file2, OnObbStateChangeListener.UNMOUNTED); 113 } 114 115 private static void assertStartsWith(String message, String prefix, String actual) { 116 if (!actual.startsWith(prefix)) { 117 throw new ComparisonFailure(message, prefix, actual); 118 } 119 } 120 121 private static class ObbObserver extends OnObbStateChangeListener { 122 private String path; 123 124 public int state = -1; 125 boolean done = false; 126 127 @Override 128 public void onObbStateChange(String path, int state) { 129 Log.d(TAG, "Received message. path=" + path + ", state=" + state); 130 synchronized (this) { 131 this.path = path; 132 this.state = state; 133 done = true; 134 notifyAll(); 135 } 136 } 137 138 public String getPath() { 139 assertTrue("Expected ObbObserver to have received a state change.", done); 140 return path; 141 } 142 143 public int getState() { 144 assertTrue("Expected ObbObserver to have received a state change.", done); 145 return state; 146 } 147 148 public boolean isDone() { 149 return done; 150 } 151 152 public boolean waitForCompletion() { 153 long waitTime = 0; 154 synchronized (this) { 155 while (!isDone() && waitTime < MAX_WAIT_TIME) { 156 try { 157 wait(WAIT_TIME_INCR); 158 waitTime += WAIT_TIME_INCR; 159 } catch (InterruptedException e) { 160 Log.i(TAG, "Interrupted during sleep", e); 161 } 162 } 163 } 164 165 return isDone(); 166 } 167 } 168 169 private File getFilePath(String name) { 170 final File filesDir = mContext.getFilesDir(); 171 final File outFile = new File(filesDir, name); 172 return outFile; 173 } 174 175 private void copyRawToFile(int rawResId, File outFile) { 176 Resources res = mContext.getResources(); 177 InputStream is = null; 178 try { 179 is = res.openRawResource(rawResId); 180 } catch (NotFoundException e) { 181 fail("Failed to load resource with id: " + rawResId); 182 } 183 FileUtils.setPermissions(outFile.getPath(), FileUtils.S_IRWXU | FileUtils.S_IRWXG 184 | FileUtils.S_IRWXO); 185 assertTrue(FileUtils.copyToFile(is, outFile)); 186 FileUtils.setPermissions(outFile.getPath(), FileUtils.S_IRWXU | FileUtils.S_IRWXG 187 | FileUtils.S_IRWXO); 188 } 189 190 private String mountObb(final int resource, final File file, int expectedState) { 191 copyRawToFile(resource, file); 192 193 final ObbObserver observer = new ObbObserver(); 194 assertTrue("mountObb call on " + file.getPath() + " should succeed", 195 mStorageManager.mountObb(file.getPath(), null, observer)); 196 197 assertTrue("Mount should have completed", 198 observer.waitForCompletion()); 199 200 if (expectedState == OnObbStateChangeListener.MOUNTED) { 201 assertTrue("OBB should be mounted", mStorageManager.isObbMounted(observer.getPath())); 202 } 203 204 assertEquals(expectedState, observer.getState()); 205 206 return observer.getPath(); 207 } 208 209 private ObbObserver mountObbWithoutWait(final int resource, final File file) { 210 copyRawToFile(resource, file); 211 212 final ObbObserver observer = new ObbObserver(); 213 assertTrue("mountObb call on " + file.getPath() + " should succeed", 214 mStorageManager.mountObb(file.getPath(), null, observer)); 215 216 return observer; 217 } 218 219 private void waitForObbActionCompletion(final File file, final ObbObserver observer, 220 int expectedState) { 221 assertTrue("Mount should have completed", observer.waitForCompletion()); 222 223 assertTrue("OBB should be mounted", mStorageManager.isObbMounted(observer.getPath())); 224 225 assertEquals(expectedState, observer.getState()); 226 } 227 228 private String checkMountedPath(final String path) { 229 final String mountPath = mStorageManager.getMountedObbPath(path); 230 assertStartsWith("Path should be in " + OBB_MOUNT_PREFIX, 231 OBB_MOUNT_PREFIX, 232 mountPath); 233 return mountPath; 234 } 235 236 private void unmountObb(final File file, int expectedState) { 237 final ObbObserver observer = new ObbObserver(); 238 239 assertTrue("unmountObb call on test1.obb should succeed", 240 mStorageManager.unmountObb(file.getPath(), false, observer)); 241 242 assertTrue("Unmount should have completed", 243 observer.waitForCompletion()); 244 245 assertEquals(expectedState, observer.getState()); 246 247 if (expectedState == OnObbStateChangeListener.UNMOUNTED) { 248 assertFalse("OBB should not be mounted", mStorageManager.isObbMounted(file.getPath())); 249 } 250 } 251 } 252