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

Commit bcf44fa9 authored by Ricky Wai's avatar Ricky Wai
Browse files

Merge BroadcastOptions and ActivityOptions PendingIntent BAL flags and

remove @hide

Patchset 1 is the same as ag/15884451.
The latest patchset is adding SystemAPI annotation to fix the broken test in patchset 1.

Bug: 192341120
Bug: 203407624
Test: atest BackgroundActivityLaunchTest
Change-Id: I1ac315a3268bba590406e834f4930b0cb4db5de8
parent a4378ef2
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -4380,6 +4380,7 @@ package android.app {
    method @Nullable public android.graphics.Rect getLaunchBounds();
    method public int getLaunchDisplayId();
    method public boolean getLockTaskMode();
    method public boolean isPendingIntentBackgroundActivityLaunchAllowed();
    method public static android.app.ActivityOptions makeBasic();
    method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int);
    method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
@@ -4393,6 +4394,7 @@ package android.app {
    method public android.app.ActivityOptions setLaunchBounds(@Nullable android.graphics.Rect);
    method public android.app.ActivityOptions setLaunchDisplayId(int);
    method public android.app.ActivityOptions setLockTaskEnabled(boolean);
    method public void setPendingIntentBackgroundActivityLaunchAllowed(boolean);
    method public android.os.Bundle toBundle();
    method public void update(android.app.ActivityOptions);
    field public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
+2 −0
Original line number Diff line number Diff line
@@ -687,9 +687,11 @@ package android.app {
  }
  public class BroadcastOptions {
    method public boolean isPendingIntentBackgroundActivityLaunchAllowed();
    method public static android.app.BroadcastOptions makeBasic();
    method @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean);
    method public void setDontSendToRestrictedApps(boolean);
    method public void setPendingIntentBackgroundActivityLaunchAllowed(boolean);
    method @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppAllowlist(long, int, int, @Nullable String);
    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(long);
    method public android.os.Bundle toBundle();
+5 −41
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ import java.util.ArrayList;
 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
 * Context.startActivity(Intent, Bundle)} and related methods.
 */
public class ActivityOptions {
public class ActivityOptions extends ComponentOptions {
    private static final String TAG = "ActivityOptions";

    /**
@@ -167,14 +167,6 @@ public class ActivityOptions {
     */
    public static final String KEY_SPLASH_SCREEN_THEME = "android.activity.splashScreenTheme";

    /**
     * PendingIntent caller allows activity start even if PendingIntent creator is in background.
     * This only works if the PendingIntent caller is allowed to start background activities,
     * for example if it's in the foreground, or has BAL permission.
     * @hide
     */
    public static final String KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED =
            "android.pendingIntent.backgroundActivityAllowed";
    /**
     * Callback for when the last frame of the animation is played.
     * @hide
@@ -389,12 +381,6 @@ public class ActivityOptions {
    /** @hide */
    public static final int ANIM_REMOTE_ANIMATION = 13;

    /**
     * Default value for KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED.
     * @hide
     **/
    public static final boolean PENDING_INTENT_BAL_ALLOWED_DEFAULT = true;

