/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.mtp;

import android.database.Cursor;
import android.media.MediaFile;
import android.media.MediaFile.MediaFileType;
import android.mtp.MtpConstants;
import android.mtp.MtpObjectInfo;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Root;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;

import java.io.FileNotFoundException;
import java.util.Arrays;

import static android.provider.DocumentsContract.Document.*;
import static com.android.mtp.MtpDatabase.strings;
import static com.android.mtp.MtpDatabaseConstants.*;
import static com.android.mtp.TestUtil.OPERATIONS_SUPPORTED;

@SmallTest
public class MtpDatabaseTest extends AndroidTestCase {
    private static final String[] COLUMN_NAMES = new String[] {
        DocumentsContract.Document.COLUMN_DOCUMENT_ID,
        MtpDatabaseConstants.COLUMN_DEVICE_ID,
        MtpDatabaseConstants.COLUMN_STORAGE_ID,
        MtpDatabaseConstants.COLUMN_OBJECT_HANDLE,
        DocumentsContract.Document.COLUMN_MIME_TYPE,
        DocumentsContract.Document.COLUMN_DISPLAY_NAME,
        DocumentsContract.Document.COLUMN_SUMMARY,
        DocumentsContract.Document.COLUMN_LAST_MODIFIED,
        DocumentsContract.Document.COLUMN_ICON,
        DocumentsContract.Document.COLUMN_FLAGS,
        DocumentsContract.Document.COLUMN_SIZE,
        MtpDatabaseConstants.COLUMN_DOCUMENT_TYPE
    };

    private final TestResources resources = new TestResources();
    MtpDatabase mDatabase;

    @Override
    public void setUp() {
        mDatabase = new MtpDatabase(getContext(), MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
    }

    @Override
    public void tearDown() {
        mDatabase.close();
        mDatabase = null;
    }

    private static int getInt(Cursor cursor, String columnName) {
        return cursor.getInt(cursor.getColumnIndex(columnName));
    }

    private static boolean isNull(Cursor cursor, String columnName) {
        return cursor.isNull(cursor.getColumnIndex(columnName));
    }

    private static String getString(Cursor cursor, String columnName) {
        return cursor.getString(cursor.getColumnIndex(columnName));
    }

    public void testPutSingleStorageDocuments() throws Exception {
        addTestDevice();

        mDatabase.getMapper().startAddingDocuments("1");
        mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(0, 1, "Storage", 1000, 2000, "")
        });
        mDatabase.getMapper().stopAddingDocuments("1");

