MtpDocumentsProviderTest.java revision bb430fa930fa0d0700e46e7b4881de2a252223dd
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
17package com.android.mtp;
18
19import android.database.Cursor;
20import android.mtp.MtpConstants;
21import android.mtp.MtpObjectInfo.Builder;
22import android.mtp.MtpObjectInfo;
23import android.net.Uri;
24import android.provider.DocumentsContract.Root;
25import android.provider.DocumentsContract;
26import android.test.AndroidTestCase;
27import android.test.suitebuilder.annotation.SmallTest;
28
29import java.io.FileNotFoundException;
30import java.io.IOException;
31import java.util.Date;
32
33@SmallTest
34public class MtpDocumentsProviderTest extends AndroidTestCase {
35    private final static Uri ROOTS_URI =
36            DocumentsContract.buildRootsUri(MtpDocumentsProvider.AUTHORITY);
37    private TestContentResolver mResolver;
38    private MtpDocumentsProvider mProvider;
39    private TestMtpManager mMtpManager;
40
41    @Override
42    public void setUp() {
43        mResolver = new TestContentResolver();
44        mMtpManager = new TestMtpManager(getContext());
45        mProvider = new MtpDocumentsProvider();
46        mProvider.onCreateForTesting(mMtpManager, mResolver);
47    }
48
49    public void testOpenAndCloseDevice() throws Exception {
50        mMtpManager.addValidDevice(0);
51        mMtpManager.setRoots(0, new MtpRoot[] {
52                new MtpRoot(
53                        0 /* deviceId */,
54                        1 /* storageId */,
55                        "Storage A" /* volume description */,
56                        1024 /* free space */,
57                        2048 /* total space */,
58                        "" /* no volume identifier */)
59        });
60
61        mProvider.openDevice(0);
62        mResolver.waitForNotification(ROOTS_URI, 1);
63
64        mProvider.closeDevice(0);
65        mResolver.waitForNotification(ROOTS_URI, 2);
66    }
67
68    public void testOpenAndCloseErrorDevice() throws Exception {
69        try {
70            mProvider.openDevice(1);
71            fail();
72        } catch (Throwable error) {
73            assertTrue(error instanceof IOException);
74        }
75
76        try {
77            mProvider.closeDevice(1);
78            fail();
79        } catch (Throwable error) {
80            assertTrue(error instanceof IOException);
81        }
82
83        // Check if the following notification is the first one or not.
84        mMtpManager.addValidDevice(0);
85        mMtpManager.setRoots(0, new MtpRoot[] {
86                new MtpRoot(
87                        0 /* deviceId */,
88                        1 /* storageId */,
89                        "Storage A" /* volume description */,
90                        1024 /* free space */,
91                        2048 /* total space */,
92                        "" /* no volume identifier */)
93        });
94        mProvider.openDevice(0);
95        mResolver.waitForNotification(ROOTS_URI, 1);
96    }
97
98    public void testCloseAllDevices() throws Exception {
99        mMtpManager.addValidDevice(0);
100        mMtpManager.setRoots(0, new MtpRoot[] {
101                new MtpRoot(
102                        0 /* deviceId */,
103                        1 /* storageId */,
104                        "Storage A" /* volume description */,
105                        1024 /* free space */,
106                        2048 /* total space */,
107                        "" /* no volume identifier */)
108        });
109        mProvider.closeAllDevices();
110        mProvider.openDevice(0);
111        mResolver.waitForNotification(ROOTS_URI, 1);
112
113        mProvider.closeAllDevices();
114        mResolver.waitForNotification(ROOTS_URI, 2);
115    }
116
117    public void testQueryRoots() throws Exception {
118        mMtpManager.addValidDevice(0);
119        mMtpManager.addValidDevice(1);
120        mMtpManager.setRoots(0, new MtpRoot[] {
121                new MtpRoot(
122                        0 /* deviceId */,
123                        1 /* storageId */,
124                        "Storage A" /* volume description */,
125                        1024 /* free space */,
126                        2048 /* total space */,
127                        "" /* no volume identifier */)
128        });
129        mMtpManager.setRoots(1, new MtpRoot[] {
130                new MtpRoot(
131                        1 /* deviceId */,
132                        1 /* storageId */,
133                        "Storage B" /* volume description */,
134                        2048 /* free space */,
135                        4096 /* total space */,
136                        "Identifier B" /* no volume identifier */)
137        });
138
139        {
140            mProvider.openDevice(0);
141            mResolver.waitForNotification(ROOTS_URI, 1);
142            final Cursor cursor = mProvider.queryRoots(null);
143            assertEquals(1, cursor.getCount());
144            cursor.moveToNext();
145            assertEquals("0_1", cursor.getString(0));
146            assertEquals(Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE, cursor.getInt(1));
147            // TODO: Add storage icon for MTP devices.
148            assertTrue(cursor.isNull(2) /* icon */);
149            assertEquals("Storage A", cursor.getString(3));
150            assertEquals("0_1_0", cursor.getString(4));
151            assertEquals(1024, cursor.getInt(5));
152        }
153
154        {
155            mProvider.openDevice(1);
156            mResolver.waitForNotification(ROOTS_URI, 2);
157            final Cursor cursor = mProvider.queryRoots(null);
158            assertEquals(2, cursor.getCount());
159            cursor.moveToNext();
160            cursor.moveToNext();
161            assertEquals("1_1", cursor.getString(0));
162            assertEquals(Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE, cursor.getInt(1));
163            // TODO: Add storage icon for MTP devices.
164            assertTrue(cursor.isNull(2) /* icon */);
165            assertEquals("Storage B", cursor.getString(3));
166            assertEquals("1_1_0", cursor.getString(4));
167            assertEquals(2048, cursor.getInt(5));
168        }
169
170        {
171            mProvider.closeAllDevices();
172            mResolver.waitForNotification(ROOTS_URI, 3);
173            final Cursor cursor = mProvider.queryRoots(null);
174            assertEquals(0, cursor.getCount());
175        }
176    }
177
178    public void testQueryRoots_error() throws Exception {
179        mMtpManager.addValidDevice(0);
180        mMtpManager.addValidDevice(1);
181        // Not set roots for device 0 so that MtpManagerMock#getRoots throws IOException.
182        mMtpManager.setRoots(1, new MtpRoot[] {
183                new MtpRoot(
184                        1 /* deviceId */,
185                        1 /* storageId */,
186                        "Storage B" /* volume description */,
187                        2048 /* free space */,
188                        4096 /* total space */,
189                        "Identifier B" /* no volume identifier */)
190        });
191        {
192            mProvider.openDevice(0);
193            mProvider.openDevice(1);
194            mResolver.waitForNotification(ROOTS_URI, 1);
195
196            final Cursor cursor = mProvider.queryRoots(null);
197            assertEquals(1, cursor.getCount());
198            cursor.moveToNext();
199            assertEquals("1_1", cursor.getString(0));
200            assertEquals(Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE, cursor.getInt(1));
201            // TODO: Add storage icon for MTP devices.
202            assertTrue(cursor.isNull(2) /* icon */);
203            assertEquals("Storage B", cursor.getString(3));
204            assertEquals("1_1_0", cursor.getString(4));
205            assertEquals(2048, cursor.getInt(5));
206        }
207    }
208
209    public void testQueryDocument() throws IOException {
210        mMtpManager.setObjectInfo(0, new MtpObjectInfo.Builder()
211                .setObjectHandle(2)
212                .setFormat(0x3801)
213                .setName("image.jpg")
214                .setDateModified(1422716400000L)
215                .setCompressedSize(1024 * 1024 * 5)
216                .setThumbCompressedSize(1024 * 50)
217                .build());
218        final Cursor cursor = mProvider.queryDocument("0_1_2", null);
219        assertEquals(1, cursor.getCount());
220
221        cursor.moveToNext();
222        assertEquals("0_1_2", cursor.getString(0));
223        assertEquals("image/jpeg", cursor.getString(1));
224        assertEquals("image.jpg", cursor.getString(2));
225        assertEquals(1422716400000L, cursor.getLong(3));
226        assertEquals(
227                DocumentsContract.Document.FLAG_SUPPORTS_DELETE |
228                DocumentsContract.Document.FLAG_SUPPORTS_WRITE |
229                DocumentsContract.Document.FLAG_SUPPORTS_THUMBNAIL,
230                cursor.getInt(4));
231        assertEquals(1024 * 1024 * 5, cursor.getInt(5));
232    }
233
234    public void testQueryDocument_directory() throws IOException {
235        mMtpManager.setObjectInfo(0, new MtpObjectInfo.Builder()
236                .setObjectHandle(2)
237                .setFormat(0x3001 /* directory format */)
238                .setName("directory")
239                .setDateModified(1422716400000L)
240                .build());
241        final Cursor cursor = mProvider.queryDocument("0_1_2", null);
242        assertEquals(1, cursor.getCount());
243
244        cursor.moveToNext();
245        assertEquals("0_1_2", cursor.getString(0));
246        assertEquals(DocumentsContract.Document.MIME_TYPE_DIR, cursor.getString(1));
247        assertEquals("directory", cursor.getString(2));
248        assertEquals(1422716400000L, cursor.getLong(3));
249        assertEquals(
250                DocumentsContract.Document.FLAG_SUPPORTS_DELETE |
251                DocumentsContract.Document.FLAG_SUPPORTS_WRITE |
252                DocumentsContract.Document.FLAG_DIR_SUPPORTS_CREATE,
253                cursor.getInt(4));
254        assertEquals(0, cursor.getInt(5));
255    }
256
257    public void testQueryDocument_forRoot() throws IOException {
258        mMtpManager.setRoots(0, new MtpRoot[] {
259                new MtpRoot(
260                        0 /* deviceId */,
261                        1 /* storageId */,
262                        "Storage A" /* volume description */,
263                        1024 /* free space */,
264                        4096 /* total space */,
265                        "" /* no volume identifier */)
266        });
267        final Cursor cursor = mProvider.queryDocument("0_1_0", null);
268        assertEquals(1, cursor.getCount());
269
270        cursor.moveToNext();
271        assertEquals("0_1_0", cursor.getString(0));
272        assertEquals(DocumentsContract.Document.MIME_TYPE_DIR, cursor.getString(1));
273        assertEquals("Storage A", cursor.getString(2));
274        assertTrue(cursor.isNull(3));
275        assertEquals(0, cursor.getInt(4));
276        assertEquals(3072, cursor.getInt(5));
277    }
278
279    public void testQueryChildDocuments() throws Exception {
280        mMtpManager.setObjectHandles(0, 0, -1, new int[] { 1 });
281
282        mMtpManager.setObjectInfo(0, new MtpObjectInfo.Builder()
283                .setObjectHandle(1)
284                .setFormat(0x3801 /* JPEG */)
285                .setName("image.jpg")
286                .setCompressedSize(1024 * 1024 * 5)
287                .setThumbCompressedSize(5 * 1024)
288                .setProtectionStatus(MtpConstants.PROTECTION_STATUS_READ_ONLY)
289                .build());
290
291        final Cursor cursor = mProvider.queryChildDocuments("0_0_0", null, null);
292        assertEquals(1, cursor.getCount());
293
294        assertTrue(cursor.moveToNext());
295        assertEquals("0_0_1", cursor.getString(0));
296        assertEquals("image/jpeg", cursor.getString(1));
297        assertEquals("image.jpg", cursor.getString(2));
298        assertEquals(0, cursor.getLong(3));
299        assertEquals(DocumentsContract.Document.FLAG_SUPPORTS_THUMBNAIL, cursor.getInt(4));
300        assertEquals(1024 * 1024 * 5, cursor.getInt(5));
301
302        assertFalse(cursor.moveToNext());
303    }
304
305    public void testQueryChildDocuments_cursorError() throws Exception {
306        try {
307            mProvider.queryChildDocuments("0_0_0", null, null);
308            fail();
309        } catch (Throwable error) {
310            assertTrue(error instanceof FileNotFoundException);
311        }
312    }
313
314    public void testQueryChildDocuments_documentError() throws Exception {
315        mMtpManager.setObjectHandles(0, 0, -1, new int[] { 1 });
316        try {
317            mProvider.queryChildDocuments("0_0_0", null, null);
318            fail();
319        } catch (Throwable error) {
320            assertTrue(error instanceof FileNotFoundException);
321        }
322    }
323
324    public void testDeleteDocument() throws FileNotFoundException {
325        mMtpManager.setObjectInfo(0, new MtpObjectInfo.Builder()
326                .setObjectHandle(1)
327                .setFormat(0x3801)
328                .setName("image.jpg")
329                .setDateModified(1422716400000L)
330                .setCompressedSize(1024 * 1024 * 5)
331                .setThumbCompressedSize(1024 * 50)
332                .build());
333        mMtpManager.setParent(0, 1, 2);
334        mProvider.deleteDocument("0_0_1");
335        assertEquals(1, mResolver.getChangeCount(
336                DocumentsContract.buildChildDocumentsUri(
337                        MtpDocumentsProvider.AUTHORITY, "0_0_2")));
338    }
339
340    public void testDeleteDocument_error() {
341        mMtpManager.setParent(0, 1, 2);
342        try {
343            mProvider.deleteDocument("0_0_1");
344            fail();
345        } catch (Throwable e) {
346            assertTrue(e instanceof IOException);
347        }
348        assertEquals(0, mResolver.getChangeCount(
349                DocumentsContract.buildChildDocumentsUri(
350                        MtpDocumentsProvider.AUTHORITY, "0_0_2")));
351    }
352}
353