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

Commit ccfbc759 authored by Achim Thesmann's avatar Achim Thesmann
Browse files

Fix logging

The logging logic used the checkedOptions directy, which means the logs
did not respect any special implicit opt-in cases. Instead of accessing
the checkedOptions, there are now dedicated fields in the BalState
object.
This also means there is no more passing through the checked options
anywhere and I removed a redundant call to determine the opt-in state
for the sender side.
Additional pure refactorings:
- use static imports for MODE_BACKGROUND_ACTIVITY_START_* constants.

Test: atest BackgroundActivityLaunchTest
Bug: 320558614
Change-Id: I8ffe2808a047eea4df17421897c7e269e3bafbfb
parent 6b2c10db
Loading
Loading
Loading
Loading
+85 −38
Original line number Diff line number Diff line
@@ -18,6 +18,10 @@ package com.android.server.wm;

import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED;
import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
import static android.app.ComponentOptions.BackgroundActivityStartMode;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
@@ -94,9 +98,9 @@ public class BackgroundActivityStartController {
    public static final ActivityOptions ACTIVITY_OPTIONS_SYSTEM_DEFINED =
            ActivityOptions.makeBasic()
                    .setPendingIntentBackgroundActivityStartMode(
                            ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED)
                            MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED)
                    .setPendingIntentCreatorBackgroundActivityStartMode(
                            ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED);
                            MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED);

    private final ActivityTaskManagerService mService;

