• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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.cts.externalstorageapp;
18 
19 import android.content.Context;
20 import android.os.Environment;
21 import android.test.AndroidTestCase;
22 import android.util.Log;
23 
24 import java.io.DataInputStream;
25 import java.io.DataOutputStream;
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.FileOutputStream;
29 import java.io.IOException;
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.List;
33 
34 /**
35  * Tests common functionality that should be supported regardless of external
36  * storage status.
37  */
38 public class CommonExternalStorageTest extends AndroidTestCase {
39     public static final String TAG = "CommonExternalStorageTest";
40 
41     public static final String PACKAGE_NONE = "com.android.cts.externalstorageapp";
42     public static final String PACKAGE_READ = "com.android.cts.readexternalstorageapp";
43     public static final String PACKAGE_WRITE = "com.android.cts.writeexternalstorageapp";
44 
45     /**
46      * Primary storage must always be mounted.
47      */
testExternalStorageMounted()48     public void testExternalStorageMounted() {
49         assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
50     }
51 
52     /**
53      * Verify that single path is always first item in multiple.
54      */
testMultipleCacheDirs()55     public void testMultipleCacheDirs() throws Exception {
56         final File single = getContext().getExternalCacheDir();
57         assertNotNull("Primary storage must always be available", single);
58         final File firstMultiple = getContext().getExternalCacheDirs()[0];
59         assertEquals(single, firstMultiple);
60     }
61 
62     /**
63      * Verify that single path is always first item in multiple.
64      */
testMultipleFilesDirs()65     public void testMultipleFilesDirs() throws Exception {
66         final File single = getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
67         assertNotNull("Primary storage must always be available", single);
68         final File firstMultiple = getContext()
69                 .getExternalFilesDirs(Environment.DIRECTORY_PICTURES)[0];
70         assertEquals(single, firstMultiple);
71     }
72 
73     /**
74      * Verify that single path is always first item in multiple.
75      */
testMultipleObbDirs()76     public void testMultipleObbDirs() throws Exception {
77         final File single = getContext().getObbDir();
78         assertNotNull("Primary storage must always be available", single);
79         final File firstMultiple = getContext().getObbDirs()[0];
80         assertEquals(single, firstMultiple);
81     }
82 
83     /**
84      * Verify we can write to our own package dirs.
85      */
testAllPackageDirsWritable()86     public void testAllPackageDirsWritable() throws Exception {
87         final List<File> paths = getAllPackageSpecificPaths(getContext());
88         for (File path : paths) {
89             assertNotNull("Valid media must be inserted during CTS", path);
90             assertEquals("Valid media must be inserted during CTS", Environment.MEDIA_MOUNTED,
91                     Environment.getStorageState(path));
92 
93             assertDirReadWriteAccess(path);
94 
95             final File directChild = new File(path, "directChild");
96             final File subdir = new File(path, "subdir");
97             final File subdirChild = new File(path, "subdirChild");
98 
99             writeInt(directChild, 32);
100             subdir.mkdirs();
101             assertDirReadWriteAccess(subdir);
102             writeInt(subdirChild, 64);
103 
104             assertEquals(32, readInt(directChild));
105             assertEquals(64, readInt(subdirChild));
106         }
107 
108         for (File path : paths) {
109             deleteContents(path);
110         }
111     }
112 
113     /**
114      * Return a set of several package-specific external storage paths.
115      */
getAllPackageSpecificPaths(Context context)116     public static List<File> getAllPackageSpecificPaths(Context context) {
117         final List<File> paths = new ArrayList<File>();
118         Collections.addAll(paths, context.getExternalCacheDirs());
119         Collections.addAll(paths, context.getExternalFilesDirs(null));
120         Collections.addAll(paths, context.getExternalFilesDirs(Environment.DIRECTORY_PICTURES));
121         Collections.addAll(paths, context.getObbDirs());
122         return paths;
123     }
124 
getAllPackageSpecificPathsExceptObb(Context context)125     public static List<File> getAllPackageSpecificPathsExceptObb(Context context) {
126         final List<File> paths = new ArrayList<File>();
127         Collections.addAll(paths, context.getExternalCacheDirs());
128         Collections.addAll(paths, context.getExternalFilesDirs(null));
129         Collections.addAll(paths, context.getExternalFilesDirs(Environment.DIRECTORY_PICTURES));
130         return paths;
131     }
132 
getPrimaryPackageSpecificPaths(Context context)133     public static List<File> getPrimaryPackageSpecificPaths(Context context) {
134         final List<File> paths = new ArrayList<File>();
135         Collections.addAll(paths, context.getExternalCacheDir());
136         Collections.addAll(paths, context.getExternalFilesDir(null));
137         Collections.addAll(paths, context.getExternalFilesDir(Environment.DIRECTORY_PICTURES));
138         Collections.addAll(paths, context.getObbDir());
139         return paths;
140     }
141 
getSecondaryPackageSpecificPaths(Context context)142     public static List<File> getSecondaryPackageSpecificPaths(Context context) {
143         final List<File> paths = new ArrayList<File>();
144         Collections.addAll(paths, dropFirst(context.getExternalCacheDirs()));
145         Collections.addAll(paths, dropFirst(context.getExternalFilesDirs(null)));
146         Collections.addAll(
147                 paths, dropFirst(context.getExternalFilesDirs(Environment.DIRECTORY_PICTURES)));
148         Collections.addAll(paths, dropFirst(context.getObbDirs()));
149         return paths;
150     }
151 
dropFirst(File[] before)152     private static File[] dropFirst(File[] before) {
153         final File[] after = new File[before.length - 1];
154         System.arraycopy(before, 1, after, 0, after.length);
155         return after;
156     }
157 
buildGiftForPackage(Context context, String packageName)158     public static File buildGiftForPackage(Context context, String packageName) {
159         final File myCache = context.getExternalCacheDir();
160         return new File(myCache.getAbsolutePath().replace(context.getPackageName(), packageName),
161                 packageName + ".gift");
162     }
163 
buildProbeFile(File dir)164     public static File buildProbeFile(File dir) {
165         return new File(dir, ".probe_" + System.nanoTime());
166     }
167 
assertDirReadOnlyAccess(File path)168     public static void assertDirReadOnlyAccess(File path) {
169         Log.d(TAG, "Asserting read-only access to " + path);
170 
171         assertTrue("exists", path.exists());
172         assertTrue("read", path.canRead());
173         assertTrue("execute", path.canExecute());
174         assertNotNull("list", path.list());
175 
176         try {
177             final File probe = buildProbeFile(path);
178             probe.createNewFile();
179             probe.delete();
180             fail("able to create probe!");
181         } catch (IOException e) {
182             // expected
183         }
184     }
185 
assertDirReadWriteAccess(File path)186     public static void assertDirReadWriteAccess(File path) {
187         Log.d(TAG, "Asserting read/write access to " + path);
188 
189         assertTrue("exists", path.exists());
190         assertTrue("read", path.canRead());
191         assertTrue("execute", path.canExecute());
192         assertNotNull("list", path.list());
193 
194         try {
195             final File probe = buildProbeFile(path);
196             probe.createNewFile();
197             probe.delete();
198         } catch (IOException e) {
199             fail("failed to create probe!");
200         }
201     }
202 
assertDirNoAccess(File path)203     public static void assertDirNoAccess(File path) {
204         Log.d(TAG, "Asserting no access to " + path);
205 
206         assertFalse("read", path.canRead());
207         assertNull("list", path.list());
208 
209         try {
210             final File probe = buildProbeFile(path);
211             probe.createNewFile();
212             probe.delete();
213             fail("able to create probe!");
214         } catch (IOException e) {
215             // expected
216         }
217     }
218 
assertDirNoWriteAccess(File path)219     public static void assertDirNoWriteAccess(File path) {
220         Log.d(TAG, "Asserting no write access to " + path);
221 
222         try {
223             final File probe = buildProbeFile(path);
224             probe.createNewFile();
225             probe.delete();
226             fail("able to create probe!");
227         } catch (IOException e) {
228             // expected
229         }
230     }
231 
assertFileReadOnlyAccess(File path)232     public static void assertFileReadOnlyAccess(File path) {
233         try {
234             new FileInputStream(path).close();
235         } catch (IOException e) {
236             fail("failed to read!");
237         }
238 
239         try {
240             new FileOutputStream(path, true).close();
241             fail("able to write!");
242         } catch (IOException e) {
243             // expected
244         }
245     }
246 
assertFileReadWriteAccess(File path)247     public static void assertFileReadWriteAccess(File path) {
248         try {
249             new FileInputStream(path).close();
250         } catch (IOException e) {
251             fail("failed to read!");
252         }
253 
254         try {
255             new FileOutputStream(path, true).close();
256         } catch (IOException e) {
257             fail("failed to write!");
258         }
259     }
260 
assertFileNoAccess(File path)261     public static void assertFileNoAccess(File path) {
262         try {
263             new FileInputStream(path).close();
264             fail("able to read!");
265         } catch (IOException e) {
266             // expected
267         }
268 
269         try {
270             new FileOutputStream(path, true).close();
271             fail("able to write!");
272         } catch (IOException e) {
273             // expected
274         }
275     }
276 
deleteContents(File dir)277     public static void deleteContents(File dir) throws IOException {
278         File[] files = dir.listFiles();
279         if (files != null) {
280             for (File file : files) {
281                 if (file.isDirectory()) {
282                     deleteContents(file);
283                 }
284                 assertTrue(file.delete());
285             }
286             assertEquals(0, dir.listFiles().length);
287         }
288     }
289 
writeInt(File file, int value)290     public static void writeInt(File file, int value) throws IOException {
291         final DataOutputStream os = new DataOutputStream(new FileOutputStream(file));
292         try {
293             os.writeInt(value);
294         } finally {
295             os.close();
296         }
297     }
298 
readInt(File file)299     public static int readInt(File file) throws IOException {
300         final DataInputStream is = new DataInputStream(new FileInputStream(file));
301         try {
302             return is.readInt();
303         } finally {
304             is.close();
305         }
306     }
307 }
308