blob: f9e8225dcb24119f8d6b75cea5efe127ceefd98f [file] [log] [blame]
Daichi Hirono6de8a0e2015-10-27 16:18:17 +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
Daichi Hirono9678f602015-10-22 12:35:05 +090017package com.android.mtp;
18
Daichi Hirono9678f602015-10-22 12:35:05 +090019import android.database.Cursor;
20import android.mtp.MtpConstants;
21import android.mtp.MtpObjectInfo;
22import android.provider.DocumentsContract;
Daichi Hirono49f920f2015-11-19 10:19:52 +090023import android.provider.DocumentsContract.Document;
Daichi Hirono0378da42015-11-05 11:56:12 +090024import android.provider.DocumentsContract.Root;
Daichi Hirono9678f602015-10-22 12:35:05 +090025import android.test.AndroidTestCase;
26import android.test.suitebuilder.annotation.SmallTest;
27
Daichi Hirono49f920f2015-11-19 10:19:52 +090028import java.io.FileNotFoundException;
Daichi Hirono49f920f2015-11-19 10:19:52 +090029
Daichi Hirono9984ebd2015-12-15 16:02:27 +090030import static android.provider.DocumentsContract.Document.*;
Daichi Hirono259ce802015-11-20 17:51:53 +090031import static com.android.mtp.MtpDatabase.strings;
Daichi Hirono9984ebd2015-12-15 16:02:27 +090032import static com.android.mtp.MtpDatabaseConstants.*;
Daichi Hirono0f325372016-02-21 15:50:30 +090033import static com.android.mtp.TestUtil.OPERATIONS_SUPPORTED;
Daichi Hirono49f920f2015-11-19 10:19:52 +090034
Daichi Hirono9678f602015-10-22 12:35:05 +090035@SmallTest
36public class MtpDatabaseTest extends AndroidTestCase {
Daichi Hirono0f325372016-02-21 15:50:30 +090037 private static final String[] COLUMN_NAMES = new String[] {
Daichi Hirono9678f602015-10-22 12:35:05 +090038 DocumentsContract.Document.COLUMN_DOCUMENT_ID,
Daichi Hirono18d70d52015-11-13 15:19:47 +090039 MtpDatabaseConstants.COLUMN_DEVICE_ID,
40 MtpDatabaseConstants.COLUMN_STORAGE_ID,
41 MtpDatabaseConstants.COLUMN_OBJECT_HANDLE,
Daichi Hirono9678f602015-10-22 12:35:05 +090042 DocumentsContract.Document.COLUMN_MIME_TYPE,
43 DocumentsContract.Document.COLUMN_DISPLAY_NAME,
44 DocumentsContract.Document.COLUMN_SUMMARY,
45 DocumentsContract.Document.COLUMN_LAST_MODIFIED,
46 DocumentsContract.Document.COLUMN_ICON,
47 DocumentsContract.Document.COLUMN_FLAGS,
Daichi Hirono4b54e032015-12-11 15:24:53 +090048 DocumentsContract.Document.COLUMN_SIZE,
49 MtpDatabaseConstants.COLUMN_DOCUMENT_TYPE
Daichi Hirono9678f602015-10-22 12:35:05 +090050 };
51
Daichi Hirono85a808b2015-10-27 17:22:13 +090052 private final TestResources resources = new TestResources();
Daichi Hirono4604b742015-11-12 12:12:48 +090053 MtpDatabase mDatabase;
54
55 @Override
56 public void setUp() {
Daichi Hirono47eb1922015-11-16 13:01:31 +090057 mDatabase = new MtpDatabase(getContext(), MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
Daichi Hirono4604b742015-11-12 12:12:48 +090058 }
59
60 @Override
61 public void tearDown() {
62 mDatabase.close();
63 mDatabase = null;
64 }
Daichi Hirono85a808b2015-10-27 17:22:13 +090065
Daichi Hirono9984ebd2015-12-15 16:02:27 +090066 private static int getInt(Cursor cursor, String columnName) {
67 return cursor.getInt(cursor.getColumnIndex(columnName));
68 }
69
70 private static boolean isNull(Cursor cursor, String columnName) {
71 return cursor.isNull(cursor.getColumnIndex(columnName));
72 }
73
74 private static String getString(Cursor cursor, String columnName) {
75 return cursor.getString(cursor.getColumnIndex(columnName));
76 }
77
Daichi Hirono81d48532015-12-16 15:03:19 +090078 public void testPutSingleStorageDocuments() throws Exception {
Daichi Hirono0f325372016-02-21 15:50:30 +090079 addTestDevice();
Daichi Hirono81d48532015-12-16 15:03:19 +090080
81 mDatabase.getMapper().startAddingDocuments("1");
Daichi Hirono0f325372016-02-21 15:50:30 +090082 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +090083 new MtpRoot(0, 1, "Storage", 1000, 2000, "")
Daichi Hirono81d48532015-12-16 15:03:19 +090084 });
85 mDatabase.getMapper().stopAddingDocuments("1");
86
87 {
88 final Cursor cursor = mDatabase.queryRootDocuments(COLUMN_NAMES);
89 assertEquals(1, cursor.getCount());
90
91 cursor.moveToNext();
92 assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
93 assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID));
94 assertEquals(1, getInt(cursor, COLUMN_STORAGE_ID));
95 assertTrue(isNull(cursor, COLUMN_OBJECT_HANDLE));
Daichi Hirono8e873642016-02-07 15:17:16 +090096 assertEquals(
97 DocumentsContract.Document.MIME_TYPE_DIR, getString(cursor, COLUMN_MIME_TYPE));
Daichi Hironof83ccbd2016-02-04 16:58:55 +090098 assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hirono81d48532015-12-16 15:03:19 +090099 assertTrue(isNull(cursor, COLUMN_SUMMARY));
100 assertTrue(isNull(cursor, COLUMN_LAST_MODIFIED));
101 assertEquals(R.drawable.ic_root_mtp, getInt(cursor, COLUMN_ICON));
102 assertEquals(0, getInt(cursor, COLUMN_FLAGS));
103 assertEquals(1000, getInt(cursor, COLUMN_SIZE));
104 assertEquals(
Daichi Hirono8e873642016-02-07 15:17:16 +0900105 MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE,
106 getInt(cursor, COLUMN_DOCUMENT_TYPE));
Daichi Hirono81d48532015-12-16 15:03:19 +0900107
108 cursor.close();
109 }
110
111 {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900112 final Cursor cursor = mDatabase.queryRoots(resources, new String [] {
Daichi Hirono81d48532015-12-16 15:03:19 +0900113 Root.COLUMN_ROOT_ID,
114 Root.COLUMN_FLAGS,
115 Root.COLUMN_ICON,
116 Root.COLUMN_TITLE,
117 Root.COLUMN_SUMMARY,
118 Root.COLUMN_DOCUMENT_ID,
119 Root.COLUMN_AVAILABLE_BYTES,
120 Root.COLUMN_CAPACITY_BYTES
121 });
122 assertEquals(1, cursor.getCount());
123
124 cursor.moveToNext();
Daichi Hirono6a5ea7e2016-02-02 16:35:03 +0900125 assertEquals(1, getInt(cursor, Root.COLUMN_ROOT_ID));
Daichi Hirono81d48532015-12-16 15:03:19 +0900126 assertEquals(
127 Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE,
128 getInt(cursor, Root.COLUMN_FLAGS));
129 assertEquals(R.drawable.ic_root_mtp, getInt(cursor, Root.COLUMN_ICON));
130 assertEquals("Device Storage", getString(cursor, Root.COLUMN_TITLE));
131 assertTrue(isNull(cursor, Root.COLUMN_SUMMARY));
Daichi Hirono6a5ea7e2016-02-02 16:35:03 +0900132 assertEquals(1, getInt(cursor, Root.COLUMN_DOCUMENT_ID));
Daichi Hirono81d48532015-12-16 15:03:19 +0900133 assertEquals(1000, getInt(cursor, Root.COLUMN_AVAILABLE_BYTES));
134 assertEquals(2000, getInt(cursor, Root.COLUMN_CAPACITY_BYTES));
135
136 cursor.close();
137 }
138 }
139
140 public void testPutStorageDocuments() throws Exception {
Daichi Hirono619afda2016-02-07 14:23:43 +0900141 addTestDevice();
142
143 mDatabase.getMapper().startAddingDocuments("1");
Daichi Hirono0f325372016-02-21 15:50:30 +0900144 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900145 new MtpRoot(0, 1, "Storage", 1000, 2000, ""),
146 new MtpRoot(0, 2, "Storage", 2000, 4000, ""),
147 new MtpRoot(0, 3, "/@#%&<>Storage", 3000, 6000,"")
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900148 });
Daichi Hirono9678f602015-10-22 12:35:05 +0900149
Daichi Hirono0378da42015-11-05 11:56:12 +0900150 {
Daichi Hirono4604b742015-11-12 12:12:48 +0900151 final Cursor cursor = mDatabase.queryRootDocuments(COLUMN_NAMES);
Daichi Hirono0378da42015-11-05 11:56:12 +0900152 assertEquals(3, cursor.getCount());
Daichi Hirono9678f602015-10-22 12:35:05 +0900153
Daichi Hirono0378da42015-11-05 11:56:12 +0900154 cursor.moveToNext();
Daichi Hirono619afda2016-02-07 14:23:43 +0900155 assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900156 assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID));
157 assertEquals(1, getInt(cursor, COLUMN_STORAGE_ID));
158 assertTrue(isNull(cursor, COLUMN_OBJECT_HANDLE));
159 assertEquals(DocumentsContract.Document.MIME_TYPE_DIR, getString(cursor, COLUMN_MIME_TYPE));
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900160 assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900161 assertTrue(isNull(cursor, COLUMN_SUMMARY));
162 assertTrue(isNull(cursor, COLUMN_LAST_MODIFIED));
163 assertEquals(R.drawable.ic_root_mtp, getInt(cursor, COLUMN_ICON));
164 assertEquals(0, getInt(cursor, COLUMN_FLAGS));
165 assertEquals(1000, getInt(cursor, COLUMN_SIZE));
Daichi Hirono4b54e032015-12-11 15:24:53 +0900166 assertEquals(
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900167 MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE, getInt(cursor, COLUMN_DOCUMENT_TYPE));
Daichi Hirono9678f602015-10-22 12:35:05 +0900168
Daichi Hirono0378da42015-11-05 11:56:12 +0900169 cursor.moveToNext();
Daichi Hirono619afda2016-02-07 14:23:43 +0900170 assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900171 assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hirono9678f602015-10-22 12:35:05 +0900172
Daichi Hirono0378da42015-11-05 11:56:12 +0900173 cursor.moveToNext();
Daichi Hirono619afda2016-02-07 14:23:43 +0900174 assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900175 assertEquals("/@#%&<>Storage", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hirono88d2f782015-10-27 16:41:06 +0900176
Daichi Hirono0378da42015-11-05 11:56:12 +0900177 cursor.close();
178 }
Daichi Hirono9678f602015-10-22 12:35:05 +0900179 }
180
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900181 private MtpObjectInfo createDocument(int objectHandle, String name, int format, int size) {
Daichi Hirono9678f602015-10-22 12:35:05 +0900182 final MtpObjectInfo.Builder builder = new MtpObjectInfo.Builder();
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900183 builder.setObjectHandle(objectHandle);
184 builder.setName(name);
185 builder.setFormat(format);
186 builder.setCompressedSize(size);
187 return builder.build();
188 }
Daichi Hirono9678f602015-10-22 12:35:05 +0900189
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900190 public void testPutChildDocuments() throws Exception {
Daichi Hirono619afda2016-02-07 14:23:43 +0900191 addTestDevice();
192 addTestStorage("1");
193
194 mDatabase.getMapper().startAddingDocuments("2");
Daichi Hirono61ba9232016-02-26 12:58:39 +0900195 mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900196 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
197 createDocument(101, "image.jpg", MtpConstants.FORMAT_EXIF_JPEG, 2 * 1024 * 1024),
198 createDocument(102, "music.mp3", MtpConstants.FORMAT_MP3, 3 * 1024 * 1024)
199 });
200
Daichi Hirono619afda2016-02-07 14:23:43 +0900201 final Cursor cursor = mDatabase.queryChildDocuments(COLUMN_NAMES, "2");
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900202 assertEquals(3, cursor.getCount());
203
Daichi Hirono9678f602015-10-22 12:35:05 +0900204 cursor.moveToNext();
Daichi Hirono619afda2016-02-07 14:23:43 +0900205 assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900206 assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID));
207 assertEquals(0, getInt(cursor, COLUMN_STORAGE_ID));
208 assertEquals(100, getInt(cursor, COLUMN_OBJECT_HANDLE));
209 assertEquals("text/plain", getString(cursor, COLUMN_MIME_TYPE));
210 assertEquals("note.txt", getString(cursor, COLUMN_DISPLAY_NAME));
211 assertTrue(isNull(cursor, COLUMN_SUMMARY));
212 assertTrue(isNull(cursor, COLUMN_LAST_MODIFIED));
213 assertTrue(isNull(cursor, COLUMN_ICON));
Daichi Hirono9678f602015-10-22 12:35:05 +0900214 assertEquals(
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900215 COLUMN_FLAGS,
Daichi Hirono9678f602015-10-22 12:35:05 +0900216 DocumentsContract.Document.FLAG_SUPPORTS_DELETE |
217 DocumentsContract.Document.FLAG_SUPPORTS_WRITE,
Daichi Hirono88d2f782015-10-27 16:41:06 +0900218 cursor.getInt(9));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900219 assertEquals(1024, getInt(cursor, COLUMN_SIZE));
Daichi Hirono4b54e032015-12-11 15:24:53 +0900220 assertEquals(
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900221 MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT, getInt(cursor, COLUMN_DOCUMENT_TYPE));
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900222
223 cursor.moveToNext();
Daichi Hirono619afda2016-02-07 14:23:43 +0900224 assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900225 assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID));
226 assertEquals(0, getInt(cursor, COLUMN_STORAGE_ID));
227 assertEquals(101, getInt(cursor, COLUMN_OBJECT_HANDLE));
228 assertEquals("image/jpeg", getString(cursor, COLUMN_MIME_TYPE));
229 assertEquals("image.jpg", getString(cursor, COLUMN_DISPLAY_NAME));
230 assertTrue(isNull(cursor, COLUMN_SUMMARY));
231 assertTrue(isNull(cursor, COLUMN_LAST_MODIFIED));
232 assertTrue(isNull(cursor, COLUMN_ICON));
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900233 assertEquals(
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900234 COLUMN_FLAGS,
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900235 DocumentsContract.Document.FLAG_SUPPORTS_DELETE |
236 DocumentsContract.Document.FLAG_SUPPORTS_WRITE,
237 cursor.getInt(9));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900238 assertEquals(2 * 1024 * 1024, getInt(cursor, COLUMN_SIZE));
Daichi Hirono4b54e032015-12-11 15:24:53 +0900239 assertEquals(
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900240 MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT, getInt(cursor, COLUMN_DOCUMENT_TYPE));
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900241
242 cursor.moveToNext();
Daichi Hirono619afda2016-02-07 14:23:43 +0900243 assertEquals(5, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900244 assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID));
245 assertEquals(0, getInt(cursor, COLUMN_STORAGE_ID));
246 assertEquals(102, getInt(cursor, COLUMN_OBJECT_HANDLE));
247 assertEquals("audio/mpeg", getString(cursor, COLUMN_MIME_TYPE));
248 assertEquals("music.mp3", getString(cursor, COLUMN_DISPLAY_NAME));
249 assertTrue(isNull(cursor, COLUMN_SUMMARY));
250 assertTrue(isNull(cursor, COLUMN_LAST_MODIFIED));
251 assertTrue(isNull(cursor, COLUMN_ICON));
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900252 assertEquals(
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900253 COLUMN_FLAGS,
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900254 DocumentsContract.Document.FLAG_SUPPORTS_DELETE |
255 DocumentsContract.Document.FLAG_SUPPORTS_WRITE,
256 cursor.getInt(9));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900257 assertEquals(3 * 1024 * 1024, getInt(cursor, COLUMN_SIZE));
Daichi Hirono4b54e032015-12-11 15:24:53 +0900258 assertEquals(
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900259 MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT, getInt(cursor, COLUMN_DOCUMENT_TYPE));
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900260
261 cursor.close();
Daichi Hirono9678f602015-10-22 12:35:05 +0900262 }
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900263
Daichi Hirono61ba9232016-02-26 12:58:39 +0900264 public void testPutChildDocuments_operationsSupported() throws Exception {
265 addTestDevice();
266 addTestStorage("1");
267
268 // Put a document with empty supported operations.
269 mDatabase.getMapper().startAddingDocuments("2");
270 mDatabase.getMapper().putChildDocuments(0, "2", new int[0], new MtpObjectInfo[] {
271 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024)
272 });
273 mDatabase.getMapper().stopAddingDocuments("2");
274
275 try (final Cursor cursor =
276 mDatabase.queryChildDocuments(strings(Document.COLUMN_FLAGS), "2")) {
277 assertEquals(1, cursor.getCount());
278 cursor.moveToNext();
279 assertEquals(0, cursor.getInt(0));
280 }
281
282 // Put a document with writable operations.
283 mDatabase.getMapper().startAddingDocuments("2");
284 mDatabase.getMapper().putChildDocuments(0, "2", new int[] {
285 MtpConstants.OPERATION_SEND_OBJECT,
286 MtpConstants.OPERATION_SEND_OBJECT_INFO,
287 }, new MtpObjectInfo[] {
288 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024)
289 });
290 mDatabase.getMapper().stopAddingDocuments("2");
291
292 try (final Cursor cursor =
293 mDatabase.queryChildDocuments(strings(Document.COLUMN_FLAGS), "2")) {
294 assertEquals(1, cursor.getCount());
295 cursor.moveToNext();
296 assertEquals(Document.FLAG_SUPPORTS_WRITE, cursor.getInt(0));
297 }
298
299 // Put a document with deletable operations.
300 mDatabase.getMapper().startAddingDocuments("2");
301 mDatabase.getMapper().putChildDocuments(0, "2", new int[] {
302 MtpConstants.OPERATION_DELETE_OBJECT
303 }, new MtpObjectInfo[] {
304 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024)
305 });
306 mDatabase.getMapper().stopAddingDocuments("2");
307
308 try (final Cursor cursor =
309 mDatabase.queryChildDocuments(strings(Document.COLUMN_FLAGS), "2")) {
310 assertEquals(1, cursor.getCount());
311 cursor.moveToNext();
312 assertEquals(Document.FLAG_SUPPORTS_DELETE, cursor.getInt(0));
313 }
314 }
315
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900316 public void testRestoreIdForRootDocuments() throws Exception {
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900317 final String[] columns = new String[] {
318 DocumentsContract.Document.COLUMN_DOCUMENT_ID,
Daichi Hirono18d70d52015-11-13 15:19:47 +0900319 MtpDatabaseConstants.COLUMN_STORAGE_ID,
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900320 DocumentsContract.Document.COLUMN_DISPLAY_NAME
321 };
Daichi Hirono4604b742015-11-12 12:12:48 +0900322
Daichi Hirono619afda2016-02-07 14:23:43 +0900323 // Add device and two storages.
324 addTestDevice();
325 mDatabase.getMapper().startAddingDocuments("1");
Daichi Hirono0f325372016-02-21 15:50:30 +0900326 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900327 new MtpRoot(0, 100, "Storage A", 1000, 0, ""),
328 new MtpRoot(0, 101, "Storage B", 1001, 0, "")
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900329 });
330
331 {
Daichi Hirono4604b742015-11-12 12:12:48 +0900332 final Cursor cursor = mDatabase.queryRootDocuments(columns);
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900333 assertEquals(2, cursor.getCount());
334 cursor.moveToNext();
Daichi Hirono619afda2016-02-07 14:23:43 +0900335 assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900336 assertEquals(100, getInt(cursor, COLUMN_STORAGE_ID));
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900337 assertEquals("Storage A", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900338 cursor.moveToNext();
Daichi Hirono619afda2016-02-07 14:23:43 +0900339 assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900340 assertEquals(101, getInt(cursor, COLUMN_STORAGE_ID));
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900341 assertEquals("Storage B", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900342 cursor.close();
343 }
344
Daichi Hirono619afda2016-02-07 14:23:43 +0900345 // Clear mapping and add a device.
Daichi Hirono259ce802015-11-20 17:51:53 +0900346 mDatabase.getMapper().clearMapping();
Daichi Hirono619afda2016-02-07 14:23:43 +0900347 addTestDevice();
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900348
349 {
Daichi Hirono4604b742015-11-12 12:12:48 +0900350 final Cursor cursor = mDatabase.queryRootDocuments(columns);
Daichi Hirono8e873642016-02-07 15:17:16 +0900351 assertEquals(0, cursor.getCount());
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900352 cursor.close();
353 }
354
Daichi Hirono619afda2016-02-07 14:23:43 +0900355 // Add two storages, but one's name is different from previous one.
356 mDatabase.getMapper().startAddingDocuments("1");
Daichi Hirono0f325372016-02-21 15:50:30 +0900357 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900358 new MtpRoot(0, 200, "Storage A", 2000, 0, ""),
359 new MtpRoot(0, 202, "Storage C", 2002, 0, "")
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900360 });
Daichi Hirono619afda2016-02-07 14:23:43 +0900361 mDatabase.getMapper().stopAddingDocuments("1");
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900362
363 {
Daichi Hirono8e873642016-02-07 15:17:16 +0900364 // After compeleting mapping, Storage A can be obtained with new storage ID.
Daichi Hirono4604b742015-11-12 12:12:48 +0900365 final Cursor cursor = mDatabase.queryRootDocuments(columns);
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900366 assertEquals(2, cursor.getCount());
367 cursor.moveToNext();
Daichi Hirono619afda2016-02-07 14:23:43 +0900368 assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900369 assertEquals(200, getInt(cursor, COLUMN_STORAGE_ID));
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900370 assertEquals("Storage A", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900371 cursor.moveToNext();
Daichi Hirono619afda2016-02-07 14:23:43 +0900372 assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900373 assertEquals(202, getInt(cursor, COLUMN_STORAGE_ID));
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900374 assertEquals("Storage C", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900375 cursor.close();
376 }
377 }
378
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900379 public void testRestoreIdForChildDocuments() throws Exception {
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900380 final String[] columns = new String[] {
381 DocumentsContract.Document.COLUMN_DOCUMENT_ID,
Daichi Hirono18d70d52015-11-13 15:19:47 +0900382 MtpDatabaseConstants.COLUMN_OBJECT_HANDLE,
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900383 DocumentsContract.Document.COLUMN_DISPLAY_NAME
384 };
Daichi Hirono619afda2016-02-07 14:23:43 +0900385
386 addTestDevice();
387 addTestStorage("1");
388
389 mDatabase.getMapper().startAddingDocuments("2");
Daichi Hirono61ba9232016-02-26 12:58:39 +0900390 mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900391 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
392 createDocument(101, "image.jpg", MtpConstants.FORMAT_EXIF_JPEG, 2 * 1024 * 1024),
393 createDocument(102, "music.mp3", MtpConstants.FORMAT_MP3, 3 * 1024 * 1024)
394 });
Daichi Hirono259ce802015-11-20 17:51:53 +0900395 mDatabase.getMapper().clearMapping();
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900396
Daichi Hirono619afda2016-02-07 14:23:43 +0900397 addTestDevice();
398 addTestStorage("1");
399
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900400 {
Daichi Hirono8e873642016-02-07 15:17:16 +0900401 // Don't return objects that lost MTP object handles.
Daichi Hirono619afda2016-02-07 14:23:43 +0900402 final Cursor cursor = mDatabase.queryChildDocuments(columns, "2");
Daichi Hirono8e873642016-02-07 15:17:16 +0900403 assertEquals(0, cursor.getCount());
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900404 cursor.close();
405 }
406
Daichi Hirono619afda2016-02-07 14:23:43 +0900407 mDatabase.getMapper().startAddingDocuments("2");
Daichi Hirono61ba9232016-02-26 12:58:39 +0900408 mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900409 createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
410 createDocument(203, "video.mp4", MtpConstants.FORMAT_MP4_CONTAINER, 1024),
411 });
Daichi Hirono619afda2016-02-07 14:23:43 +0900412 mDatabase.getMapper().stopAddingDocuments("2");
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900413
414 {
Daichi Hirono619afda2016-02-07 14:23:43 +0900415 final Cursor cursor = mDatabase.queryChildDocuments(columns, "2");
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900416 assertEquals(2, cursor.getCount());
417
418 cursor.moveToNext();
Daichi Hirono619afda2016-02-07 14:23:43 +0900419 assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900420 assertEquals(200, getInt(cursor, COLUMN_OBJECT_HANDLE));
421 assertEquals("note.txt", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900422
423 cursor.moveToNext();
Daichi Hirono619afda2016-02-07 14:23:43 +0900424 assertEquals(6, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900425 assertEquals(203, getInt(cursor, COLUMN_OBJECT_HANDLE));
426 assertEquals("video.mp4", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hirono619afda2016-02-07 14:23:43 +0900427
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900428 cursor.close();
429 }
430 }
431
Daichi Hironob3fe72b2015-12-15 07:45:06 +0000432 public void testRestoreIdForDifferentDevices() throws Exception {
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900433 final String[] columns = new String[] {
434 DocumentsContract.Document.COLUMN_DOCUMENT_ID,
Daichi Hirono18d70d52015-11-13 15:19:47 +0900435 MtpDatabaseConstants.COLUMN_STORAGE_ID,
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900436 DocumentsContract.Document.COLUMN_DISPLAY_NAME
437 };
Daichi Hirono0378da42015-11-05 11:56:12 +0900438 final String[] rootColumns = new String[] {
439 Root.COLUMN_ROOT_ID,
440 Root.COLUMN_AVAILABLE_BYTES
441 };
Daichi Hirono81d48532015-12-16 15:03:19 +0900442 mDatabase.getMapper().startAddingDocuments(null);
Daichi Hirono619afda2016-02-07 14:23:43 +0900443 mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
Daichi Hironoebd24052016-02-06 21:05:57 +0900444 0, "Device A", "Device key A", true, new MtpRoot[0], null, null));
Daichi Hirono619afda2016-02-07 14:23:43 +0900445 mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
Daichi Hironoebd24052016-02-06 21:05:57 +0900446 1, "Device B", "Device key B", true, new MtpRoot[0], null, null));
Daichi Hirono81d48532015-12-16 15:03:19 +0900447 mDatabase.getMapper().stopAddingDocuments(null);
448
449 mDatabase.getMapper().startAddingDocuments("1");
450 mDatabase.getMapper().startAddingDocuments("2");
Daichi Hirono0f325372016-02-21 15:50:30 +0900451 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900452 new MtpRoot(0, 100, "Storage", 0, 0, "")
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900453 });
Daichi Hirono0f325372016-02-21 15:50:30 +0900454 mDatabase.getMapper().putStorageDocuments("2", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900455 new MtpRoot(1, 100, "Storage", 0, 0, "")
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900456 });
457
458 {
Daichi Hirono4604b742015-11-12 12:12:48 +0900459 final Cursor cursor = mDatabase.queryRootDocuments(columns);
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900460 assertEquals(2, cursor.getCount());
461 cursor.moveToNext();
Daichi Hirono81d48532015-12-16 15:03:19 +0900462 assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900463 assertEquals(100, getInt(cursor, COLUMN_STORAGE_ID));
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900464 assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900465 cursor.moveToNext();
Daichi Hirono81d48532015-12-16 15:03:19 +0900466 assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900467 assertEquals(100, getInt(cursor, COLUMN_STORAGE_ID));
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900468 assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900469 cursor.close();
470 }
471
Daichi Hirono0378da42015-11-05 11:56:12 +0900472 {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900473 final Cursor cursor = mDatabase.queryRoots(resources, rootColumns);
Daichi Hirono0378da42015-11-05 11:56:12 +0900474 assertEquals(2, cursor.getCount());
475 cursor.moveToNext();
Daichi Hirono6a5ea7e2016-02-02 16:35:03 +0900476 assertEquals(1, getInt(cursor, Root.COLUMN_ROOT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900477 assertEquals(0, getInt(cursor, Root.COLUMN_AVAILABLE_BYTES));
Daichi Hirono0378da42015-11-05 11:56:12 +0900478 cursor.moveToNext();
Daichi Hirono6a5ea7e2016-02-02 16:35:03 +0900479 assertEquals(2, getInt(cursor, Root.COLUMN_ROOT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900480 assertEquals(0, getInt(cursor, Root.COLUMN_AVAILABLE_BYTES));
Daichi Hirono0378da42015-11-05 11:56:12 +0900481 cursor.close();
482 }
483
Daichi Hirono259ce802015-11-20 17:51:53 +0900484 mDatabase.getMapper().clearMapping();
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900485
Daichi Hirono619afda2016-02-07 14:23:43 +0900486 mDatabase.getMapper().startAddingDocuments(null);
487 mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
Daichi Hironoebd24052016-02-06 21:05:57 +0900488 0, "Device A", "Device key A", true, new MtpRoot[0], null, null));
Daichi Hirono619afda2016-02-07 14:23:43 +0900489 mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
Daichi Hironoebd24052016-02-06 21:05:57 +0900490 1, "Device B", "Device key B", true, new MtpRoot[0], null, null));
Daichi Hirono619afda2016-02-07 14:23:43 +0900491 mDatabase.getMapper().stopAddingDocuments(null);
492
Daichi Hirono81d48532015-12-16 15:03:19 +0900493 mDatabase.getMapper().startAddingDocuments("1");
494 mDatabase.getMapper().startAddingDocuments("2");
Daichi Hirono0f325372016-02-21 15:50:30 +0900495 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900496 new MtpRoot(0, 200, "Storage", 2000, 0, "")
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900497 });
Daichi Hirono0f325372016-02-21 15:50:30 +0900498 mDatabase.getMapper().putStorageDocuments("2", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900499 new MtpRoot(1, 300, "Storage", 3000, 0, "")
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900500 });
Daichi Hirono81d48532015-12-16 15:03:19 +0900501 mDatabase.getMapper().stopAddingDocuments("1");
502 mDatabase.getMapper().stopAddingDocuments("2");
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900503
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900504 {
Daichi Hirono4604b742015-11-12 12:12:48 +0900505 final Cursor cursor = mDatabase.queryRootDocuments(columns);
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900506 assertEquals(2, cursor.getCount());
507 cursor.moveToNext();
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900508 assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900509 assertEquals(200, getInt(cursor, COLUMN_STORAGE_ID));
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900510 assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900511 cursor.moveToNext();
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900512 assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900513 assertEquals(300, getInt(cursor, COLUMN_STORAGE_ID));
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900514 assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900515 cursor.close();
516 }
Daichi Hirono0378da42015-11-05 11:56:12 +0900517
518 {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900519 final Cursor cursor = mDatabase.queryRoots(resources, rootColumns);
Daichi Hirono0378da42015-11-05 11:56:12 +0900520 assertEquals(2, cursor.getCount());
521 cursor.moveToNext();
Daichi Hirono6a5ea7e2016-02-02 16:35:03 +0900522 assertEquals(1, getInt(cursor, Root.COLUMN_ROOT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900523 assertEquals(2000, getInt(cursor, Root.COLUMN_AVAILABLE_BYTES));
Daichi Hirono0378da42015-11-05 11:56:12 +0900524 cursor.moveToNext();
Daichi Hirono6a5ea7e2016-02-02 16:35:03 +0900525 assertEquals(2, getInt(cursor, Root.COLUMN_ROOT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900526 assertEquals(3000, getInt(cursor, Root.COLUMN_AVAILABLE_BYTES));
Daichi Hirono0378da42015-11-05 11:56:12 +0900527 cursor.close();
528 }
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900529 }
530
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900531 public void testRestoreIdForDifferentParents() throws Exception {
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900532 final String[] columns = new String[] {
533 DocumentsContract.Document.COLUMN_DOCUMENT_ID,
Daichi Hirono18d70d52015-11-13 15:19:47 +0900534 MtpDatabaseConstants.COLUMN_OBJECT_HANDLE
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900535 };
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900536
Daichi Hirono619afda2016-02-07 14:23:43 +0900537 // Add device, storage, and two directories.
538 addTestDevice();
539 addTestStorage("1");
540 mDatabase.getMapper().startAddingDocuments("2");
Daichi Hirono61ba9232016-02-26 12:58:39 +0900541 mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
Daichi Hirono619afda2016-02-07 14:23:43 +0900542 createDocument(50, "A", MtpConstants.FORMAT_ASSOCIATION, 0),
543 createDocument(51, "B", MtpConstants.FORMAT_ASSOCIATION, 0),
544 });
545 mDatabase.getMapper().stopAddingDocuments("2");
546
547 // Put note.txt in each directory.
548 mDatabase.getMapper().startAddingDocuments("3");
549 mDatabase.getMapper().startAddingDocuments("4");
Daichi Hirono61ba9232016-02-26 12:58:39 +0900550 mDatabase.getMapper().putChildDocuments(0, "3", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900551 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
552 });
Daichi Hirono61ba9232016-02-26 12:58:39 +0900553 mDatabase.getMapper().putChildDocuments(0, "4", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900554 createDocument(101, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
555 });
Daichi Hirono619afda2016-02-07 14:23:43 +0900556
557 // Clear mapping.
Daichi Hirono259ce802015-11-20 17:51:53 +0900558 mDatabase.getMapper().clearMapping();
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900559
Daichi Hirono619afda2016-02-07 14:23:43 +0900560 // Add device, storage, and two directories again.
561 addTestDevice();
562 addTestStorage("1");
563 mDatabase.getMapper().startAddingDocuments("2");
Daichi Hirono61ba9232016-02-26 12:58:39 +0900564 mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
Daichi Hirono619afda2016-02-07 14:23:43 +0900565 createDocument(50, "A", MtpConstants.FORMAT_ASSOCIATION, 0),
566 createDocument(51, "B", MtpConstants.FORMAT_ASSOCIATION, 0),
567 });
568 mDatabase.getMapper().stopAddingDocuments("2");
569
570 // Add note.txt in each directory again.
571 mDatabase.getMapper().startAddingDocuments("3");
572 mDatabase.getMapper().startAddingDocuments("4");
Daichi Hirono61ba9232016-02-26 12:58:39 +0900573 mDatabase.getMapper().putChildDocuments(0, "3", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900574 createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
575 });
Daichi Hirono61ba9232016-02-26 12:58:39 +0900576 mDatabase.getMapper().putChildDocuments(0, "4", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900577 createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
578 });
Daichi Hirono619afda2016-02-07 14:23:43 +0900579 mDatabase.getMapper().stopAddingDocuments("3");
580 mDatabase.getMapper().stopAddingDocuments("4");
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900581
Daichi Hirono619afda2016-02-07 14:23:43 +0900582 // Check if the two note.txt are mapped correctly.
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900583 {
Daichi Hirono619afda2016-02-07 14:23:43 +0900584 final Cursor cursor = mDatabase.queryChildDocuments(columns, "3");
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900585 assertEquals(1, cursor.getCount());
586 cursor.moveToNext();
Daichi Hirono619afda2016-02-07 14:23:43 +0900587 assertEquals(5, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900588 assertEquals(200, getInt(cursor, COLUMN_OBJECT_HANDLE));
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900589 cursor.close();
590 }
591 {
Daichi Hirono619afda2016-02-07 14:23:43 +0900592 final Cursor cursor = mDatabase.queryChildDocuments(columns, "4");
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900593 assertEquals(1, cursor.getCount());
594 cursor.moveToNext();
Daichi Hirono619afda2016-02-07 14:23:43 +0900595 assertEquals(6, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9fca5412016-02-07 13:20:22 +0900596 assertEquals(201, getInt(cursor, COLUMN_OBJECT_HANDLE));
Daichi Hironoa8a3722e2015-10-26 16:39:54 +0900597 cursor.close();
598 }
599 }
600
Daichi Hirono619afda2016-02-07 14:23:43 +0900601 public void testClearMtpIdentifierBeforeResolveRootDocuments() throws Exception {
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900602 final String[] columns = new String[] {
603 DocumentsContract.Document.COLUMN_DOCUMENT_ID,
Daichi Hirono18d70d52015-11-13 15:19:47 +0900604 MtpDatabaseConstants.COLUMN_STORAGE_ID,
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900605 DocumentsContract.Document.COLUMN_DISPLAY_NAME
606 };
Daichi Hirono0378da42015-11-05 11:56:12 +0900607 final String[] rootColumns = new String[] {
608 Root.COLUMN_ROOT_ID,
609 Root.COLUMN_AVAILABLE_BYTES
610 };
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900611
Daichi Hirono8e873642016-02-07 15:17:16 +0900612 addTestDevice();
Daichi Hirono81d48532015-12-16 15:03:19 +0900613
614 mDatabase.getMapper().startAddingDocuments("1");
Daichi Hirono0f325372016-02-21 15:50:30 +0900615 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900616 new MtpRoot(0, 100, "Storage", 0, 0, ""),
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900617 });
Daichi Hirono259ce802015-11-20 17:51:53 +0900618 mDatabase.getMapper().clearMapping();
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900619
Daichi Hironoebd24052016-02-06 21:05:57 +0900620 addTestDevice();
Daichi Hirono619afda2016-02-07 14:23:43 +0900621
622 try (final Cursor cursor = mDatabase.queryRoots(resources, rootColumns)) {
623 assertEquals(1, cursor.getCount());
624 cursor.moveToNext();
625 assertEquals("1", getString(cursor, Root.COLUMN_ROOT_ID));
626 }
627
Daichi Hirono81d48532015-12-16 15:03:19 +0900628 mDatabase.getMapper().startAddingDocuments("1");
Daichi Hirono0f325372016-02-21 15:50:30 +0900629 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900630 new MtpRoot(0, 200, "Storage", 2000, 0, ""),
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900631 });
Daichi Hirono259ce802015-11-20 17:51:53 +0900632 mDatabase.getMapper().clearMapping();
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900633
Daichi Hironoebd24052016-02-06 21:05:57 +0900634 addTestDevice();
Daichi Hirono619afda2016-02-07 14:23:43 +0900635
Daichi Hirono81d48532015-12-16 15:03:19 +0900636 mDatabase.getMapper().startAddingDocuments("1");
Daichi Hirono0f325372016-02-21 15:50:30 +0900637 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900638 new MtpRoot(0, 300, "Storage", 3000, 0, ""),
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900639 });
Daichi Hirono81d48532015-12-16 15:03:19 +0900640 mDatabase.getMapper().stopAddingDocuments("1");
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900641
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900642 {
Daichi Hirono4604b742015-11-12 12:12:48 +0900643 final Cursor cursor = mDatabase.queryRootDocuments(columns);
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900644 assertEquals(1, cursor.getCount());
645 cursor.moveToNext();
Daichi Hirono81d48532015-12-16 15:03:19 +0900646 assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900647 assertEquals(300, getInt(cursor, COLUMN_STORAGE_ID));
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900648 assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900649 cursor.close();
650 }
Daichi Hirono0378da42015-11-05 11:56:12 +0900651 {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900652 final Cursor cursor = mDatabase.queryRoots(resources, rootColumns);
Daichi Hirono0378da42015-11-05 11:56:12 +0900653 assertEquals(1, cursor.getCount());
654 cursor.moveToNext();
Daichi Hirono6a5ea7e2016-02-02 16:35:03 +0900655 assertEquals(1, getInt(cursor, Root.COLUMN_ROOT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900656 assertEquals(3000, getInt(cursor, Root.COLUMN_AVAILABLE_BYTES));
Daichi Hirono0378da42015-11-05 11:56:12 +0900657 cursor.close();
658 }
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900659 }
660
661 public void testPutSameNameRootsAfterClearing() throws Exception {
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900662 final String[] columns = new String[] {
663 DocumentsContract.Document.COLUMN_DOCUMENT_ID,
Daichi Hirono18d70d52015-11-13 15:19:47 +0900664 MtpDatabaseConstants.COLUMN_STORAGE_ID,
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900665 DocumentsContract.Document.COLUMN_DISPLAY_NAME
666 };
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900667
Daichi Hirono619afda2016-02-07 14:23:43 +0900668 // Add a device and a storage.
669 addTestDevice();
670 addTestStorage("1");
671
672 // Disconnect devices.
Daichi Hirono259ce802015-11-20 17:51:53 +0900673 mDatabase.getMapper().clearMapping();
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900674
Daichi Hirono619afda2016-02-07 14:23:43 +0900675 // Add a device and two storages that has same name.
676 addTestDevice();
677 mDatabase.getMapper().startAddingDocuments("1");
Daichi Hirono0f325372016-02-21 15:50:30 +0900678 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900679 new MtpRoot(0, 200, "Storage", 2000, 0, ""),
680 new MtpRoot(0, 201, "Storage", 2001, 0, ""),
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900681 });
Daichi Hirono619afda2016-02-07 14:23:43 +0900682 mDatabase.getMapper().stopAddingDocuments("1");
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900683
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900684 {
Daichi Hirono4604b742015-11-12 12:12:48 +0900685 final Cursor cursor = mDatabase.queryRootDocuments(columns);
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900686 assertEquals(2, cursor.getCount());
Daichi Hirono619afda2016-02-07 14:23:43 +0900687
688 // First storage reuse document ID of previous storage.
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900689 cursor.moveToNext();
Daichi Hirono9fca5412016-02-07 13:20:22 +0900690 // One reuses exisitng document ID 1.
Daichi Hirono619afda2016-02-07 14:23:43 +0900691 assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900692 assertEquals(200, getInt(cursor, COLUMN_STORAGE_ID));
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900693 assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hirono619afda2016-02-07 14:23:43 +0900694
695 // Second one has new document ID.
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900696 cursor.moveToNext();
Daichi Hirono619afda2016-02-07 14:23:43 +0900697 assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900698 assertEquals(201, getInt(cursor, COLUMN_STORAGE_ID));
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900699 assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hirono619afda2016-02-07 14:23:43 +0900700
Daichi Hirono6de8a0e2015-10-27 16:18:17 +0900701 cursor.close();
702 }
703 }
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900704
Daichi Hirono619afda2016-02-07 14:23:43 +0900705 public void testReplaceExistingRoots() throws Exception {
Daichi Hirono8e873642016-02-07 15:17:16 +0900706 addTestDevice();
Daichi Hirono81d48532015-12-16 15:03:19 +0900707
Daichi Hirono4604b742015-11-12 12:12:48 +0900708 // The client code should be able to replace existing rows with new information.
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900709 // Add one.
Daichi Hirono81d48532015-12-16 15:03:19 +0900710 mDatabase.getMapper().startAddingDocuments("1");
Daichi Hirono0f325372016-02-21 15:50:30 +0900711 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900712 new MtpRoot(0, 100, "Storage A", 0, 0, ""),
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900713 });
Daichi Hirono81d48532015-12-16 15:03:19 +0900714 mDatabase.getMapper().stopAddingDocuments("1");
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900715 // Replace it.
Daichi Hirono81d48532015-12-16 15:03:19 +0900716 mDatabase.getMapper().startAddingDocuments("1");
Daichi Hirono0f325372016-02-21 15:50:30 +0900717 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900718 new MtpRoot(0, 100, "Storage B", 1000, 1000, ""),
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900719 });
Daichi Hirono81d48532015-12-16 15:03:19 +0900720 mDatabase.getMapper().stopAddingDocuments("1");
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900721 {
722 final String[] columns = new String[] {
723 DocumentsContract.Document.COLUMN_DOCUMENT_ID,
Daichi Hirono18d70d52015-11-13 15:19:47 +0900724 MtpDatabaseConstants.COLUMN_STORAGE_ID,
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900725 DocumentsContract.Document.COLUMN_DISPLAY_NAME
726 };
Daichi Hirono4604b742015-11-12 12:12:48 +0900727 final Cursor cursor = mDatabase.queryRootDocuments(columns);
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900728 assertEquals(1, cursor.getCount());
729 cursor.moveToNext();
Daichi Hirono81d48532015-12-16 15:03:19 +0900730 assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900731 assertEquals(100, getInt(cursor, COLUMN_STORAGE_ID));
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900732 assertEquals("Storage B", getString(cursor, COLUMN_DISPLAY_NAME));
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900733 cursor.close();
734 }
735 {
736 final String[] columns = new String[] {
737 Root.COLUMN_ROOT_ID,
Daichi Hirono81d48532015-12-16 15:03:19 +0900738 Root.COLUMN_TITLE,
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900739 Root.COLUMN_AVAILABLE_BYTES
740 };
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900741 final Cursor cursor = mDatabase.queryRoots(resources, columns);
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900742 assertEquals(1, cursor.getCount());
743 cursor.moveToNext();
Daichi Hirono6a5ea7e2016-02-02 16:35:03 +0900744 assertEquals(1, getInt(cursor, Root.COLUMN_ROOT_ID));
Daichi Hirono81d48532015-12-16 15:03:19 +0900745 assertEquals("Device Storage B", getString(cursor, Root.COLUMN_TITLE));
Daichi Hirono9984ebd2015-12-15 16:02:27 +0900746 assertEquals(1000, getInt(cursor, Root.COLUMN_AVAILABLE_BYTES));
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900747 cursor.close();
748 }
749 }
750
Daichi Hirono619afda2016-02-07 14:23:43 +0900751 public void testFailToReplaceExisitingUnmappedRoots() throws Exception {
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900752 // The client code should not be able to replace rows before resolving 'unmapped' rows.
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900753 // Add one.
Daichi Hirono619afda2016-02-07 14:23:43 +0900754 addTestDevice();
Daichi Hirono81d48532015-12-16 15:03:19 +0900755 mDatabase.getMapper().startAddingDocuments("1");
Daichi Hirono0f325372016-02-21 15:50:30 +0900756 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900757 new MtpRoot(0, 100, "Storage A", 0, 0, ""),
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900758 });
Daichi Hirono259ce802015-11-20 17:51:53 +0900759 mDatabase.getMapper().clearMapping();
Daichi Hirono49f920f2015-11-19 10:19:52 +0900760
Daichi Hirono619afda2016-02-07 14:23:43 +0900761 addTestDevice();
762 try (final Cursor oldCursor =
763 mDatabase.queryRoots(resources, strings(Root.COLUMN_ROOT_ID))) {
764 assertEquals(1, oldCursor.getCount());
765 oldCursor.moveToNext();
766 assertEquals("1", getString(oldCursor, Root.COLUMN_ROOT_ID));
Daichi Hirono49f920f2015-11-19 10:19:52 +0900767
Daichi Hirono619afda2016-02-07 14:23:43 +0900768 // Add one.
769 mDatabase.getMapper().startAddingDocuments("1");
Daichi Hirono0f325372016-02-21 15:50:30 +0900770 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hirono619afda2016-02-07 14:23:43 +0900771 new MtpRoot(0, 101, "Storage B", 1000, 1000, ""),
772 });
773 // Add one more before resolving unmapped documents.
Daichi Hirono0f325372016-02-21 15:50:30 +0900774 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hirono619afda2016-02-07 14:23:43 +0900775 new MtpRoot(0, 102, "Storage B", 1000, 1000, ""),
776 });
777 mDatabase.getMapper().stopAddingDocuments("1");
Daichi Hirono49f920f2015-11-19 10:19:52 +0900778
Daichi Hirono619afda2016-02-07 14:23:43 +0900779 // Because the roots shares the same name, the roots should have new IDs.
780 try (final Cursor newCursor = mDatabase.queryChildDocuments(
781 strings(Document.COLUMN_DOCUMENT_ID), "1")) {
782 assertEquals(2, newCursor.getCount());
783 newCursor.moveToNext();
784 assertFalse(oldCursor.getString(0).equals(newCursor.getString(0)));
785 newCursor.moveToNext();
786 assertFalse(oldCursor.getString(0).equals(newCursor.getString(0)));
787 }
788 }
Daichi Hirono49f920f2015-11-19 10:19:52 +0900789 }
790
Daichi Hirono619afda2016-02-07 14:23:43 +0900791 public void testQueryDocuments() throws Exception {
792 addTestDevice();
793 addTestStorage("1");
Daichi Hirono49f920f2015-11-19 10:19:52 +0900794
Daichi Hirono619afda2016-02-07 14:23:43 +0900795 final Cursor cursor = mDatabase.queryDocument("2", strings(Document.COLUMN_DISPLAY_NAME));
Daichi Hirono49f920f2015-11-19 10:19:52 +0900796 assertEquals(1, cursor.getCount());
797 cursor.moveToNext();
Daichi Hirono619afda2016-02-07 14:23:43 +0900798 assertEquals("Storage", getString(cursor, Document.COLUMN_DISPLAY_NAME));
Daichi Hirono49f920f2015-11-19 10:19:52 +0900799 cursor.close();
800 }
801
Daichi Hirono619afda2016-02-07 14:23:43 +0900802 public void testQueryRoots() throws Exception {
Daichi Hirono81d48532015-12-16 15:03:19 +0900803 // Add device document.
Daichi Hirono8e873642016-02-07 15:17:16 +0900804 addTestDevice();
Daichi Hirono81d48532015-12-16 15:03:19 +0900805
806 // It the device does not have storages, it shows a device root.
807 {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900808 final Cursor cursor = mDatabase.queryRoots(resources, strings(Root.COLUMN_TITLE));
Daichi Hirono81d48532015-12-16 15:03:19 +0900809 assertEquals(1, cursor.getCount());
810 cursor.moveToNext();
811 assertEquals("Device", cursor.getString(0));
812 cursor.close();
813 }
814
815 mDatabase.getMapper().startAddingDocuments("1");
Daichi Hirono0f325372016-02-21 15:50:30 +0900816 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900817 new MtpRoot(0, 100, "Storage A", 0, 0, "")
Daichi Hirono81d48532015-12-16 15:03:19 +0900818 });
819 mDatabase.getMapper().stopAddingDocuments("1");
820
821 // It the device has single storage, it shows a storage root.
822 {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900823 final Cursor cursor = mDatabase.queryRoots(resources, strings(Root.COLUMN_TITLE));
Daichi Hirono81d48532015-12-16 15:03:19 +0900824 assertEquals(1, cursor.getCount());
825 cursor.moveToNext();
826 assertEquals("Device Storage A", cursor.getString(0));
827 cursor.close();
828 }
829
830 mDatabase.getMapper().startAddingDocuments("1");
Daichi Hirono0f325372016-02-21 15:50:30 +0900831 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900832 new MtpRoot(0, 100, "Storage A", 0, 0, ""),
833 new MtpRoot(0, 101, "Storage B", 0, 0, "")
Daichi Hirono81d48532015-12-16 15:03:19 +0900834 });
835 mDatabase.getMapper().stopAddingDocuments("1");
836
837 // It the device has multiple storages, it shows a device root.
838 {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900839 final Cursor cursor = mDatabase.queryRoots(resources, strings(Root.COLUMN_TITLE));
Daichi Hirono81d48532015-12-16 15:03:19 +0900840 assertEquals(1, cursor.getCount());
841 cursor.moveToNext();
842 assertEquals("Device", cursor.getString(0));
843 cursor.close();
844 }
845 }
846
Daichi Hirono49f920f2015-11-19 10:19:52 +0900847 public void testGetParentId() throws FileNotFoundException {
Daichi Hirono619afda2016-02-07 14:23:43 +0900848 addTestDevice();
Daichi Hirono49f920f2015-11-19 10:19:52 +0900849
Daichi Hirono7a375c42015-12-14 17:14:29 +0900850 mDatabase.getMapper().startAddingDocuments("1");
Daichi Hirono0f325372016-02-21 15:50:30 +0900851 mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900852 new MtpRoot(0, 100, "Storage A", 0, 0, ""),
Daichi Hirono49f920f2015-11-19 10:19:52 +0900853 });
Daichi Hirono7a375c42015-12-14 17:14:29 +0900854 mDatabase.getMapper().stopAddingDocuments("1");
Daichi Hirono49f920f2015-11-19 10:19:52 +0900855
Daichi Hirono7a375c42015-12-14 17:14:29 +0900856 mDatabase.getMapper().startAddingDocuments("2");
Daichi Hirono61ba9232016-02-26 12:58:39 +0900857 mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
858 createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
859 });
Daichi Hirono7a375c42015-12-14 17:14:29 +0900860 mDatabase.getMapper().stopAddingDocuments("2");
Daichi Hirono49f920f2015-11-19 10:19:52 +0900861
Daichi Hirono619afda2016-02-07 14:23:43 +0900862 assertEquals("2", mDatabase.getParentIdentifier("3").mDocumentId);
863 }
864
865 public void testDeleteDocument() throws Exception {
866 addTestDevice();
867 addTestStorage("1");
868
869 mDatabase.getMapper().startAddingDocuments("2");
Daichi Hirono61ba9232016-02-26 12:58:39 +0900870 mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
871 createDocument(200, "dir", MtpConstants.FORMAT_ASSOCIATION, 1024),
872 });
Daichi Hirono619afda2016-02-07 14:23:43 +0900873 mDatabase.getMapper().stopAddingDocuments("2");
874
875 mDatabase.getMapper().startAddingDocuments("3");
Daichi Hirono61ba9232016-02-26 12:58:39 +0900876 mDatabase.getMapper().putChildDocuments(0, "3", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
877 createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
878 });
Daichi Hirono619afda2016-02-07 14:23:43 +0900879 mDatabase.getMapper().stopAddingDocuments("3");
880
881 mDatabase.deleteDocument("3");
Daichi Hirono49f920f2015-11-19 10:19:52 +0900882
883 {
884 // Do not query deleted documents.
885 final Cursor cursor =
Daichi Hirono619afda2016-02-07 14:23:43 +0900886 mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "2");
Daichi Hirono49f920f2015-11-19 10:19:52 +0900887 assertEquals(0, cursor.getCount());
888 cursor.close();
889 }
890
891 {
892 // Child document should be deleted also.
893 final Cursor cursor =
Daichi Hirono619afda2016-02-07 14:23:43 +0900894 mDatabase.queryDocument("4", strings(Document.COLUMN_DOCUMENT_ID));
Daichi Hirono49f920f2015-11-19 10:19:52 +0900895 assertEquals(0, cursor.getCount());
896 cursor.close();
897 }
898 }
899
Daichi Hirono619afda2016-02-07 14:23:43 +0900900 public void testPutNewDocument() throws Exception {
901 addTestDevice();
902 addTestStorage("1");
Daichi Hirono49f920f2015-11-19 10:19:52 +0900903
904 assertEquals(
Daichi Hirono619afda2016-02-07 14:23:43 +0900905 "3",
Daichi Hirono49f920f2015-11-19 10:19:52 +0900906 mDatabase.putNewDocument(
Daichi Hirono61ba9232016-02-26 12:58:39 +0900907 0, "2", OPERATIONS_SUPPORTED,
908 createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024)));
Daichi Hirono49f920f2015-11-19 10:19:52 +0900909
910 {
911 final Cursor cursor =
Daichi Hirono619afda2016-02-07 14:23:43 +0900912 mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "2");
Daichi Hirono49f920f2015-11-19 10:19:52 +0900913 assertEquals(1, cursor.getCount());
914 cursor.moveToNext();
915 assertEquals("3", cursor.getString(0));
916 cursor.close();
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900917 }
Daichi Hirono619afda2016-02-07 14:23:43 +0900918
919 // The new document should not be mapped with existing invalidated document.
920 mDatabase.getMapper().clearMapping();
Daichi Hirono8e873642016-02-07 15:17:16 +0900921 addTestDevice();
922 addTestStorage("1");
923
Daichi Hirono619afda2016-02-07 14:23:43 +0900924 mDatabase.getMapper().startAddingDocuments("2");
925 mDatabase.putNewDocument(
Daichi Hirono61ba9232016-02-26 12:58:39 +0900926 0, "2", OPERATIONS_SUPPORTED,
Daichi Hirono619afda2016-02-07 14:23:43 +0900927 createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024));
928 mDatabase.getMapper().stopAddingDocuments("2");
929
930 {
931 final Cursor cursor =
932 mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "2");
933 assertEquals(1, cursor.getCount());
934 cursor.moveToNext();
935 assertEquals("4", cursor.getString(0));
936 cursor.close();
937 }
Daichi Hironocfcb0c02015-11-10 12:52:59 +0900938 }
Daichi Hirono20754c52015-12-15 18:52:26 +0900939
Daichi Hirono619afda2016-02-07 14:23:43 +0900940 public void testGetDocumentIdForDevice() throws Exception {
941 addTestDevice();
942 assertEquals("1", mDatabase.getDocumentIdForDevice(0));
Daichi Hirono20754c52015-12-15 18:52:26 +0900943 }
Daichi Hirono83983d72016-01-29 17:37:36 +0900944
Daichi Hirono619afda2016-02-07 14:23:43 +0900945 public void testGetClosedDevice() throws Exception {
Daichi Hirono83983d72016-01-29 17:37:36 +0900946 mDatabase.getMapper().startAddingDocuments(null);
947 mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
Daichi Hironoebd24052016-02-06 21:05:57 +0900948 0, "Device", null /* deviceKey */, /* opened is */ false, new MtpRoot[0], null,
949 null));
Daichi Hirono83983d72016-01-29 17:37:36 +0900950 mDatabase.getMapper().stopAddingDocuments(null);
951
952 final String[] columns = new String [] {
953 DocumentsContract.Root.COLUMN_ROOT_ID,
954 DocumentsContract.Root.COLUMN_TITLE,
955 DocumentsContract.Root.COLUMN_AVAILABLE_BYTES
956 };
Daichi Hironof83ccbd2016-02-04 16:58:55 +0900957 try (final Cursor cursor = mDatabase.queryRoots(resources, columns)) {
Daichi Hirono83983d72016-01-29 17:37:36 +0900958 assertEquals(1, cursor.getCount());
959 assertTrue(cursor.moveToNext());
960 assertEquals(1, cursor.getLong(0));
961 assertEquals("Device", cursor.getString(1));
962 assertTrue(cursor.isNull(2));
963 }
964 }
Daichi Hirono619afda2016-02-07 14:23:43 +0900965
Daichi Hironoebd24052016-02-06 21:05:57 +0900966 public void testMappingWithoutKey() throws FileNotFoundException {
967 mDatabase.getMapper().startAddingDocuments(null);
968 mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
969 0, "Device", null /* device key */, /* opened is */ true, new MtpRoot[0], null,
970 null));
971 mDatabase.getMapper().stopAddingDocuments(null);
972
973 mDatabase.getMapper().startAddingDocuments(null);
974 mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
975 0, "Device", null /* device key */, /* opened is */ true, new MtpRoot[0], null,
976 null));
977 mDatabase.getMapper().stopAddingDocuments(null);
978
979 try (final Cursor cursor =
980 mDatabase.queryRoots(resources, strings(DocumentsContract.Root.COLUMN_ROOT_ID))) {
981 assertEquals(1, cursor.getCount());
982 assertTrue(cursor.moveToNext());
983 assertEquals(1, cursor.getLong(0));
984 }
985 }
986
987 public void testMappingFailsWithoutKey() throws FileNotFoundException {
988 mDatabase.getMapper().startAddingDocuments(null);
989 mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
990 0, "Device", null /* device key */, /* opened is */ true, new MtpRoot[0], null,
991 null));
992 mDatabase.getMapper().stopAddingDocuments(null);
993
994 // MTP identifier is cleared here. Mapping no longer works without device key.
995 mDatabase.getMapper().startAddingDocuments(null);
996 mDatabase.getMapper().stopAddingDocuments(null);
997
998 mDatabase.getMapper().startAddingDocuments(null);
999 mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
1000 0, "Device", null /* device key */, /* opened is */ true, new MtpRoot[0], null,
1001 null));
1002 mDatabase.getMapper().stopAddingDocuments(null);
1003
1004 try (final Cursor cursor =
1005 mDatabase.queryRoots(resources, strings(DocumentsContract.Root.COLUMN_ROOT_ID))) {
1006 assertEquals(1, cursor.getCount());
1007 assertTrue(cursor.moveToNext());
1008 assertEquals(2, cursor.getLong(0));
1009 }
1010 }
1011
1012 public void testUpdateDocumentWithoutChange() throws FileNotFoundException {
1013 mDatabase.getMapper().startAddingDocuments(null);
1014 assertTrue(mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
1015 0, "Device", "device_key", /* opened is */ true, new MtpRoot[0], null,
1016 null)));
1017 assertFalse(mDatabase.getMapper().stopAddingDocuments(null));
1018
1019 mDatabase.getMapper().startAddingDocuments(null);
1020 assertFalse(mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
1021 0, "Device", "device_key", /* opened is */ true, new MtpRoot[0], null,
1022 null)));
1023 assertFalse(mDatabase.getMapper().stopAddingDocuments(null));
1024 }
1025
Daichi Hirono619afda2016-02-07 14:23:43 +09001026 private void addTestDevice() throws FileNotFoundException {
Daichi Hironof578fa22016-02-19 18:05:42 +09001027 TestUtil.addTestDevice(mDatabase);
Daichi Hirono619afda2016-02-07 14:23:43 +09001028 }
1029
1030 private void addTestStorage(String parentId) throws FileNotFoundException {
Daichi Hironof578fa22016-02-19 18:05:42 +09001031 TestUtil.addTestStorage(mDatabase, parentId);
Daichi Hirono619afda2016-02-07 14:23:43 +09001032 }
Daichi Hirono9678f602015-10-22 12:35:05 +09001033}