summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Evan Severson <evanseverson@google.com> 2024-01-19 17:31:41 -0800
committer Evan Severson <evanseverson@google.com> 2024-02-08 16:15:11 -0800
commitbc6b6fee25a0f3f445834fca17bdcbef638e53ef (patch)
treef29e72df0a940cbccf45b7736dd7c489ac9547d2
parentba33a16569985c34f7ca822ce775ea44c88c77bb (diff)
[AppOps] Remove unwanted UidState objects more quickly
We have more modern ways to query a snapshot of packages on the device, in fact we have already been using this so we can apply it to other work that we do where we need to remove or update UidStates objects that may represent packages that no longer exist or are outdated. Bug: 320850079 Test: Boot and verify improvement in this logcat "SystemServerTiming: PhaseActivityManagerReady took to complete:" Change-Id: Ic4011b8ecb45aee97ca08d85220f6892bd07fa6f
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java208
1 files changed, 101 insertions, 107 deletions
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index fe3617087ec4..4f9526a9d977 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -164,7 +164,6 @@ import com.android.modules.utils.TypedXmlSerializer;
import com.android.server.LocalManagerRegistry;
import com.android.server.LocalServices;
import com.android.server.LockGuard;
-import com.android.server.SystemServerInitThreadPool;
import com.android.server.SystemServiceManager;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
import com.android.server.pm.PackageList;
@@ -1046,69 +1045,8 @@ public class AppOpsService extends IAppOpsService.Stub {
return;
}
- ArrayMap<String, String> dstAttributionTags = new ArrayMap<>();
- ArraySet<String> attributionTags = new ArraySet<>();
- attributionTags.add(null);
- if (pkg.getAttributions() != null) {
- int numAttributions = pkg.getAttributions().size();
- for (int attributionNum = 0; attributionNum < numAttributions;
- attributionNum++) {
- ParsedAttribution attribution = pkg.getAttributions().get(attributionNum);
- attributionTags.add(attribution.getTag());
-
- int numInheritFrom = attribution.getInheritFrom().size();
- for (int inheritFromNum = 0; inheritFromNum < numInheritFrom;
- inheritFromNum++) {
- dstAttributionTags.put(attribution.getInheritFrom().get(inheritFromNum),
- attribution.getTag());
- }
- }
- }
-
synchronized (AppOpsService.this) {
- UidState uidState = mUidStates.get(uid);
- if (uidState == null) {
- return;
- }
-
- Ops ops = uidState.pkgOps.get(pkgName);
- if (ops == null) {
- return;
- }
-
- // Reset cached package properties to re-initialize when needed
- ops.bypass = null;
- ops.knownAttributionTags.clear();
-
- // Merge data collected for removed attributions into their successor
- // attributions
- int numOps = ops.size();
- for (int opNum = 0; opNum < numOps; opNum++) {
- Op op = ops.valueAt(opNum);
- for (int deviceIndex = op.mDeviceAttributedOps.size() - 1; deviceIndex >= 0;
- deviceIndex--) {
- ArrayMap<String, AttributedOp> attributedOps =
- op.mDeviceAttributedOps.valueAt(deviceIndex);
- for (int tagIndex = attributedOps.size() - 1; tagIndex >= 0;
- tagIndex--) {
- String tag = attributedOps.keyAt(tagIndex);
- if (attributionTags.contains(tag)) {
- // attribution still exist after upgrade
- continue;
- }
-
- String newAttributionTag = dstAttributionTags.get(tag);
-
- AttributedOp newAttributedOp = op.getOrCreateAttribution(op,
- newAttributionTag,
- op.mDeviceAttributedOps.keyAt(deviceIndex));
- newAttributedOp.add(attributedOps.get(tag));
- attributedOps.remove(tag);
-
- scheduleFastWriteLocked();
- }
- }
- }
+ refreshAttributionsLocked(pkg, uid);
}
}
}
@@ -1132,41 +1070,6 @@ public class AppOpsService extends IAppOpsService.Stub {
mContext.registerReceiverAsUser(mOnPackageUpdatedReceiver, UserHandle.ALL,
packageUpdateFilter, null, null);
- synchronized (this) {
- for (int uidNum = mUidStates.size() - 1; uidNum >= 0; uidNum--) {
- int uid = mUidStates.keyAt(uidNum);
- UidState uidState = mUidStates.valueAt(uidNum);
-
- String[] pkgsInUid = getPackagesForUid(uidState.uid);
- if (ArrayUtils.isEmpty(pkgsInUid) && uid >= Process.FIRST_APPLICATION_UID) {
- uidState.clear();
- mUidStates.removeAt(uidNum);
- scheduleFastWriteLocked();
- continue;
- }
-
- ArrayMap<String, Ops> pkgs = uidState.pkgOps;
-
- int numPkgs = pkgs.size();
- for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
- String pkg = pkgs.keyAt(pkgNum);
-
- String action;
- if (!ArrayUtils.contains(pkgsInUid, pkg)) {
- action = ACTION_PACKAGE_REMOVED;
- } else {
- action = Intent.ACTION_PACKAGE_REPLACED;
- }
-
- SystemServerInitThreadPool.submit(
- () -> mOnPackageUpdatedReceiver.onReceive(mContext, new Intent(action)
- .setData(Uri.fromParts("package", pkg, null))
- .putExtra(Intent.EXTRA_UID, uid)),
- "Update app-ops uidState in case package " + pkg + " changed");
- }
- }
- }
-
prepareInternalCallbacks();
final IntentFilter packageSuspendFilter = new IntentFilter();
@@ -1270,17 +1173,10 @@ public class AppOpsService extends IAppOpsService.Stub {
int userId = userIds[i];
initializeUserUidStatesLocked(userId, packageStates, knownUids);
}
- }
- // Remove what may have been added during persistence parsing
- for (int i = mUidStates.size() - 1; i >= 0; i--) {
- int uid = mUidStates.keyAt(i);
- if (!knownUids.get(uid, false)) {
- mUidStates.removeAt(i);
- }
+ trimUidStatesLocked(knownUids, packageStates);
+ mUidStatesInitialized = true;
}
-
- mUidStatesInitialized = true;
}
}
@@ -1336,6 +1232,104 @@ public class AppOpsService extends IAppOpsService.Stub {
createSandboxUidStateIfNotExistsForAppLocked(uid, knownUids);
}
+ private void trimUidStatesLocked(SparseBooleanArray knownUids,
+ Map<String, PackageState> packageStates) {
+ synchronized (this) {
+ // Remove what may have been added during persistence parsing
+ for (int i = mUidStates.size() - 1; i >= 0; i--) {
+ int uid = mUidStates.keyAt(i);
+ if (knownUids.get(uid, false)) {
+ if (uid >= Process.FIRST_APPLICATION_UID) {
+ ArrayMap<String, Ops> pkgOps = mUidStates.valueAt(i).pkgOps;
+ for (int j = 0; j < pkgOps.size(); j++) {
+ String pkgName = pkgOps.keyAt(j);
+ if (!packageStates.containsKey(pkgName)) {
+ pkgOps.removeAt(j);
+ continue;
+ }
+ AndroidPackage pkg = packageStates.get(pkgName).getAndroidPackage();
+ if (pkg != null) {
+ refreshAttributionsLocked(pkg, uid);
+ }
+ }
+ if (pkgOps.isEmpty()) {
+ mUidStates.remove(i);
+ }
+ }
+ } else {
+ mUidStates.removeAt(i);
+ }
+ }
+ }
+ }
+
+ @GuardedBy("this")
+ private void refreshAttributionsLocked(AndroidPackage pkg, int uid) {
+ String pkgName = pkg.getPackageName();
+ ArrayMap<String, String> dstAttributionTags = new ArrayMap<>();
+ ArraySet<String> attributionTags = new ArraySet<>();
+ attributionTags.add(null);
+ if (pkg.getAttributions() != null) {
+ int numAttributions = pkg.getAttributions().size();
+ for (int attributionNum = 0; attributionNum < numAttributions;
+ attributionNum++) {
+ ParsedAttribution attribution = pkg.getAttributions().get(attributionNum);
+ attributionTags.add(attribution.getTag());
+
+ int numInheritFrom = attribution.getInheritFrom().size();
+ for (int inheritFromNum = 0; inheritFromNum < numInheritFrom;
+ inheritFromNum++) {
+ dstAttributionTags.put(attribution.getInheritFrom().get(inheritFromNum),
+ attribution.getTag());
+ }
+ }
+ }
+
+ UidState uidState = mUidStates.get(uid);
+ if (uidState == null) {
+ return;
+ }
+
+ Ops ops = uidState.pkgOps.get(pkgName);
+ if (ops == null) {
+ return;
+ }
+
+ // Reset cached package properties to re-initialize when needed
+ ops.bypass = null;
+ ops.knownAttributionTags.clear();
+
+ // Merge data collected for removed attributions into their successor
+ // attributions
+ int numOps = ops.size();
+ for (int opNum = 0; opNum < numOps; opNum++) {
+ Op op = ops.valueAt(opNum);
+ for (int deviceIndex = op.mDeviceAttributedOps.size() - 1; deviceIndex >= 0;
+ deviceIndex--) {
+ ArrayMap<String, AttributedOp> attributedOps =
+ op.mDeviceAttributedOps.valueAt(deviceIndex);
+ for (int tagIndex = attributedOps.size() - 1; tagIndex >= 0;
+ tagIndex--) {
+ String tag = attributedOps.keyAt(tagIndex);
+ if (attributionTags.contains(tag)) {
+ // attribution still exist after upgrade
+ continue;
+ }
+
+ String newAttributionTag = dstAttributionTags.get(tag);
+
+ AttributedOp newAttributedOp = op.getOrCreateAttribution(op,
+ newAttributionTag,
+ op.mDeviceAttributedOps.keyAt(deviceIndex));
+ newAttributedOp.add(attributedOps.get(tag));
+ attributedOps.remove(tag);
+
+ scheduleFastWriteLocked();
+ }
+ }
+ }
+ }
+
/**
* Sets a policy for handling app ops.
*