        {
            final Cursor cursor = mDatabase.queryRootDocuments(COLUMN_NAMES);
            assertEquals(1, cursor.getCount());

            cursor.moveToNext();
            assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID));
            assertEquals(1, getInt(cursor, COLUMN_STORAGE_ID));
            assertTrue(isNull(cursor, COLUMN_OBJECT_HANDLE));
            assertEquals(
                    DocumentsContract.Document.MIME_TYPE_DIR, getString(cursor, COLUMN_MIME_TYPE));
            assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
            assertTrue(isNull(cursor, COLUMN_SUMMARY));
            assertTrue(isNull(cursor, COLUMN_LAST_MODIFIED));
            assertEquals(R.drawable.ic_root_mtp, getInt(cursor, COLUMN_ICON));
            assertEquals(Document.FLAG_DIR_SUPPORTS_CREATE, getInt(cursor, COLUMN_FLAGS));
            assertEquals(1000, getInt(cursor, COLUMN_SIZE));
            assertEquals(
                    MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE,
                    getInt(cursor, COLUMN_DOCUMENT_TYPE));

            cursor.close();
        }

        {
            final Cursor cursor = mDatabase.queryRoots(resources, new String [] {
                    Root.COLUMN_ROOT_ID,
                    Root.COLUMN_FLAGS,
                    Root.COLUMN_ICON,
                    Root.COLUMN_TITLE,
                    Root.COLUMN_SUMMARY,
                    Root.COLUMN_DOCUMENT_ID,
                    Root.COLUMN_AVAILABLE_BYTES,
                    Root.COLUMN_CAPACITY_BYTES
            });
            assertEquals(1, cursor.getCount());

            cursor.moveToNext();
            assertEquals(1, getInt(cursor, Root.COLUMN_ROOT_ID));
            assertEquals(
                    Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE,
                    getInt(cursor, Root.COLUMN_FLAGS));
            assertEquals(R.drawable.ic_root_mtp, getInt(cursor, Root.COLUMN_ICON));
            assertEquals("Device Storage", getString(cursor, Root.COLUMN_TITLE));
            assertTrue(isNull(cursor, Root.COLUMN_SUMMARY));
            assertEquals(1, getInt(cursor, Root.COLUMN_DOCUMENT_ID));
            assertEquals(1000, getInt(cursor, Root.COLUMN_AVAILABLE_BYTES));
            assertEquals(2000, getInt(cursor, Root.COLUMN_CAPACITY_BYTES));

            cursor.close();
        }
    }

    public void testPutStorageDocuments() throws Exception {
        addTestDevice();

        mDatabase.getMapper().startAddingDocuments("1");
        mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(0, 1, "Storage", 1000, 2000, ""),
                new MtpRoot(0, 2, "Storage", 2000, 4000, ""),
                new MtpRoot(0, 3, "/@#%&<>Storage", 3000, 6000,"")
        });

        {
            final Cursor cursor = mDatabase.queryRootDocuments(COLUMN_NAMES);
            assertEquals(3, cursor.getCount());

            cursor.moveToNext();
            assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID));
            assertEquals(1, getInt(cursor, COLUMN_STORAGE_ID));
            assertTrue(isNull(cursor, COLUMN_OBJECT_HANDLE));
            assertEquals(DocumentsContract.Document.MIME_TYPE_DIR, getString(cursor, COLUMN_MIME_TYPE));
            assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
            assertTrue(isNull(cursor, COLUMN_SUMMARY));
            assertTrue(isNull(cursor, COLUMN_LAST_MODIFIED));
            assertEquals(R.drawable.ic_root_mtp, getInt(cursor, COLUMN_ICON));
            assertEquals(Document.FLAG_DIR_SUPPORTS_CREATE, getInt(cursor, COLUMN_FLAGS));
            assertEquals(1000, getInt(cursor, COLUMN_SIZE));
            assertEquals(
                    MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE, getInt(cursor, COLUMN_DOCUMENT_TYPE));

            cursor.moveToNext();
            assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));

            cursor.moveToNext();
            assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals("/@#%&<>Storage", getString(cursor, COLUMN_DISPLAY_NAME));

            cursor.close();
        }
    }

    private MtpObjectInfo createDocument(int objectHandle, String name, int format, int size) {
        final MtpObjectInfo.Builder builder = new MtpObjectInfo.Builder();
        builder.setObjectHandle(objectHandle);
        builder.setName(name);
        builder.setFormat(format);
        builder.setCompressedSize(size);
        return builder.build();
    }

    public void testPutChildDocuments() throws Exception {
        addTestDevice();
        addTestStorage("1");

        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
                createDocument(101, "image.jpg", MtpConstants.FORMAT_EXIF_JPEG, 2 * 1024 * 1024),
                createDocument(102, "music.mp3", MtpConstants.FORMAT_MP3, 3 * 1024 * 1024)
        }, new long[] { 1024L, 2L * 1024L * 1024L, 3L * 1024L * 1024L});

        final Cursor cursor = mDatabase.queryChildDocuments(COLUMN_NAMES, "2");
        assertEquals(3, cursor.getCount());

        cursor.moveToNext();
        assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
        assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID));
        assertEquals(0, getInt(cursor, COLUMN_STORAGE_ID));
        assertEquals(100, getInt(cursor, COLUMN_OBJECT_HANDLE));
        assertEquals("text/plain", getString(cursor, COLUMN_MIME_TYPE));
        assertEquals("note.txt", getString(cursor, COLUMN_DISPLAY_NAME));
        assertTrue(isNull(cursor, COLUMN_SUMMARY));
        assertTrue(isNull(cursor, COLUMN_LAST_MODIFIED));
        assertTrue(isNull(cursor, COLUMN_ICON));
        assertEquals(
                COLUMN_FLAGS,
                DocumentsContract.Document.FLAG_SUPPORTS_DELETE |
                DocumentsContract.Document.FLAG_SUPPORTS_WRITE,
                cursor.getInt(9));
        assertEquals(1024, getInt(cursor, COLUMN_SIZE));
        assertEquals(
                MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT, getInt(cursor, COLUMN_DOCUMENT_TYPE));

        cursor.moveToNext();
        assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID));
        assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID));
        assertEquals(0, getInt(cursor, COLUMN_STORAGE_ID));
        assertEquals(101, getInt(cursor, COLUMN_OBJECT_HANDLE));
        assertEquals("image/jpeg", getString(cursor, COLUMN_MIME_TYPE));
        assertEquals("image.jpg", getString(cursor, COLUMN_DISPLAY_NAME));
        assertTrue(isNull(cursor, COLUMN_SUMMARY));
        assertTrue(isNull(cursor, COLUMN_LAST_MODIFIED));
        assertTrue(isNull(cursor, COLUMN_ICON));
        assertEquals(
                COLUMN_FLAGS,
                DocumentsContract.Document.FLAG_SUPPORTS_DELETE |
                DocumentsContract.Document.FLAG_SUPPORTS_WRITE,
                cursor.getInt(9));
        assertEquals(2 * 1024 * 1024, getInt(cursor, COLUMN_SIZE));
        assertEquals(
                MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT, getInt(cursor, COLUMN_DOCUMENT_TYPE));

        cursor.moveToNext();
        assertEquals(5, getInt(cursor, COLUMN_DOCUMENT_ID));
        assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID));
        assertEquals(0, getInt(cursor, COLUMN_STORAGE_ID));
        assertEquals(102, getInt(cursor, COLUMN_OBJECT_HANDLE));
        assertEquals("audio/mpeg", getString(cursor, COLUMN_MIME_TYPE));
        assertEquals("music.mp3", getString(cursor, COLUMN_DISPLAY_NAME));
        assertTrue(isNull(cursor, COLUMN_SUMMARY));
        assertTrue(isNull(cursor, COLUMN_LAST_MODIFIED));
        assertTrue(isNull(cursor, COLUMN_ICON));
        assertEquals(
                COLUMN_FLAGS,
                DocumentsContract.Document.FLAG_SUPPORTS_DELETE |
                DocumentsContract.Document.FLAG_SUPPORTS_WRITE,
                cursor.getInt(9));
        assertEquals(3 * 1024 * 1024, getInt(cursor, COLUMN_SIZE));
        assertEquals(
                MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT, getInt(cursor, COLUMN_DOCUMENT_TYPE));

        cursor.close();
    }

    public void testPutChildDocuments_operationsSupported() throws Exception {
        addTestDevice();
        addTestStorage("1");

        // Put a document with empty supported operations.
        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.getMapper().putChildDocuments(0, "2", new int[0], new MtpObjectInfo[] {
                createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024)
        }, new long[] { 1024L });
        mDatabase.getMapper().stopAddingDocuments("2");

        try (final Cursor cursor =
                mDatabase.queryChildDocuments(strings(Document.COLUMN_FLAGS), "2")) {
            assertEquals(1, cursor.getCount());
            cursor.moveToNext();
            assertEquals(0, cursor.getInt(0));
        }

        // Put a document with writable operations.
        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.getMapper().putChildDocuments(0, "2", new int[] {
                MtpConstants.OPERATION_SEND_OBJECT,
                MtpConstants.OPERATION_SEND_OBJECT_INFO,
        }, new MtpObjectInfo[] {
                createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024)
        }, new long[] { 1024L });
        mDatabase.getMapper().stopAddingDocuments("2");

        try (final Cursor cursor =
                mDatabase.queryChildDocuments(strings(Document.COLUMN_FLAGS), "2")) {
            assertEquals(1, cursor.getCount());
            cursor.moveToNext();
            assertEquals(Document.FLAG_SUPPORTS_WRITE, cursor.getInt(0));
        }

        // Put a document with deletable operations.
        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.getMapper().putChildDocuments(0, "2", new int[] {
                MtpConstants.OPERATION_DELETE_OBJECT
        }, new MtpObjectInfo[] {
                createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024)
        }, new long[] { 1024L });
        mDatabase.getMapper().stopAddingDocuments("2");

        try (final Cursor cursor =
                mDatabase.queryChildDocuments(strings(Document.COLUMN_FLAGS), "2")) {
            assertEquals(1, cursor.getCount());
            cursor.moveToNext();
            assertEquals(Document.FLAG_SUPPORTS_DELETE, cursor.getInt(0));
        }
    }

    public void testRestoreIdForRootDocuments() throws Exception {
        final String[] columns = new String[] {
                DocumentsContract.Document.COLUMN_DOCUMENT_ID,
                MtpDatabaseConstants.COLUMN_STORAGE_ID,
                DocumentsContract.Document.COLUMN_DISPLAY_NAME
        };

        // Add device and two storages.
        addTestDevice();
        mDatabase.getMapper().startAddingDocuments("1");
        mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(0, 100, "Storage A", 1000, 0, ""),
                new MtpRoot(0, 101, "Storage B", 1001, 0, "")
        });

        {
            final Cursor cursor = mDatabase.queryRootDocuments(columns);
            assertEquals(2, cursor.getCount());
            cursor.moveToNext();
            assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(100, getInt(cursor, COLUMN_STORAGE_ID));
            assertEquals("Storage A", getString(cursor, COLUMN_DISPLAY_NAME));
            cursor.moveToNext();
            assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(101, getInt(cursor, COLUMN_STORAGE_ID));
            assertEquals("Storage B", getString(cursor, COLUMN_DISPLAY_NAME));
            cursor.close();
        }

        // Clear mapping and add a device.
        mDatabase.getMapper().clearMapping();
        addTestDevice();

        {
            final Cursor cursor = mDatabase.queryRootDocuments(columns);
            assertEquals(0, cursor.getCount());
            cursor.close();
        }

        // Add two storages, but one's name is different from previous one.
        mDatabase.getMapper().startAddingDocuments("1");
        mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(0, 200, "Storage A", 2000, 0, ""),
                new MtpRoot(0, 202, "Storage C", 2002, 0, "")
        });
        mDatabase.getMapper().stopAddingDocuments("1");

        {
            // After compeleting mapping, Storage A can be obtained with new storage ID.
            final Cursor cursor = mDatabase.queryRootDocuments(columns);
            assertEquals(2, cursor.getCount());
            cursor.moveToNext();
            assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(200, getInt(cursor, COLUMN_STORAGE_ID));
            assertEquals("Storage A", getString(cursor, COLUMN_DISPLAY_NAME));
            cursor.moveToNext();
            assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(202, getInt(cursor, COLUMN_STORAGE_ID));
            assertEquals("Storage C", getString(cursor, COLUMN_DISPLAY_NAME));
            cursor.close();
        }
    }

    public void testRestoreIdForChildDocuments() throws Exception {
        final String[] columns = new String[] {
                DocumentsContract.Document.COLUMN_DOCUMENT_ID,
                MtpDatabaseConstants.COLUMN_OBJECT_HANDLE,
                DocumentsContract.Document.COLUMN_DISPLAY_NAME
        };

        addTestDevice();
        addTestStorage("1");

        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
                createDocument(101, "image.jpg", MtpConstants.FORMAT_EXIF_JPEG, 2 * 1024 * 1024),
                createDocument(102, "music.mp3", MtpConstants.FORMAT_MP3, 3 * 1024 * 1024)
        }, new long[] { 1024L, 2L * 1024L * 1024L, 3L * 1024L * 1024L});
        mDatabase.getMapper().clearMapping();

        addTestDevice();
        addTestStorage("1");

        {
            // Don't return objects that lost MTP object handles.
            final Cursor cursor = mDatabase.queryChildDocuments(columns, "2");
            assertEquals(0, cursor.getCount());
            cursor.close();
        }

        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
                createDocument(203, "video.mp4", MtpConstants.FORMAT_MP4_CONTAINER, 1024),
        }, new long[] { 1024L, 1024L });
        mDatabase.getMapper().stopAddingDocuments("2");

        {
            final Cursor cursor = mDatabase.queryChildDocuments(columns, "2");
            assertEquals(2, cursor.getCount());

            cursor.moveToNext();
            assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(200, getInt(cursor, COLUMN_OBJECT_HANDLE));
            assertEquals("note.txt", getString(cursor, COLUMN_DISPLAY_NAME));

            cursor.moveToNext();
            assertEquals(6, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(203, getInt(cursor, COLUMN_OBJECT_HANDLE));
            assertEquals("video.mp4", getString(cursor, COLUMN_DISPLAY_NAME));

            cursor.close();
        }
    }

    public void testRestoreIdForDifferentDevices() throws Exception {
        final String[] columns = new String[] {
                DocumentsContract.Document.COLUMN_DOCUMENT_ID,
                MtpDatabaseConstants.COLUMN_STORAGE_ID,
                DocumentsContract.Document.COLUMN_DISPLAY_NAME
        };
        final String[] rootColumns = new String[] {
                Root.COLUMN_ROOT_ID,
                Root.COLUMN_AVAILABLE_BYTES
        };
        mDatabase.getMapper().startAddingDocuments(null);
        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
                0, "Device A", "Device key A", true, new MtpRoot[0], null, null));
        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
                1, "Device B", "Device key B", true, new MtpRoot[0], null, null));
        mDatabase.getMapper().stopAddingDocuments(null);

        mDatabase.getMapper().startAddingDocuments("1");
        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(0, 100, "Storage", 0, 0, "")
        });
        mDatabase.getMapper().putStorageDocuments("2", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(1, 100, "Storage", 0, 0, "")
        });

        {
            final Cursor cursor = mDatabase.queryRootDocuments(columns);
            assertEquals(2, cursor.getCount());
            cursor.moveToNext();
            assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(100, getInt(cursor, COLUMN_STORAGE_ID));
            assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
            cursor.moveToNext();
            assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(100, getInt(cursor, COLUMN_STORAGE_ID));
            assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
            cursor.close();
        }

        {
            final Cursor cursor = mDatabase.queryRoots(resources, rootColumns);
            assertEquals(2, cursor.getCount());
            cursor.moveToNext();
            assertEquals(1, getInt(cursor, Root.COLUMN_ROOT_ID));
            assertEquals(0, getInt(cursor, Root.COLUMN_AVAILABLE_BYTES));
            cursor.moveToNext();
            assertEquals(2, getInt(cursor, Root.COLUMN_ROOT_ID));
            assertEquals(0, getInt(cursor, Root.COLUMN_AVAILABLE_BYTES));
            cursor.close();
        }

        mDatabase.getMapper().clearMapping();

        mDatabase.getMapper().startAddingDocuments(null);
        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
                0, "Device A", "Device key A", true, new MtpRoot[0], null, null));
        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
                1, "Device B", "Device key B", true, new MtpRoot[0], null, null));
        mDatabase.getMapper().stopAddingDocuments(null);

        mDatabase.getMapper().startAddingDocuments("1");
        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(0, 200, "Storage", 2000, 0, "")
        });
        mDatabase.getMapper().putStorageDocuments("2", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(1, 300, "Storage", 3000, 0, "")
        });
        mDatabase.getMapper().stopAddingDocuments("1");
        mDatabase.getMapper().stopAddingDocuments("2");

        {
            final Cursor cursor = mDatabase.queryRootDocuments(columns);
            assertEquals(2, cursor.getCount());
            cursor.moveToNext();
            assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(200, getInt(cursor, COLUMN_STORAGE_ID));
            assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
            cursor.moveToNext();
            assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(300, getInt(cursor, COLUMN_STORAGE_ID));
            assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
            cursor.close();
        }

        {
            final Cursor cursor = mDatabase.queryRoots(resources, rootColumns);
            assertEquals(2, cursor.getCount());
            cursor.moveToNext();
            assertEquals(1, getInt(cursor, Root.COLUMN_ROOT_ID));
            assertEquals(2000, getInt(cursor, Root.COLUMN_AVAILABLE_BYTES));
            cursor.moveToNext();
            assertEquals(2, getInt(cursor, Root.COLUMN_ROOT_ID));
            assertEquals(3000, getInt(cursor, Root.COLUMN_AVAILABLE_BYTES));
            cursor.close();
        }
    }

    public void testRestoreIdForDifferentParents() throws Exception {
        final String[] columns = new String[] {
                DocumentsContract.Document.COLUMN_DOCUMENT_ID,
                MtpDatabaseConstants.COLUMN_OBJECT_HANDLE
        };

        // Add device, storage, and two directories.
        addTestDevice();
        addTestStorage("1");
        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                createDocument(50, "A", MtpConstants.FORMAT_ASSOCIATION, 0),
                createDocument(51, "B", MtpConstants.FORMAT_ASSOCIATION, 0),
        }, new long[] { 0L, 0L });
        mDatabase.getMapper().stopAddingDocuments("2");

        // Put note.txt in each directory.
        mDatabase.getMapper().startAddingDocuments("3");
        mDatabase.getMapper().startAddingDocuments("4");
        mDatabase.getMapper().putChildDocuments(0, "3", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
        }, new long[] { 1024L });
        mDatabase.getMapper().putChildDocuments(0, "4", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                createDocument(101, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
        }, new long[] { 1024L });

        // Clear mapping.
        mDatabase.getMapper().clearMapping();

        // Add device, storage, and two directories again.
        addTestDevice();
        addTestStorage("1");
        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                createDocument(50, "A", MtpConstants.FORMAT_ASSOCIATION, 0),
                createDocument(51, "B", MtpConstants.FORMAT_ASSOCIATION, 0),
        }, new long[] { 0L, 0L });
        mDatabase.getMapper().stopAddingDocuments("2");

        // Add note.txt in each directory again.
        mDatabase.getMapper().startAddingDocuments("3");
        mDatabase.getMapper().startAddingDocuments("4");
        mDatabase.getMapper().putChildDocuments(0, "3", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
        }, new long[] { 1024L });
        mDatabase.getMapper().putChildDocuments(0, "4", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
        }, new long[] { 1024L });
        mDatabase.getMapper().stopAddingDocuments("3");
        mDatabase.getMapper().stopAddingDocuments("4");

        // Check if the two note.txt are mapped correctly.
        {
            final Cursor cursor = mDatabase.queryChildDocuments(columns, "3");
            assertEquals(1, cursor.getCount());
            cursor.moveToNext();
            assertEquals(5, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(200, getInt(cursor, COLUMN_OBJECT_HANDLE));
            cursor.close();
        }
        {
            final Cursor cursor = mDatabase.queryChildDocuments(columns, "4");
            assertEquals(1, cursor.getCount());
            cursor.moveToNext();
            assertEquals(6, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(201, getInt(cursor, COLUMN_OBJECT_HANDLE));
            cursor.close();
        }
    }

    public void testClearMtpIdentifierBeforeResolveRootDocuments() throws Exception {
        final String[] columns = new String[] {
                DocumentsContract.Document.COLUMN_DOCUMENT_ID,
                MtpDatabaseConstants.COLUMN_STORAGE_ID,
                DocumentsContract.Document.COLUMN_DISPLAY_NAME
        };
        final String[] rootColumns = new String[] {
                Root.COLUMN_ROOT_ID,
                Root.COLUMN_AVAILABLE_BYTES
        };

        addTestDevice();

        mDatabase.getMapper().startAddingDocuments("1");
        mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(0, 100, "Storage", 0, 0, ""),
        });
        mDatabase.getMapper().clearMapping();

        addTestDevice();

        try (final Cursor cursor = mDatabase.queryRoots(resources, rootColumns)) {
            assertEquals(1, cursor.getCount());
            cursor.moveToNext();
            assertEquals("1", getString(cursor, Root.COLUMN_ROOT_ID));
        }

        mDatabase.getMapper().startAddingDocuments("1");
        mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(0, 200, "Storage", 2000, 0, ""),
        });
        mDatabase.getMapper().clearMapping();

        addTestDevice();

        mDatabase.getMapper().startAddingDocuments("1");
        mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(0, 300, "Storage", 3000, 0, ""),
        });
        mDatabase.getMapper().stopAddingDocuments("1");

        {
            final Cursor cursor = mDatabase.queryRootDocuments(columns);
            assertEquals(1, cursor.getCount());
            cursor.moveToNext();
            assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(300, getInt(cursor, COLUMN_STORAGE_ID));
            assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
            cursor.close();
        }
        {
            final Cursor cursor = mDatabase.queryRoots(resources, rootColumns);
            assertEquals(1, cursor.getCount());
            cursor.moveToNext();
            assertEquals(1, getInt(cursor, Root.COLUMN_ROOT_ID));
            assertEquals(3000, getInt(cursor, Root.COLUMN_AVAILABLE_BYTES));
            cursor.close();
        }
    }

    public void testPutSameNameRootsAfterClearing() throws Exception {
        final String[] columns = new String[] {
                DocumentsContract.Document.COLUMN_DOCUMENT_ID,
                MtpDatabaseConstants.COLUMN_STORAGE_ID,
                DocumentsContract.Document.COLUMN_DISPLAY_NAME
        };

        // Add a device and a storage.
        addTestDevice();
        addTestStorage("1");

        // Disconnect devices.
        mDatabase.getMapper().clearMapping();

        // Add a device and two storages that has same name.
        addTestDevice();
        mDatabase.getMapper().startAddingDocuments("1");
        mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(0, 200, "Storage", 2000, 0, ""),
                new MtpRoot(0, 201, "Storage", 2001, 0, ""),
        });
        mDatabase.getMapper().stopAddingDocuments("1");

        {
            final Cursor cursor = mDatabase.queryRootDocuments(columns);
            assertEquals(2, cursor.getCount());

            // First storage reuse document ID of previous storage.
            cursor.moveToNext();
            // One reuses exisitng document ID 1.
            assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(200, getInt(cursor, COLUMN_STORAGE_ID));
            assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));

            // Second one has new document ID.
            cursor.moveToNext();
            assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(201, getInt(cursor, COLUMN_STORAGE_ID));
            assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));

            cursor.close();
        }
    }

    public void testReplaceExistingRoots() throws Exception {
        addTestDevice();

        // The client code should be able to replace existing rows with new information.
        // Add one.
        mDatabase.getMapper().startAddingDocuments("1");
        mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(0, 100, "Storage A", 0, 0, ""),
        });
        mDatabase.getMapper().stopAddingDocuments("1");
        // Replace it.
        mDatabase.getMapper().startAddingDocuments("1");
        mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(0, 100, "Storage B", 1000, 1000, ""),
        });
        mDatabase.getMapper().stopAddingDocuments("1");
        {
            final String[] columns = new String[] {
                    DocumentsContract.Document.COLUMN_DOCUMENT_ID,
                    MtpDatabaseConstants.COLUMN_STORAGE_ID,
                    DocumentsContract.Document.COLUMN_DISPLAY_NAME
            };
            final Cursor cursor = mDatabase.queryRootDocuments(columns);
            assertEquals(1, cursor.getCount());
            cursor.moveToNext();
            assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
            assertEquals(100, getInt(cursor, COLUMN_STORAGE_ID));
            assertEquals("Storage B", getString(cursor, COLUMN_DISPLAY_NAME));
            cursor.close();
        }
        {
            final String[] columns = new String[] {
                    Root.COLUMN_ROOT_ID,
                    Root.COLUMN_TITLE,
                    Root.COLUMN_AVAILABLE_BYTES
            };
            final Cursor cursor = mDatabase.queryRoots(resources, columns);
            assertEquals(1, cursor.getCount());
            cursor.moveToNext();
            assertEquals(1, getInt(cursor, Root.COLUMN_ROOT_ID));
            assertEquals("Device Storage B", getString(cursor, Root.COLUMN_TITLE));
            assertEquals(1000, getInt(cursor, Root.COLUMN_AVAILABLE_BYTES));
            cursor.close();
        }
    }

    public void testFailToReplaceExisitingUnmappedRoots() throws Exception {
        // The client code should not be able to replace rows before resolving 'unmapped' rows.
        // Add one.
        addTestDevice();
        mDatabase.getMapper().startAddingDocuments("1");
        mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(0, 100, "Storage A", 0, 0, ""),
        });
        mDatabase.getMapper().clearMapping();

        addTestDevice();
        try (final Cursor oldCursor =
                mDatabase.queryRoots(resources, strings(Root.COLUMN_ROOT_ID))) {
            assertEquals(1, oldCursor.getCount());
            oldCursor.moveToNext();
            assertEquals("1", getString(oldCursor, Root.COLUMN_ROOT_ID));

            // Add one.
            mDatabase.getMapper().startAddingDocuments("1");
            mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                    new MtpRoot(0, 101, "Storage B", 1000, 1000, ""),
            });
            // Add one more before resolving unmapped documents.
            mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                    new MtpRoot(0, 102, "Storage B", 1000, 1000, ""),
            });
            mDatabase.getMapper().stopAddingDocuments("1");

            // Because the roots shares the same name, the roots should have new IDs.
            try (final Cursor newCursor = mDatabase.queryChildDocuments(
                    strings(Document.COLUMN_DOCUMENT_ID), "1")) {
                assertEquals(2, newCursor.getCount());
                newCursor.moveToNext();
                assertFalse(oldCursor.getString(0).equals(newCursor.getString(0)));
                newCursor.moveToNext();
                assertFalse(oldCursor.getString(0).equals(newCursor.getString(0)));
            }
        }
    }

    public void testQueryDocuments() throws Exception {
        addTestDevice();
        addTestStorage("1");

        final Cursor cursor = mDatabase.queryDocument("2", strings(Document.COLUMN_DISPLAY_NAME));
        assertEquals(1, cursor.getCount());
        cursor.moveToNext();
        assertEquals("Storage", getString(cursor, Document.COLUMN_DISPLAY_NAME));
        cursor.close();
    }

    public void testQueryRoots() throws Exception {
        // Add device document.
        addTestDevice();

        // It the device does not have storages, it shows a device root.
        {
            final Cursor cursor = mDatabase.queryRoots(resources, strings(Root.COLUMN_TITLE));
            assertEquals(1, cursor.getCount());
            cursor.moveToNext();
            assertEquals("Device", cursor.getString(0));
            cursor.close();
        }

        mDatabase.getMapper().startAddingDocuments("1");
        mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(0, 100, "Storage A", 0, 0, "")
        });
        mDatabase.getMapper().stopAddingDocuments("1");

        // It the device has single storage, it shows a storage root.
        {
            final Cursor cursor = mDatabase.queryRoots(resources, strings(Root.COLUMN_TITLE));
            assertEquals(1, cursor.getCount());
            cursor.moveToNext();
            assertEquals("Device Storage A", cursor.getString(0));
            cursor.close();
        }

        mDatabase.getMapper().startAddingDocuments("1");
        mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(0, 100, "Storage A", 0, 0, ""),
                new MtpRoot(0, 101, "Storage B", 0, 0, "")
        });
        mDatabase.getMapper().stopAddingDocuments("1");

        // It the device has multiple storages, it shows a device root.
        {
            final Cursor cursor = mDatabase.queryRoots(resources, strings(Root.COLUMN_TITLE));
            assertEquals(1, cursor.getCount());
            cursor.moveToNext();
            assertEquals("Device", cursor.getString(0));
            cursor.close();
        }
    }

    public void testGetParentId() throws FileNotFoundException {
        addTestDevice();

        mDatabase.getMapper().startAddingDocuments("1");
        mDatabase.getMapper().putStorageDocuments("1", OPERATIONS_SUPPORTED, new MtpRoot[] {
                new MtpRoot(0, 100, "Storage A", 0, 0, ""),
        });
        mDatabase.getMapper().stopAddingDocuments("1");

        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
        }, new long[] { 1024L });
        mDatabase.getMapper().stopAddingDocuments("2");

        assertEquals("2", mDatabase.getParentIdentifier("3").mDocumentId);
    }

    public void testDeleteDocument() throws Exception {
        addTestDevice();
        addTestStorage("1");

        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                createDocument(200, "dir", MtpConstants.FORMAT_ASSOCIATION, 1024),
        }, new long[] { 1024L });
        mDatabase.getMapper().stopAddingDocuments("2");

        mDatabase.getMapper().startAddingDocuments("3");
        mDatabase.getMapper().putChildDocuments(0, "3", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
        }, new long[] { 1024L });
        mDatabase.getMapper().stopAddingDocuments("3");

        mDatabase.deleteDocument("3");

        {
            // Do not query deleted documents.
            final Cursor cursor =
                    mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "2");
            assertEquals(0, cursor.getCount());
            cursor.close();
        }

        {
            // Child document should be deleted also.
            final Cursor cursor =
                    mDatabase.queryDocument("4", strings(Document.COLUMN_DOCUMENT_ID));
            assertEquals(0, cursor.getCount());
            cursor.close();
        }
    }

    public void testPutNewDocument() throws Exception {
        addTestDevice();
        addTestStorage("1");

        assertEquals(
                "3",
                mDatabase.putNewDocument(
                        0, "2", OPERATIONS_SUPPORTED,
                        createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
                        1024L));

        {
            final Cursor cursor =
                    mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "2");
            assertEquals(1, cursor.getCount());
            cursor.moveToNext();
            assertEquals("3", cursor.getString(0));
            cursor.close();
        }

        // The new document should not be mapped with existing invalidated document.
        mDatabase.getMapper().clearMapping();
        addTestDevice();
        addTestStorage("1");

        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.putNewDocument(
                0, "2", OPERATIONS_SUPPORTED,
                createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
                1024L);
        mDatabase.getMapper().stopAddingDocuments("2");

        {
            final Cursor cursor =
                    mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "2");
            assertEquals(1, cursor.getCount());
            cursor.moveToNext();
            assertEquals("4", cursor.getString(0));
            cursor.close();
        }
    }

    public void testGetDocumentIdForDevice() throws Exception {
        addTestDevice();
        assertEquals("1", mDatabase.getDocumentIdForDevice(0));
    }

    public void testGetClosedDevice() throws Exception {
        mDatabase.getMapper().startAddingDocuments(null);
        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
                0, "Device", null /* deviceKey */, /* opened is */ false, new MtpRoot[0], null,
                null));
        mDatabase.getMapper().stopAddingDocuments(null);

        final String[] columns = new String [] {
                DocumentsContract.Root.COLUMN_ROOT_ID,
                DocumentsContract.Root.COLUMN_TITLE,
                DocumentsContract.Root.COLUMN_AVAILABLE_BYTES
        };
        try (final Cursor cursor = mDatabase.queryRoots(resources, columns)) {
            assertEquals(1, cursor.getCount());
            assertTrue(cursor.moveToNext());
            assertEquals(1, cursor.getLong(0));
            assertEquals("Device", cursor.getString(1));
            assertTrue(cursor.isNull(2));
        }
    }

    public void testMappingWithoutKey() throws FileNotFoundException {
        mDatabase.getMapper().startAddingDocuments(null);
        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
                0, "Device", null /* device key */, /* opened is */ true, new MtpRoot[0], null,
                null));
        mDatabase.getMapper().stopAddingDocuments(null);

        mDatabase.getMapper().startAddingDocuments(null);
        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
                0, "Device", null /* device key */, /* opened is */ true, new MtpRoot[0], null,
                null));
        mDatabase.getMapper().stopAddingDocuments(null);

        try (final Cursor cursor =
                mDatabase.queryRoots(resources, strings(DocumentsContract.Root.COLUMN_ROOT_ID))) {
            assertEquals(1, cursor.getCount());
            assertTrue(cursor.moveToNext());
            assertEquals(1, cursor.getLong(0));
        }
    }

    public void testMappingFailsWithoutKey() throws FileNotFoundException {
        mDatabase.getMapper().startAddingDocuments(null);
        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
                0, "Device", null /* device key */, /* opened is */ true, new MtpRoot[0], null,
                null));
        mDatabase.getMapper().stopAddingDocuments(null);

        // MTP identifier is cleared here. Mapping no longer works without device key.
        mDatabase.getMapper().startAddingDocuments(null);
        mDatabase.getMapper().stopAddingDocuments(null);

        mDatabase.getMapper().startAddingDocuments(null);
        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
                0, "Device", null /* device key */, /* opened is */ true, new MtpRoot[0], null,
                null));
        mDatabase.getMapper().stopAddingDocuments(null);

        try (final Cursor cursor =
                mDatabase.queryRoots(resources, strings(DocumentsContract.Root.COLUMN_ROOT_ID))) {
            assertEquals(1, cursor.getCount());
            assertTrue(cursor.moveToNext());
            assertEquals(2, cursor.getLong(0));
        }
    }

    public void testUpdateDocumentWithoutChange() throws FileNotFoundException {
        mDatabase.getMapper().startAddingDocuments(null);
        assertTrue(mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
                0, "Device", "device_key", /* opened is */ true, new MtpRoot[0], null,
                null)));
        assertFalse(mDatabase.getMapper().stopAddingDocuments(null));

        mDatabase.getMapper().startAddingDocuments(null);
        assertFalse(mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
                0, "Device", "device_key", /* opened is */ true, new MtpRoot[0], null,
                null)));
        assertFalse(mDatabase.getMapper().stopAddingDocuments(null));
    }

    public void testSetBootCount() {
        assertEquals(0, mDatabase.getLastBootCount());
        mDatabase.setLastBootCount(10);
        assertEquals(10, mDatabase.getLastBootCount());
        try {
            mDatabase.setLastBootCount(-1);
            fail();
        } catch (IllegalArgumentException e) {}
    }

    public void testCleanDatabase() throws FileNotFoundException {
        // Add tree.
        addTestDevice();
        addTestStorage("1");
        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                createDocument(100, "apple.txt", MtpConstants.FORMAT_TEXT, 1024),
                createDocument(101, "orange.txt", MtpConstants.FORMAT_TEXT, 1024),
        }, new long[] { 1024L, 1024L });
        mDatabase.getMapper().stopAddingDocuments("2");

        // Disconnect the device.
        mDatabase.getMapper().startAddingDocuments(null);
        mDatabase.getMapper().stopAddingDocuments(null);

        // Clean database.
        mDatabase.cleanDatabase(new Uri[] {
                DocumentsContract.buildDocumentUri(MtpDocumentsProvider.AUTHORITY, "3")
        });

        // Add tree again.
        addTestDevice();
        addTestStorage("1");
        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                createDocument(100, "apple.txt", MtpConstants.FORMAT_TEXT, 1024),
                createDocument(101, "orange.txt", MtpConstants.FORMAT_TEXT, 1024),
        }, new long[] { 1024L, 1024L });
        mDatabase.getMapper().stopAddingDocuments("2");

        try (final Cursor cursor = mDatabase.queryChildDocuments(
                strings(COLUMN_DOCUMENT_ID, Document.COLUMN_DISPLAY_NAME), "2")) {
            assertEquals(2, cursor.getCount());

            // Persistent uri uses the same ID.
            cursor.moveToNext();
            assertEquals("3", cursor.getString(0));
            assertEquals("apple.txt", cursor.getString(1));

            // Others does not.
            cursor.moveToNext();
            assertEquals("5", cursor.getString(0));
            assertEquals("orange.txt", cursor.getString(1));
        }
    }

    public void testFormatCodeForMpeg() throws FileNotFoundException {
        addTestDevice();
        addTestStorage("1");
        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
            createDocument(100, "audio.m4a", MtpConstants.FORMAT_MPEG, 1000),
            createDocument(101, "video.m4v", MtpConstants.FORMAT_MPEG, 1000),
            createDocument(102, "unknown.mp4", MtpConstants.FORMAT_MPEG, 1000),
            createDocument(103, "inconsistent.txt", MtpConstants.FORMAT_MPEG, 1000),
            createDocument(104, "noext", MtpConstants.FORMAT_UNDEFINED, 1000),
        }, new long[] { 1000L, 1000L, 1000L, 1000L, 1000L });
        mDatabase.getMapper().stopAddingDocuments("2");
        try (final Cursor cursor = mDatabase.queryChildDocuments(
                strings(COLUMN_DISPLAY_NAME,  COLUMN_MIME_TYPE),
                "2")) {
            assertEquals(5, cursor.getCount());
            cursor.moveToNext();
            assertEquals("audio.m4a", cursor.getString(0));
            assertEquals("audio/mp4", cursor.getString(1));
            cursor.moveToNext();
            assertEquals("video.m4v", cursor.getString(0));
            assertEquals("video/mp4", cursor.getString(1));
            cursor.moveToNext();
            // Assume that the file is video as we don't have any hints to find out if the file is
            // video or audio.
            assertEquals("unknown.mp4", cursor.getString(0));
            assertEquals("video/mp4", cursor.getString(1));
            // Don't return mime type that is inconsistent with format code.
            cursor.moveToNext();
            assertEquals("inconsistent.txt", cursor.getString(0));
            assertEquals("video/mp4", cursor.getString(1));
            cursor.moveToNext();
            assertEquals("noext", cursor.getString(0));
            assertEquals("application/octet-stream", cursor.getString(1));
        }
    }

    private void addTestDevice() throws FileNotFoundException {
        TestUtil.addTestDevice(mDatabase);
    }

    private void addTestStorage(String parentId) throws FileNotFoundException {
        TestUtil.addTestStorage(mDatabase, parentId);
    }
}
