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