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