Loading core/java/android/os/storage/VolumeInfo.java +1 −1 Original line number Diff line number Diff line Loading @@ -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 { Loading core/java/com/android/internal/content/FileSystemProvider.java +24 −4 Original line number Diff line number Diff line Loading @@ -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( Loading Loading @@ -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 { Loading @@ -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); } Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -308,6 +324,7 @@ public abstract class FileSystemProvider extends DocumentsProvider { throw new IllegalStateException("Failed to delete " + file); } onDocIdChanged(docId); removeFromMediaStore(visibleFile, isDirectory); } Loading Loading @@ -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); } Loading packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +25 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 { Loading @@ -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); Loading @@ -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; Loading @@ -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)); Loading Loading
core/java/android/os/storage/VolumeInfo.java +1 −1 Original line number Diff line number Diff line Loading @@ -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 { Loading
core/java/com/android/internal/content/FileSystemProvider.java +24 −4 Original line number Diff line number Diff line Loading @@ -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( Loading Loading @@ -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 { Loading @@ -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); } Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -308,6 +324,7 @@ public abstract class FileSystemProvider extends DocumentsProvider { throw new IllegalStateException("Failed to delete " + file); } onDocIdChanged(docId); removeFromMediaStore(visibleFile, isDirectory); } Loading Loading @@ -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); } Loading
packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +25 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 { Loading @@ -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); Loading @@ -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; Loading @@ -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)); Loading