summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Alex Buynytskyy <alexbuy@google.com> 2020-06-09 20:43:30 -0700
committer Alex Buynytskyy <alexbuy@google.com> 2020-06-17 08:37:35 -0700
commit892ba455ac02e816fc863588f84d44eae7153ed4 (patch)
tree93478b62d557852f3914ee7f920183b806fe52a3
parentb85fc66146dee0c345b56d06994987a56d99c163 (diff)
Defer recomputeComponentVisibility.
Reduces initial packages scan time: 588ms->421ms. Bug: 157191740 Test: adb reboot; adb logcat | grep "Finished scanning system apps" Change-Id: If3425f1ab9a4faf237eb40068190fd4e12521ab6
-rw-r--r--services/core/java/com/android/server/pm/AppsFilter.java51
1 files changed, 33 insertions, 18 deletions
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index ccda5875d9fa..ab6f9e2dccda 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -96,6 +96,14 @@ public class AppsFilter {
private final SparseSetArray<Integer> mQueriesViaComponent = new SparseSetArray<>();
/**
+ * Pending full recompute of mQueriesViaComponent. Occurs when a package adds a new set of
+ * protected broadcast. This in turn invalidates all prior additions and require a very
+ * computationally expensive recomputing.
+ * Full recompute is done lazily at the point when we use mQueriesViaComponent to filter apps.
+ */
+ private boolean mQueriesViaComponentRequireRecompute = false;
+
+ /**
* A set of App IDs that are always queryable by any package, regardless of their manifest
* content.
*/
@@ -278,7 +286,7 @@ public class AppsFilter {
private void updateEnabledState(AndroidPackage pkg) {
// TODO(b/135203078): Do not use toAppInfo
- final boolean enabled = mInjector.getCompatibility().isChangeEnabled(
+ final boolean enabled = mInjector.getCompatibility().isChangeEnabledInternal(
PackageManager.FILTER_APPLICATION_QUERY, pkg.toAppInfoWithoutState());
if (enabled) {
mDisabledPackages.remove(pkg.getPackageName());
@@ -523,9 +531,8 @@ public class AppsFilter {
return;
}
- if (!newPkg.getProtectedBroadcasts().isEmpty()) {
- mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts());
- recomputeComponentVisibility(existingSettings, newPkg.getPackageName());
+ if (mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts())) {
+ mQueriesViaComponentRequireRecompute = true;
}
final boolean newIsForceQueryable =
@@ -550,7 +557,8 @@ public class AppsFilter {
final AndroidPackage existingPkg = existingSetting.pkg;
// let's evaluate the ability of already added packages to see this new package
if (!newIsForceQueryable) {
- if (canQueryViaComponents(existingPkg, newPkg, mProtectedBroadcasts)) {
+ if (!mQueriesViaComponentRequireRecompute && canQueryViaComponents(existingPkg,
+ newPkg, mProtectedBroadcasts)) {
mQueriesViaComponent.add(existingSetting.appId, newPkgSetting.appId);
}
if (canQueryViaPackage(existingPkg, newPkg)
@@ -560,7 +568,8 @@ public class AppsFilter {
}
// now we'll evaluate our new package's ability to see existing packages
if (!mForceQueryable.contains(existingSetting.appId)) {
- if (canQueryViaComponents(newPkg, existingPkg, mProtectedBroadcasts)) {
+ if (!mQueriesViaComponentRequireRecompute && canQueryViaComponents(newPkg,
+ existingPkg, mProtectedBroadcasts)) {
mQueriesViaComponent.add(newPkgSetting.appId, existingSetting.appId);
}
if (canQueryViaPackage(newPkg, existingPkg)
@@ -689,13 +698,11 @@ public class AppsFilter {
return ret;
}
- private void recomputeComponentVisibility(ArrayMap<String, PackageSetting> existingSettings,
- @Nullable String excludePackage) {
+ private void recomputeComponentVisibility(ArrayMap<String, PackageSetting> existingSettings) {
mQueriesViaComponent.clear();
for (int i = existingSettings.size() - 1; i >= 0; i--) {
PackageSetting setting = existingSettings.valueAt(i);
if (setting.pkg == null
- || setting.pkg.getPackageName().equals(excludePackage)
|| mForceQueryable.contains(setting.appId)) {
continue;
}
@@ -704,8 +711,7 @@ public class AppsFilter {
continue;
}
final PackageSetting otherSetting = existingSettings.valueAt(j);
- if (otherSetting.pkg == null
- || otherSetting.pkg.getPackageName().equals(excludePackage)) {
+ if (otherSetting.pkg == null) {
continue;
}
if (canQueryViaComponents(setting.pkg, otherSetting.pkg, mProtectedBroadcasts)) {
@@ -713,6 +719,7 @@ public class AppsFilter {
}
}
}
+ mQueriesViaComponentRequireRecompute = false;
}
/**
@@ -787,9 +794,11 @@ public class AppsFilter {
}
}
- mQueriesViaComponent.remove(setting.appId);
- for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) {
- mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i), setting.appId);
+ if (!mQueriesViaComponentRequireRecompute) {
+ mQueriesViaComponent.remove(setting.appId);
+ for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) {
+ mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i), setting.appId);
+ }
}
mQueriesViaPackage.remove(setting.appId);
for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) {
@@ -810,10 +819,11 @@ public class AppsFilter {
if (!setting.pkg.getProtectedBroadcasts().isEmpty()) {
final String removingPackageName = setting.pkg.getPackageName();
- mProtectedBroadcasts.clear();
- mProtectedBroadcasts.addAll(
- collectProtectedBroadcasts(settings, removingPackageName));
- recomputeComponentVisibility(settings, removingPackageName);
+ final Set<String> protectedBroadcasts = mProtectedBroadcasts;
+ mProtectedBroadcasts = collectProtectedBroadcasts(settings, removingPackageName);
+ if (!mProtectedBroadcasts.containsAll(protectedBroadcasts)) {
+ mQueriesViaComponentRequireRecompute = true;
+ }
}
mOverlayReferenceMapper.removePkg(setting.name);
@@ -1003,6 +1013,11 @@ public class AppsFilter {
}
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaComponent");
+ if (mQueriesViaComponentRequireRecompute) {
+ mStateProvider.runWithState((settings, users) -> {
+ recomputeComponentVisibility(settings);
+ });
+ }
if (mQueriesViaComponent.contains(callingAppId, targetAppId)) {
if (DEBUG_LOGGING) {
log(callingSetting, targetPkgSetting, "queries component");