    private String mPackageName;
    private Rect mLaunchBounds;
    private int mAnimationType = ANIM_UNDEFINED;
@@ -446,7 +432,6 @@ public class ActivityOptions {
    private String mSplashScreenThemeResName;
    @SplashScreen.SplashScreenStyle
    private int mSplashScreenStyle;
    private boolean mPendingIntentBalAllowed = PENDING_INTENT_BAL_ALLOWED_DEFAULT;
    private boolean mRemoveWithTaskOrganizer;
    private boolean mLaunchedFromBubble;
    private boolean mTransientLaunch;
@@ -1096,13 +1081,12 @@ public class ActivityOptions {
    }

    private ActivityOptions() {
        super();
    }

    /** @hide */
    public ActivityOptions(Bundle opts) {
        // If the remote side sent us bad parcelables, they won't get the
        // results they want, which is their loss.
        opts.setDefusable(true);
        super(opts);

        mPackageName = opts.getString(KEY_PACKAGE_NAME);
        try {
@@ -1200,8 +1184,6 @@ public class ActivityOptions {
        mRemoteTransition = opts.getParcelable(KEY_REMOTE_TRANSITION);
        mOverrideTaskTransition = opts.getBoolean(KEY_OVERRIDE_TASK_TRANSITION);
        mSplashScreenThemeResName = opts.getString(KEY_SPLASH_SCREEN_THEME);
        mPendingIntentBalAllowed = opts.getBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED,
                PENDING_INTENT_BAL_ALLOWED_DEFAULT);
        mRemoveWithTaskOrganizer = opts.getBoolean(KEY_REMOVE_WITH_TASK_ORGANIZER);
        mLaunchedFromBubble = opts.getBoolean(KEY_LAUNCHED_FROM_BUBBLE);
        mTransientLaunch = opts.getBoolean(KEY_TRANSIENT_LAUNCH);
@@ -1425,24 +1407,6 @@ public class ActivityOptions {
        return mSplashScreenStyle;
    }

    /**
     * Set PendingIntent activity is allowed to be started in the background if the caller
     * can start background activities.
     * @hide
     */
    public void setPendingIntentBackgroundActivityLaunchAllowed(boolean allowed) {
        mPendingIntentBalAllowed = allowed;
    }

    /**
     * Get PendingIntent activity is allowed to be started in the background if the caller
     * can start background activities.
     * @hide
     */
    public boolean isPendingIntentBackgroundActivityLaunchAllowed() {
        return mPendingIntentBalAllowed;
    }

    /**
     * Sets whether the activity is to be launched into LockTask mode.
     *
@@ -1868,8 +1832,9 @@ public class ActivityOptions {
     * object; you must not modify it, but can supply it to the startActivity
     * methods that take an options Bundle.
     */
    @Override
    public Bundle toBundle() {
        Bundle b = new Bundle();
        Bundle b = super.toBundle();
        if (mPackageName != null) {
            b.putString(KEY_PACKAGE_NAME, mPackageName);
        }
@@ -2016,7 +1981,6 @@ public class ActivityOptions {
        if (mSplashScreenThemeResName != null && !mSplashScreenThemeResName.isEmpty()) {
            b.putString(KEY_SPLASH_SCREEN_THEME, mSplashScreenThemeResName);
        }
        b.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, mPendingIntentBalAllowed);
        if (mRemoveWithTaskOrganizer) {
            b.putBoolean(KEY_REMOVE_WITH_TASK_ORGANIZER, mRemoveWithTaskOrganizer);
        }
+25 −37
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ import android.os.PowerExemptionManager.TempAllowListType;
 * {@hide}
 */
@SystemApi
public class BroadcastOptions {
public class BroadcastOptions extends ComponentOptions {
    private long mTemporaryAppAllowlistDuration;
    private @TempAllowListType int mTemporaryAppAllowlistType;
    private @ReasonCode int mTemporaryAppAllowlistReasonCode;
@@ -43,7 +43,6 @@ public class BroadcastOptions {
    private int mMaxManifestReceiverApiLevel = Build.VERSION_CODES.CUR_DEVELOPMENT;
    private boolean mDontSendToRestrictedApps = false;
    private boolean mAllowBackgroundActivityStarts;
    private boolean mPendingIntentBalAllowed = ActivityOptions.PENDING_INTENT_BAL_ALLOWED_DEFAULT;

    /**
     * How long to temporarily put an app on the power allowlist when executing this broadcast
@@ -79,16 +78,6 @@ public class BroadcastOptions {
    private static final String KEY_DONT_SEND_TO_RESTRICTED_APPS =
            "android:broadcast.dontSendToRestrictedApps";

    /**
     * PendingIntent caller allows activity start even if PendingIntent creator is in background.
     * This only works if the PendingIntent caller is allowed to start background activities,
     * for example if it's in the foreground, or has BAL permission.
     * TODO: Merge it with ActivityOptions.
     * @hide
     */
    public static final String KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED =
            "android.pendingIntent.backgroundActivityAllowed";

    /**
     * Corresponds to {@link #setBackgroundActivityStartsAllowed}.
     */
@@ -119,12 +108,14 @@ public class BroadcastOptions {
    }

    private BroadcastOptions() {
        super();
        resetTemporaryAppAllowlist();
    }

    /** @hide */
    @TestApi
    public BroadcastOptions(@NonNull Bundle opts) {
        super(opts);
        // Match the logic in toBundle().
        if (opts.containsKey(KEY_TEMPORARY_APP_ALLOWLIST_DURATION)) {
            mTemporaryAppAllowlistDuration = opts.getLong(KEY_TEMPORARY_APP_ALLOWLIST_DURATION);
@@ -141,8 +132,6 @@ public class BroadcastOptions {
        mDontSendToRestrictedApps = opts.getBoolean(KEY_DONT_SEND_TO_RESTRICTED_APPS, false);
        mAllowBackgroundActivityStarts = opts.getBoolean(KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS,
                false);
        mPendingIntentBalAllowed = opts.getBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED,
                ActivityOptions.PENDING_INTENT_BAL_ALLOWED_DEFAULT);
    }

    /**
@@ -203,6 +192,26 @@ public class BroadcastOptions {
        mTemporaryAppAllowlistReason = null;
    }

    /**
     * Set PendingIntent activity is allowed to be started in the background if the caller
     * can start background activities.
     * @hide
     */
    @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
    public void setPendingIntentBackgroundActivityLaunchAllowed(boolean allowed) {
        super.setPendingIntentBackgroundActivityLaunchAllowed(allowed);
    }

    /**
     * Get PendingIntent activity is allowed to be started in the background if the caller
     * can start background activities.
     * @hide
     */
    @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
    public boolean isPendingIntentBackgroundActivityLaunchAllowed() {
        return super.isPendingIntentBackgroundActivityLaunchAllowed();
    }

    /**
     * Return {@link #setTemporaryAppAllowlist}.
     * @hide
@@ -313,26 +322,6 @@ public class BroadcastOptions {
        return mAllowBackgroundActivityStarts;
    }

    /**
     * Set PendingIntent activity is allowed to be started in the background if the caller
     * can start background activities.
     * TODO: Merge it with ActivityOptions.
     * @hide
     */
    public void setPendingIntentBackgroundActivityLaunchAllowed(boolean allowed) {
        mPendingIntentBalAllowed = allowed;
    }

    /**
     * Get PendingIntent activity is allowed to be started in the background if the caller
     * can start background activities.
     * TODO: Merge it with ActivityOptions.
     * @hide
     */
    public boolean isPendingIntentBackgroundActivityLaunchAllowed() {
        return mPendingIntentBalAllowed;
    }

    /**
     * Returns the created options as a Bundle, which can be passed to
     * {@link android.content.Context#sendBroadcast(android.content.Intent)
@@ -341,8 +330,9 @@ public class BroadcastOptions {
     * object; you must not modify it, but can supply it to the sendBroadcast
     * methods that take an options Bundle.
     */
    @Override
    public Bundle toBundle() {
        Bundle b = new Bundle();
        Bundle b = super.toBundle();
        if (isTemporaryAppAllowlistSet()) {
            b.putLong(KEY_TEMPORARY_APP_ALLOWLIST_DURATION, mTemporaryAppAllowlistDuration);
            b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_TYPE, mTemporaryAppAllowlistType);
@@ -361,8 +351,6 @@ public class BroadcastOptions {
        if (mAllowBackgroundActivityStarts) {
            b.putBoolean(KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS, true);
        }
        // TODO: Add API for BroadcastOptions and have a shared base class with ActivityOptions.
        b.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, mPendingIntentBalAllowed);
        return b.isEmpty() ? null : b;
    }
}
+76 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.app;

import android.os.Bundle;

/**
 * @hide
 */
public class ComponentOptions {

    /**
     * Default value for KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED.
     * @hide
     **/
    public static final boolean PENDING_INTENT_BAL_ALLOWED_DEFAULT = true;

    /**
     * PendingIntent caller allows activity start even if PendingIntent creator is in background.
     * This only works if the PendingIntent caller is allowed to start background activities,
     * for example if it's in the foreground, or has BAL permission.
     * @hide
     */
    public static final String KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED =
            "android.pendingIntent.backgroundActivityAllowed";

    private boolean mPendingIntentBalAllowed = PENDING_INTENT_BAL_ALLOWED_DEFAULT;

    ComponentOptions() {
    }

    ComponentOptions(Bundle opts) {
        // If the remote side sent us bad parcelables, they won't get the
        // results they want, which is their loss.
        opts.setDefusable(true);
        setPendingIntentBackgroundActivityLaunchAllowed(
                opts.getBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED,
                        PENDING_INTENT_BAL_ALLOWED_DEFAULT));
    }

    /**
     * Set PendingIntent activity is allowed to be started in the background if the caller
     * can start background activities.
     */
    public void setPendingIntentBackgroundActivityLaunchAllowed(boolean allowed) {
        mPendingIntentBalAllowed = allowed;
    }

    /**
     * Get PendingIntent activity is allowed to be started in the background if the caller
     * can start background activities.
     */
    public boolean isPendingIntentBackgroundActivityLaunchAllowed() {
        return mPendingIntentBalAllowed;
    }

    public Bundle toBundle() {
        Bundle b = new Bundle();
        b.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, mPendingIntentBalAllowed);
        return b;
    }
}