blob: b1b31744c88b356e5d08f1848933bf596db03a0e [file] [log] [blame]
Kenny Root17eb6fb2010-10-06 15:02:52 -07001/*
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 com.android.server;
18
Kenny Root17eb6fb2010-10-06 15:02:52 -070019import android.content.Context;
20import android.content.res.Resources;
21import android.content.res.Resources.NotFoundException;
Kenny Root17eb6fb2010-10-06 15:02:52 -070022import android.os.FileUtils;
23import android.os.storage.OnObbStateChangeListener;
24import android.os.storage.StorageManager;
25import android.test.AndroidTestCase;
26import android.test.ComparisonFailure;
27import android.test.suitebuilder.annotation.LargeTest;
28import android.util.Log;
29
Jeff Sharkey4fbbda42012-09-24 18:34:07 -070030import com.android.frameworks.servicestests.R;
31
Kenny Root17eb6fb2010-10-06 15:02:52 -070032import java.io.File;
33import java.io.InputStream;
34
35public 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
Kenny Root17eb6fb2010-10-06 15:02:52 -070043 private static void assertStartsWith(String message, String prefix, String actual) {
44 if (!actual.startsWith(prefix)) {
45 throw new ComparisonFailure(message, prefix, actual);
46 }
47 }
48
Kenny Rootaf9d6672010-10-08 09:21:39 -070049 private static class ObbObserver extends OnObbStateChangeListener {
50 private String path;
Kenny Root17eb6fb2010-10-06 15:02:52 -070051
Kenny Rootaf9d6672010-10-08 09:21:39 -070052 public int state = -1;
Kenny Root17eb6fb2010-10-06 15:02:52 -070053 boolean done = false;
54
55 @Override
Kenny Rootaf9d6672010-10-08 09:21:39 -070056 public void onObbStateChange(String path, int state) {
57 Log.d(TAG, "Received message. path=" + path + ", state=" + state);
Kenny Root17eb6fb2010-10-06 15:02:52 -070058 synchronized (this) {
59 this.path = path;
60 this.state = state;
61 done = true;
62 notifyAll();
63 }
64 }
65
Kenny Rootaf9d6672010-10-08 09:21:39 -070066 public String getPath() {
67 assertTrue("Expected ObbObserver to have received a state change.", done);
68 return path;
69 }
70
71 public int getState() {
72 assertTrue("Expected ObbObserver to have received a state change.", done);
73 return state;
74 }
75
Kenny Root17eb6fb2010-10-06 15:02:52 -070076 public void reset() {
77 this.path = null;
Kenny Rootaf9d6672010-10-08 09:21:39 -070078 this.state = -1;
Kenny Root17eb6fb2010-10-06 15:02:52 -070079 done = false;
80 }
81
82 public boolean isDone() {
83 return done;
84 }
Kenny Root17eb6fb2010-10-06 15:02:52 -070085
Kenny Rootaf9d6672010-10-08 09:21:39 -070086 public boolean waitForCompletion() {
87 long waitTime = 0;
88 synchronized (this) {
89 while (!isDone() && waitTime < MAX_WAIT_TIME) {
90 try {
91 wait(WAIT_TIME_INCR);
92 waitTime += WAIT_TIME_INCR;
93 } catch (InterruptedException e) {
94 Log.i(TAG, "Interrupted during sleep", e);
95 }
Kenny Root17eb6fb2010-10-06 15:02:52 -070096 }
97 }
Kenny Root17eb6fb2010-10-06 15:02:52 -070098
Kenny Rootaf9d6672010-10-08 09:21:39 -070099 return isDone();
100 }
Kenny Root17eb6fb2010-10-06 15:02:52 -0700101 }
Kenny Rootaf9d6672010-10-08 09:21:39 -0700102
Kenny Root17eb6fb2010-10-06 15:02:52 -0700103 private File getFilePath(String name) {
104 final File filesDir = mContext.getFilesDir();
105 final File outFile = new File(filesDir, name);
106 return outFile;
107 }
108
109 private void copyRawToFile(int rawResId, File outFile) {
110 Resources res = mContext.getResources();
111 InputStream is = null;
112 try {
113 is = res.openRawResource(rawResId);
114 } catch (NotFoundException e) {
115 fail("Failed to load resource with id: " + rawResId);
116 }
117 FileUtils.setPermissions(outFile.getPath(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
118 | FileUtils.S_IRWXO, -1, -1);
119 assertTrue(FileUtils.copyToFile(is, outFile));
120 FileUtils.setPermissions(outFile.getPath(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
121 | FileUtils.S_IRWXO, -1, -1);
122 }
123
124 private StorageManager getStorageManager() {
125 return (StorageManager) getContext().getSystemService(Context.STORAGE_SERVICE);
126 }
127
128 private void mountObb(StorageManager sm, final int resource, final File file,
Kenny Rootaf9d6672010-10-08 09:21:39 -0700129 int expectedState) {
Kenny Root17eb6fb2010-10-06 15:02:52 -0700130 copyRawToFile(resource, file);
131
Kenny Rootaf9d6672010-10-08 09:21:39 -0700132 final ObbObserver observer = new ObbObserver();
Kenny Root17eb6fb2010-10-06 15:02:52 -0700133 assertTrue("mountObb call on " + file.getPath() + " should succeed",
134 sm.mountObb(file.getPath(), null, observer));
135
136 assertTrue("Mount should have completed",
Kenny Rootaf9d6672010-10-08 09:21:39 -0700137 observer.waitForCompletion());
138
139 if (expectedState == OnObbStateChangeListener.MOUNTED) {
140 assertTrue("OBB should be mounted", sm.isObbMounted(file.getPath()));
141 }
Kenny Root17eb6fb2010-10-06 15:02:52 -0700142
143 assertEquals("Actual file and resolved file should be the same",
Kenny Rootaf9d6672010-10-08 09:21:39 -0700144 file.getPath(), observer.getPath());
Kenny Root17eb6fb2010-10-06 15:02:52 -0700145
Kenny Rootaf9d6672010-10-08 09:21:39 -0700146 assertEquals(expectedState, observer.getState());
Kenny Root17eb6fb2010-10-06 15:02:52 -0700147 }
148
Kenny Rootaf9d6672010-10-08 09:21:39 -0700149 private ObbObserver mountObbWithoutWait(final StorageManager sm, final int resource,
150 final File file) {
151 copyRawToFile(resource, file);
152
153 final ObbObserver observer = new ObbObserver();
154 assertTrue("mountObb call on " + file.getPath() + " should succeed", sm.mountObb(file
155 .getPath(), null, observer));
156
157 return observer;
158 }
159
160 private void waitForObbActionCompletion(final StorageManager sm, final File file,
161 final ObbObserver observer, int expectedState, boolean checkPath) {
162 assertTrue("Mount should have completed", observer.waitForCompletion());
163
164 assertTrue("OBB should be mounted", sm.isObbMounted(file.getPath()));
165
166 if (checkPath) {
167 assertEquals("Actual file and resolved file should be the same", file.getPath(),
168 observer.getPath());
169 }
170
171 assertEquals(expectedState, observer.getState());
172 }
173
174 private String checkMountedPath(final StorageManager sm, final File file) {
Kenny Root17eb6fb2010-10-06 15:02:52 -0700175 final String mountPath = sm.getMountedObbPath(file.getPath());
176 assertStartsWith("Path should be in " + OBB_MOUNT_PREFIX,
177 OBB_MOUNT_PREFIX,
178 mountPath);
179 return mountPath;
180 }
181
Kenny Rootaf9d6672010-10-08 09:21:39 -0700182 private void unmountObb(final StorageManager sm, final File file, int expectedState) {
183 final ObbObserver observer = new ObbObserver();
184
Kenny Root17eb6fb2010-10-06 15:02:52 -0700185 assertTrue("unmountObb call on test1.obb should succeed",
Xiaohui Chen621b3fc2015-10-02 14:41:42 -0700186 sm.unmountObb(file.getPath(), false, observer));
Kenny Root17eb6fb2010-10-06 15:02:52 -0700187
188 assertTrue("Unmount should have completed",
Kenny Rootaf9d6672010-10-08 09:21:39 -0700189 observer.waitForCompletion());
190
191 assertEquals(expectedState, observer.getState());
192
193 if (expectedState == OnObbStateChangeListener.UNMOUNTED) {
194 assertFalse("OBB should not be mounted", sm.isObbMounted(file.getPath()));
195 }
Kenny Root17eb6fb2010-10-06 15:02:52 -0700196 }
197
198 @LargeTest
199 public void testMountAndUnmountObbNormal() {
200 StorageManager sm = getStorageManager();
201
202 final File outFile = getFilePath("test1.obb");
203
Kenny Rootaf9d6672010-10-08 09:21:39 -0700204 mountObb(sm, R.raw.test1, outFile, OnObbStateChangeListener.MOUNTED);
205
206 mountObb(sm, R.raw.test1, outFile, OnObbStateChangeListener.ERROR_ALREADY_MOUNTED);
Kenny Root17eb6fb2010-10-06 15:02:52 -0700207
208 final String mountPath = checkMountedPath(sm, outFile);
209 final File mountDir = new File(mountPath);
210
211 assertTrue("OBB mounted path should be a directory",
212 mountDir.isDirectory());
213
Kenny Rootaf9d6672010-10-08 09:21:39 -0700214 unmountObb(sm, outFile, OnObbStateChangeListener.UNMOUNTED);
Kenny Root17eb6fb2010-10-06 15:02:52 -0700215 }
216
217 @LargeTest
218 public void testAttemptMountNonObb() {
219 StorageManager sm = getStorageManager();
220
221 final File outFile = getFilePath("test1_nosig.obb");
222
Sudheer Shanka25469aa2018-08-27 15:50:23 -0700223 try {
224 mountObb(sm, R.raw.test1_nosig, outFile, OnObbStateChangeListener.ERROR_INTERNAL);
225 fail("mountObb should've failed with an exception");
226 } catch (IllegalArgumentException e) {
227 // Expected
228 }
Kenny Root17eb6fb2010-10-06 15:02:52 -0700229
230 assertFalse("OBB should not be mounted",
231 sm.isObbMounted(outFile.getPath()));
232
233 assertNull("OBB's mounted path should be null",
234 sm.getMountedObbPath(outFile.getPath()));
235 }
236
237 @LargeTest
238 public void testAttemptMountObbWrongPackage() {
239 StorageManager sm = getStorageManager();
240
241 final File outFile = getFilePath("test1_wrongpackage.obb");
242
Kenny Rootaf9d6672010-10-08 09:21:39 -0700243 mountObb(sm, R.raw.test1_wrongpackage, outFile,
244 OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
Kenny Root17eb6fb2010-10-06 15:02:52 -0700245
246 assertFalse("OBB should not be mounted",
247 sm.isObbMounted(outFile.getPath()));
248
249 assertNull("OBB's mounted path should be null",
250 sm.getMountedObbPath(outFile.getPath()));
251 }
Kenny Rootaf9d6672010-10-08 09:21:39 -0700252
253 @LargeTest
254 public void testMountAndUnmountTwoObbs() {
255 StorageManager sm = getStorageManager();
256
257 final File file1 = getFilePath("test1.obb");
258 final File file2 = getFilePath("test2.obb");
259
260 ObbObserver oo1 = mountObbWithoutWait(sm, R.raw.test1, file1);
261 ObbObserver oo2 = mountObbWithoutWait(sm, R.raw.test1, file2);
262
263 Log.d(TAG, "Waiting for OBB #1 to complete mount");
264 waitForObbActionCompletion(sm, file1, oo1, OnObbStateChangeListener.MOUNTED, false);
265 Log.d(TAG, "Waiting for OBB #2 to complete mount");
266 waitForObbActionCompletion(sm, file2, oo2, OnObbStateChangeListener.MOUNTED, false);
267
268 final String mountPath1 = checkMountedPath(sm, file1);
269 final File mountDir1 = new File(mountPath1);
270 assertTrue("OBB mounted path should be a directory", mountDir1.isDirectory());
271
272 final String mountPath2 = checkMountedPath(sm, file2);
273 final File mountDir2 = new File(mountPath2);
274 assertTrue("OBB mounted path should be a directory", mountDir2.isDirectory());
275
276 unmountObb(sm, file1, OnObbStateChangeListener.UNMOUNTED);
277 unmountObb(sm, file2, OnObbStateChangeListener.UNMOUNTED);
278 }
Kenny Root17eb6fb2010-10-06 15:02:52 -0700279}