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

Commit 64c8239c authored by Achim Thesmann's avatar Achim Thesmann
Browse files

Allow a PendingIntent's creator to revoke BAL privilege.

Currently if the creator of a PendingIntent is allowed to start a background activity the PendingIntent has the same privilege even if started by another process in the background that does not have this permission. This change allows creators to opt out of this behavior. Nothing changes if the creator does not actively opt out.

Test: atest  com.android.server.wm.ActivityStarterTests
Bug: 261780465
Change-Id: I29db44d4fb07fa4a178a0d2e5822f655cfa56c39
parent e807a4fe
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -4756,6 +4756,7 @@ package android.app {
    method public int getLaunchDisplayId();
    method public boolean getLockTaskMode();
    method public int getPendingIntentBackgroundActivityStartMode();
    method public int getPendingIntentCreatorBackgroundActivityStartMode();
    method public int getSplashScreenStyle();
    method @Deprecated public boolean isPendingIntentBackgroundActivityLaunchAllowed();
    method public boolean isShareIdentityEnabled();
@@ -4776,6 +4777,7 @@ package android.app {
    method public android.app.ActivityOptions setLockTaskEnabled(boolean);
    method @Deprecated public void setPendingIntentBackgroundActivityLaunchAllowed(boolean);
    method @NonNull public android.app.ActivityOptions setPendingIntentBackgroundActivityStartMode(int);
    method @NonNull public android.app.ActivityOptions setPendingIntentCreatorBackgroundActivityStartMode(int);
    method @NonNull public android.app.ActivityOptions setShareIdentityEnabled(boolean);
    method @NonNull public android.app.ActivityOptions setSplashScreenStyle(int);
    method public android.os.Bundle toBundle();
+38 −15
Original line number Diff line number Diff line
@@ -387,8 +387,8 @@ public class ActivityOptions extends ComponentOptions {
    /** See {@link #setDismissKeyguard()}. */
    private static final String KEY_DISMISS_KEYGUARD = "android.activity.dismissKeyguard";

    private static final String KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE =
            "android.activity.ignorePendingIntentCreatorForegroundState";
    private static final String KEY_PENDING_INTENT_CREATOR_BACKGROUND_ACTIVITY_START_MODE =
            "android.activity.pendingIntentCreatorBackgroundActivityStartMode";

    /**
     * @see #setLaunchCookie
@@ -489,7 +489,9 @@ public class ActivityOptions extends ComponentOptions {
    private boolean mTransientLaunch;
    private PictureInPictureParams mLaunchIntoPipParams;
    private boolean mDismissKeyguard;
    private boolean mIgnorePendingIntentCreatorForegroundState;
    @BackgroundActivityStartMode
    private int mPendingIntentCreatorBackgroundActivityStartMode =
            MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
    private boolean mDisableStartingWindow;

    /**
@@ -1297,8 +1299,9 @@ public class ActivityOptions extends ComponentOptions {
        mIsEligibleForLegacyPermissionPrompt =
                opts.getBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE);
        mDismissKeyguard = opts.getBoolean(KEY_DISMISS_KEYGUARD);
        mIgnorePendingIntentCreatorForegroundState = opts.getBoolean(
                KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE);
        mPendingIntentCreatorBackgroundActivityStartMode = opts.getInt(
                KEY_PENDING_INTENT_CREATOR_BACKGROUND_ACTIVITY_START_MODE,
                MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED);
        mDisableStartingWindow = opts.getBoolean(KEY_DISABLE_STARTING_WINDOW);
    }

@@ -1999,19 +2002,38 @@ public class ActivityOptions extends ComponentOptions {
     * Sets background activity launch logic won't use pending intent creator foreground state.
     *
     * @hide
     * @deprecated use {@link #setPendingIntentCreatorBackgroundActivityStartMode(int)} instead
     */
    public ActivityOptions setIgnorePendingIntentCreatorForegroundState(boolean state) {
        mIgnorePendingIntentCreatorForegroundState = state;
    @Deprecated
    public ActivityOptions setIgnorePendingIntentCreatorForegroundState(boolean ignore) {
        mPendingIntentCreatorBackgroundActivityStartMode = ignore
                ? MODE_BACKGROUND_ACTIVITY_START_DENIED : MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
        return this;
    }

    /**
     * @return whether background activity launch logic should use pending intent creator
     * foreground state.
     * @hide
     * Allow a {@link PendingIntent} to use the privilege of its creator to start background
     * activities.
     *
     * @param mode the {@link android.app.ComponentOptions.BackgroundActivityStartMode} being set
     * @throws IllegalArgumentException is the value is not a valid
     * {@link android.app.ComponentOptions.BackgroundActivityStartMode}
     */
    @NonNull
    public ActivityOptions setPendingIntentCreatorBackgroundActivityStartMode(
            @BackgroundActivityStartMode int mode) {
        mPendingIntentCreatorBackgroundActivityStartMode = mode;
        return this;
    }

    /**
     * Returns the mode to start background activities granted by the creator of the
     * {@link PendingIntent}.
     *
     * @return the {@link android.app.ComponentOptions.BackgroundActivityStartMode} currently set
     */
    public boolean getIgnorePendingIntentCreatorForegroundState() {
        return mIgnorePendingIntentCreatorForegroundState;
    public @BackgroundActivityStartMode int getPendingIntentCreatorBackgroundActivityStartMode() {
        return mPendingIntentCreatorBackgroundActivityStartMode;
    }

    /**
@@ -2285,9 +2307,10 @@ public class ActivityOptions extends ComponentOptions {
        if (mDismissKeyguard) {
            b.putBoolean(KEY_DISMISS_KEYGUARD, mDismissKeyguard);
        }
        if (mIgnorePendingIntentCreatorForegroundState) {
            b.putBoolean(KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE,
                    mIgnorePendingIntentCreatorForegroundState);
        if (mPendingIntentCreatorBackgroundActivityStartMode
                != MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED) {
            b.putInt(KEY_PENDING_INTENT_CREATOR_BACKGROUND_ACTIVITY_START_MODE,
                    mPendingIntentCreatorBackgroundActivityStartMode);
        }
        if (mDisableStartingWindow) {
            b.putBoolean(KEY_DISABLE_STARTING_WINDOW, mDisableStartingWindow);
+3 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.BackgroundStartPrivileges;
import android.app.ComponentOptions;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -166,7 +167,8 @@ public class BackgroundActivityStartController {
        final boolean useCallingUidState =
                originatingPendingIntent == null
                        || checkedOptions == null
                        || !checkedOptions.getIgnorePendingIntentCreatorForegroundState();
                        || checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
                                != ComponentOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED;
        if (useCallingUidState) {
            if (callingUid == Process.ROOT_UID
                    || callingAppId == Process.SYSTEM_UID
+2 −2
Original line number Diff line number Diff line
@@ -146,8 +146,8 @@ public class SafeActivityOptions {
                .setLaunchRootTask(options.getLaunchRootTask())
                .setPendingIntentBackgroundActivityStartMode(
                        options.getPendingIntentBackgroundActivityStartMode())
                .setIgnorePendingIntentCreatorForegroundState(
                        options.getIgnorePendingIntentCreatorForegroundState());
                .setPendingIntentCreatorBackgroundActivityStartMode(
                        options.getPendingIntentCreatorBackgroundActivityStartMode());
    }

    /**