diff options
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  |