DocumentsProvider.java revision 911d7f411f36f2279aae44c89ff1d33a29140046
1aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey/* 2aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * Copyright (C) 2013 The Android Open Source Project 3aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * 4aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * you may not use this file except in compliance with the License. 6aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * You may obtain a copy of the License at 7aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * 8aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * 10aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * Unless required by applicable law or agreed to in writing, software 11aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * See the License for the specific language governing permissions and 14aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * limitations under the License. 15aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey */ 16aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 17aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeypackage android.provider; 18aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 19aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport static android.provider.DocumentsContract.EXTRA_THUMBNAIL_SIZE; 20aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport static android.provider.DocumentsContract.METHOD_CREATE_DOCUMENT; 21aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport static android.provider.DocumentsContract.METHOD_DELETE_DOCUMENT; 22ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport static android.provider.DocumentsContract.getDocumentId; 23ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport static android.provider.DocumentsContract.getRootId; 24ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport static android.provider.DocumentsContract.getSearchDocumentsQuery; 25aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 26aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport android.content.ContentProvider; 27aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport android.content.ContentValues; 28aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport android.content.Context; 29aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport android.content.Intent; 30aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport android.content.UriMatcher; 31e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkeyimport android.content.pm.PackageManager; 32aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport android.content.pm.ProviderInfo; 33aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport android.content.res.AssetFileDescriptor; 34aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport android.database.Cursor; 35aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport android.graphics.Point; 36aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport android.net.Uri; 37aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport android.os.Bundle; 38aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport android.os.CancellationSignal; 39aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport android.os.ParcelFileDescriptor; 40aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport android.os.ParcelFileDescriptor.OnCloseListener; 41ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport android.provider.DocumentsContract.Document; 42aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport android.util.Log; 43aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 44aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport libcore.io.IoUtils; 45aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 46aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport java.io.FileNotFoundException; 47aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 48aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey/** 49aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * Base class for a document provider. A document provider should extend this 50aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * class and implement the abstract methods. 51aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * <p> 52aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * Each document provider expresses one or more "roots" which each serve as the 53aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * top-level of a tree. For example, a root could represent an account, or a 54aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * physical storage device. Under each root, documents are referenced by 55ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * {@link Document#COLUMN_DOCUMENT_ID}, which must not change once returned. 56aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * <p> 57aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * Documents can be either an openable file (with a specific MIME type), or a 58aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * directory containing additional documents (with the 59ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * {@link Document#MIME_TYPE_DIR} MIME type). Each document can have different 60ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * capabilities, as described by {@link Document#COLUMN_FLAGS}. The same 61ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * {@link Document#COLUMN_DOCUMENT_ID} can be included in multiple directories. 62aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * <p> 63aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * Document providers must be protected with the 64aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * {@link android.Manifest.permission#MANAGE_DOCUMENTS} permission, which can 65aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * only be requested by the system. The system-provided UI then issues narrow 66aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * Uri permission grants for individual documents when the user explicitly picks 67aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * documents. 68aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * 69aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * @see Intent#ACTION_OPEN_DOCUMENT 70aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * @see Intent#ACTION_CREATE_DOCUMENT 71aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey */ 72aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeypublic abstract class DocumentsProvider extends ContentProvider { 73aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey private static final String TAG = "DocumentsProvider"; 74aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 75a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey private static final int MATCH_ROOTS = 1; 76a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey private static final int MATCH_ROOT = 2; 77a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey private static final int MATCH_RECENT = 3; 78a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey private static final int MATCH_DOCUMENT = 4; 79a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey private static final int MATCH_CHILDREN = 5; 80a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey private static final int MATCH_SEARCH = 6; 81aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 82aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey private String mAuthority; 83aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 84aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey private UriMatcher mMatcher; 85aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 86ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey /** 87ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * Implementation is provided by the parent class. 88ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey */ 89aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @Override 90aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey public void attachInfo(Context context, ProviderInfo info) { 91aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey mAuthority = info.authority; 92aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 93aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey mMatcher = new UriMatcher(UriMatcher.NO_MATCH); 94a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey mMatcher.addURI(mAuthority, "root", MATCH_ROOTS); 95a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey mMatcher.addURI(mAuthority, "root/*", MATCH_ROOT); 96ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey mMatcher.addURI(mAuthority, "root/*/recent", MATCH_RECENT); 97ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey mMatcher.addURI(mAuthority, "document/*", MATCH_DOCUMENT); 98ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey mMatcher.addURI(mAuthority, "document/*/children", MATCH_CHILDREN); 99ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey mMatcher.addURI(mAuthority, "document/*/search", MATCH_SEARCH); 100aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 101aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey // Sanity check our setup 102aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (!info.exported) { 103aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey throw new SecurityException("Provider must be exported"); 104aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 105aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (!info.grantUriPermissions) { 106aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey throw new SecurityException("Provider must grantUriPermissions"); 107aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 108aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (!android.Manifest.permission.MANAGE_DOCUMENTS.equals(info.readPermission) 109aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey || !android.Manifest.permission.MANAGE_DOCUMENTS.equals(info.writePermission)) { 110aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey throw new SecurityException("Provider must be protected by MANAGE_DOCUMENTS"); 111aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 112aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 113aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey super.attachInfo(context, info); 114aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 115aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 116aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey /** 117ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * Create a new document and return its {@link Document#COLUMN_DOCUMENT_ID}. 118ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * A provider must allocate a new {@link Document#COLUMN_DOCUMENT_ID} to 119ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * represent the document, which must not change once returned. 120aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * 121ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @param documentId the parent directory to create the new document under. 122aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * @param mimeType the MIME type associated with the new document. 123aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * @param displayName the display name of the new document. 124aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey */ 125aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @SuppressWarnings("unused") 126ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public String createDocument(String documentId, String mimeType, String displayName) 127aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey throws FileNotFoundException { 128aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey throw new UnsupportedOperationException("Create not supported"); 129aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 130aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 131aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey /** 132ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * Delete the given document. Upon returning, any Uri permission grants for 133ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * the given document will be revoked. If additional documents were deleted 134ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * as a side effect of this call, such as documents inside a directory, the 135ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * implementor is responsible for revoking those permissions. 136aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * 137ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @param documentId the document to delete. 138aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey */ 139aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @SuppressWarnings("unused") 140ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public void deleteDocument(String documentId) throws FileNotFoundException { 141ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey throw new UnsupportedOperationException("Delete not supported"); 142aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 143aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 144ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public abstract Cursor queryRoots(String[] projection) throws FileNotFoundException; 145ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey 146aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @SuppressWarnings("unused") 147ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public Cursor queryRecentDocuments(String rootId, String[] projection) 148ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey throws FileNotFoundException { 149ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey throw new UnsupportedOperationException("Recent not supported"); 150aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 151aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 152aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey /** 153aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * Return metadata for the given document. A provider should avoid making 154aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * network requests to keep this request fast. 155aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * 156ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @param documentId the document to return. 157aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey */ 158ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public abstract Cursor queryDocument(String documentId, String[] projection) 159ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey throws FileNotFoundException; 160aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 161aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey /** 162aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * Return the children of the given document which is a directory. 163aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * 164ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @param parentDocumentId the directory to return children for. 165aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey */ 166ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public abstract Cursor queryChildDocuments( 167ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey String parentDocumentId, String[] projection, String sortOrder) 168ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey throws FileNotFoundException; 169aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 170aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey /** 171aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * Return documents that that match the given query, starting the search at 172aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * the given directory. 173aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * 174ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @param parentDocumentId the directory to start search at. 175aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey */ 176aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @SuppressWarnings("unused") 177ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public Cursor querySearchDocuments(String parentDocumentId, String query, String[] projection) 178ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey throws FileNotFoundException { 179aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey throw new UnsupportedOperationException("Search not supported"); 180aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 181aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 182aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey /** 183aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * Return MIME type for the given document. Must match the value of 184ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * {@link Document#COLUMN_MIME_TYPE} for this document. 185aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey */ 186ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public String getDocumentType(String documentId) throws FileNotFoundException { 187ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey final Cursor cursor = queryDocument(documentId, null); 188aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey try { 189aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (cursor.moveToFirst()) { 190ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_MIME_TYPE)); 191aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } else { 192aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return null; 193aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 194aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } finally { 195aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey IoUtils.closeQuietly(cursor); 196aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 197aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 198aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 199aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey /** 200aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * Open and return the requested document. A provider should return a 201aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * reliable {@link ParcelFileDescriptor} to detect when the remote caller 202aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * has finished reading or writing the document. A provider may return a 203aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * pipe or socket pair if the mode is exclusively 204aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * {@link ParcelFileDescriptor#MODE_READ_ONLY} or 205aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * {@link ParcelFileDescriptor#MODE_WRITE_ONLY}, but complex modes like 206aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * {@link ParcelFileDescriptor#MODE_READ_WRITE} require a normal file on 207aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * disk. If a provider blocks while downloading content, it should 208aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * periodically check {@link CancellationSignal#isCanceled()} to abort 209aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * abandoned open requests. 210aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * 211aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * @param docId the document to return. 212aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * @param mode the mode to open with, such as 'r', 'w', or 'rw'. 213aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * @param signal used by the caller to signal if the request should be 214aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * cancelled. 215aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * @see ParcelFileDescriptor#open(java.io.File, int, android.os.Handler, 216aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * OnCloseListener) 217aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * @see ParcelFileDescriptor#createReliablePipe() 218aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * @see ParcelFileDescriptor#createReliableSocketPair() 219aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey */ 220aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey public abstract ParcelFileDescriptor openDocument( 221aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey String docId, String mode, CancellationSignal signal) throws FileNotFoundException; 222aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 223aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey /** 224aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * Open and return a thumbnail of the requested document. A provider should 225aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * return a thumbnail closely matching the hinted size, attempting to serve 226aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * from a local cache if possible. A provider should never return images 227aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * more than double the hinted size. If a provider performs expensive 228aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * operations to download or generate a thumbnail, it should periodically 229aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * check {@link CancellationSignal#isCanceled()} to abort abandoned 230aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * thumbnail requests. 231aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * 232aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * @param docId the document to return. 233aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * @param sizeHint hint of the optimal thumbnail dimensions. 234aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * @param signal used by the caller to signal if the request should be 235aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey * cancelled. 236ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @see Document#FLAG_SUPPORTS_THUMBNAIL 237aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey */ 238aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @SuppressWarnings("unused") 239aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey public AssetFileDescriptor openDocumentThumbnail( 240aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey String docId, Point sizeHint, CancellationSignal signal) throws FileNotFoundException { 241aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey throw new UnsupportedOperationException("Thumbnails not supported"); 242aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 243aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 244ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey /** 245ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * Implementation is provided by the parent class. Cannot be overriden. 246ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * 247ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @see #queryRoots(String[]) 248ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @see #queryRecentDocuments(String, String[]) 249ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @see #queryDocument(String, String[]) 250ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @see #queryChildDocuments(String, String[], String) 251ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @see #querySearchDocuments(String, String, String[]) 252ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey */ 253aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @Override 254ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public final Cursor query(Uri uri, String[] projection, String selection, 255ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey String[] selectionArgs, String sortOrder) { 256aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey try { 257aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey switch (mMatcher.match(uri)) { 258a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey case MATCH_ROOTS: 259ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return queryRoots(projection); 260ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case MATCH_RECENT: 261ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return queryRecentDocuments(getRootId(uri), projection); 262aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case MATCH_DOCUMENT: 263ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return queryDocument(getDocumentId(uri), projection); 264aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case MATCH_CHILDREN: 265ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return queryChildDocuments(getDocumentId(uri), projection, sortOrder); 266aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case MATCH_SEARCH: 267ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return querySearchDocuments( 268ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey getDocumentId(uri), getSearchDocumentsQuery(uri), projection); 269aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey default: 270aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey throw new UnsupportedOperationException("Unsupported Uri " + uri); 271aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 272aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } catch (FileNotFoundException e) { 273aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey Log.w(TAG, "Failed during query", e); 274aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return null; 275aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 276aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 277aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 278ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey /** 279ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * Implementation is provided by the parent class. Cannot be overriden. 280ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * 281ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @see #getDocumentType(String) 282ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey */ 283aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @Override 284aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey public final String getType(Uri uri) { 285aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey try { 286aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey switch (mMatcher.match(uri)) { 287a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey case MATCH_ROOT: 288a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey return DocumentsContract.Root.MIME_TYPE_ITEM; 289aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case MATCH_DOCUMENT: 290ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return getDocumentType(getDocumentId(uri)); 291aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey default: 292aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return null; 293aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 294aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } catch (FileNotFoundException e) { 295aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey Log.w(TAG, "Failed during getType", e); 296aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return null; 297aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 298aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 299aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 300ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey /** 301ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * Implementation is provided by the parent class. Throws by default, and 302ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * cannot be overriden. 303ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * 304ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @see #createDocument(String, String, String) 305ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey */ 306aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @Override 307aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey public final Uri insert(Uri uri, ContentValues values) { 308aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey throw new UnsupportedOperationException("Insert not supported"); 309aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 310aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 311ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey /** 312ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * Implementation is provided by the parent class. Throws by default, and 313ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * cannot be overriden. 314ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * 315ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @see #deleteDocument(String) 316ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey */ 317aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @Override 318aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey public final int delete(Uri uri, String selection, String[] selectionArgs) { 319aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey throw new UnsupportedOperationException("Delete not supported"); 320aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 321aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 322ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey /** 323ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * Implementation is provided by the parent class. Throws by default, and 324ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * cannot be overriden. 325ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey */ 326aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @Override 327aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey public final int update( 328aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey Uri uri, ContentValues values, String selection, String[] selectionArgs) { 329aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey throw new UnsupportedOperationException("Update not supported"); 330aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 331aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 332911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey /** 333911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey * Implementation is provided by the parent class. Can be overridden to 334911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey * provide additional functionality, but subclasses <em>must</em> always 335911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey * call the superclass. If the superclass returns {@code null}, the subclass 336911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey * may implement custom behavior. 337911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey * 338911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey * @see #openDocument(String, String, CancellationSignal) 339911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey * @see #deleteDocument(String) 340911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey */ 341aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @Override 342911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey public Bundle call(String method, String arg, Bundle extras) { 343e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey final Context context = getContext(); 344e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey 345aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (!method.startsWith("android:")) { 346aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey // Let non-platform methods pass through 347911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey return super.call(method, arg, extras); 348aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 349aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 350ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey final String documentId = extras.getString(Document.COLUMN_DOCUMENT_ID); 351ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey final Uri documentUri = DocumentsContract.buildDocumentUri(mAuthority, documentId); 352e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey 353e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey // Require that caller can manage given document 354e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey final boolean callerHasManage = 355e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey context.checkCallingOrSelfPermission(android.Manifest.permission.MANAGE_DOCUMENTS) 356e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey == PackageManager.PERMISSION_GRANTED; 357e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey if (!callerHasManage) { 358e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey getContext().enforceCallingOrSelfUriPermission( 359e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey documentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, method); 360e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey } 361aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 362aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey final Bundle out = new Bundle(); 363aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey try { 364ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey if (METHOD_CREATE_DOCUMENT.equals(method)) { 365ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey final String mimeType = extras.getString(Document.COLUMN_MIME_TYPE); 366ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME); 367aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 368ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey final String newDocumentId = createDocument(documentId, mimeType, displayName); 369ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey out.putString(Document.COLUMN_DOCUMENT_ID, newDocumentId); 370aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 371e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey // Extend permission grant towards caller if needed 372e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey if (!callerHasManage) { 373e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey final Uri newDocumentUri = DocumentsContract.buildDocumentUri( 374e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey mAuthority, newDocumentId); 375911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey context.grantUriPermission(getCallingPackage(), newDocumentUri, 376e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey Intent.FLAG_GRANT_READ_URI_PERMISSION 377e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 378e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION); 379e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey } 380e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey 381aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } else if (METHOD_DELETE_DOCUMENT.equals(method)) { 382e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey deleteDocument(documentId); 383e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey 384e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey // Document no longer exists, clean up any grants 385e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey context.revokeUriPermission(documentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION 386e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 387e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION); 388aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 389aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } else { 390aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey throw new UnsupportedOperationException("Method not supported " + method); 391aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 392aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } catch (FileNotFoundException e) { 393aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey throw new IllegalStateException("Failed call " + method, e); 394aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 395aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return out; 396aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 397aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 398ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey /** 399ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * Implementation is provided by the parent class. 400ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * 401ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @see #openDocument(String, String, CancellationSignal) 402ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey */ 403aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @Override 404aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey public final ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { 405ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return openDocument(getDocumentId(uri), mode, null); 406aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 407aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 408ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey /** 409ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * Implementation is provided by the parent class. 410ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * 411ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @see #openDocument(String, String, CancellationSignal) 412ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey */ 413aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @Override 414aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey public final ParcelFileDescriptor openFile(Uri uri, String mode, CancellationSignal signal) 415aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey throws FileNotFoundException { 416ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return openDocument(getDocumentId(uri), mode, signal); 417aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 418aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 419ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey /** 420ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * Implementation is provided by the parent class. 421ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * 422ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @see #openDocumentThumbnail(String, Point, CancellationSignal) 423ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey */ 424aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @Override 425aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey public final AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts) 426aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey throws FileNotFoundException { 427aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (opts != null && opts.containsKey(EXTRA_THUMBNAIL_SIZE)) { 428aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey final Point sizeHint = opts.getParcelable(EXTRA_THUMBNAIL_SIZE); 429ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return openDocumentThumbnail(getDocumentId(uri), sizeHint, null); 430aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } else { 431aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return super.openTypedAssetFile(uri, mimeTypeFilter, opts); 432aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 433aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 434aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 435ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey /** 436ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * Implementation is provided by the parent class. 437ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * 438ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * @see #openDocumentThumbnail(String, Point, CancellationSignal) 439ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey */ 440aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @Override 441aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey public final AssetFileDescriptor openTypedAssetFile( 442aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey Uri uri, String mimeTypeFilter, Bundle opts, CancellationSignal signal) 443aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey throws FileNotFoundException { 444aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (opts != null && opts.containsKey(EXTRA_THUMBNAIL_SIZE)) { 445aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey final Point sizeHint = opts.getParcelable(EXTRA_THUMBNAIL_SIZE); 446ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return openDocumentThumbnail(getDocumentId(uri), sizeHint, signal); 447aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } else { 448aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return super.openTypedAssetFile(uri, mimeTypeFilter, opts, signal); 449aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 450aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 451aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey} 452