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}.
*/
public File getInternalPathForUser(int userId) {
if (type == TYPE_PUBLIC && !isVisible()) {
if (type == TYPE_PUBLIC) {
// TODO: plumb through cleaner path from vold
return new File(path.replace("/storage/", "/mnt/media_rw/"));
} else {

View File

@@ -85,6 +85,14 @@ public abstract class FileSystemProvider extends DocumentsProvider {
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
public boolean onCreate() {
throw new UnsupportedOperationException(
@@ -185,6 +193,7 @@ public abstract class FileSystemProvider extends DocumentsProvider {
throw new IllegalStateException("Failed to mkdir " + file);
}
childId = getDocIdForFile(file);
onDocIdChanged(childId);
addFolderToMediaStore(getFileForDocId(childId, true));
} else {
try {
@@ -192,6 +201,7 @@ public abstract class FileSystemProvider extends DocumentsProvider {
throw new IllegalStateException("Failed to touch " + file);
}
childId = getDocIdForFile(file);
onDocIdChanged(childId);
} catch (IOException 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 after = FileUtils.buildUniqueFile(before.getParentFile(), displayName);
final File visibleFileBefore = getFileForDocId(docId, true);
if (!before.renameTo(after)) {
throw new IllegalStateException("Failed to rename to " + 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)) {
scanFile(after);
scanFile(afterVisibleFile);
return afterDocId;
} else {
return null;
@@ -259,6 +273,8 @@ public abstract class FileSystemProvider extends DocumentsProvider {
}
final String docId = getDocIdForFile(after);
onDocIdChanged(sourceDocumentId);
onDocIdChanged(docId);
moveInMediaStore(visibleFileBefore, getFileForDocId(docId, true));
return docId;
@@ -308,6 +324,7 @@ public abstract class FileSystemProvider extends DocumentsProvider {
throw new IllegalStateException("Failed to delete " + file);
}
onDocIdChanged(docId);
removeFromMediaStore(visibleFile, isDirectory);
}
@@ -418,7 +435,10 @@ public abstract class FileSystemProvider extends DocumentsProvider {
try {
// When finished writing, kick off media scanner
return ParcelFileDescriptor.open(
file, pfdMode, mHandler, (IOException e) -> scanFile(visibleFile));
file, pfdMode, mHandler, (IOException e) -> {
onDocIdChanged(documentId);
scanFile(visibleFile);
});
} catch (IOException 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.Root;
import android.provider.Settings;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.DebugUtils;
@@ -360,14 +363,19 @@ public class ExternalStorageProvider extends FileSystemProvider {
@Override
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);
return buildFile(root, docId, visible);
return buildFile(root, docId, visible, mustExist);
}
private Pair<RootInfo, File> resolveDocId(String docId, boolean visible)
throws FileNotFoundException {
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 {
@@ -385,7 +393,7 @@ public class ExternalStorageProvider extends FileSystemProvider {
return root;
}
private File buildFile(RootInfo root, String docId, boolean visible)
private File buildFile(RootInfo root, String docId, boolean visible, boolean mustExist)
throws FileNotFoundException {
final int splitIndex = docId.indexOf(':', 1);
final String path = docId.substring(splitIndex + 1);
@@ -398,7 +406,7 @@ public class ExternalStorageProvider extends FileSystemProvider {
target.mkdirs();
}
target = new File(target, path);
if (!target.exists()) {
if (mustExist && !target.exists()) {
throw new FileNotFoundException("Missing file for " + docId + " at " + target);
}
return target;
@@ -409,6 +417,19 @@ public class ExternalStorageProvider extends FileSystemProvider {
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
public Cursor queryRoots(String[] projection) throws FileNotFoundException {
final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection));