From d5a13b9d63b30718d84bc67bd836361346fc68af Mon Sep 17 00:00:00 2001 From: Jackal Guo Date: Mon, 1 Feb 2021 10:26:48 +0800 Subject: [PATCH] Invalidate cached result of getPackagesForUid In order to reduce repeating binder call, there is an optimization to cache the query result of getPackagesForUid. However, the cached result don't update while granting package visibility temporarily. Bug: 167656333 Bug: 178980212 Test: atest CtsAppEnumerationTestCases Change-Id: I35e80c89f749c5aa288689275e78580610eecb46 --- .../com/android/server/pm/AppsFilter.java | 41 ++++++++++--------- .../android/server/pm/InstantAppRegistry.java | 22 +++++++--- .../server/pm/PackageManagerService.java | 8 +++- 3 files changed, 45 insertions(+), 26 deletions(-) diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java index f8990c0653413..5d7c41c7b08f3 100644 --- a/services/core/java/com/android/server/pm/AppsFilter.java +++ b/services/core/java/com/android/server/pm/AppsFilter.java @@ -588,29 +588,32 @@ public class AppsFilter implements Watchable, Snappable { * * @param recipientUid the uid gaining visibility of the {@code visibleUid}. * @param visibleUid the uid becoming visible to the {@recipientUid} + * @return {@code true} if implicit access was not already granted. */ - public void grantImplicitAccess(int recipientUid, int visibleUid) { - if (recipientUid != visibleUid) { - final boolean changed = mImplicitlyQueryable.add(recipientUid, visibleUid); - if (changed && DEBUG_LOGGING) { - Slog.i(TAG, "implicit access granted: " + recipientUid + " -> " + visibleUid); - } - synchronized (mCacheLock) { - if (mShouldFilterCache != null) { - // update the cache in a one-off manner since we've got all the information we - // need. - SparseBooleanArray visibleUids = mShouldFilterCache.get(recipientUid); - if (visibleUids == null) { - visibleUids = new SparseBooleanArray(); - mShouldFilterCache.put(recipientUid, visibleUids); - } - visibleUids.put(visibleUid, false); + public boolean grantImplicitAccess(int recipientUid, int visibleUid) { + if (recipientUid == visibleUid) { + return false; + } + final boolean changed = mImplicitlyQueryable.add(recipientUid, visibleUid); + if (changed && DEBUG_LOGGING) { + Slog.i(TAG, "implicit access granted: " + recipientUid + " -> " + visibleUid); + } + synchronized (mCacheLock) { + if (mShouldFilterCache != null) { + // update the cache in a one-off manner since we've got all the information we + // need. + SparseBooleanArray visibleUids = mShouldFilterCache.get(recipientUid); + if (visibleUids == null) { + visibleUids = new SparseBooleanArray(); + mShouldFilterCache.put(recipientUid, visibleUids); } - } - if (changed) { - onChanged(); + visibleUids.put(visibleUid, false); } } + if (changed) { + onChanged(); + } + return changed; } public void onSystemReady() { diff --git a/services/core/java/com/android/server/pm/InstantAppRegistry.java b/services/core/java/com/android/server/pm/InstantAppRegistry.java index c3bca285dca32..15e1d5281bfad 100644 --- a/services/core/java/com/android/server/pm/InstantAppRegistry.java +++ b/services/core/java/com/android/server/pm/InstantAppRegistry.java @@ -470,23 +470,34 @@ class InstantAppRegistry implements Watchable, Snappable { return instantGrantList.get(instantAppId); } + /** + * Allows an app to see an instant app. + * + * @param userId the userId in which this access is being granted + * @param intent when provided, this serves as the intent that caused + * this access to be granted + * @param recipientUid the uid of the app receiving visibility + * @param instantAppId the app ID of the instant app being made visible + * to the recipient + * @return {@code true} if access is granted. + */ @GuardedBy("mService.mLock") - public void grantInstantAccessLPw(@UserIdInt int userId, @Nullable Intent intent, + public boolean grantInstantAccessLPw(@UserIdInt int userId, @Nullable Intent intent, int recipientUid, int instantAppId) { if (mInstalledInstantAppUids == null) { - return; // no instant apps installed; no need to grant + return false; // no instant apps installed; no need to grant } WatchedSparseBooleanArray instantAppList = mInstalledInstantAppUids.get(userId); if (instantAppList == null || !instantAppList.get(instantAppId)) { - return; // instant app id isn't installed; no need to grant + return false; // instant app id isn't installed; no need to grant } if (instantAppList.get(recipientUid)) { - return; // target app id is an instant app; no need to grant + return false; // target app id is an instant app; no need to grant } if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction())) { final Set categories = intent.getCategories(); if (categories != null && categories.contains(Intent.CATEGORY_BROWSABLE)) { - return; // launched via VIEW/BROWSABLE intent; no need to grant + return false; // launched via VIEW/BROWSABLE intent; no need to grant } } WatchedSparseArray targetAppList = mInstantGrants.get(userId); @@ -500,6 +511,7 @@ class InstantAppRegistry implements Watchable, Snappable { targetAppList.put(recipientUid, instantGrantList); } instantGrantList.put(instantAppId, true /*granted*/); + return true; } @GuardedBy("mService.mLock") diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index f68113d5520ab..0cb6247631740 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -27187,6 +27187,7 @@ public class PackageManagerService extends IPackageManager.Stub final boolean instantApp = isInstantAppInternal(visiblePackage.getPackageName(), userId, visibleUid); + final boolean accessGranted; if (instantApp) { if (!direct) { // if the interaction that lead to this granting access to an instant app @@ -27194,10 +27195,13 @@ public class PackageManagerService extends IPackageManager.Stub // grant. return; } - mInstantAppRegistry.grantInstantAccessLPw(userId, intent, + accessGranted = mInstantAppRegistry.grantInstantAccessLPw(userId, intent, recipientAppId, UserHandle.getAppId(visibleUid) /*instantAppId*/); } else { - mAppsFilter.grantImplicitAccess(recipientUid, visibleUid); + accessGranted = mAppsFilter.grantImplicitAccess(recipientUid, visibleUid); + } + if (accessGranted) { + ApplicationPackageManager.invalidateGetPackagesForUidCache(); } } }