Update path in MediaStore when moving/renaming a file/folder.

Also fix a bug that doesn't trigger directory specific update for
removal.

Test: Manual tests.
Bug: 31001477
Change-Id: Ibae8a7aa5c72c82dc5e3cb4951fbc91ea6456964
(cherry picked from commit c574ec40640d83dfbbb0f022103c6dfa774bca40)
This commit is contained in:
Garfield Tan
2017-03-10 15:38:15 -08:00
parent 7d754b150f
commit 9bd2f6c990

View File

@@ -18,6 +18,7 @@ package com.android.internal.content;
import android.annotation.CallSuper;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
@@ -157,10 +158,9 @@ public abstract class FileSystemProvider extends DocumentsProvider {
if (!before.renameTo(after)) {
throw new IllegalStateException("Failed to rename to " + after);
}
removeFromMediaStore(visibleFileBefore);
final String afterDocId = getDocIdForFile(after);
scanFile(getFileForDocId(afterDocId, true));
moveInMediaStore(visibleFileBefore, getFileForDocId(afterDocId, true));
if (!TextUtils.equals(docId, afterDocId)) {
return afterDocId;
@@ -169,22 +169,6 @@ public abstract class FileSystemProvider extends DocumentsProvider {
}
}
@Override
public void deleteDocument(String docId) throws FileNotFoundException {
final File file = getFileForDocId(docId);
final File visibleFile = getFileForDocId(docId, true);
final boolean isDirectory = file.isDirectory();
if (isDirectory) {
FileUtils.deleteContents(file);
}
if (!file.delete()) {
throw new IllegalStateException("Failed to delete " + file);
}
removeFromMediaStore(visibleFile);
}
@Override
public String moveDocument(String sourceDocumentId, String sourceParentDocumentId,
String targetParentDocumentId)
@@ -200,22 +184,56 @@ public abstract class FileSystemProvider extends DocumentsProvider {
throw new IllegalStateException("Failed to move to " + after);
}
// Notify media store to update its content
removeFromMediaStore(visibleFileBefore);
final String docId = getDocIdForFile(after);
scanFile(getFileForDocId(docId, true));
moveInMediaStore(visibleFileBefore, getFileForDocId(docId, true));
return docId;
}
private void removeFromMediaStore(File visibleFile) throws FileNotFoundException {
private void moveInMediaStore(File oldVisibleFile, File newVisibleFile) {
if (newVisibleFile != null) {
final ContentResolver resolver = getContext().getContentResolver();
final Uri externalUri = MediaStore.Files.getContentUri("external");
ContentValues values = new ContentValues();
values.put(MediaStore.Files.FileColumns.DATA, newVisibleFile.getAbsolutePath());
// Logic borrowed from MtpDatabase.
// note - we are relying on a special case in MediaProvider.update() to update
// the paths for all children in the case where this is a directory.
final String path = oldVisibleFile.getAbsolutePath();
resolver.update(externalUri,
values,
"_data LIKE ? AND lower(_data)=lower(?)",
new String[] { path, path });
}
}
@Override
public void deleteDocument(String docId) throws FileNotFoundException {
final File file = getFileForDocId(docId);
final File visibleFile = getFileForDocId(docId, true);
final boolean isDirectory = file.isDirectory();
if (isDirectory) {
FileUtils.deleteContents(file);
}
if (!file.delete()) {
throw new IllegalStateException("Failed to delete " + file);
}
removeFromMediaStore(visibleFile, isDirectory);
}
private void removeFromMediaStore(File visibleFile, boolean isFolder)
throws FileNotFoundException {
if (visibleFile != null) {
final ContentResolver resolver = getContext().getContentResolver();
final Uri externalUri = MediaStore.Files.getContentUri("external");
// Remove media store entries for any files inside this directory, using
// path prefix match. Logic borrowed from MtpDatabase.
if (visibleFile.isDirectory()) {
if (isFolder) {
final String path = visibleFile.getAbsolutePath() + "/";
resolver.delete(externalUri,
"_data LIKE ?1 AND lower(substr(_data,1,?2))=lower(?3)",