• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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.mtp;
18 
19 import android.os.ParcelFileDescriptor;
20 import android.os.storage.StorageManager;
21 import android.system.ErrnoException;
22 import android.system.Os;
23 import android.test.AndroidTestCase;
24 import android.test.suitebuilder.annotation.MediumTest;
25 
26 import libcore.io.IoUtils;
27 
28 import java.io.File;
29 import java.io.FileNotFoundException;
30 import java.io.IOException;
31 import java.util.Arrays;
32 
33 @MediumTest
34 public class AppFuseTest extends AndroidTestCase {
testMount()35     public void testMount() throws ErrnoException, IOException {
36         final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
37         final AppFuse appFuse = new AppFuse("test", new TestCallback());
38         appFuse.mount(storageManager);
39         final File file = appFuse.getMountPoint();
40         assertTrue(file.isDirectory());
41         assertEquals(1, Os.stat(file.getPath()).st_ino);
42         appFuse.close();
43         assertTrue(1 != Os.stat(file.getPath()).st_ino);
44     }
45 
testOpenFile()46     public void testOpenFile() throws IOException {
47         final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
48         final int INODE = 10;
49         final AppFuse appFuse = new AppFuse(
50                 "test",
51                 new TestCallback() {
52                     @Override
53                     public long getFileSize(int inode) throws FileNotFoundException {
54                         if (INODE == inode) {
55                             return 1024;
56                         }
57                         throw new FileNotFoundException();
58                     }
59                 });
60         appFuse.mount(storageManager);
61         final ParcelFileDescriptor fd = appFuse.openFile(
62                 INODE, ParcelFileDescriptor.MODE_READ_ONLY);
63         fd.close();
64         appFuse.close();
65     }
66 
testOpenFile_fileNotFound()67     public void testOpenFile_fileNotFound() throws IOException {
68         final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
69         final int INODE = 10;
70         final AppFuse appFuse = new AppFuse("test", new TestCallback());
71         appFuse.mount(storageManager);
72         try {
73             appFuse.openFile(INODE, ParcelFileDescriptor.MODE_READ_ONLY);
74             fail();
75         } catch (FileNotFoundException exp) {}
76         appFuse.close();
77     }
78 
testOpenFile_illegalMode()79     public void testOpenFile_illegalMode() throws IOException {
80         final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
81         final int INODE = 10;
82         final AppFuse appFuse = new AppFuse("test", new TestCallback());
83         appFuse.mount(storageManager);
84         try {
85             appFuse.openFile(INODE, ParcelFileDescriptor.MODE_READ_WRITE);
86             fail();
87         } catch (IllegalArgumentException exp) {}
88         appFuse.close();
89     }
90 
testReadFile()91     public void testReadFile() throws IOException {
92         final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
93         final int fileInode = 10;
94         final byte[] fileBytes = new byte[] { 'a', 'b', 'c', 'd', 'e' };
95         final AppFuse appFuse = new AppFuse(
96                 "test",
97                 new TestCallback() {
98                     @Override
99                     public long getFileSize(int inode) throws FileNotFoundException {
100                         if (inode == fileInode) {
101                             return fileBytes.length;
102                         }
103                         return super.getFileSize(inode);
104                     }
105 
106                     @Override
107                     public long readObjectBytes(int inode, long offset, long size, byte[] bytes)
108                             throws IOException {
109                         if (inode == fileInode) {
110                             int i = 0;
111                             while (i < size && i + offset < fileBytes.length)  {
112                                 bytes[i] = fileBytes[(int) (i + offset)];
113                                 i++;
114                             }
115                             return i;
116                         }
117                         return super.readObjectBytes(inode, offset, size, bytes);
118                     }
119                 });
120         appFuse.mount(storageManager);
121         final ParcelFileDescriptor fd = appFuse.openFile(
122                 fileInode, ParcelFileDescriptor.MODE_READ_ONLY);
123         try (final ParcelFileDescriptor.AutoCloseInputStream stream =
124                 new ParcelFileDescriptor.AutoCloseInputStream(fd)) {
125             final byte[] buffer = new byte[1024];
126             final int size = stream.read(buffer, 0, buffer.length);
127             assertEquals(5, size);
128         }
129         appFuse.close();
130     }
131 
testWriteFile()132     public void testWriteFile() throws IOException {
133         final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
134         final int INODE = 10;
135         final byte[] resultBytes = new byte[5];
136         final AppFuse appFuse = new AppFuse(
137                 "test",
138                 new TestCallback() {
139                     @Override
140                     public long getFileSize(int inode) throws FileNotFoundException {
141                         if (inode != INODE) {
142                             throw new FileNotFoundException();
143                         }
144                         return resultBytes.length;
145                     }
146 
147                     @Override
148                     public int writeObjectBytes(
149                             long fileHandle, int inode, long offset, int size, byte[] bytes) {
150                         for (int i = 0; i < size; i++) {
151                             resultBytes[(int)(offset + i)] = bytes[i];
152                         }
153                         return size;
154                     }
155                 });
156         appFuse.mount(storageManager);
157         final ParcelFileDescriptor fd = appFuse.openFile(
158                 INODE, ParcelFileDescriptor.MODE_WRITE_ONLY | ParcelFileDescriptor.MODE_TRUNCATE);
159         try (final ParcelFileDescriptor.AutoCloseOutputStream stream =
160                 new ParcelFileDescriptor.AutoCloseOutputStream(fd)) {
161             stream.write('a');
162             stream.write('b');
163             stream.write('c');
164             stream.write('d');
165             stream.write('e');
166         }
167         final byte[] BYTES = new byte[] { 'a', 'b', 'c', 'd', 'e' };
168         assertTrue(Arrays.equals(BYTES, resultBytes));
169         appFuse.close();
170     }
171 
testWriteFile_writeError()172     public void testWriteFile_writeError() throws IOException {
173         final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
174         final int INODE = 10;
175         final AppFuse appFuse = new AppFuse(
176                 "test",
177                 new TestCallback() {
178                     @Override
179                     public long getFileSize(int inode) throws FileNotFoundException {
180                         if (inode != INODE) {
181                             throw new FileNotFoundException();
182                         }
183                         return 5;
184                     }
185                 });
186         appFuse.mount(storageManager);
187         final ParcelFileDescriptor fd = appFuse.openFile(
188                 INODE, ParcelFileDescriptor.MODE_WRITE_ONLY | ParcelFileDescriptor.MODE_TRUNCATE);
189         try (final ParcelFileDescriptor.AutoCloseOutputStream stream =
190                 new ParcelFileDescriptor.AutoCloseOutputStream(fd)) {
191             stream.write('a');
192             fail();
193         } catch (IOException e) {
194         }
195         appFuse.close();
196     }
197 
testWriteFile_flushError()198     public void testWriteFile_flushError() throws IOException {
199         final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
200         final int INODE = 10;
201         final AppFuse appFuse = new AppFuse(
202                 "test",
203                 new TestCallback() {
204                     @Override
205                     public long getFileSize(int inode) throws FileNotFoundException {
206                         if (inode != INODE) {
207                             throw new FileNotFoundException();
208                         }
209                         return 5;
210                     }
211 
212                     @Override
213                     public int writeObjectBytes(
214                             long fileHandle, int inode, long offset, int size, byte[] bytes) {
215                         return size;
216                     }
217 
218                     @Override
219                     public void flushFileHandle(long fileHandle) throws IOException {
220                         throw new IOException();
221                     }
222                 });
223         appFuse.mount(storageManager);
224         final ParcelFileDescriptor fd = appFuse.openFile(
225                 INODE, ParcelFileDescriptor.MODE_WRITE_ONLY | ParcelFileDescriptor.MODE_TRUNCATE);
226         try (final ParcelFileDescriptor.AutoCloseOutputStream stream =
227                 new ParcelFileDescriptor.AutoCloseOutputStream(fd)) {
228             stream.write('a');
229             try {
230                 IoUtils.close(fd.getFileDescriptor());
231                 fail();
232             } catch (IOException e) {
233             }
234         }
235         appFuse.close();
236     }
237 
238     private static class TestCallback implements AppFuse.Callback {
239         @Override
getFileSize(int inode)240         public long getFileSize(int inode) throws FileNotFoundException {
241             throw new FileNotFoundException();
242         }
243 
244         @Override
readObjectBytes(int inode, long offset, long size, byte[] bytes)245         public long readObjectBytes(int inode, long offset, long size, byte[] bytes)
246                 throws IOException {
247             throw new IOException();
248         }
249 
250         @Override
writeObjectBytes(long fileHandle, int inode, long offset, int size, byte[] bytes)251         public int writeObjectBytes(long fileHandle, int inode, long offset, int size, byte[] bytes)
252                 throws IOException {
253             throw new IOException();
254         }
255 
256         @Override
flushFileHandle(long fileHandle)257         public void flushFileHandle(long fileHandle) throws IOException {}
258 
259         @Override
closeFileHandle(long fileHandle)260         public void closeFileHandle(long fileHandle) {}
261     }
262 }
263