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

Commit 49cf50ae authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Include pending media as well when deleting mediastore entries." into...

Merge "Include pending media as well when deleting mediastore entries." into rvc-dev am: 442399b1 am: 377d13b3

Change-Id: I63d31dfc947892f674b5c4ff775618bde046f3b2
parents e09b0f86 377d13b3
Loading
Loading
Loading
Loading
+12 −0
Original line number Original line Diff line number Diff line
@@ -3827,6 +3827,18 @@ public abstract class ContentResolver implements ContentInterface {
        return queryArgs;
        return queryArgs;
    }
    }


    /** @hide */
    public static @NonNull Bundle includeSqlSelectionArgs(@NonNull Bundle queryArgs,
            @Nullable String selection, @Nullable String[] selectionArgs) {
        if (selection != null) {
            queryArgs.putString(QUERY_ARG_SQL_SELECTION, selection);
        }
        if (selectionArgs != null) {
            queryArgs.putStringArray(QUERY_ARG_SQL_SELECTION_ARGS, selectionArgs);
        }
        return queryArgs;
    }

    /**
    /**
     * Returns structured sort args formatted as an SQL sort clause.
     * Returns structured sort args formatted as an SQL sort clause.
     *
     *
+21 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package android.database;
package android.database;


import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ContentValues;
import android.content.ContentValues;
@@ -1548,4 +1549,24 @@ public class DatabaseUtils {
        }
        }
        return -1;
        return -1;
    }
    }

    /**
     * Escape the given argument for use in a {@code LIKE} statement.
     * @hide
     */
    public static String escapeForLike(@NonNull String arg) {
        // Shamelessly borrowed from com.android.providers.media.util.DatabaseUtils
        final StringBuilder sb = new StringBuilder();
        for (int i = 0; i < arg.length(); i++) {
            final char c = arg.charAt(i);
            switch (c) {
                case '%': sb.append('\\');
                    break;
                case '_': sb.append('\\');
                    break;
            }
            sb.append(c);
        }
        return sb.toString();
    }
}
}
+20 −18
Original line number Original line Diff line number Diff line
@@ -23,6 +23,7 @@ import android.content.ContentResolver;
import android.content.Intent;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.MatrixCursor;
import android.database.MatrixCursor;
import android.database.MatrixCursor.RowBuilder;
import android.database.MatrixCursor.RowBuilder;
import android.graphics.Point;
import android.graphics.Point;
@@ -38,6 +39,7 @@ import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsProvider;
import android.provider.DocumentsProvider;
import android.provider.MediaStore;
import android.provider.MediaStore;
import android.provider.MediaStore.Files.FileColumns;
import android.provider.MetadataReader;
import android.provider.MetadataReader;
import android.system.Int64Ref;
import android.system.Int64Ref;
import android.text.TextUtils;
import android.text.TextUtils;
@@ -333,15 +335,17 @@ public abstract class FileSystemProvider extends DocumentsProvider {
        if (isDirectory) {
        if (isDirectory) {
            FileUtils.deleteContents(file);
            FileUtils.deleteContents(file);
        }
        }
        if (!file.delete()) {
        // We could be deleting pending media which doesn't have any content yet, so only throw
        // if the file exists and we fail to delete it.
        if (file.exists() && !file.delete()) {
            throw new IllegalStateException("Failed to delete " + file);
            throw new IllegalStateException("Failed to delete " + file);
        }
        }


        onDocIdChanged(docId);
        onDocIdChanged(docId);
        removeFromMediaStore(visibleFile, isDirectory);
        removeFromMediaStore(visibleFile);
    }
    }


    private void removeFromMediaStore(@Nullable File visibleFile, boolean isFolder)
    private void removeFromMediaStore(@Nullable File visibleFile)
            throws FileNotFoundException {
            throws FileNotFoundException {
        // visibleFolder is null if we're removing a document from external thumb drive or SD card.
        // visibleFolder is null if we're removing a document from external thumb drive or SD card.
        if (visibleFile != null) {
        if (visibleFile != null) {
@@ -350,21 +354,19 @@ public abstract class FileSystemProvider extends DocumentsProvider {
            try {
            try {
                final ContentResolver resolver = getContext().getContentResolver();
                final ContentResolver resolver = getContext().getContentResolver();
                final Uri externalUri = MediaStore.Files.getContentUri("external");
                final Uri externalUri = MediaStore.Files.getContentUri("external");

                final Bundle queryArgs = new Bundle();
                // Remove media store entries for any files inside this directory, using
                queryArgs.putInt(MediaStore.QUERY_ARG_MATCH_PENDING, MediaStore.MATCH_INCLUDE);
                // path prefix match. Logic borrowed from MtpDatabase.

                if (isFolder) {
                // Remove the media store entry corresponding to visibleFile and if it is a
                    final String path = visibleFile.getAbsolutePath() + "/";
                // directory, also remove media store entries for any files inside this directory.
                    resolver.delete(externalUri,
                // Logic borrowed from com.android.providers.media.scan.ModernMediaScanner.
                            "_data LIKE ?1 AND lower(substr(_data,1,?2))=lower(?3)",
                final String pathEscapedForLike = DatabaseUtils.escapeForLike(
                            new String[]{path + "%", Integer.toString(path.length()), path});
                        visibleFile.getAbsolutePath());
                }
                ContentResolver.includeSqlSelectionArgs(queryArgs,

                        FileColumns.DATA + " LIKE ? ESCAPE '\\' OR "
                // Remove media store entry for this exact file.
                                + FileColumns.DATA + " LIKE ? ESCAPE '\\'",
                final String path = visibleFile.getAbsolutePath();
                        new String[] {pathEscapedForLike + "/%", pathEscapedForLike});
                resolver.delete(externalUri,
                resolver.delete(externalUri, queryArgs);
                        "_data LIKE ?1 AND lower(_data)=lower(?2)",
                        new String[]{path, path});
            } finally {
            } finally {
                Binder.restoreCallingIdentity(token);
                Binder.restoreCallingIdentity(token);
            }
            }