Merge "Update user cache when coming from isAppCloneUserPair()." into sc-dev
diff --git a/src/com/android/providers/media/LocalCallingIdentity.java b/src/com/android/providers/media/LocalCallingIdentity.java
index 60b4e0e..77a4c6b 100644
--- a/src/com/android/providers/media/LocalCallingIdentity.java
+++ b/src/com/android/providers/media/LocalCallingIdentity.java
@@ -130,7 +130,12 @@
} else {
user = UserHandle.getUserHandleForUid(binderUid);
}
- if (!userCache.userSharesMediaWithParent(user)) {
+ // We need to use the cached variant here, because the uncached version may
+ // make a binder transaction, which would cause infinite recursion here.
+ // Using the cached variant is fine, because we shouldn't be getting any binder
+ // requests for this volume before it has been mounted anyway, at which point
+ // we must already know about the new user.
+ if (!userCache.userSharesMediaWithParentCached(user)) {
// It's possible that we got a cross-profile intent from a regular work profile; in
// that case, the request was explicitly targeted at the media database of the owner
// user; reflect that here.
diff --git a/src/com/android/providers/media/util/UserCache.java b/src/com/android/providers/media/util/UserCache.java
index 3db82c4..38d5326 100644
--- a/src/com/android/providers/media/util/UserCache.java
+++ b/src/com/android/providers/media/util/UserCache.java
@@ -117,16 +117,36 @@
/**
* Returns whether the passed in user shares media with its parent (or peer).
+ *
+ * @param user user to check
+ * @return whether the user shares media with its parent
+ */
+ public boolean userSharesMediaWithParent(@NonNull UserHandle user) {
+ if (Process.myUserHandle().equals(user)) {
+ // Early return path - the owner user doesn't have a parent
+ return false;
+ }
+ boolean found = userSharesMediaWithParentCached(user);
+ if (!found) {
+ // Update the cache and try again
+ update();
+ found = userSharesMediaWithParentCached(user);
+ }
+ return found;
+ }
+
+ /**
+ * Returns whether the passed in user shares media with its parent (or peer).
* Note that the value returned here is based on cached data; it relies on
* other callers to keep the user cache up-to-date.
*
* @param user user to check
* @return whether the user shares media with its parent
*/
- public boolean userSharesMediaWithParent(@NonNull UserHandle user) {
+ public boolean userSharesMediaWithParentCached(@NonNull UserHandle user) {
synchronized (mLock) {
// It must be a user that we manage, and not equal to the main user that we run as
- return user != Process.myUserHandle() && mUsers.contains(user);
+ return !Process.myUserHandle().equals(user) && mUsers.contains(user);
}
}
}