199bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay/* 299bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay * Copyright (C) 2015 The Android Open Source Project 399bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay * 499bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay * Licensed under the Apache License, Version 2.0 (the "License"); 599bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay * you may not use this file except in compliance with the License. 699bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay * You may obtain a copy of the License at 799bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay * 899bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay * http://www.apache.org/licenses/LICENSE-2.0 999bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay * 1099bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay * Unless required by applicable law or agreed to in writing, software 1199bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay * distributed under the License is distributed on an "AS IS" BASIS, 1299bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1399bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay * See the License for the specific language governing permissions and 1499bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay * limitations under the License. 1599bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay */ 1699bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay 1799bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKaypackage com.android.documentsui; 1899bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay 19bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport static android.provider.DocumentsContract.buildChildDocumentsUri; 20bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport static android.provider.DocumentsContract.buildDocumentUri; 21bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport static android.provider.DocumentsContract.buildRootsUri; 22d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport static com.android.documentsui.base.DocumentInfo.getCursorString; 2322797f589b5251585b069622de0417a0c240ac35Steve McKayimport static com.android.internal.util.Preconditions.checkArgument; 24bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport static junit.framework.Assert.assertEquals; 25bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport static junit.framework.Assert.assertNotNull; 26bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport static junit.framework.Assert.fail; 2799bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay 2899bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKayimport android.content.ContentProviderClient; 2999bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKayimport android.database.Cursor; 3099bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKayimport android.net.Uri; 31bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport android.os.Bundle; 32bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport android.os.ParcelFileDescriptor; 33bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport android.os.ParcelFileDescriptor.AutoCloseInputStream; 34bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport android.os.ParcelFileDescriptor.AutoCloseOutputStream; 3599bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKayimport android.os.RemoteException; 3699bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKayimport android.provider.DocumentsContract; 3799bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKayimport android.provider.DocumentsContract.Document; 3899bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKayimport android.provider.DocumentsContract.Root; 39bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport android.support.annotation.Nullable; 40bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport android.test.MoreAsserts; 4122797f589b5251585b069622de0417a0c240ac35Steve McKayimport android.text.TextUtils; 4299bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay 43d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport com.android.documentsui.base.DocumentInfo; 44d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport com.android.documentsui.base.RootInfo; 45d9caa6ab53aa784acaf241c0ded3c4ae2d342bf8Steve McKayimport com.android.documentsui.roots.RootCursorWrapper; 4699bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay 47bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport com.google.android.collect.Lists; 48bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 4999bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKayimport libcore.io.IoUtils; 50bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport libcore.io.Streams; 51bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 52bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport java.io.IOException; 53bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport java.util.ArrayList; 54bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport java.util.List; 5599bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay 5699bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay/** 5799bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay * Provides support for creation of documents in a test settings. 5899bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay */ 5999bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKaypublic class DocumentsProviderHelper { 6099bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay 6199bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay private final String mAuthority; 62bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay private final ContentProviderClient mClient; 6399bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay 6499bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay public DocumentsProviderHelper(String authority, ContentProviderClient client) { 6522797f589b5251585b069622de0417a0c240ac35Steve McKay checkArgument(!TextUtils.isEmpty(authority)); 6699bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay mAuthority = authority; 67bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay mClient = client; 6899bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay } 6999bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay 70bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public RootInfo getRoot(String documentId) throws RemoteException { 71bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay final Uri rootsUri = buildRootsUri(mAuthority); 7299bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay Cursor cursor = null; 7399bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay try { 7499bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay cursor = mClient.query(rootsUri, null, null, null, null); 7599bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay while (cursor.moveToNext()) { 76bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay if (documentId.equals(getCursorString(cursor, Root.COLUMN_ROOT_ID))) { 7799bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay return RootInfo.fromRootsCursor(mAuthority, cursor); 7899bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay } 7999bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay } 80bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throw new IllegalArgumentException("Can't find matching root for id=" + documentId); 8199bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay } catch (Exception e) { 82bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throw new RuntimeException("Can't load root for id=" + documentId , e); 8399bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay } finally { 8499bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay IoUtils.closeQuietly(cursor); 8599bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay } 8699bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay } 8799bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay 8899bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay public Uri createDocument(Uri parentUri, String mimeType, String name) { 8999bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay if (name.contains("/")) { 9099bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay throw new IllegalArgumentException("Name and mimetype probably interposed."); 9199bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay } 9299bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay try { 93bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay Uri uri = DocumentsContract.createDocument(mClient, parentUri, mimeType, name); 94bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return uri; 9599bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay } catch (RemoteException e) { 96a2ad8dfc42a4fcd5391423605b5d48fa28ee7fc5Tomasz Mikolajewski throw new RuntimeException("Couldn't create document: " + name + " with mimetype " 97a2ad8dfc42a4fcd5391423605b5d48fa28ee7fc5Tomasz Mikolajewski + mimeType, e); 9899bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay } 9999bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay } 10099bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay 101bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public Uri createDocument(String parentId, String mimeType, String name) { 102bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay Uri parentUri = buildDocumentUri(mAuthority, parentId); 103bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return createDocument(parentUri, mimeType, name); 104bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 105bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 106bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public Uri createDocument(RootInfo root, String mimeType, String name) { 107bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return createDocument(root.documentId, mimeType, name); 108bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 109bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 110fe7f53647db0b1b50dff9489a77656046c20bf7bTomasz Mikolajewski public Uri createDocumentWithFlags(String documentId, String mimeType, String name, int flags, 111fe7f53647db0b1b50dff9489a77656046c20bf7bTomasz Mikolajewski String... streamTypes) 11218410b7e10fb6e5841c1a309e706aa2d68552a6bAga Wronska throws RemoteException { 11318410b7e10fb6e5841c1a309e706aa2d68552a6bAga Wronska Bundle in = new Bundle(); 11418410b7e10fb6e5841c1a309e706aa2d68552a6bAga Wronska in.putInt(StubProvider.EXTRA_FLAGS, flags); 11518410b7e10fb6e5841c1a309e706aa2d68552a6bAga Wronska in.putString(StubProvider.EXTRA_PARENT_ID, documentId); 11618410b7e10fb6e5841c1a309e706aa2d68552a6bAga Wronska in.putString(Document.COLUMN_MIME_TYPE, mimeType); 11718410b7e10fb6e5841c1a309e706aa2d68552a6bAga Wronska in.putString(Document.COLUMN_DISPLAY_NAME, name); 118fe7f53647db0b1b50dff9489a77656046c20bf7bTomasz Mikolajewski in.putStringArrayList(StubProvider.EXTRA_STREAM_TYPES, Lists.newArrayList(streamTypes)); 11918410b7e10fb6e5841c1a309e706aa2d68552a6bAga Wronska 12018410b7e10fb6e5841c1a309e706aa2d68552a6bAga Wronska Bundle out = mClient.call("createDocumentWithFlags", null, in); 12118410b7e10fb6e5841c1a309e706aa2d68552a6bAga Wronska Uri uri = out.getParcelable(DocumentsContract.EXTRA_URI); 12218410b7e10fb6e5841c1a309e706aa2d68552a6bAga Wronska return uri; 12318410b7e10fb6e5841c1a309e706aa2d68552a6bAga Wronska } 12418410b7e10fb6e5841c1a309e706aa2d68552a6bAga Wronska 12599bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay public Uri createFolder(Uri parentUri, String name) { 12699bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay return createDocument(parentUri, Document.MIME_TYPE_DIR, name); 12799bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay } 12899bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay 129bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public Uri createFolder(String parentId, String name) { 130bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay Uri parentUri = buildDocumentUri(mAuthority, parentId); 131bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return createDocument(parentUri, Document.MIME_TYPE_DIR, name); 13299bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay } 13399bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay 13499bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay public Uri createFolder(RootInfo root, String name) { 13599bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay return createDocument(root, Document.MIME_TYPE_DIR, name); 13699bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay } 137bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 138bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void writeDocument(Uri documentUri, byte[] contents) 139bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throws RemoteException, IOException { 140bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay ParcelFileDescriptor file = mClient.openFile(documentUri, "w", null); 141bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay try (AutoCloseOutputStream out = new AutoCloseOutputStream(file)) { 142bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay out.write(contents, 0, contents.length); 143bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 144ca92ecf53ae5f1c3399b50c488b51018f8c93e5bGarfield Tan waitForWrite(); 145ca92ecf53ae5f1c3399b50c488b51018f8c93e5bGarfield Tan } 146ca92ecf53ae5f1c3399b50c488b51018f8c93e5bGarfield Tan 147ca92ecf53ae5f1c3399b50c488b51018f8c93e5bGarfield Tan public void waitForWrite() throws RemoteException { 1481e80be78050dcf5b73b2eb2011a5ce109bf2a277Garfield Tan mClient.call("waitForWrite", null, null); 149bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 150bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 151bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public byte[] readDocument(Uri documentUri) throws RemoteException, IOException { 152bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay ParcelFileDescriptor file = mClient.openFile(documentUri, "r", null); 153bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay byte[] buf = null; 154bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay try (AutoCloseInputStream in = new AutoCloseInputStream(file)) { 155bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay buf = Streams.readFully(in); 156bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 157bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return buf; 158bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 159bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 160bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void assertChildCount(Uri parentUri, int expected) throws Exception { 161bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay List<DocumentInfo> children = listChildren(parentUri); 162bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay assertEquals("Incorrect file count after copy", expected, children.size()); 163bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 164bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 165bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void assertChildCount(String parentId, int expected) throws Exception { 166ceedd1fb5c9e34096bbe1c11e79fa0d96471611eGarfield Tan List<DocumentInfo> children = listChildren(parentId, -1); 167bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay assertEquals("Incorrect file count after copy", expected, children.size()); 168bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 169bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 170bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void assertChildCount(RootInfo root, int expected) throws Exception { 171bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay assertChildCount(root.documentId, expected); 172bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 173bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 174bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void assertHasFile(Uri parentUri, String name) throws Exception { 175bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay List<DocumentInfo> children = listChildren(parentUri); 176bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay for (DocumentInfo child : children) { 177bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay if (name.equals(child.displayName) && !child.isDirectory()) { 178bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return; 179bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 180bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 181bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay fail("Could not find file named=" + name + " in children " + children); 182bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 183bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 184bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void assertHasFile(String parentId, String name) throws Exception { 185bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay Uri parentUri = buildDocumentUri(mAuthority, parentId); 186bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay assertHasFile(parentUri, name); 187bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 188bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 189bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void assertHasFile(RootInfo root, String name) throws Exception { 190bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay assertHasFile(root.documentId, name); 191bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 192bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 193bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void assertHasDirectory(Uri parentUri, String name) throws Exception { 194bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay List<DocumentInfo> children = listChildren(parentUri); 195bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay for (DocumentInfo child : children) { 196bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay if (name.equals(child.displayName) && child.isDirectory()) { 197bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return; 198bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 199bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 200bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay fail("Could not find name=" + name + " in children " + children); 201bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 202bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 203bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void assertHasDirectory(String parentId, String name) throws Exception { 204bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay Uri parentUri = buildDocumentUri(mAuthority, parentId); 205bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay assertHasDirectory(parentUri, name); 206bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 207bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 208bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void assertHasDirectory(RootInfo root, String name) throws Exception { 209bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay assertHasDirectory(root.documentId, name); 210bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 211bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 212bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void assertDoesNotExist(Uri parentUri, String name) throws Exception { 213bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay List<DocumentInfo> children = listChildren(parentUri); 214bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay for (DocumentInfo child : children) { 215bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay if (name.equals(child.displayName)) { 216bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay fail("Found name=" + name + " in children " + children); 217bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 218bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 219bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 220bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 221bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void assertDoesNotExist(String parentId, String name) throws Exception { 222bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay Uri parentUri = buildDocumentUri(mAuthority, parentId); 223bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay assertDoesNotExist(parentUri, name); 224bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 225bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 226bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void assertDoesNotExist(RootInfo root, String name) throws Exception { 227bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay assertDoesNotExist(root.getUri(), name); 228bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 229bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 230bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public @Nullable DocumentInfo findFile(String parentId, String name) 231bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throws Exception { 232bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay List<DocumentInfo> children = listChildren(parentId); 233bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay for (DocumentInfo child : children) { 234bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay if (name.equals(child.displayName)) { 235bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return child; 236bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 237bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 238bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return null; 239bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 240bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 241bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public DocumentInfo findDocument(String parentId, String name) throws Exception { 242bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay List<DocumentInfo> children = listChildren(parentId); 243bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay for (DocumentInfo child : children) { 244bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay if (name.equals(child.displayName)) { 245bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return child; 246bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 247bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 248bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return null; 249bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 250bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 251bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public DocumentInfo findDocument(Uri parentUri, String name) throws Exception { 252bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay List<DocumentInfo> children = listChildren(parentUri); 253bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay for (DocumentInfo child : children) { 254bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay if (name.equals(child.displayName)) { 255bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return child; 256bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 257bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 258bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return null; 259bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 260bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 261bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public List<DocumentInfo> listChildren(Uri parentUri) throws Exception { 262bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay String id = DocumentsContract.getDocumentId(parentUri); 263bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return listChildren(id); 264bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 265bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 266bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public List<DocumentInfo> listChildren(String documentId) throws Exception { 267ceedd1fb5c9e34096bbe1c11e79fa0d96471611eGarfield Tan return listChildren(documentId, 100); 268ceedd1fb5c9e34096bbe1c11e79fa0d96471611eGarfield Tan } 269ceedd1fb5c9e34096bbe1c11e79fa0d96471611eGarfield Tan 270ceedd1fb5c9e34096bbe1c11e79fa0d96471611eGarfield Tan public List<DocumentInfo> listChildren(Uri parentUri, int maxCount) throws Exception { 271ceedd1fb5c9e34096bbe1c11e79fa0d96471611eGarfield Tan String id = DocumentsContract.getDocumentId(parentUri); 272ceedd1fb5c9e34096bbe1c11e79fa0d96471611eGarfield Tan return listChildren(id, maxCount); 273ceedd1fb5c9e34096bbe1c11e79fa0d96471611eGarfield Tan } 274ceedd1fb5c9e34096bbe1c11e79fa0d96471611eGarfield Tan 275ceedd1fb5c9e34096bbe1c11e79fa0d96471611eGarfield Tan public List<DocumentInfo> listChildren(String documentId, int maxCount) throws Exception { 276bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay Uri uri = buildChildDocumentsUri(mAuthority, documentId); 277bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay List<DocumentInfo> children = new ArrayList<>(); 278bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay try (Cursor cursor = mClient.query(uri, null, null, null, null, null)) { 279ceedd1fb5c9e34096bbe1c11e79fa0d96471611eGarfield Tan Cursor wrapper = new RootCursorWrapper(mAuthority, "totally-fake", cursor, maxCount); 28022797f589b5251585b069622de0417a0c240ac35Steve McKay while (wrapper.moveToNext()) { 28122797f589b5251585b069622de0417a0c240ac35Steve McKay children.add(DocumentInfo.fromDirectoryCursor(wrapper)); 282bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 283bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 284bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return children; 285bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 286bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 287bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void assertFileContents(Uri documentUri, byte[] expected) throws Exception { 28822797f589b5251585b069622de0417a0c240ac35Steve McKay MoreAsserts.assertEquals( 28922797f589b5251585b069622de0417a0c240ac35Steve McKay "Copied file contents differ", 29022797f589b5251585b069622de0417a0c240ac35Steve McKay expected, readDocument(documentUri)); 291bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 292bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 293bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void assertFileContents(String parentId, String fileName, byte[] expected) 294bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throws Exception { 295bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay DocumentInfo file = findFile(parentId, fileName); 296bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay assertNotNull(file); 297bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay assertFileContents(file.derivedUri, expected); 298bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 299bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 300bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay /** 301bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay * A helper method for StubProvider only. Won't work with other providers. 302bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay * @throws RemoteException 303bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay */ 304bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public Uri createVirtualFile( 305bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay RootInfo root, String path, String mimeType, byte[] content, String... streamTypes) 306bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throws RemoteException { 307bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 308bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay Bundle args = new Bundle(); 309bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay args.putString(StubProvider.EXTRA_ROOT, root.rootId); 310bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay args.putString(StubProvider.EXTRA_PATH, path); 311bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay args.putString(Document.COLUMN_MIME_TYPE, mimeType); 312bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay args.putStringArrayList(StubProvider.EXTRA_STREAM_TYPES, Lists.newArrayList(streamTypes)); 313bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay args.putByteArray(StubProvider.EXTRA_CONTENT, content); 314bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 315bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay Bundle result = mClient.call("createVirtualFile", null, args); 316bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay String documentId = result.getString(Document.COLUMN_DOCUMENT_ID); 317bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 318bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return DocumentsContract.buildDocumentUri(mAuthority, documentId); 319bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 32018410b7e10fb6e5841c1a309e706aa2d68552a6bAga Wronska 3211566618f399086abfd360ad4f0797793744e98d7Garfield Tan public void setLoadingDuration(long duration) throws RemoteException { 3221566618f399086abfd360ad4f0797793744e98d7Garfield Tan final Bundle extra = new Bundle(); 3231566618f399086abfd360ad4f0797793744e98d7Garfield Tan extra.putLong(DocumentsContract.EXTRA_LOADING, duration); 3241566618f399086abfd360ad4f0797793744e98d7Garfield Tan mClient.call("setLoadingDuration", null, extra); 3251566618f399086abfd360ad4f0797793744e98d7Garfield Tan } 326ceedd1fb5c9e34096bbe1c11e79fa0d96471611eGarfield Tan 327ceedd1fb5c9e34096bbe1c11e79fa0d96471611eGarfield Tan public void configure(String args, Bundle configuration) throws RemoteException { 328ceedd1fb5c9e34096bbe1c11e79fa0d96471611eGarfield Tan mClient.call("configure", args, configuration); 329ceedd1fb5c9e34096bbe1c11e79fa0d96471611eGarfield Tan } 33099bcc6aa4dbcfaf6206d9bee496f7388fa9ab17cSteve McKay} 331