Merge "Return to modifying raw /mnt/media_rw paths." into pi-dev am: f7d3e028ae
am: 1394fd25ca
Change-Id: If6904b6dc431dab74e326b75f37b58ee3c99feef
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user