diff options
| author | 2024-11-20 08:40:25 +0000 | |
|---|---|---|
| committer | 2024-11-20 08:40:25 +0000 | |
| commit | 54d9f9d1a50f6a6f5c36e5bb61cf586dc0a341e7 (patch) | |
| tree | 1a8e25735afabc7ba332b2d20b7c0c098ff5c56c | |
| parent | fc5f20ff851de906b9c46c66b2bb2269cffc3336 (diff) | |
| parent | f2b717e5d0ee5528817455b04ac6f8326cdbe498 (diff) | |
Merge "Store and log details for non-app visible windows" into main
4 files changed, 77 insertions, 25 deletions
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java index bce8c2be271e..852a0ac054f4 100644 --- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java +++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java @@ -1016,7 +1016,8 @@ public class BackgroundActivityStartController { } if (state.mCallingUidHasNonAppVisibleWindow) { return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW, - /*background*/ false, "callingUid has non-app visible window"); + /*background*/ false, "callingUid has non-app visible window " + + mService.mActiveUids.getNonAppVisibleWindowDetails(state.mCallingUid)); } // Don't abort if the callerApp or other processes of that uid are considered to be in the // foreground. @@ -1142,7 +1143,8 @@ public class BackgroundActivityStartController { } if (state.mRealCallingUidHasNonAppVisibleWindow) { return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW, - /*background*/ false, "realCallingUid has non-app visible window"); + /*background*/ false, "realCallingUid has non-app visible window " + + mService.mActiveUids.getNonAppVisibleWindowDetails(state.mRealCallingUid)); } // Don't abort if the realCallerApp or other processes of that uid are considered to be in @@ -1894,20 +1896,8 @@ public class BackgroundActivityStartController { (state.mOriginatingPendingIntent != null)); } - if (finalVerdict.getRawCode() == BAL_ALLOW_GRACE_PERIOD) { - if (state.realCallerExplicitOptInOrAutoOptIn() - && state.mResultForRealCaller.allows() - && state.mResultForRealCaller.getRawCode() != BAL_ALLOW_GRACE_PERIOD) { - // real caller could allow with a different exemption - } else if (state.callerExplicitOptInOrAutoOptIn() && state.mResultForCaller.allows() - && state.mResultForCaller.getRawCode() != BAL_ALLOW_GRACE_PERIOD) { - // caller could allow with a different exemption - } else { - // log to determine grace period length distribution - Slog.wtf(TAG, "Activity start ONLY allowed by BAL_ALLOW_GRACE_PERIOD " - + finalVerdict.mMessage + ": " + state); - } - } + logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_GRACE_PERIOD); + logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_NON_APP_VISIBLE_WINDOW); if (balImprovedMetrics()) { if (shouldLogStats(finalVerdict, state)) { @@ -1946,6 +1936,30 @@ public class BackgroundActivityStartController { return finalVerdict; } + /** + * Logs details about the activity starts if the only reason it is allowed is the provided + * {@code balCode}. + */ + private static void logIfOnlyAllowedBy(BalVerdict finalVerdict, BalState state, int balCode) { + if (finalVerdict.getRawCode() == balCode) { + if (state.realCallerExplicitOptInOrAutoOptIn() + && state.mResultForRealCaller != null + && state.mResultForRealCaller.allows() + && state.mResultForRealCaller.getRawCode() != balCode) { + // real caller could allow with a different exemption + } else if (state.callerExplicitOptInOrAutoOptIn() + && state.mResultForCaller != null + && state.mResultForCaller.allows() + && state.mResultForCaller.getRawCode() != balCode) { + // caller could allow with a different exemption + } else { + // log to determine grace period length distribution + Slog.wtf(TAG, "Activity start ONLY allowed by " + balCodeToString(balCode) + " " + + finalVerdict.mMessage + ": " + state); + } + } + } + @VisibleForTesting boolean shouldLogStats(BalVerdict finalVerdict, BalState state) { if (finalVerdict.getRawCode() == BAL_ALLOW_VISIBLE_WINDOW) { diff --git a/services/core/java/com/android/server/wm/MirrorActiveUids.java b/services/core/java/com/android/server/wm/MirrorActiveUids.java index b9aa9599babe..b7bf16257f24 100644 --- a/services/core/java/com/android/server/wm/MirrorActiveUids.java +++ b/services/core/java/com/android/server/wm/MirrorActiveUids.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import android.app.ActivityManager.ProcessState; +import android.util.SparseArray; import android.util.SparseIntArray; import java.io.PrintWriter; @@ -34,6 +35,8 @@ class MirrorActiveUids { /** Uid -> number of non-app visible windows belong to the uid. */ private final SparseIntArray mNumNonAppVisibleWindowMap = new SparseIntArray(); + /** Type -> Uid -> number of non-app visible windows for type/uid. */ + private final SparseArray<SparseIntArray> mNumNonAppVisibleWindowMapByType = new SparseArray(); synchronized void onUidActive(int uid, int procState) { mUidStates.put(uid, procState); @@ -55,17 +58,31 @@ class MirrorActiveUids { } /** Called when the surface of non-application (exclude toast) window is shown or hidden. */ - synchronized void onNonAppSurfaceVisibilityChanged(int uid, boolean visible) { - final int index = mNumNonAppVisibleWindowMap.indexOfKey(uid); + synchronized void onNonAppSurfaceVisibilityChanged(int uid, int type, boolean visible) { + updateCount(uid, visible, mNumNonAppVisibleWindowMap); + updateCount(uid, visible, getNumNonAppVisibleWindowMapByType(type)); + } + + private SparseIntArray getNumNonAppVisibleWindowMapByType(int type) { + SparseIntArray result = mNumNonAppVisibleWindowMapByType.get(type); + if (result == null) { + result = new SparseIntArray(); + mNumNonAppVisibleWindowMapByType.append(type, result); + } + return result; + } + + private void updateCount(int uid, boolean visible, SparseIntArray numNonAppVisibleWindowMap) { + final int index = numNonAppVisibleWindowMap.indexOfKey(uid); if (index >= 0) { - final int num = mNumNonAppVisibleWindowMap.valueAt(index) + (visible ? 1 : -1); + final int num = numNonAppVisibleWindowMap.valueAt(index) + (visible ? 1 : -1); if (num > 0) { - mNumNonAppVisibleWindowMap.setValueAt(index, num); + numNonAppVisibleWindowMap.setValueAt(index, num); } else { - mNumNonAppVisibleWindowMap.removeAt(index); + numNonAppVisibleWindowMap.removeAt(index); } } else if (visible) { - mNumNonAppVisibleWindowMap.append(uid, 1); + numNonAppVisibleWindowMap.append(uid, 1); } } @@ -78,6 +95,24 @@ class MirrorActiveUids { return mNumNonAppVisibleWindowMap.get(uid) > 0; } + /** + * Returns details about the windows that contribute to the result of + * {@link #hasNonAppVisibleWindow(int)}. + * + * @return a map of window type to count + */ + synchronized SparseIntArray getNonAppVisibleWindowDetails(int uid) { + SparseIntArray result = new SparseIntArray(); + for (int i = 0; i < mNumNonAppVisibleWindowMapByType.size(); i++) { + SparseIntArray numNonAppVisibleWindowMap = mNumNonAppVisibleWindowMapByType.valueAt(i); + int count = numNonAppVisibleWindowMap.get(uid); + if (count > 0) { + result.append(mNumNonAppVisibleWindowMapByType.keyAt(i), count); + } + } + return result; + } + synchronized void dump(PrintWriter pw, String prefix) { pw.print(prefix + "NumNonAppVisibleWindowUidMap:["); for (int i = mNumNonAppVisibleWindowMap.size() - 1; i >= 0; i--) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index d7128afb43a3..82947377d01e 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -3436,7 +3436,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP && mAttrs.type != TYPE_PRIVATE_PRESENTATION && !(mAttrs.type == TYPE_PRESENTATION && isOnVirtualDisplay()) ) { - mWmService.mAtmService.mActiveUids.onNonAppSurfaceVisibilityChanged(mOwnerUid, shown); + mWmService.mAtmService.mActiveUids.onNonAppSurfaceVisibilityChanged(mOwnerUid, + mAttrs.type, shown); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java b/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java index ade591d006f5..da010ae3c96a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java @@ -333,7 +333,8 @@ public class BackgroundActivityStartControllerExemptionTests { int realCallingPid = REGULAR_PID_2; // setup state - mActiveUids.onNonAppSurfaceVisibilityChanged(callingUid, true); + mActiveUids.onNonAppSurfaceVisibilityChanged(callingUid, + WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY, true); when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW); // prepare call @@ -367,7 +368,8 @@ public class BackgroundActivityStartControllerExemptionTests { int realCallingPid = REGULAR_PID_2; // setup state - mActiveUids.onNonAppSurfaceVisibilityChanged(realCallingUid, true); + mActiveUids.onNonAppSurfaceVisibilityChanged(realCallingUid, + WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY, true); when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW); // prepare call |