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

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

Refine Background Activity Launch (BAL) Modes

This CL refines the `BackgroundActivityStartMode` constants in `ActivityOptions` to provide clearer and more secure control over background activity launches.

Key changes include:

* Introduce `MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS`: This new constant explicitly grants all BAL privileges, including those associated with the `START_ACTIVITIES_FROM_BACKGROUND` permission. It mirrors the behavior of the deprecated `MODE_BACKGROUND_ACTIVITY_START_ALLOWED` when used with the (now obsolete) `setPendingIntentBackgroundActivityLaunchAllowedByPermission` API. This ensures apps don't inadvertently gain broader BAL privileges when upgrading to SDK 35 or higher.

* Introduce `MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE`: This new constant offers a safer alternative by granting BAL privileges only when the app is visible to the user. This aligns with the common use case where activities are started in response to user interaction with a visible UI element.

* Deprecate `MODE_BACKGROUND_ACTIVITY_START_ALLOWED`: The existing `MODE_BACKGROUND_ACTIVITY_START_ALLOWED` constant is deprecated to encourage the use of the more explicit and secure new constants.

* Naming Convention: The new constants use "ALLOW" instead of "ALLOWED" to indicate an instruction rather than a result. This distinction clarifies the purpose of these constants and aligns with the intended usage.  With `MODE_BACKGROUND_ACTIVITY_START_ALLOWED` being deprecated and `MODE_BACKGROUND_ACTIVITY_START_DENIED` rarely being used because it is the default when targeting SDK 35+, this naming inconsistency with  is less of a concern.

These changes improve the clarity and security of background activity launch controls, guiding developers towards best practices and minimizing the risk of unintended behavior.

Test: atest BackgroundActivityLaunchTests
Flag: com.android.window.flags.bal_additional_start_modes
Bug: 352182359
Change-Id: Id82d8a3260fd04b477739803441f16d2f0c6bac3
parent 276222e0
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -4947,8 +4947,10 @@ package android.app {
    method public void update(android.app.ActivityOptions);
    field public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
    field public static final String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages";
    field public static final int MODE_BACKGROUND_ACTIVITY_START_ALLOWED = 1; // 0x1
    field public static final int MODE_BACKGROUND_ACTIVITY_START_DENIED = 2; // 0x2
    field @Deprecated @FlaggedApi("com.android.window.flags.bal_additional_start_modes") public static final int MODE_BACKGROUND_ACTIVITY_START_ALLOWED = 1; // 0x1
    field @FlaggedApi("com.android.window.flags.bal_additional_start_modes") public static final int MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS = 3; // 0x3
    field @FlaggedApi("com.android.window.flags.bal_additional_start_modes") public static final int MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE = 4; // 0x4
    field @FlaggedApi("com.android.window.flags.bal_additional_start_modes") public static final int MODE_BACKGROUND_ACTIVITY_START_DENIED = 2; // 0x2
    field public static final int MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED = 0; // 0x0
  }
+43 −12
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@ import android.window.RemoteTransition;
import android.window.SplashScreen;
import android.window.WindowContainerToken;

import com.android.window.flags.Flags;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -109,35 +111,64 @@ public class ActivityOptions extends ComponentOptions {
            MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS,
            MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE})
    public @interface BackgroundActivityStartMode {}

    /**
     * No explicit value chosen. The system will decide whether to grant privileges.
     * The system determines whether to grant background activity start privileges. This is the
     * default behavior if no explicit mode is specified.
     */
    public static final int MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED = 0;
    /**
     * Allow the {@link PendingIntent} to use the background activity start privileges.
     */
     * Grants the {@link PendingIntent} background activity start privileges.
     *
     * This behaves the same as {@link #MODE_BACKGROUND_ACTIVITY_START_ALLOWED_ALWAYS}, except it
     * does not grant background activity launch permissions based on the privileged permission
     * <code>START_ACTIVITIES_FROM_BACKGROUND</code>.
     *
     * @deprecated Use {@link #MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE} to allow starts
     * only when the app is visible or {@link #MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS} to
     * allow starts at any time (see <a
     * href="https://developer.android.com/guide/components/activities/background-starts">
     * Restrictions on starting activities from the background</a>).
     */
    @Deprecated
    @FlaggedApi(Flags.FLAG_BAL_ADDITIONAL_START_MODES)
    public static final int MODE_BACKGROUND_ACTIVITY_START_ALLOWED = 1;
    /**
     * Deny the {@link PendingIntent} to use the background activity start privileges.
     * Denies the {@link PendingIntent} any background activity start privileges.
     */
    @FlaggedApi(Flags.FLAG_BAL_ADDITIONAL_START_MODES)
    public static final int MODE_BACKGROUND_ACTIVITY_START_DENIED = 2;
    /**
     * Allow the {@link PendingIntent} to use ALL background activity start privileges, including
     * special permissions that will allow starts at any time.
     * Grants the {@link PendingIntent} all background activity start privileges, including
     * those normally reserved for privileged contexts (e.g., companion apps or those with the
     * {@code START_ACTIVITIES_FROM_BACKGROUND} permission).
     *
     * @hide
     * <p><b>Caution:</b> This mode should be used sparingly. Most apps should use
     * {@link #MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE} instead, relying on notifications
     * or foreground services for background interactions to minimize user disruption. However,
     * this mode  is necessary for specific use cases, such as companion apps responding to
     * prompts from a connected device.
     *
     * <p>For more information on background activity start restrictions, see:
     * <a href="https://developer.android.com/guide/components/activities/background-starts">
     * Restrictions on starting activities from  the background</a>
     */
    @FlaggedApi(Flags.FLAG_BAL_ADDITIONAL_START_MODES)
    public static final int MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS = 3;
    /**
     * Allow the {@link PendingIntent} to use background activity start privileges based on
     * visibility of the app.
     * Grants the {@link PendingIntent} background activity start privileges only when the app
     * has a visible window (i.e., is visible to the user). This is the recommended mode for most
     * apps to minimize disruption to the user experience.
     *
     * @hide
     * <p>For more information on background activity start restrictions, see:
     * <a href="https://developer.android.com/guide/components/activities/background-starts">
     * Restrictions on starting activities from the background</a>
     */
    @FlaggedApi(Flags.FLAG_BAL_ADDITIONAL_START_MODES)
    public static final int MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE = 4;
    /**
     * Special behavior for compatibility.
     * Similar to {@link #MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED}
     * Provides compatibility with previous Android versions regarding background activity starts.
     * Similar to {@link #MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED}.
     *
     * @hide
     */