blob: db25421afab00b68aee920ac9f0db4f2f74cac1b [file] [log] [blame]
Daichi Hirono6baa16e2015-08-12 13:51:59 +09001/*
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.content.Context;
20import android.database.Cursor;
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +090021import android.mtp.MtpObjectInfo;
Daichi Hirono6baa16e2015-08-12 13:51:59 +090022import android.net.Uri;
23import android.provider.DocumentsContract;
24import android.test.AndroidTestCase;
Daichi Hirono4604b742015-11-12 12:12:48 +090025import android.test.suitebuilder.annotation.MediumTest;
Daichi Hirono6baa16e2015-08-12 13:51:59 +090026
27import java.io.IOException;
Daichi Hirono6baa16e2015-08-12 13:51:59 +090028import java.util.HashMap;
29import java.util.Map;
30import java.util.concurrent.CountDownLatch;
31
Daichi Hirono4604b742015-11-12 12:12:48 +090032@MediumTest
Daichi Hirono6baa16e2015-08-12 13:51:59 +090033public class DocumentLoaderTest extends AndroidTestCase {
Daichi Hirono47eb1922015-11-16 13:01:31 +090034 private MtpDatabase mDatabase;
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +090035 private BlockableTestMtpManager mManager;
Daichi Hirono6baa16e2015-08-12 13:51:59 +090036 private TestContentResolver mResolver;
37 private DocumentLoader mLoader;
Daichi Hirono6a5ea7e2016-02-02 16:35:03 +090038 final private Identifier mParentIdentifier = new Identifier(
Daichi Hirono619afda2016-02-07 14:23:43 +090039 0, 0, 0, "2", MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE);
Daichi Hirono6baa16e2015-08-12 13:51:59 +090040
41 @Override
Daichi Hirono619afda2016-02-07 14:23:43 +090042 public void setUp() throws Exception {
Daichi Hirono47eb1922015-11-16 13:01:31 +090043 mDatabase = new MtpDatabase(getContext(), MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
Daichi Hirono619afda2016-02-07 14:23:43 +090044
45 mDatabase.getMapper().startAddingDocuments(null);
46 mDatabase.getMapper().putDeviceDocument(
Daichi Hirono4e94b8d2016-02-21 22:42:41 +090047 new MtpDeviceRecord(0, "Device", null, true, new MtpRoot[0], null, null));
Daichi Hirono619afda2016-02-07 14:23:43 +090048 mDatabase.getMapper().stopAddingDocuments(null);
49
50 mDatabase.getMapper().startAddingDocuments("1");
Daichi Hirono0f325372016-02-21 15:50:30 +090051 mDatabase.getMapper().putStorageDocuments("1", new int[0], new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +090052 new MtpRoot(0, 0, "Storage", 1000, 1000, "")
Daichi Hirono47eb1922015-11-16 13:01:31 +090053 });
Daichi Hirono619afda2016-02-07 14:23:43 +090054 mDatabase.getMapper().stopAddingDocuments("1");
55
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +090056 mManager = new BlockableTestMtpManager(getContext());
Daichi Hirono6baa16e2015-08-12 13:51:59 +090057 mResolver = new TestContentResolver();
Daichi Hirono61ba9232016-02-26 12:58:39 +090058 mLoader = new DocumentLoader(
59 new MtpDeviceRecord(
60 0, "Device", "Key", true, new MtpRoot[0],
61 TestUtil.OPERATIONS_SUPPORTED, new int[0]),
62 mManager,
63 mResolver,
64 mDatabase);
Daichi Hirono47eb1922015-11-16 13:01:31 +090065 }
66
67 @Override
Daichi Hirono4e94b8d2016-02-21 22:42:41 +090068 public void tearDown() throws Exception {
69 mLoader.close();
Daichi Hirono47eb1922015-11-16 13:01:31 +090070 mDatabase.close();
Daichi Hirono6baa16e2015-08-12 13:51:59 +090071 }
72
Daichi Hirono8b9024f2015-08-12 12:59:09 +090073 public void testBasic() throws Exception {
Daichi Hirono6baa16e2015-08-12 13:51:59 +090074 final Uri uri = DocumentsContract.buildChildDocumentsUri(
Daichi Hirono9e8a4fa2015-11-19 16:13:38 +090075 MtpDocumentsProvider.AUTHORITY, mParentIdentifier.mDocumentId);
Daichi Hirono6baa16e2015-08-12 13:51:59 +090076 setUpDocument(mManager, 40);
77 mManager.blockDocument(0, 15);
78 mManager.blockDocument(0, 35);
79
80 {
81 final Cursor cursor = mLoader.queryChildDocuments(
82 MtpDocumentsProvider.DEFAULT_DOCUMENT_PROJECTION, mParentIdentifier);
83 assertEquals(DocumentLoader.NUM_INITIAL_ENTRIES, cursor.getCount());
84 }
85
86 Thread.sleep(DocumentLoader.NOTIFY_PERIOD_MS);
87 mManager.unblockDocument(0, 15);
88 mResolver.waitForNotification(uri, 1);
89
90 {
91 final Cursor cursor = mLoader.queryChildDocuments(
92 MtpDocumentsProvider.DEFAULT_DOCUMENT_PROJECTION, mParentIdentifier);
93 assertEquals(
94 DocumentLoader.NUM_INITIAL_ENTRIES + DocumentLoader.NUM_LOADING_ENTRIES,
95 cursor.getCount());
96 }
97
98 mManager.unblockDocument(0, 35);
99 mResolver.waitForNotification(uri, 2);
100
101 {
102 final Cursor cursor = mLoader.queryChildDocuments(
103 MtpDocumentsProvider.DEFAULT_DOCUMENT_PROJECTION, mParentIdentifier);
104 assertEquals(40, cursor.getCount());
105 }
106
107 assertEquals(2, mResolver.getChangeCount(uri));
108 }
109
110 private void setUpDocument(TestMtpManager manager, int count) {
111 int[] childDocuments = new int[count];
112 for (int i = 0; i < childDocuments.length; i++) {
113 final int objectHandle = i + 1;
114 childDocuments[i] = objectHandle;
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +0900115 manager.setObjectInfo(0, new MtpObjectInfo.Builder()
116 .setObjectHandle(objectHandle)
Daichi Hirono47eb1922015-11-16 13:01:31 +0900117 .setName(Integer.toString(i))
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +0900118 .build());
Daichi Hirono6baa16e2015-08-12 13:51:59 +0900119 }
120 manager.setObjectHandles(0, 0, MtpManager.OBJECT_HANDLE_ROOT_CHILDREN, childDocuments);
121 }
122
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +0900123 private static class BlockableTestMtpManager extends TestMtpManager {
Daichi Hirono6baa16e2015-08-12 13:51:59 +0900124 final private Map<String, CountDownLatch> blockedDocuments = new HashMap<>();
125
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +0900126 BlockableTestMtpManager(Context context) {
Daichi Hirono6baa16e2015-08-12 13:51:59 +0900127 super(context);
128 }
129
130 void blockDocument(int deviceId, int objectHandle) {
131 blockedDocuments.put(pack(deviceId, objectHandle), new CountDownLatch(1));
132 }
133
134 void unblockDocument(int deviceId, int objectHandle) {
135 blockedDocuments.get(pack(deviceId, objectHandle)).countDown();
136 }
137
138 @Override
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +0900139 MtpObjectInfo getObjectInfo(int deviceId, int objectHandle) throws IOException {
Daichi Hirono6baa16e2015-08-12 13:51:59 +0900140 final CountDownLatch latch = blockedDocuments.get(pack(deviceId, objectHandle));
141 if (latch != null) {
142 try {
143 latch.await();
144 } catch(InterruptedException e) {
145 fail();
146 }
147 }
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +0900148 return super.getObjectInfo(deviceId, objectHandle);
Daichi Hirono6baa16e2015-08-12 13:51:59 +0900149 }
150 }
151}