Home | History | Annotate | Download | only in cts
      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