Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 54d9f9d1 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Store and log details for non-app visible windows" into main

parents fc5f20ff f2b717e5
Loading
Loading
Loading
Loading
+30 −16
Original line number Diff line number Diff line
@@ -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) {
+41 −6
Original line number Diff line number Diff line
@@ -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--) {
+2 −1
Original line number Diff line number Diff line
@@ -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);
        }
    }

+4 −2
Original line number Diff line number Diff line
@@ -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