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