Home | History | Annotate | Download | only in storage
      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 android.os.storage;
     18 
     19 import android.os.ParcelFileDescriptor;
     20 import android.os.ProxyFileDescriptorCallback;
     21 import android.system.ErrnoException;
     22 import android.test.suitebuilder.annotation.LargeTest;
     23 import android.util.Log;
     24 
     25 import com.android.frameworks.coretests.R;
     26 
     27 import java.io.File;
     28 import java.util.concurrent.ThreadFactory;
     29 
     30 public class StorageManagerIntegrationTest extends StorageManagerBaseTest {
     31     private static String LOG_TAG = "StorageManagerIntegrationTest";
     32 
     33     /**
     34      * Tests mounting a single OBB file and verifies its contents.
     35      */
     36     @LargeTest
     37     public void testMountSingleObb() throws Exception {
     38         final File file = createObbFile(OBB_FILE_1, R.raw.obb_file1);
     39         String filePath = file.getAbsolutePath();
     40         mountObb(filePath);
     41         verifyObb1Contents(filePath);
     42         unmountObb(filePath, DONT_FORCE);
     43     }
     44 
     45     /**
     46      * Tests mounting several OBB files and verifies its contents.
     47      */
     48     @LargeTest
     49     public void testMountMultipleObb() throws Exception {
     50         File file1 = null;
     51         File file2 = null;
     52         File file3 = null;
     53         try {
     54             file1 = createObbFile(OBB_FILE_1, R.raw.obb_file1);
     55             String filePath1 = file1.getAbsolutePath();
     56             mountObb(filePath1);
     57             verifyObb1Contents(filePath1);
     58 
     59             file2 = createObbFile(OBB_FILE_2, R.raw.obb_file2);
     60             String filePath2 = file2.getAbsolutePath();
     61             mountObb(filePath2);
     62             verifyObb2Contents(filePath2);
     63 
     64             file3 = createObbFile(OBB_FILE_3, R.raw.obb_file3);
     65             String filePath3 = file3.getAbsolutePath();
     66             mountObb(filePath3);
     67             verifyObb3Contents(filePath3);
     68 
     69             unmountObb(filePath1, DONT_FORCE);
     70             unmountObb(filePath2, DONT_FORCE);
     71             unmountObb(filePath3, DONT_FORCE);
     72         } finally {
     73             if (file1 != null) {
     74                 file1.delete();
     75             }
     76             if (file2 != null) {
     77                 file2.delete();
     78             }
     79             if (file3 != null) {
     80                 file3.delete();
     81             }
     82         }
     83     }
     84 
     85     /**
     86      * Tests mounting a single encrypted OBB file and verifies its contents.
     87      */
     88     @LargeTest
     89     public void testMountSingleEncryptedObb() throws Exception {
     90         final File file = createObbFile(OBB_FILE_3_ENCRYPTED, R.raw.obb_enc_file100_orig3);
     91         String filePath = file.getAbsolutePath();
     92         mountObb(filePath, OBB_FILE_3_PASSWORD, OnObbStateChangeListener.MOUNTED);
     93         verifyObb3Contents(filePath);
     94         unmountObb(filePath, DONT_FORCE);
     95     }
     96 
     97     /**
     98      * Tests mounting a single encrypted OBB file using an invalid password.
     99      */
    100     @LargeTest
    101     public void testMountSingleEncryptedObbInvalidPassword() throws Exception {
    102         final File file = createObbFile("bad password@$%#@^*(!&)", R.raw.obb_enc_file100_orig3);
    103         String filePath = file.getAbsolutePath();
    104         mountObb(filePath, OBB_FILE_1_PASSWORD, OnObbStateChangeListener.ERROR_COULD_NOT_MOUNT);
    105     }
    106 
    107     /**
    108      * Tests simultaneously mounting 2 encrypted OBBs with different keys and verifies contents.
    109      */
    110     @LargeTest
    111     public void testMountTwoEncryptedObb() throws Exception {
    112         File file3 = null;
    113         File file1 = null;
    114         try {
    115             file3 = createObbFile(OBB_FILE_3_ENCRYPTED, R.raw.obb_enc_file100_orig3);
    116             String filePath3 = file3.getAbsolutePath();
    117             mountObb(filePath3, OBB_FILE_3_PASSWORD, OnObbStateChangeListener.MOUNTED);
    118             verifyObb3Contents(filePath3);
    119 
    120             file1 = createObbFile(OBB_FILE_1_ENCRYPTED, R.raw.obb_enc_file100_orig1);
    121             String filePath1 = file1.getAbsolutePath();
    122             mountObb(filePath1, OBB_FILE_1_PASSWORD, OnObbStateChangeListener.MOUNTED);
    123             verifyObb1Contents(filePath1);
    124 
    125             unmountObb(filePath3, DONT_FORCE);
    126             unmountObb(filePath1, DONT_FORCE);
    127         } finally {
    128             if (file3 != null) {
    129                 file3.delete();
    130             }
    131             if (file1 != null) {
    132                 file1.delete();
    133             }
    134         }
    135     }
    136 
    137     /**
    138      * Tests that we can not force unmount when a file is currently open on the OBB.
    139      */
    140     @LargeTest
    141     public void testUnmount_DontForce() throws Exception {
    142         final File file = createObbFile(OBB_FILE_1, R.raw.obb_file1);
    143         String obbFilePath = file.getAbsolutePath();
    144 
    145         MountingObbThread mountingThread = new MountingObbThread(obbFilePath,
    146                 OBB_FILE_1_CONTENTS_1);
    147 
    148         try {
    149             mountingThread.start();
    150 
    151             long waitTime = 0;
    152             while (!mountingThread.isFileOpenOnObb()) {
    153                 synchronized (mountingThread) {
    154                     Log.i(LOG_TAG, "Waiting for file to be opened on OBB...");
    155                     mountingThread.wait(WAIT_TIME_INCR);
    156                     waitTime += WAIT_TIME_INCR;
    157                     if (waitTime > MAX_WAIT_TIME) {
    158                         fail("Timed out waiting for file file to be opened on OBB!");
    159                     }
    160                 }
    161             }
    162 
    163             unmountObb(obbFilePath, DONT_FORCE);
    164 
    165             // verify still mounted
    166             assertTrue("mounted path should not be null!", obbFilePath != null);
    167             assertTrue("mounted path should still be mounted!", mSm.isObbMounted(obbFilePath));
    168 
    169             // close the opened file
    170             mountingThread.doStop();
    171 
    172             // try unmounting again (should succeed this time)
    173             unmountObb(obbFilePath, DONT_FORCE);
    174             assertFalse("mounted path should no longer be mounted!",
    175                     mSm.isObbMounted(obbFilePath));
    176         } catch (InterruptedException e) {
    177             fail("Timed out waiting for file on OBB to be opened...");
    178         }
    179     }
    180 
    181     /**
    182      * Tests mounting a single OBB that isn't signed.
    183      */
    184     @LargeTest
    185     public void testMountUnsignedObb() throws Exception {
    186         final File file = createObbFile(OBB_FILE_2_UNSIGNED, R.raw.obb_file2_nosign);
    187         String filePath = file.getAbsolutePath();
    188         mountObb(filePath, OBB_FILE_2_UNSIGNED, OnObbStateChangeListener.ERROR_INTERNAL);
    189     }
    190 
    191     /**
    192      * Tests mounting a single OBB that is signed with a different package.
    193      */
    194     @LargeTest
    195     public void testMountBadPackageNameObb() throws Exception {
    196         final File file = createObbFile(OBB_FILE_3_BAD_PACKAGENAME, R.raw.obb_file3_bad_packagename);
    197         String filePath = file.getAbsolutePath();
    198         mountObb(filePath, OBB_FILE_3_BAD_PACKAGENAME,
    199                 OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
    200     }
    201 
    202     /**
    203      * Tests remounting a single OBB that has already been mounted.
    204      */
    205     @LargeTest
    206     public void testRemountObb() throws Exception {
    207         final File file = createObbFile(OBB_FILE_1, R.raw.obb_file1);
    208         String filePath = file.getAbsolutePath();
    209         mountObb(filePath);
    210         verifyObb1Contents(filePath);
    211         mountObb(filePath, null, OnObbStateChangeListener.ERROR_ALREADY_MOUNTED);
    212         verifyObb1Contents(filePath);
    213         unmountObb(filePath, DONT_FORCE);
    214     }
    215 
    216     @LargeTest
    217     public void testOpenProxyFileDescriptor() throws Exception {
    218         final ProxyFileDescriptorCallback callback = new ProxyFileDescriptorCallback() {
    219             @Override
    220             public long onGetSize() throws ErrnoException {
    221                 return 0;
    222             }
    223 
    224             @Override
    225             public void onRelease() {}
    226         };
    227 
    228         final MyThreadFactory factory = new MyThreadFactory();
    229         int firstMountId;
    230         try (final ParcelFileDescriptor fd = mSm.openProxyFileDescriptor(
    231                 ParcelFileDescriptor.MODE_READ_ONLY, callback, null, factory)) {
    232             assertNotSame(Thread.State.TERMINATED, factory.thread.getState());
    233             firstMountId = mSm.getProxyFileDescriptorMountPointId();
    234             assertNotSame(-1, firstMountId);
    235         }
    236 
    237         // After closing descriptor, the loop should terminate.
    238         factory.thread.join(3000);
    239         assertEquals(Thread.State.TERMINATED, factory.thread.getState());
    240 
    241         // StorageManager should mount another bridge on the next open request.
    242         try (final ParcelFileDescriptor fd = mSm.openProxyFileDescriptor(
    243                 ParcelFileDescriptor.MODE_WRITE_ONLY, callback, null, factory)) {
    244             assertNotSame(Thread.State.TERMINATED, factory.thread.getState());
    245             assertNotSame(firstMountId, mSm.getProxyFileDescriptorMountPointId());
    246         }
    247     }
    248 
    249     private static class MyThreadFactory implements ThreadFactory {
    250         Thread thread = null;
    251 
    252         @Override
    253         public Thread newThread(Runnable r) {
    254             thread = new Thread(r);
    255             return thread;
    256         }
    257     }
    258 }
    259