Add DocumentsProvider::removeDocument().
Multi-parents are supported already in moveDocument(). For parity, this CL adds removeDocument, so it's possible to delete a file from a specific parent. Bug: 26481380 Change-Id: Icd4213abc0c3413931902f4f8984746c84c65e52
This commit is contained in:
@@ -31545,6 +31545,7 @@ package android.provider {
|
||||
method public static java.lang.String getTreeDocumentId(android.net.Uri);
|
||||
method public static boolean isDocumentUri(android.content.Context, android.net.Uri);
|
||||
method public static android.net.Uri moveDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri, android.net.Uri);
|
||||
method public static boolean removeDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri);
|
||||
method public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String);
|
||||
field public static final java.lang.String EXTRA_ERROR = "error";
|
||||
field public static final java.lang.String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF";
|
||||
@@ -31570,6 +31571,7 @@ package android.provider {
|
||||
field public static final int FLAG_SUPPORTS_COPY = 128; // 0x80
|
||||
field public static final int FLAG_SUPPORTS_DELETE = 4; // 0x4
|
||||
field public static final int FLAG_SUPPORTS_MOVE = 256; // 0x100
|
||||
field public static final int FLAG_SUPPORTS_REMOVE = 2048; // 0x800
|
||||
field public static final int FLAG_SUPPORTS_RENAME = 64; // 0x40
|
||||
field public static final int FLAG_SUPPORTS_THUMBNAIL = 1; // 0x1
|
||||
field public static final int FLAG_SUPPORTS_WRITE = 2; // 0x2
|
||||
@@ -31617,6 +31619,7 @@ package android.provider {
|
||||
method public android.database.Cursor queryRecentDocuments(java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
|
||||
method public abstract android.database.Cursor queryRoots(java.lang.String[]) throws java.io.FileNotFoundException;
|
||||
method public android.database.Cursor querySearchDocuments(java.lang.String, java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
|
||||
method public boolean removeDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
|
||||
method public java.lang.String renameDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
|
||||
method public final void revokeDocumentPermission(java.lang.String);
|
||||
method public final int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
|
||||
|
||||
@@ -33444,6 +33444,7 @@ package android.provider {
|
||||
method public static java.lang.String getTreeDocumentId(android.net.Uri);
|
||||
method public static boolean isDocumentUri(android.content.Context, android.net.Uri);
|
||||
method public static android.net.Uri moveDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri, android.net.Uri);
|
||||
method public static boolean removeDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri);
|
||||
method public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String);
|
||||
field public static final java.lang.String EXTRA_ERROR = "error";
|
||||
field public static final java.lang.String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF";
|
||||
@@ -33469,6 +33470,7 @@ package android.provider {
|
||||
field public static final int FLAG_SUPPORTS_COPY = 128; // 0x80
|
||||
field public static final int FLAG_SUPPORTS_DELETE = 4; // 0x4
|
||||
field public static final int FLAG_SUPPORTS_MOVE = 256; // 0x100
|
||||
field public static final int FLAG_SUPPORTS_REMOVE = 2048; // 0x800
|
||||
field public static final int FLAG_SUPPORTS_RENAME = 64; // 0x40
|
||||
field public static final int FLAG_SUPPORTS_THUMBNAIL = 1; // 0x1
|
||||
field public static final int FLAG_SUPPORTS_WRITE = 2; // 0x2
|
||||
@@ -33516,6 +33518,7 @@ package android.provider {
|
||||
method public android.database.Cursor queryRecentDocuments(java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
|
||||
method public abstract android.database.Cursor queryRoots(java.lang.String[]) throws java.io.FileNotFoundException;
|
||||
method public android.database.Cursor querySearchDocuments(java.lang.String, java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
|
||||
method public boolean removeDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
|
||||
method public java.lang.String renameDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
|
||||
method public final void revokeDocumentPermission(java.lang.String);
|
||||
method public final int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
|
||||
|
||||
@@ -31558,6 +31558,7 @@ package android.provider {
|
||||
method public static java.lang.String getTreeDocumentId(android.net.Uri);
|
||||
method public static boolean isDocumentUri(android.content.Context, android.net.Uri);
|
||||
method public static android.net.Uri moveDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri, android.net.Uri);
|
||||
method public static boolean removeDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri);
|
||||
method public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String);
|
||||
field public static final java.lang.String EXTRA_ERROR = "error";
|
||||
field public static final java.lang.String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF";
|
||||
@@ -31583,6 +31584,7 @@ package android.provider {
|
||||
field public static final int FLAG_SUPPORTS_COPY = 128; // 0x80
|
||||
field public static final int FLAG_SUPPORTS_DELETE = 4; // 0x4
|
||||
field public static final int FLAG_SUPPORTS_MOVE = 256; // 0x100
|
||||
field public static final int FLAG_SUPPORTS_REMOVE = 2048; // 0x800
|
||||
field public static final int FLAG_SUPPORTS_RENAME = 64; // 0x40
|
||||
field public static final int FLAG_SUPPORTS_THUMBNAIL = 1; // 0x1
|
||||
field public static final int FLAG_SUPPORTS_WRITE = 2; // 0x2
|
||||
@@ -31630,6 +31632,7 @@ package android.provider {
|
||||
method public android.database.Cursor queryRecentDocuments(java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
|
||||
method public abstract android.database.Cursor queryRoots(java.lang.String[]) throws java.io.FileNotFoundException;
|
||||
method public android.database.Cursor querySearchDocuments(java.lang.String, java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
|
||||
method public boolean removeDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
|
||||
method public java.lang.String renameDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
|
||||
method public final void revokeDocumentPermission(java.lang.String);
|
||||
method public final int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
|
||||
|
||||
@@ -234,6 +234,9 @@ public final class DocumentsContract {
|
||||
* @see #FLAG_DIR_PREFERS_LAST_MODIFIED
|
||||
* @see #FLAG_VIRTUAL_DOCUMENT
|
||||
* @see #FLAG_ARCHIVE
|
||||
* @see #FLAG_SUPPORTS_COPY
|
||||
* @see #FLAG_SUPPORTS_MOVE
|
||||
* @see #FLAG_SUPPORTS_REMOVE
|
||||
*/
|
||||
public static final String COLUMN_FLAGS = "flags";
|
||||
|
||||
@@ -370,6 +373,15 @@ public final class DocumentsContract {
|
||||
*/
|
||||
public static final int FLAG_ARCHIVE = 1 << 10;
|
||||
|
||||
/**
|
||||
* Flag indicating that a document can be removed from a parent.
|
||||
*
|
||||
* @see #COLUMN_FLAGS
|
||||
* @see DocumentsContract#removeDocument(ContentProviderClient, Uri, Uri)
|
||||
* @see DocumentsProvider#removeDocument(String, String)
|
||||
*/
|
||||
public static final int FLAG_SUPPORTS_REMOVE = 1 << 11;
|
||||
|
||||
/**
|
||||
* Flag indicating that document titles should be hidden when viewing
|
||||
* this directory in a larger format grid. For example, a directory
|
||||
@@ -612,6 +624,8 @@ public final class DocumentsContract {
|
||||
public static final String METHOD_MOVE_DOCUMENT = "android:moveDocument";
|
||||
/** {@hide} */
|
||||
public static final String METHOD_IS_CHILD_DOCUMENT = "android:isChildDocument";
|
||||
/** {@hide} */
|
||||
public static final String METHOD_REMOVE_DOCUMENT = "android:removeDocument";
|
||||
|
||||
/** {@hide} */
|
||||
public static final String EXTRA_PARENT_URI = "parentUri";
|
||||
@@ -1203,6 +1217,41 @@ public final class DocumentsContract {
|
||||
return out.getParcelable(DocumentsContract.EXTRA_URI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given document from a parent directory.
|
||||
*
|
||||
* <p>In contrast to {@link #deleteDocument} it requires specifying the parent.
|
||||
* This method is especially useful if the document can be in multiple parents.
|
||||
*
|
||||
* @param documentUri document with {@link Document#FLAG_SUPPORTS_REMOVE}
|
||||
* @param parentDocumentUri parent document of the document to remove.
|
||||
* @return true if the document was removed successfully.
|
||||
*/
|
||||
public static boolean removeDocument(ContentResolver resolver, Uri documentUri,
|
||||
Uri parentDocumentUri) {
|
||||
final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
|
||||
documentUri.getAuthority());
|
||||
try {
|
||||
removeDocument(client, documentUri, parentDocumentUri);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Failed to remove document", e);
|
||||
return false;
|
||||
} finally {
|
||||
ContentProviderClient.releaseQuietly(client);
|
||||
}
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
public static void removeDocument(ContentProviderClient client, Uri documentUri,
|
||||
Uri parentDocumentUri) throws RemoteException {
|
||||
final Bundle in = new Bundle();
|
||||
in.putParcelable(DocumentsContract.EXTRA_URI, documentUri);
|
||||
in.putParcelable(DocumentsContract.EXTRA_PARENT_URI, parentDocumentUri);
|
||||
|
||||
client.call(METHOD_REMOVE_DOCUMENT, null, in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the given image for thumbnail purposes, using any embedded EXIF
|
||||
* thumbnail if available, and providing orientation hints from the parent
|
||||
|
||||
@@ -21,6 +21,7 @@ import static android.provider.DocumentsContract.METHOD_CREATE_DOCUMENT;
|
||||
import static android.provider.DocumentsContract.METHOD_DELETE_DOCUMENT;
|
||||
import static android.provider.DocumentsContract.METHOD_IS_CHILD_DOCUMENT;
|
||||
import static android.provider.DocumentsContract.METHOD_MOVE_DOCUMENT;
|
||||
import static android.provider.DocumentsContract.METHOD_REMOVE_DOCUMENT;
|
||||
import static android.provider.DocumentsContract.METHOD_RENAME_DOCUMENT;
|
||||
import static android.provider.DocumentsContract.buildDocumentUri;
|
||||
import static android.provider.DocumentsContract.buildDocumentUriMaybeUsingTree;
|
||||
@@ -300,6 +301,25 @@ public abstract class DocumentsProvider extends ContentProvider {
|
||||
throws FileNotFoundException {
|
||||
throw new UnsupportedOperationException("Move not supported");
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the requested document or a document tree.
|
||||
*
|
||||
* <p>In contrast to {@link #deleteDocument} it requires specifying the parent.
|
||||
* This method is especially useful if the document can be in multiple parents.
|
||||
*
|
||||
* <p>It's the responsibility of the provider to revoke grants if the document is
|
||||
* removed from the last parent, and effectively the document is deleted.
|
||||
*
|
||||
* @param documentId the document to remove.
|
||||
* @param parentDocumentId the parent of the document to move.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public boolean removeDocument(String documentId, String parentDocumentId)
|
||||
throws FileNotFoundException {
|
||||
throw new UnsupportedOperationException("Remove not supported");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all roots currently provided. To display to users, you must define
|
||||
* at least one root. You should avoid making network requests to keep this
|
||||
@@ -822,6 +842,17 @@ public abstract class DocumentsProvider extends ContentProvider {
|
||||
// Original document no longer exists, clean up any grants.
|
||||
revokeDocumentPermission(documentId);
|
||||
|
||||
} else if (METHOD_REMOVE_DOCUMENT.equals(method)) {
|
||||
final Uri parentSourceUri = extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI);
|
||||
final String parentSourceId = DocumentsContract.getDocumentId(parentSourceUri);
|
||||
|
||||
enforceReadPermissionInner(parentSourceUri, getCallingPackage(), null);
|
||||
enforceWritePermissionInner(documentUri, getCallingPackage(), null);
|
||||
removeDocument(documentId, parentSourceId);
|
||||
|
||||
// It's responsibility of the provider to revoke any grants, as the document may be
|
||||
// still attached to another parents.
|
||||
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Method not supported " + method);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user