Allow volume paths from both users when verifying file columns.

assertFileColumnsConsistent() verifies that the value specified in the
DATA column matches up with the path of the volume. When there's
a clone profile, we don't always know whether a volume name like
external_primary refers to the volume of the owner user, or the clone
user. In particular, media scanning may happen in the context of the
owner user, yet it may be scanning a volume of a clone user.

To fix this, just return the paths for all users that we manage.

Bug: 183949139
Test: TEST_MAPPING
Change-Id: If999ac17c3492901a035092d1886c1ee123899c7
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index 5e01c06..283d5a1 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -417,9 +417,21 @@
         return mVolumeCache.getVolumeId(file);
     }
 
-    public @NonNull Collection<File> getVolumeScanPaths(String volumeName)
+    private @NonNull Collection<File> getAllowedVolumePaths(String volumeName)
             throws FileNotFoundException {
-        return mVolumeCache.getVolumeScanPaths(volumeName, mCallingIdentity.get().getUser());
+        // This method is used to verify whether a path belongs to a certain volume name;
+        // we can't always use the calling user's identity here to determine exactly which
+        // volume is meant, because the MediaScanner may scan paths belonging to another user,
+        // eg a clone user.
+        // So, for volumes like external_primary, just return allowed paths for all users.
+        List<UserHandle> users = mUserCache.getUsersCached();
+        ArrayList<File> allowedPaths = new ArrayList<>();
+        for (UserHandle user : users) {
+            Collection<File> volumeScanPaths = mVolumeCache.getVolumeScanPaths(volumeName, user);
+            allowedPaths.addAll(volumeScanPaths);
+        }
+
+        return allowedPaths;
     }
 
     /**
@@ -3489,7 +3501,7 @@
         final String volumeName = resolveVolumeName(uri);
         try {
             // Quick check that the requested path actually lives on volume
-            final Collection<File> allowed = getVolumeScanPaths(volumeName);
+            final Collection<File> allowed = getAllowedVolumePaths(volumeName);
             final File actual = new File(values.getAsString(MediaColumns.DATA))
                     .getCanonicalFile();
             if (!FileUtils.contains(allowed, actual)) {
diff --git a/src/com/android/providers/media/util/UserCache.java b/src/com/android/providers/media/util/UserCache.java
index 885e07e..276e3f8 100644
--- a/src/com/android/providers/media/util/UserCache.java
+++ b/src/com/android/providers/media/util/UserCache.java
@@ -84,6 +84,12 @@
         }
     }
 
+    public @NonNull List<UserHandle> getUsersCached() {
+        synchronized (mLock) {
+            return (List<UserHandle>) mUsers.clone();
+        }
+    }
+
     public @NonNull Context getContextForUser(@NonNull UserHandle user) {
         Context userContext;
         synchronized (mLock) {