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

Commit b2fe21ee authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Update the database for file operations in FileSystemProvider"

parents bf0b3284 69e1ad70
Loading
Loading
Loading
Loading
+21 −43
Original line number Original line Diff line number Diff line
@@ -20,15 +20,14 @@ import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.ContentResolver;
import android.content.Context;
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;
import android.net.Uri;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.CancellationSignal;
import android.os.FileObserver;
import android.os.FileObserver;
@@ -39,7 +38,6 @@ 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;
@@ -66,6 +64,7 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.LinkedList;
import java.util.List;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Predicate;
import java.util.function.Predicate;
@@ -271,8 +270,7 @@ public abstract class FileSystemProvider extends DocumentsProvider {
                throw new IllegalStateException("Failed to touch " + file + ": " + e);
                throw new IllegalStateException("Failed to touch " + file + ": " + e);
            }
            }
        }
        }
        MediaStore.scanFile(getContext().getContentResolver(), file);
        updateMediaStore(getContext(), file);

        return childId;
        return childId;
    }
    }


@@ -295,7 +293,9 @@ public abstract class FileSystemProvider extends DocumentsProvider {
        onDocIdChanged(afterDocId);
        onDocIdChanged(afterDocId);


        final File afterVisibleFile = getFileForDocId(afterDocId, true);
        final File afterVisibleFile = getFileForDocId(afterDocId, true);
        moveInMediaStore(beforeVisibleFile, afterVisibleFile);

        updateMediaStore(getContext(), beforeVisibleFile);
        updateMediaStore(getContext(), afterVisibleFile);


        if (!TextUtils.equals(docId, afterDocId)) {
        if (!TextUtils.equals(docId, afterDocId)) {
            return afterDocId;
            return afterDocId;
@@ -323,17 +323,23 @@ public abstract class FileSystemProvider extends DocumentsProvider {
        onDocIdChanged(sourceDocumentId);
        onDocIdChanged(sourceDocumentId);
        onDocIdDeleted(sourceDocumentId);
        onDocIdDeleted(sourceDocumentId);
        onDocIdChanged(docId);
        onDocIdChanged(docId);
        moveInMediaStore(visibleFileBefore, getFileForDocId(docId, true));
        // update the database

        updateMediaStore(getContext(), visibleFileBefore);
        updateMediaStore(getContext(), getFileForDocId(docId, true));
        return docId;
        return docId;
    }
    }


    private void moveInMediaStore(@Nullable File oldVisibleFile, @Nullable File newVisibleFile) {
    private static void updateMediaStore(@NonNull Context context, File file) {
        if (oldVisibleFile != null) {
        if (file != null) {
            MediaStore.scanFile(getContext().getContentResolver(), oldVisibleFile);
            final ContentResolver resolver = context.getContentResolver();
            final String noMedia = ".nomedia";
            // For file, check whether the file name is .nomedia or not.
            // If yes, scan the parent directory to update all files in the directory.
            if (!file.isDirectory() && file.getName().toLowerCase(Locale.ROOT).endsWith(noMedia)) {
                MediaStore.scanFile(resolver, file.getParentFile());
            } else {
                MediaStore.scanFile(resolver, file);
            }
            }
        if (newVisibleFile != null) {
            MediaStore.scanFile(getContext().getContentResolver(), newVisibleFile);
        }
        }
    }
    }


@@ -354,35 +360,7 @@ public abstract class FileSystemProvider extends DocumentsProvider {


        onDocIdChanged(docId);
        onDocIdChanged(docId);
        onDocIdDeleted(docId);
        onDocIdDeleted(docId);
        removeFromMediaStore(visibleFile);
        updateMediaStore(getContext(), visibleFile);
    }

    private void removeFromMediaStore(@Nullable File visibleFile)
            throws FileNotFoundException {
        // visibleFolder is null if we're removing a document from external thumb drive or SD card.
        if (visibleFile != null) {
            final long token = Binder.clearCallingIdentity();

            try {
                final ContentResolver resolver = getContext().getContentResolver();
                final Uri externalUri = MediaStore.Files.getContentUri("external");
                final Bundle queryArgs = new Bundle();
                queryArgs.putInt(MediaStore.QUERY_ARG_MATCH_PENDING, MediaStore.MATCH_INCLUDE);

                // Remove the media store entry corresponding to visibleFile and if it is a
                // directory, also remove media store entries for any files inside this directory.
                // Logic borrowed from com.android.providers.media.scan.ModernMediaScanner.
                final String pathEscapedForLike = DatabaseUtils.escapeForLike(
                        visibleFile.getAbsolutePath());
                ContentResolver.includeSqlSelectionArgs(queryArgs,
                        FileColumns.DATA + " LIKE ? ESCAPE '\\' OR "
                                + FileColumns.DATA + " LIKE ? ESCAPE '\\'",
                        new String[] {pathEscapedForLike + "/%", pathEscapedForLike});
                resolver.delete(externalUri, queryArgs);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }
    }
    }


    @Override
    @Override