Merge "Return to modifying raw /mnt/media_rw paths." into pi-dev

am: f7d3e028ae

Change-Id: I61692ebdc49233923863ce773bb42a07498551b0
This commit is contained in:
Jeff Sharkey
2018-05-02 14:29:10 -07:00
committed by android-build-merger
3 changed files with 50 additions and 9 deletions

View File

@@ -312,7 +312,7 @@ public class VolumeInfo implements Parcelable {
* {@link android.Manifest.permission#WRITE_MEDIA_STORAGE}. * {@link android.Manifest.permission#WRITE_MEDIA_STORAGE}.
*/ */
public File getInternalPathForUser(int userId) { public File getInternalPathForUser(int userId) {
if (type == TYPE_PUBLIC && !isVisible()) { if (type == TYPE_PUBLIC) {
// TODO: plumb through cleaner path from vold // TODO: plumb through cleaner path from vold
return new File(path.replace("/storage/", "/mnt/media_rw/")); return new File(path.replace("/storage/", "/mnt/media_rw/"));
} else { } else {

View File

@@ -85,6 +85,14 @@ public abstract class FileSystemProvider extends DocumentsProvider {
protected abstract Uri buildNotificationUri(String docId); protected abstract Uri buildNotificationUri(String docId);
/**
* Callback indicating that the given document has been modified. This gives
* the provider a hook to invalidate cached data, such as {@code sdcardfs}.
*/
protected void onDocIdChanged(String docId) {
// Default is no-op
}
@Override @Override
public boolean onCreate() { public boolean onCreate() {
throw new UnsupportedOperationException( throw new UnsupportedOperationException(
@@ -185,6 +193,7 @@ public abstract class FileSystemProvider extends DocumentsProvider {
throw new IllegalStateException("Failed to mkdir " + file); throw new IllegalStateException("Failed to mkdir " + file);
} }
childId = getDocIdForFile(file); childId = getDocIdForFile(file);
onDocIdChanged(childId);
addFolderToMediaStore(getFileForDocId(childId, true)); addFolderToMediaStore(getFileForDocId(childId, true));
} else { } else {
try { try {
@@ -192,6 +201,7 @@ public abstract class FileSystemProvider extends DocumentsProvider {
throw new IllegalStateException("Failed to touch " + file); throw new IllegalStateException("Failed to touch " + file);
} }
childId = getDocIdForFile(file); childId = getDocIdForFile(file);
onDocIdChanged(childId);
} catch (IOException e) { } catch (IOException e) {
throw new IllegalStateException("Failed to touch " + file + ": " + e); throw new IllegalStateException("Failed to touch " + file + ": " + e);
} }
@@ -227,16 +237,20 @@ public abstract class FileSystemProvider extends DocumentsProvider {
final File before = getFileForDocId(docId); final File before = getFileForDocId(docId);
final File after = FileUtils.buildUniqueFile(before.getParentFile(), displayName); final File after = FileUtils.buildUniqueFile(before.getParentFile(), displayName);
final File visibleFileBefore = getFileForDocId(docId, true);
if (!before.renameTo(after)) { if (!before.renameTo(after)) {
throw new IllegalStateException("Failed to rename to " + after); throw new IllegalStateException("Failed to rename to " + after);
} }
final String afterDocId = getDocIdForFile(after); final String afterDocId = getDocIdForFile(after);
moveInMediaStore(visibleFileBefore, getFileForDocId(afterDocId, true)); onDocIdChanged(docId);
onDocIdChanged(afterDocId);
final File beforeVisibleFile = getFileForDocId(docId, true);
final File afterVisibleFile = getFileForDocId(afterDocId, true);
moveInMediaStore(beforeVisibleFile, afterVisibleFile);
if (!TextUtils.equals(docId, afterDocId)) { if (!TextUtils.equals(docId, afterDocId)) {
scanFile(after); scanFile(afterVisibleFile);
return afterDocId; return afterDocId;
} else { } else {
return null; return null;
@@ -259,6 +273,8 @@ public abstract class FileSystemProvider extends DocumentsProvider {
} }
final String docId = getDocIdForFile(after); final String docId = getDocIdForFile(after);
onDocIdChanged(sourceDocumentId);
onDocIdChanged(docId);
moveInMediaStore(visibleFileBefore, getFileForDocId(docId, true)); moveInMediaStore(visibleFileBefore, getFileForDocId(docId, true));
return docId; return docId;
@@ -308,6 +324,7 @@ public abstract class FileSystemProvider extends DocumentsProvider {
throw new IllegalStateException("Failed to delete " + file); throw new IllegalStateException("Failed to delete " + file);
} }
onDocIdChanged(docId);
removeFromMediaStore(visibleFile, isDirectory); removeFromMediaStore(visibleFile, isDirectory);
} }
@@ -418,7 +435,10 @@ public abstract class FileSystemProvider extends DocumentsProvider {
try { try {
// When finished writing, kick off media scanner // When finished writing, kick off media scanner
return ParcelFileDescriptor.open( return ParcelFileDescriptor.open(
file, pfdMode, mHandler, (IOException e) -> scanFile(visibleFile)); file, pfdMode, mHandler, (IOException e) -> {
onDocIdChanged(documentId);
scanFile(visibleFile);
});
} catch (IOException e) { } catch (IOException e) {
throw new FileNotFoundException("Failed to open for writing: " + e); throw new FileNotFoundException("Failed to open for writing: " + e);
} }

View File

@@ -38,6 +38,9 @@ import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Path; import android.provider.DocumentsContract.Path;
import android.provider.DocumentsContract.Root; import android.provider.DocumentsContract.Root;
import android.provider.Settings; import android.provider.Settings;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.DebugUtils; import android.util.DebugUtils;
@@ -360,14 +363,19 @@ public class ExternalStorageProvider extends FileSystemProvider {
@Override @Override
protected File getFileForDocId(String docId, boolean visible) throws FileNotFoundException { protected File getFileForDocId(String docId, boolean visible) throws FileNotFoundException {
return getFileForDocId(docId, visible, true);
}
private File getFileForDocId(String docId, boolean visible, boolean mustExist)
throws FileNotFoundException {
RootInfo root = getRootFromDocId(docId); RootInfo root = getRootFromDocId(docId);
return buildFile(root, docId, visible); return buildFile(root, docId, visible, mustExist);
} }
private Pair<RootInfo, File> resolveDocId(String docId, boolean visible) private Pair<RootInfo, File> resolveDocId(String docId, boolean visible)
throws FileNotFoundException { throws FileNotFoundException {
RootInfo root = getRootFromDocId(docId); RootInfo root = getRootFromDocId(docId);
return Pair.create(root, buildFile(root, docId, visible)); return Pair.create(root, buildFile(root, docId, visible, true));
} }
private RootInfo getRootFromDocId(String docId) throws FileNotFoundException { private RootInfo getRootFromDocId(String docId) throws FileNotFoundException {
@@ -385,7 +393,7 @@ public class ExternalStorageProvider extends FileSystemProvider {
return root; return root;
} }
private File buildFile(RootInfo root, String docId, boolean visible) private File buildFile(RootInfo root, String docId, boolean visible, boolean mustExist)
throws FileNotFoundException { throws FileNotFoundException {
final int splitIndex = docId.indexOf(':', 1); final int splitIndex = docId.indexOf(':', 1);
final String path = docId.substring(splitIndex + 1); final String path = docId.substring(splitIndex + 1);
@@ -398,7 +406,7 @@ public class ExternalStorageProvider extends FileSystemProvider {
target.mkdirs(); target.mkdirs();
} }
target = new File(target, path); target = new File(target, path);
if (!target.exists()) { if (mustExist && !target.exists()) {
throw new FileNotFoundException("Missing file for " + docId + " at " + target); throw new FileNotFoundException("Missing file for " + docId + " at " + target);
} }
return target; return target;
@@ -409,6 +417,19 @@ public class ExternalStorageProvider extends FileSystemProvider {
return DocumentsContract.buildChildDocumentsUri(AUTHORITY, docId); return DocumentsContract.buildChildDocumentsUri(AUTHORITY, docId);
} }
@Override
protected void onDocIdChanged(String docId) {
try {
// Touch the visible path to ensure that any sdcardfs caches have
// been updated to reflect underlying changes on disk.
final File visiblePath = getFileForDocId(docId, true, false);
if (visiblePath != null) {
Os.access(visiblePath.getAbsolutePath(), OsConstants.F_OK);
}
} catch (FileNotFoundException | ErrnoException ignored) {
}
}
@Override @Override
public Cursor queryRoots(String[] projection) throws FileNotFoundException { public Cursor queryRoots(String[] projection) throws FileNotFoundException {
final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection)); final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection));