1 use android_hardware_security_see_storage::aidl::android::hardware::security::see::storage::{
2 CreationMode::CreationMode, FileMode::FileMode, ISecureStorage as SecureStorage,
3 IStorageSession::IStorageSession, OpenOptions::OpenOptions,
4 };
5 use binder::ExceptionCode;
6 use test::{assert_ok, expect, fail};
7
8 mod helpers;
9 use helpers::{ensure_deleted, Exists};
10
11 const CREATE_EXCLUSIVE: &'static OpenOptions = &OpenOptions {
12 createMode: CreationMode::CREATE_EXCLUSIVE,
13 accessMode: FileMode::READ_WRITE,
14 truncateOnOpen: true,
15 };
16
17 const NO_CREATE: &'static OpenOptions = &OpenOptions {
18 createMode: CreationMode::NO_CREATE,
19 accessMode: FileMode::READ_WRITE,
20 truncateOnOpen: false,
21 };
22
create_delete(ss: &(impl IStorageSession + ?Sized))23 pub(crate) fn create_delete(ss: &(impl IStorageSession + ?Sized)) {
24 let fname = "test_create_delete_file";
25 assert_ok!(ensure_deleted(ss, fname, Exists::Unknown));
26
27 {
28 // Create file
29 let _file = assert_ok!(ss.openFile(fname, CREATE_EXCLUSIVE));
30 assert_ok!(ss.commitChanges());
31
32 // Try to create file again
33 match ss.openFile(fname, CREATE_EXCLUSIVE) {
34 Ok(_) => fail!("openFile (on existing file) unexpectedly succeeded"),
35 Err(e)
36 if e.exception_code() == ExceptionCode::SERVICE_SPECIFIC
37 && e.service_specific_error() == SecureStorage::ERR_ALREADY_EXISTS =>
38 {
39 ()
40 }
41 Err(e) => fail!("openFile (on existing file) failed with: {}", e),
42 };
43 assert_ok!(ss.commitChanges());
44
45 // File closes
46 }
47
48 assert_ok!(ensure_deleted(ss, fname, Exists::Must));
49 }
50
create_move_delete(ss: &(impl IStorageSession + ?Sized))51 pub(crate) fn create_move_delete(ss: &(impl IStorageSession + ?Sized)) {
52 let fname1 = "test_create_move_delete_1_file";
53 let fname2 = "test_create_move_delete_2_file";
54
55 assert_ok!(ensure_deleted(ss, fname1, Exists::Unknown));
56 assert_ok!(ensure_deleted(ss, fname2, Exists::Unknown));
57
58 {
59 // Create file
60 let file = assert_ok!(ss.openFile(fname1, CREATE_EXCLUSIVE));
61 assert_ok!(ss.commitChanges());
62
63 // Move fname1 -> fname2
64 assert_ok!(file.rename(fname2, CreationMode::CREATE_EXCLUSIVE));
65 assert_ok!(ss.commitChanges());
66
67 // Try to create fname2, with file still alive
68 match ss.openFile(fname2, CREATE_EXCLUSIVE) {
69 Ok(_) => fail!("openFile unexpectedly succeeded"),
70 Err(e)
71 if e.exception_code() == ExceptionCode::SERVICE_SPECIFIC
72 && e.service_specific_error() == SecureStorage::ERR_ALREADY_EXISTS =>
73 {
74 ()
75 }
76 Err(e) => fail!("openFile failed with unexpected error: {}", e),
77 };
78 assert_ok!(ss.commitChanges());
79
80 // file closes
81 }
82
83 // Try to create fname2, now that file is closed
84 match ss.openFile(fname2, CREATE_EXCLUSIVE) {
85 Ok(_) => fail!("openFile unexpectedly succeeded"),
86 Err(e)
87 if e.exception_code() == ExceptionCode::SERVICE_SPECIFIC
88 && e.service_specific_error() == SecureStorage::ERR_ALREADY_EXISTS =>
89 {
90 ()
91 }
92 Err(e) => fail!("openFile failed with unexpected error: {}", e),
93 };
94 assert_ok!(ss.commitChanges());
95
96 {
97 // Recreate fname1
98 let file = assert_ok!(ss.openFile(fname1, CREATE_EXCLUSIVE));
99 assert_ok!(ss.commitChanges());
100
101 // Move doesn't work now that fname2 exists
102 match file.rename(fname2, CreationMode::CREATE_EXCLUSIVE) {
103 Ok(_) => panic!("rename unexpectedly succeeded"),
104 Err(e)
105 if e.exception_code() == ExceptionCode::SERVICE_SPECIFIC
106 && e.service_specific_error() == SecureStorage::ERR_ALREADY_EXISTS =>
107 {
108 ()
109 }
110 Err(e) => panic!("rename failed with unexpected error: {}", e),
111 };
112
113 // file closes
114 }
115
116 assert_ok!(ensure_deleted(ss, fname1, Exists::Must));
117 assert_ok!(ensure_deleted(ss, fname2, Exists::Must));
118 }
119
file_list(ss: &(impl IStorageSession + ?Sized))120 pub(crate) fn file_list(ss: &(impl IStorageSession + ?Sized)) {
121 use core::array::from_fn;
122 use std::collections::HashSet;
123
124 let fnames: [String; 100] = from_fn(|i| format!("test_file_list_{:02}_file", i));
125 for fname in &fnames {
126 assert_ok!(ensure_deleted(ss, fname, Exists::Unknown), "file: {}", fname);
127 }
128
129 {
130 let dir = assert_ok!(ss.openDir(""));
131 let filenames = assert_ok!(dir.readNextFilenames(0));
132 expect!(filenames.is_empty(), "Found unexpected files: {:?}", filenames);
133 }
134
135 // Create, commit, and close file #0
136 {
137 let _file = assert_ok!(ss.openFile(&fnames[0], CREATE_EXCLUSIVE));
138 assert_ok!(ss.commitChanges());
139 }
140 // Create and close (don't commit) other files
141 for fname in &fnames[1..] {
142 let _file = assert_ok!(ss.openFile(fname, CREATE_EXCLUSIVE), "for fname {}", fname);
143 }
144
145 let mut read_file_names = HashSet::new();
146 {
147 let dir = assert_ok!(ss.openDir(""));
148 let mut filenames = assert_ok!(dir.readNextFilenames(0));
149 while !filenames.is_empty() {
150 for filename in filenames {
151 let existed = read_file_names.replace(filename);
152 if let Some(previous) = existed {
153 fail!("NextFilenameResult returned file more than once: {}", previous);
154 }
155 }
156 filenames = assert_ok!(dir.readNextFilenames(0));
157 }
158 }
159 assert_ok!(ss.commitChanges());
160
161 // Clean up
162 for fname in &fnames {
163 assert_ok!(ensure_deleted(ss, fname, Exists::Must), "file: {}", fname);
164 }
165
166 let expected = fnames.into_iter().collect::<HashSet<_>>();
167 let missing = expected.difference(&read_file_names).collect::<Vec<_>>();
168 let extra = read_file_names.difference(&expected).collect::<Vec<_>>();
169
170 expect!(missing.is_empty(), "Did not find the following expected files: {:?}", missing);
171 expect!(extra.is_empty(), "Found the following unexpected files: {:?}", extra);
172 }
173
write_read_sequential(ss: &(impl IStorageSession + ?Sized))174 pub(crate) fn write_read_sequential(ss: &(impl IStorageSession + ?Sized)) {
175 use helpers::{read_pattern, write_pattern};
176
177 let fname = "test_write_read_sequential";
178 let chunks = 32;
179 let chunk_len = 2048;
180
181 assert_ok!(ensure_deleted(ss, fname, Exists::Unknown));
182
183 {
184 let file = assert_ok!(ss.openFile(fname, CREATE_EXCLUSIVE));
185 assert_ok!(ss.commitChanges());
186
187 assert_ok!(write_pattern(&*file, 0, chunks, chunk_len));
188 assert_ok!(ss.commitChanges());
189
190 assert_ok!(read_pattern(&*file, 0, chunks, chunk_len));
191 } // file closes
192
193 {
194 let file = assert_ok!(ss.openFile(fname, NO_CREATE));
195 assert_ok!(read_pattern(&*file, 0, chunks, chunk_len));
196 } // file closes
197
198 assert_ok!(ensure_deleted(ss, fname, Exists::Must));
199 }
200