@@ -240,6 +244,7 @@ public class BackgroundActivityStartController {
        private final WindowProcessController mRealCallerApp;
        private final boolean mIsCallForResult;
        private final ActivityOptions mCheckedOptions;
        private final String mAutoOptInReason;
        private BalVerdict mResultForCaller;
        private BalVerdict mResultForRealCaller;

@@ -263,19 +268,27 @@ public class BackgroundActivityStartController {
            mRealCallingPackage = mService.getPackageNameIfUnique(realCallingUid, realCallingPid);
            mIsCallForResult = resultRecord != null;
            mCheckedOptions = checkedOptions;
            if (balRequireOptInByPendingIntentCreator() // auto-opt in introduced with this feature
                    && (originatingPendingIntent == null // not a PendingIntent
                    || mIsCallForResult) // sent for result
            ) {
            @BackgroundActivityStartMode int callerBackgroundActivityStartMode =
                    checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode();
            @BackgroundActivityStartMode int realCallerBackgroundActivityStartMode =
                    checkedOptions.getPendingIntentBackgroundActivityStartMode();

            if (balRequireOptInByPendingIntentCreator() && originatingPendingIntent == null) {
                mAutoOptInReason = "notPendingIntent";
            } else if (balRequireOptInByPendingIntentCreator() && mIsCallForResult) {
                mAutoOptInReason = "callForResult";
            } else {
                mAutoOptInReason = null;
            }

            if (mAutoOptInReason != null) {
                // grant BAL privileges unless explicitly opted out
                mBalAllowedByPiCreatorWithHardening = mBalAllowedByPiCreator =
                        checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
                                == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED
                        callerBackgroundActivityStartMode == MODE_BACKGROUND_ACTIVITY_START_DENIED
                                ? BackgroundStartPrivileges.NONE
                                : BackgroundStartPrivileges.ALLOW_BAL;
                mBalAllowedByPiSender =
                        checkedOptions.getPendingIntentBackgroundActivityStartMode()
                                == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED
                mBalAllowedByPiSender = realCallerBackgroundActivityStartMode
                        == MODE_BACKGROUND_ACTIVITY_START_DENIED
                        ? BackgroundStartPrivileges.NONE
                        : BackgroundStartPrivileges.ALLOW_BAL;
            } else {
@@ -283,8 +296,8 @@ public class BackgroundActivityStartController {
                mBalAllowedByPiCreatorWithHardening = getBackgroundStartPrivilegesAllowedByCreator(
                        callingUid, callingPackage, checkedOptions);
                final BackgroundStartPrivileges mBalAllowedByPiCreatorWithoutHardening =
                        checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
                                == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED
                        callerBackgroundActivityStartMode
                                == MODE_BACKGROUND_ACTIVITY_START_DENIED
                                ? BackgroundStartPrivileges.NONE
                                : BackgroundStartPrivileges.ALLOW_BAL;
                mBalAllowedByPiCreator = balRequireOptInByPendingIntentCreator()
@@ -326,11 +339,11 @@ public class BackgroundActivityStartController {
        private BackgroundStartPrivileges getBackgroundStartPrivilegesAllowedByCreator(
                int callingUid, String callingPackage, ActivityOptions checkedOptions) {
            switch (checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()) {
                case ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED:
                case MODE_BACKGROUND_ACTIVITY_START_ALLOWED:
                    return BackgroundStartPrivileges.ALLOW_BAL;
                case ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED:
                case MODE_BACKGROUND_ACTIVITY_START_DENIED:
                    return BackgroundStartPrivileges.NONE;
                case ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED:
                case MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED:
                    // no explicit choice by the app - let us decide what to do
                    if (callingPackage != null) {
                        // determine based on the calling/creating package
@@ -431,6 +444,7 @@ public class BackgroundActivityStartController {
            sb.append("; hasRealCaller: ").append(hasRealCaller());
            sb.append("; isCallForResult: ").append(mIsCallForResult);
            sb.append("; isPendingIntent: ").append(isPendingIntent());
            sb.append("; autoOptInReason: ").append(mAutoOptInReason);
            if (hasRealCaller()) {
                sb.append("; realCallingPackage: ")
                        .append(getDebugPackageName(mRealCallingPackage, mRealCallingUid));
@@ -456,6 +470,50 @@ public class BackgroundActivityStartController {
            sb.append("]");
            return sb.toString();
        }

        public boolean isPendingIntentBalAllowedByPermission() {
            return PendingIntentRecord.isPendingIntentBalAllowedByPermission(mCheckedOptions);
        }

        public boolean callerExplicitOptInOrAutoOptIn() {
            if (mAutoOptInReason == null) {
                return mCheckedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
                        == MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
            } else {
                return mCheckedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
                        != MODE_BACKGROUND_ACTIVITY_START_DENIED;
            }
        }

        public boolean realCallerExplicitOptInOrAutoOptIn() {
            if (mAutoOptInReason == null) {
                return mCheckedOptions.getPendingIntentBackgroundActivityStartMode()
                        == MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
            } else {
                return mCheckedOptions.getPendingIntentBackgroundActivityStartMode()
                        != MODE_BACKGROUND_ACTIVITY_START_DENIED;
            }
        }

        public boolean callerExplicitOptOut() {
            return mCheckedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
                    == MODE_BACKGROUND_ACTIVITY_START_DENIED;
        }

        public boolean realCallerExplicitOptOut() {
            return mCheckedOptions.getPendingIntentBackgroundActivityStartMode()
                    == MODE_BACKGROUND_ACTIVITY_START_DENIED;
        }

        public boolean callerExplicitOptInOrOut() {
            return mCheckedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
                    != MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
        }

        public boolean realCallerExplicitOptInOrOut() {
            return mCheckedOptions.getPendingIntentBackgroundActivityStartMode()
                    != MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
        }
    }

    static class BalVerdict {
@@ -624,7 +682,7 @@ public class BackgroundActivityStartController {
        // PendingIntents is null).
        BalVerdict resultForRealCaller = state.callerIsRealCaller() && resultForCaller.allows()
                ? resultForCaller
                : checkBackgroundActivityStartAllowedBySender(state, checkedOptions)
                : checkBackgroundActivityStartAllowedBySender(state)
                        .setBasedOnRealCaller();
        state.setResultForRealCaller(resultForRealCaller);

@@ -634,18 +692,14 @@ public class BackgroundActivityStartController {
        }

        // Handle cases with explicit opt-in
        if (resultForCaller.allows()
                && checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
                == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED) {
        if (resultForCaller.allows() && state.callerExplicitOptInOrAutoOptIn()) {
            if (DEBUG_ACTIVITY_STARTS) {
                Slog.d(TAG, "Activity start explicitly allowed by caller. "
                        + state.dump());
            }
            return allowBasedOnCaller(state);
        }
        if (resultForRealCaller.allows()
                && checkedOptions.getPendingIntentBackgroundActivityStartMode()
                == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED) {
        if (resultForRealCaller.allows() && state.realCallerExplicitOptInOrAutoOptIn()) {
            if (DEBUG_ACTIVITY_STARTS) {
                Slog.d(TAG, "Activity start explicitly allowed by real caller. "
                        + state.dump());
@@ -653,12 +707,9 @@ public class BackgroundActivityStartController {
            return allowBasedOnRealCaller(state);
        }
        // Handle PendingIntent cases with default behavior next
        boolean callerCanAllow = resultForCaller.allows()
                && checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
                == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
        boolean callerCanAllow = resultForCaller.allows() && !state.callerExplicitOptOut();
        boolean realCallerCanAllow = resultForRealCaller.allows()
                && checkedOptions.getPendingIntentBackgroundActivityStartMode()
                == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
                && !state.realCallerExplicitOptOut();
        if (callerCanAllow && realCallerCanAllow) {
            // Both caller and real caller allow with system defined behavior
            if (state.mBalAllowedByPiCreatorWithHardening.allowsBackgroundActivityStarts()) {
@@ -880,11 +931,9 @@ public class BackgroundActivityStartController {
     * @return A code denoting which BAL rule allows an activity to be started,
     * or {@link #BAL_BLOCK} if the launch should be blocked
     */
    BalVerdict checkBackgroundActivityStartAllowedBySender(
            BalState state,
            ActivityOptions checkedOptions) {
    BalVerdict checkBackgroundActivityStartAllowedBySender(BalState state) {

        if (PendingIntentRecord.isPendingIntentBalAllowedByPermission(checkedOptions)
        if (state.isPendingIntentBalAllowedByPermission()
                && ActivityManager.checkComponentPermission(
                android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND,
                state.mRealCallingUid, NO_PROCESS_UID, true) == PackageManager.PERMISSION_GRANTED) {
@@ -1545,13 +1594,11 @@ public class BackgroundActivityStartController {
                state.mRealCallingUid,
                state.mResultForCaller == null ? BAL_BLOCK : state.mResultForCaller.getRawCode(),
                state.mBalAllowedByPiCreator.allowsBackgroundActivityStarts(),
                state.mCheckedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
                        != ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED,
                state.callerExplicitOptInOrOut(),
                state.mResultForRealCaller == null ? BAL_BLOCK
                        : state.mResultForRealCaller.getRawCode(),
                state.mBalAllowedByPiSender.allowsBackgroundActivityStarts(),
                state.mCheckedOptions.getPendingIntentBackgroundActivityStartMode()
                        != ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED
                state.realCallerExplicitOptInOrOut()
        );
    }