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