1 /*
2  * Copyright (C) 2017 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;
18 
19 import static android.os.Environment.HAS_ANDROID;
20 import static android.os.Environment.HAS_DCIM;
21 import static android.os.Environment.HAS_DOWNLOADS;
22 import static android.os.Environment.HAS_OTHER;
23 import static android.os.Environment.classifyExternalStorageDirectory;
24 
25 import static com.google.common.truth.Truth.assertThat;
26 
27 import static org.junit.Assert.assertEquals;
28 
29 import android.content.Context;
30 import android.os.storage.StorageManager;
31 
32 import androidx.test.InstrumentationRegistry;
33 import androidx.test.runner.AndroidJUnit4;
34 
35 import org.junit.After;
36 import org.junit.Before;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 
40 import java.io.File;
41 import java.util.ArrayList;
42 import java.util.UUID;
43 import java.util.function.BiFunction;
44 
45 @RunWith(AndroidJUnit4.class)
46 public class EnvironmentTest {
47     private File dir;
48 
getContext()49     private static Context getContext() {
50         return InstrumentationRegistry.getContext();
51     }
52 
53     @Before
setUp()54     public void setUp() throws Exception {
55         dir = getContext().getDir("testing", Context.MODE_PRIVATE);
56         FileUtils.deleteContents(dir);
57     }
58 
59     @After
tearDown()60     public void tearDown() throws Exception {
61         FileUtils.deleteContents(dir);
62     }
63 
64     @Test
testClassify_empty()65     public void testClassify_empty() {
66         assertEquals(0, classifyExternalStorageDirectory(dir));
67     }
68 
69     @Test
testClassify_emptyDirs()70     public void testClassify_emptyDirs() {
71         Environment.buildPath(dir, "DCIM").mkdirs();
72         Environment.buildPath(dir, "DCIM", "January").mkdirs();
73         Environment.buildPath(dir, "Downloads").mkdirs();
74         Environment.buildPath(dir, "LOST.DIR").mkdirs();
75         assertEquals(0, classifyExternalStorageDirectory(dir));
76     }
77 
78     @Test
testClassify_emptyFactory()79     public void testClassify_emptyFactory() throws Exception {
80         Environment.buildPath(dir, "autorun.inf").createNewFile();
81         Environment.buildPath(dir, "LaunchU3.exe").createNewFile();
82         Environment.buildPath(dir, "LaunchPad.zip").createNewFile();
83         assertEquals(0, classifyExternalStorageDirectory(dir));
84     }
85 
86     @Test
testClassify_photos()87     public void testClassify_photos() throws Exception {
88         Environment.buildPath(dir, "DCIM").mkdirs();
89         Environment.buildPath(dir, "DCIM", "IMG_1024.JPG").createNewFile();
90         Environment.buildPath(dir, "Download").mkdirs();
91         Environment.buildPath(dir, "Download", "foobar.pdf").createNewFile();
92         assertEquals(HAS_DCIM | HAS_DOWNLOADS, classifyExternalStorageDirectory(dir));
93     }
94 
95     @Test
testClassify_other()96     public void testClassify_other() throws Exception {
97         Environment.buildPath(dir, "Android").mkdirs();
98         Environment.buildPath(dir, "Android", "com.example").mkdirs();
99         Environment.buildPath(dir, "Android", "com.example", "internal.dat").createNewFile();
100         Environment.buildPath(dir, "Linux").mkdirs();
101         Environment.buildPath(dir, "Linux", "install-amd64-minimal-20170907.iso").createNewFile();
102         assertEquals(HAS_ANDROID | HAS_OTHER, classifyExternalStorageDirectory(dir));
103     }
104 
105     @Test
testClassify_otherRoot()106     public void testClassify_otherRoot() throws Exception {
107         Environment.buildPath(dir, "Taxes.pdf").createNewFile();
108         assertEquals(HAS_OTHER, classifyExternalStorageDirectory(dir));
109     }
110 
111     @Test
testDataCePackageDirectoryForUser()112     public void testDataCePackageDirectoryForUser() {
113         testDataPackageDirectoryForUser(
114                 (uuid, userHandle) -> Environment.getDataCePackageDirectoryForUser(
115                         uuid, userHandle, getContext().getPackageName()),
116                 (uuid, user) -> Environment.getDataUserCePackageDirectory(
117                         uuid, user, getContext().getPackageName())
118         );
119     }
120 
121     @Test
testDataDePackageDirectoryForUser()122     public void testDataDePackageDirectoryForUser() {
123         testDataPackageDirectoryForUser(
124                 (uuid, userHandle) -> Environment.getDataDePackageDirectoryForUser(
125                         uuid, userHandle, getContext().getPackageName()),
126                 (uuid, user) -> Environment.getDataUserDePackageDirectory(
127                         uuid, user, getContext().getPackageName())
128         );
129     }
130 
testDataPackageDirectoryForUser( BiFunction<UUID, UserHandle, File> publicApi, BiFunction<String, Integer, File> hideApi)131     private void testDataPackageDirectoryForUser(
132             BiFunction<UUID, UserHandle, File> publicApi,
133             BiFunction<String, Integer, File> hideApi) {
134         var uuids = new ArrayList<String>();
135         uuids.add(null); // Private internal
136         uuids.add("primary_physical");
137         uuids.add("system");
138         uuids.add("3939-3939"); // FAT Volume
139         uuids.add("57554103-df3e-4475-ae7a-8feba49353ac"); // Random valid UUID
140         var userHandle = UserHandle.of(0);
141 
142         // Check that the @hide method is consistent with the public API
143         for (String uuid : uuids) {
144             assertThat(publicApi.apply(StorageManager.convert(uuid), userHandle))
145                     .isEqualTo(hideApi.apply(uuid, 0));
146         }
147     }
148 }
149