Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d46ecbcc authored by Tomasz Mikolajewski's avatar Tomasz Mikolajewski
Browse files

Add support for multi-parents to DocumentsProvider::moveDocument.

Bug: 26481380
Change-Id: I96290268fd49072a334bde9c04c5313de8540f56
parent e7695829
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -342,8 +342,8 @@ public final class DocumentsContract {
         * within the same document provider.
         *
         * @see #COLUMN_FLAGS
         * @see DocumentsContract#moveDocument(ContentProviderClient, Uri, Uri)
         * @see DocumentsProvider#moveDocument(String, String)
         * @see DocumentsContract#moveDocument(ContentProviderClient, Uri, Uri, Uri)
         * @see DocumentsProvider#moveDocument(String, String, String)
         */
        public static final int FLAG_SUPPORTS_MOVE = 1 << 8;

@@ -613,6 +613,8 @@ public final class DocumentsContract {
    /** {@hide} */
    public static final String METHOD_IS_CHILD_DOCUMENT = "android:isChildDocument";

    /** {@hide} */
    public static final String EXTRA_PARENT_URI = "parentUri";
    /** {@hide} */
    public static final String EXTRA_URI = "uri";

@@ -1170,17 +1172,19 @@ public final class DocumentsContract {
     * Moves the given document under a new parent.
     *
     * @param sourceDocumentUri document with {@link Document#FLAG_SUPPORTS_MOVE}
     * @param sourceParentDocumentUri parent document of the document to move.
     * @param targetParentDocumentUri document which will become a new parent of the source
     *         document.
     * @return the moved document, or {@code null} if failed.
     * @hide
     */
    public static Uri moveDocument(ContentResolver resolver, Uri sourceDocumentUri,
            Uri targetParentDocumentUri) {
            Uri sourceParentDocumentUri, Uri targetParentDocumentUri) {
        final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
                sourceDocumentUri.getAuthority());
        try {
            return moveDocument(client, sourceDocumentUri, targetParentDocumentUri);
            return moveDocument(client, sourceParentDocumentUri, sourceDocumentUri,
                    targetParentDocumentUri);
        } catch (Exception e) {
            Log.w(TAG, "Failed to move document", e);
            return null;
@@ -1191,9 +1195,10 @@ public final class DocumentsContract {

    /** {@hide} */
    public static Uri moveDocument(ContentProviderClient client, Uri sourceDocumentUri,
            Uri targetParentDocumentUri) throws RemoteException {
            Uri sourceParentDocumentUri, Uri targetParentDocumentUri) throws RemoteException {
        final Bundle in = new Bundle();
        in.putParcelable(DocumentsContract.EXTRA_URI, sourceDocumentUri);
        in.putParcelable(DocumentsContract.EXTRA_PARENT_URI, sourceParentDocumentUri);
        in.putParcelable(DocumentsContract.EXTRA_TARGET_URI, targetParentDocumentUri);

        final Bundle out = client.call(METHOD_MOVE_DOCUMENT, null, in);
+11 −6
Original line number Diff line number Diff line
@@ -289,12 +289,14 @@ public abstract class DocumentsProvider extends ContentProvider {
     * be returned.
     *
     * @param sourceDocumentId the document to move.
     * @param sourceParentDocumentId the parent of the document to move.
     * @param targetParentDocumentId the target document to be a new parent of the
     *     source document.
     * @hide
     */
    @SuppressWarnings("unused")
    public String moveDocument(String sourceDocumentId, String targetParentDocumentId)
    public String moveDocument(String sourceDocumentId, String sourceParentDocumentId,
            String targetParentDocumentId)
            throws FileNotFoundException {
        throw new UnsupportedOperationException("Move not supported");
    }
@@ -759,7 +761,7 @@ public abstract class DocumentsProvider extends ContentProvider {

                out.putParcelable(DocumentsContract.EXTRA_URI, newDocumentUri);

                // Original document no longer exists, clean up any grants
                // Original document no longer exists, clean up any grants.
                revokeDocumentPermission(documentId);
            }

@@ -767,7 +769,7 @@ public abstract class DocumentsProvider extends ContentProvider {
            enforceWritePermissionInner(documentUri, getCallingPackage(), null);
            deleteDocument(documentId);

            // Document no longer exists, clean up any grants
            // Document no longer exists, clean up any grants.
            revokeDocumentPermission(documentId);

        } else if (METHOD_COPY_DOCUMENT.equals(method)) {
@@ -793,13 +795,16 @@ public abstract class DocumentsProvider extends ContentProvider {
            }

        } else if (METHOD_MOVE_DOCUMENT.equals(method)) {
            final Uri parentSourceUri = extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI);
            final String parentSourceId = DocumentsContract.getDocumentId(parentSourceUri);
            final Uri targetUri = extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI);
            final String targetId = DocumentsContract.getDocumentId(targetUri);

            enforceReadPermissionInner(documentUri, getCallingPackage(), null);
            enforceWritePermissionInner(documentUri, getCallingPackage(), null);
            enforceReadPermissionInner(parentSourceUri, getCallingPackage(), null);
            enforceWritePermissionInner(targetUri, getCallingPackage(), null);

            final String newDocumentId = moveDocument(documentId, targetId);
            final String newDocumentId = moveDocument(documentId, parentSourceId, targetId);

            if (newDocumentId != null) {
                final Uri newDocumentUri = buildDocumentUriMaybeUsingTree(documentUri,
@@ -814,7 +819,7 @@ public abstract class DocumentsProvider extends ContentProvider {
                out.putParcelable(DocumentsContract.EXTRA_URI, newDocumentUri);
            }

            // Original document no longer exists, clean up any grants
            // Original document no longer exists, clean up any grants.
            revokeDocumentPermission(documentId);

        } else {
+2 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static com.android.documentsui.services.FileOperationService.OPERATION_MO
import android.app.Notification;
import android.app.Notification.Builder;
import android.content.Context;
import android.net.Uri;
import android.os.RemoteException;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
@@ -85,7 +86,7 @@ final class MoveJob extends CopyJob {
        if (src.authority.equals(dest.authority)) {
            if ((src.flags & Document.FLAG_SUPPORTS_MOVE) != 0) {
                if (DocumentsContract.moveDocument(getClient(src), src.derivedUri,
                        dest.derivedUri) == null) {
                        Uri.EMPTY /* Not used yet */, dest.derivedUri) == null) {
                    onFileFailed(src);
                    return false;
                }
+2 −1
Original line number Diff line number Diff line
@@ -463,7 +463,8 @@ public class ExternalStorageProvider extends DocumentsProvider {
    }

    @Override
    public String moveDocument(String sourceDocumentId, String targetParentDocumentId)
    public String moveDocument(String sourceDocumentId, String sourceParentDocumentId,
            String targetParentDocumentId)
            throws FileNotFoundException {
        final File before = getFileForDocId(sourceDocumentId);
        final File after = new File(getFileForDocId(targetParentDocumentId), before.getName());