diff options
author | Garfield Tan <xutan@google.com> | 2017-01-09 18:04:43 -0800 |
---|---|---|
committer | Garfield Tan <xutan@google.com> | 2017-01-09 18:11:34 -0800 |
commit | dc9593e79101012821a03ed5786cef41fc89387f (patch) | |
tree | 1efbf89aeec9e845055085c6d72579f64f1f0fa9 /packages/ExternalStorageProvider/src | |
parent | e7e4998784f6ca4ad8b50ba766e10a2aefaf0ddb (diff) |
Check visible paths as well when generate docId from file system path.
getDocumentUri(String, List<UriPermission>) needs it because MediaStore
can only provide path under visible paths for external SD cards.
Test: Manual test w/ SD card. Relative CTS tests pass. Happy to add
automated tests for SD card cases if somebody shows me how.
Bug: 33819522
Change-Id: I15cdd60a2d2c94275dd661f20b5b0deb0d80d258
Diffstat (limited to 'packages/ExternalStorageProvider/src')
-rw-r--r-- | packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java index 8cf375a47ae6..cbd295e1f85e 100644 --- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java @@ -287,26 +287,23 @@ public class ExternalStorageProvider extends DocumentsProvider { String path = file.getAbsolutePath(); // Find the most-specific root path - String mostSpecificId = null; - String mostSpecificPath = null; - synchronized (mRootsLock) { - for (int i = 0; i < mRoots.size(); i++) { - final String rootId = mRoots.keyAt(i); - final String rootPath = mRoots.valueAt(i).path.getAbsolutePath(); - if (path.startsWith(rootPath) && (mostSpecificPath == null - || rootPath.length() > mostSpecificPath.length())) { - mostSpecificId = rootId; - mostSpecificPath = rootPath; - } - } + boolean visiblePath = false; + RootInfo mostSpecificRoot = getMostSpecificRootForPath(path, false); + + if (mostSpecificRoot == null) { + // Try visible path if no internal path matches. MediaStore uses visible paths. + visiblePath = true; + mostSpecificRoot = getMostSpecificRootForPath(path, true); } - if (mostSpecificPath == null) { + if (mostSpecificRoot == null) { throw new FileNotFoundException("Failed to find root that contains " + path); } // Start at first char of path under root - final String rootPath = mostSpecificPath; + final String rootPath = visiblePath + ? mostSpecificRoot.visiblePath.getAbsolutePath() + : mostSpecificRoot.path.getAbsolutePath(); if (rootPath.equals(path)) { path = ""; } else if (rootPath.endsWith("/")) { @@ -322,7 +319,29 @@ public class ExternalStorageProvider extends DocumentsProvider { } } - return mostSpecificId + ':' + path; + return mostSpecificRoot.rootId + ':' + path; + } + + private RootInfo getMostSpecificRootForPath(String path, boolean visible) { + // Find the most-specific root path + RootInfo mostSpecificRoot = null; + String mostSpecificPath = null; + synchronized (mRootsLock) { + for (int i = 0; i < mRoots.size(); i++) { + final RootInfo root = mRoots.valueAt(i); + final File rootFile = visible ? root.visiblePath : root.path; + if (rootFile != null) { + final String rootPath = rootFile.getAbsolutePath(); + if (path.startsWith(rootPath) && (mostSpecificPath == null + || rootPath.length() > mostSpecificPath.length())) { + mostSpecificRoot = root; + mostSpecificPath = rootPath; + } + } + } + } + + return mostSpecificRoot; } private File getFileForDocId(String docId) throws FileNotFoundException { @@ -519,15 +538,13 @@ public class ExternalStorageProvider extends DocumentsProvider { boolean matchesRequestedDoc = false; if (DocumentsContract.isTreeUri(uri)) { final String parentDocId = DocumentsContract.getTreeDocumentId(uri); - File parentFile = getFileForDocId(parentDocId); - if (FileUtils.contains(parentFile, doc)) { + if (isChildDocument(parentDocId, docId)) { treeUriPermission = uriPermission; matchesRequestedDoc = true; } } else { final String candidateDocId = DocumentsContract.getDocumentId(uri); - final File candidateDoc = getFileForDocId(candidateDocId); - if (Objects.equals(doc.getAbsolutePath(), candidateDoc.getAbsolutePath())) { + if (Objects.equals(docId, candidateDocId)) { docUriPermission = uriPermission; matchesRequestedDoc = true; } |