From 8b2e84fc0162d172b0639043d90f1dbd874f4fe6 Mon Sep 17 00:00:00 2001 From: Dmitry Muhomor Date: Fri, 30 Dec 2022 15:52:02 +0200 Subject: [PATCH] [temporary] extra logging to debug app-ops getting reset after reboot Hard to reproduce this issue manually, seems to be timing-related. --- .../android/server/appop/AppOpsService.java | 22 +++++++++++++++++++ .../android/server/pm/PackageRemovedInfo.java | 3 +++ 2 files changed, 25 insertions(+) diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index e31c952e10f9..8aae8091cb99 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -1819,6 +1819,7 @@ public void onReceive(Context context, Intent intent) { } Ops removedOps = uidState.pkgOps.remove(pkgName); + Slog.d(TAG_OP_RESET_DEBUG, "removed ops for " + pkgName + ", reason: ACTION_PACKAGE_REMOVED"); if (removedOps != null) { scheduleFastWriteLocked(); } @@ -1913,6 +1914,7 @@ public void systemReady() { String[] pkgsInUid = getPackagesForUid(uidState.uid); if (ArrayUtils.isEmpty(pkgsInUid)) { + Slog.d(TAG_OP_RESET_DEBUG, "no pkgs in uid " + uidState.uid + ", clearing its state"); uidState.clear(); mUidStates.removeAt(uidNum); scheduleFastWriteLocked(); @@ -2039,16 +2041,20 @@ public void packageRemoved(int uid, String packageName) { return; } + Slog.d(TAG_OP_RESET_DEBUG, "packageRemoved " + packageName + " uid " + uid); + Ops ops = null; // Remove any package state if such. if (uidState.pkgOps != null) { + Slog.d(TAG_OP_RESET_DEBUG, "packageRemoved " + packageName + " uid " + uid + ", removing pkgOps"); ops = uidState.pkgOps.remove(packageName); } // If we just nuked the last package state check if the UID is valid. if (ops != null && uidState.pkgOps.isEmpty() && getPackagesForUid(uid).length <= 0) { + Slog.d(TAG_OP_RESET_DEBUG, "packageRemoved " + packageName + " uid " + uid + ", removing uidState"); mUidStates.remove(uid); } @@ -2082,6 +2088,7 @@ && getPackagesForUid(uid).length <= 0) { public void uidRemoved(int uid) { synchronized (this) { if (mUidStates.indexOfKey(uid) >= 0) { + Slog.d(TAG_OP_RESET_DEBUG, "uidRemoved " + uid); mUidStates.remove(uid); scheduleFastWriteLocked(); } @@ -2952,6 +2959,7 @@ static final class ChangeRec { @Override public void resetAllModes(int reqUserId, String reqPackageName) { + Slog.d(TAG, "resetAllModes for " + reqPackageName + " userId " + reqUserId, new Throwable()); final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); reqUserId = ActivityManager.handleIncomingUser(callingPid, callingUid, reqUserId, @@ -4937,6 +4945,7 @@ void readState() { Slog.w(TAG, "Failed parsing " + e); } finally { if (!success) { + Slog.d(TAG_OP_RESET_DEBUG, "parsing failed, clearing uid states"); mUidStates.clear(); } try { @@ -6694,6 +6703,7 @@ public void removeUser(int userHandle) throws RemoteException { ClientUserRestrictionState opRestrictions = mOpUserRestrictions.valueAt(i); opRestrictions.removeUser(userHandle); } + Slog.d(TAG_OP_RESET_DEBUG, "removeUser " + userHandle, new Throwable()); removeUidsForUserLocked(userHandle); } } @@ -6776,6 +6786,7 @@ public void resetPackageOpsNoHistory(@NonNull String packageName) { return; } Ops removedOps = uidState.pkgOps.remove(packageName); + Slog.d(TAG_OP_RESET_DEBUG, "removed ops for " + packageName, new Throwable()); if (removedOps != null) { scheduleFastWriteLocked(); } @@ -7131,6 +7142,8 @@ private static int resolveUid(String packageName) { return -1; } + private static volatile Throwable prevThrowable; + private static String[] getPackagesForUid(int uid) { String[] packageNames = null; @@ -7142,6 +7155,13 @@ private static String[] getPackagesForUid(int uid) { } catch (RemoteException e) { /* ignore - local call */ } + } else { + var t = new Throwable(); + var prev = prevThrowable; + if (prev == null || !Arrays.equals(prev.getStackTrace(), t.getStackTrace())) { + prevThrowable = t; + Slog.d(TAG_OP_RESET_DEBUG, "AppGlobals.getPackageManager() is null", t); + } } if (packageNames == null) { return EmptyArray.STRING; @@ -7814,4 +7834,6 @@ private Void finishDelegateProxyOperationImpl(int code, return null; } } + + public static final String TAG_OP_RESET_DEBUG = "AppOpResetDebug"; } diff --git a/services/core/java/com/android/server/pm/PackageRemovedInfo.java b/services/core/java/com/android/server/pm/PackageRemovedInfo.java index 28ad4b61d8c7..c9a4b3c3954b 100644 --- a/services/core/java/com/android/server/pm/PackageRemovedInfo.java +++ b/services/core/java/com/android/server/pm/PackageRemovedInfo.java @@ -27,10 +27,12 @@ import android.content.Intent; import android.os.Bundle; import android.os.PowerExemptionManager; +import android.util.Slog; import android.util.SparseArray; import com.android.internal.util.ArrayUtils; import com.android.server.LocalServices; +import com.android.server.appop.AppOpsService; final class PackageRemovedInfo { final PackageSender mPackageSender; @@ -151,6 +153,7 @@ private void sendPackageRemovedBroadcastInternal(boolean killApp, boolean remove // If a system app's updates are uninstalled the UID is not actually removed. Some // services need to know the package name affected. if (isReplace) { + Slog.d(AppOpsService.TAG_OP_RESET_DEBUG, "sendPackageRemovedBroadcastInternal " + mRemovedPackage, new Throwable()); extras.putString(Intent.EXTRA_PACKAGE_NAME, mRemovedPackage); }