• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.scopedstorage.cts.lib;
18 
19 import static android.scopedstorage.cts.lib.TestUtils.assertThrows;
20 import static android.scopedstorage.cts.lib.TestUtils.getAndroidDir;
21 import static android.system.OsConstants.F_OK;
22 import static android.system.OsConstants.R_OK;
23 import static android.system.OsConstants.W_OK;
24 
25 import static com.google.common.truth.Truth.assertThat;
26 
27 import static org.junit.Assume.assumeFalse;
28 
29 import android.system.ErrnoException;
30 import android.system.Os;
31 
32 import java.io.File;
33 import java.util.Arrays;
34 import java.util.Set;
35 import java.util.stream.Collectors;
36 
37 /**
38  * Utility class to test media access using the file system.
39  *
40  * Its twin class {@link ResolverAccessTestUtils } covers testing using the Content Resolver API.
41  */
42 public class FilePathAccessTestUtils {
assertFileAccess_existsOnly(File file)43     public static void assertFileAccess_existsOnly(File file) throws Exception {
44         assertThat(file.isFile()).isTrue();
45         assertAccess(file, true /* file exists */, false /* can read */, false /* can write */);
46     }
47 
assertFileAccess_readOnly(File file)48     public static void assertFileAccess_readOnly(File file) throws Exception {
49         assertThat(file.isFile()).isTrue();
50         assertAccess(file, true /* file exists */, true /* can read */, false /* can write */);
51     }
52 
assertFileAccess_readWrite(File file)53     public static void assertFileAccess_readWrite(File file) throws Exception {
54         assertThat(file.isFile()).isTrue();
55         assertAccess(file, true/* file exists */, true /* can read */, true /* can write */);
56     }
57 
assertDirectoryAccess(File dir, boolean exists, boolean canWrite)58     public static void assertDirectoryAccess(File dir, boolean exists, boolean canWrite)
59             throws Exception {
60         // This util does not handle app data directories.
61         assumeFalse(dir.getAbsolutePath().startsWith(getAndroidDir().getAbsolutePath())
62                 && !dir.equals(getAndroidDir()));
63         assertThat(dir.isDirectory()).isEqualTo(exists);
64         // For non-app data directories, exists => canRead().
65         assertAccess(dir, exists, exists, exists && canWrite);
66     }
67 
assertAccess(File file, boolean exists, boolean canRead, boolean canWrite)68     public static void assertAccess(File file, boolean exists, boolean canRead, boolean canWrite)
69             throws Exception {
70         assertAccess(file, exists, canRead, canWrite, true /* checkExists */);
71     }
72 
assertCannotReadOrWrite(File file)73     public static void assertCannotReadOrWrite(File file)
74             throws Exception {
75         // App data directories have different 'x' bits on upgrading vs new devices. Let's not
76         // check 'exists', by passing checkExists=false. But assert this app cannot read or write
77         // the other app's file.
78         assertAccess(file, false /* value is moot */, false /* canRead */,
79                 false /* canWrite */, false /* checkExists */);
80     }
81 
assertCanAccessMyAppFile(File file)82     public static void assertCanAccessMyAppFile(File file)
83             throws Exception {
84         assertAccess(file, true, true /* canRead */,
85                 true /*canWrite */, true /* checkExists */);
86     }
87 
assertAccess(File file, boolean exists, boolean canRead, boolean canWrite, boolean checkExists)88     private static void assertAccess(File file, boolean exists, boolean canRead, boolean canWrite,
89             boolean checkExists) throws Exception {
90         if (checkExists) {
91             assertThat(file.exists()).isEqualTo(exists);
92         }
93         assertThat(file.canRead()).isEqualTo(canRead);
94         assertThat(file.canWrite()).isEqualTo(canWrite);
95         if (file.isDirectory()) {
96             if (checkExists) {
97                 assertThat(file.canExecute()).isEqualTo(exists);
98             }
99         } else {
100             assertThat(file.canExecute()).isFalse(); // Filesytem is mounted with MS_NOEXEC
101         }
102 
103         // Test some combinations of mask.
104         assertAccess(file, R_OK, canRead);
105         assertAccess(file, W_OK, canWrite);
106         assertAccess(file, R_OK | W_OK, canRead && canWrite);
107         assertAccess(file, W_OK | F_OK, canWrite);
108 
109         if (checkExists) {
110             assertAccess(file, F_OK, exists);
111         }
112     }
113 
assertAccess(File file, int mask, boolean expected)114     private static void assertAccess(File file, int mask, boolean expected) throws Exception {
115         if (expected) {
116             assertThat(Os.access(file.getAbsolutePath(), mask)).isTrue();
117         } else {
118             assertThrows(ErrnoException.class, () -> Os.access(file.getAbsolutePath(), mask));
119         }
120     }
121 
122     /**
123      * Checks that specific files are visible and others are not in a given folder
124      */
assertFileAccess_listFiles(File dir, Set<File> expected, Set<File> notExpected)125     public static void assertFileAccess_listFiles(File dir, Set<File> expected,
126             Set<File> notExpected) {
127         assertThat(dir.isDirectory()).isTrue();
128         Set<File> files = Arrays.stream(dir.listFiles()).collect(Collectors.toSet());
129         assertThat(files).containsAtLeastElementsIn(expected);
130         assertThat(files).containsNoneIn(notExpected);
131     }
132 }
133