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

Commit cba1edbc authored by Jing Ji's avatar Jing Ji Committed by Android (Google) Code Review
Browse files

Merge changes from topic "fgs_246792057_type"

* changes:
  Implement the foreground service type enforcement
  Introduce foreground service type enforcement
parents 420271ea 4826749a
Loading
Loading
Loading
Loading
+27 −10
Original line number Diff line number Diff line
@@ -91,6 +91,18 @@ package android {
    field public static final String EXPAND_STATUS_BAR = "android.permission.EXPAND_STATUS_BAR";
    field public static final String FACTORY_TEST = "android.permission.FACTORY_TEST";
    field public static final String FOREGROUND_SERVICE = "android.permission.FOREGROUND_SERVICE";
    field public static final String FOREGROUND_SERVICE_CAMERA = "android.permission.FOREGROUND_SERVICE_CAMERA";
    field public static final String FOREGROUND_SERVICE_CONNECTED_DEVICE = "android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE";
    field public static final String FOREGROUND_SERVICE_DATA_SYNC = "android.permission.FOREGROUND_SERVICE_DATA_SYNC";
    field public static final String FOREGROUND_SERVICE_HEALTH = "android.permission.FOREGROUND_SERVICE_HEALTH";
    field public static final String FOREGROUND_SERVICE_LOCATION = "android.permission.FOREGROUND_SERVICE_LOCATION";
    field public static final String FOREGROUND_SERVICE_MEDIA_PLAYBACK = "android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK";
    field public static final String FOREGROUND_SERVICE_MEDIA_PROJECTION = "android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION";
    field public static final String FOREGROUND_SERVICE_MICROPHONE = "android.permission.FOREGROUND_SERVICE_MICROPHONE";
    field public static final String FOREGROUND_SERVICE_PHONE_CALL = "android.permission.FOREGROUND_SERVICE_PHONE_CALL";
    field public static final String FOREGROUND_SERVICE_REMOTE_MESSAGING = "android.permission.FOREGROUND_SERVICE_REMOTE_MESSAGING";
    field public static final String FOREGROUND_SERVICE_SPECIAL_USE = "android.permission.FOREGROUND_SERVICE_SPECIAL_USE";
    field public static final String FOREGROUND_SERVICE_SYSTEM_EXEMPTED = "android.permission.FOREGROUND_SERVICE_SYSTEM_EXEMPTED";
    field public static final String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
    field public static final String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED";
    field public static final String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
@@ -6946,7 +6958,7 @@ package android.app {
    method public void onTrimMemory(int);
    method public boolean onUnbind(android.content.Intent);
    method public final void startForeground(int, android.app.Notification);
    method public final void startForeground(int, @NonNull android.app.Notification, int);
    method public final void startForeground(int, @NonNull android.app.Notification, @RequiresPermission int);
    method @Deprecated public final void stopForeground(boolean);
    method public final void stopForeground(int);
    method public final void stopSelf();
@@ -12194,6 +12206,7 @@ package android.content.pm {
    field public static final int PERMISSION_DENIED = -1; // 0xffffffff
    field public static final int PERMISSION_GRANTED = 0; // 0x0
    field public static final String PROPERTY_MEDIA_CAPABILITIES = "android.media.PROPERTY_MEDIA_CAPABILITIES";
    field public static final String PROPERTY_SPECIAL_USE_FGS_SUBTYPE = "android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE";
    field public static final int SIGNATURE_FIRST_NOT_SIGNED = -1; // 0xffffffff
    field public static final int SIGNATURE_MATCH = 0; // 0x0
    field public static final int SIGNATURE_NEITHER_SIGNED = 1; // 0x1
@@ -12407,16 +12420,20 @@ package android.content.pm {
    field public static final int FLAG_SINGLE_USER = 1073741824; // 0x40000000
    field public static final int FLAG_STOP_WITH_TASK = 1; // 0x1
    field public static final int FLAG_USE_APP_ZYGOTE = 8; // 0x8
    field public static final int FOREGROUND_SERVICE_TYPE_CAMERA = 64; // 0x40
    field public static final int FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE = 16; // 0x10
    field public static final int FOREGROUND_SERVICE_TYPE_DATA_SYNC = 1; // 0x1
    field public static final int FOREGROUND_SERVICE_TYPE_LOCATION = 8; // 0x8
    field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_CAMERA}, anyOf={android.Manifest.permission.CAMERA}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_CAMERA = 64; // 0x40
    field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE}, anyOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.CHANGE_NETWORK_STATE, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.CHANGE_WIFI_MULTICAST_STATE, android.Manifest.permission.NFC, android.Manifest.permission.TRANSMIT_IR}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE = 16; // 0x10
    field @Deprecated @RequiresPermission(value=android.Manifest.permission.FOREGROUND_SERVICE_DATA_SYNC, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_DATA_SYNC = 1; // 0x1
    field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_HEALTH}, anyOf={android.Manifest.permission.ACTIVITY_RECOGNITION, android.Manifest.permission.BODY_SENSORS, android.Manifest.permission.HIGH_SAMPLING_RATE_SENSORS}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_HEALTH = 256; // 0x100
    field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_LOCATION}, anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_LOCATION = 8; // 0x8
    field public static final int FOREGROUND_SERVICE_TYPE_MANIFEST = -1; // 0xffffffff
    field public static final int FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK = 2; // 0x2
    field public static final int FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION = 32; // 0x20
    field public static final int FOREGROUND_SERVICE_TYPE_MICROPHONE = 128; // 0x80
    field public static final int FOREGROUND_SERVICE_TYPE_NONE = 0; // 0x0
    field public static final int FOREGROUND_SERVICE_TYPE_PHONE_CALL = 4; // 0x4
    field @RequiresPermission(value=android.Manifest.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK = 2; // 0x2
    field @RequiresPermission(value=android.Manifest.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION = 32; // 0x20
    field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_MICROPHONE}, anyOf={android.Manifest.permission.CAPTURE_AUDIO_OUTPUT, android.Manifest.permission.RECORD_AUDIO}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_MICROPHONE = 128; // 0x80
    field @Deprecated public static final int FOREGROUND_SERVICE_TYPE_NONE = 0; // 0x0
    field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_PHONE_CALL}, anyOf={android.Manifest.permission.MANAGE_OWN_CALLS}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_PHONE_CALL = 4; // 0x4
    field @RequiresPermission(value=android.Manifest.permission.FOREGROUND_SERVICE_REMOTE_MESSAGING, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING = 512; // 0x200
    field @RequiresPermission(value=android.Manifest.permission.FOREGROUND_SERVICE_SPECIAL_USE, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_SPECIAL_USE = 1073741824; // 0x40000000
    field @RequiresPermission(value=android.Manifest.permission.FOREGROUND_SERVICE_SYSTEM_EXEMPTED, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED = 1024; // 0x400
    field public int flags;
    field public String permission;
  }
+23 −2
Original line number Diff line number Diff line
@@ -1398,9 +1398,18 @@ public class AppOpsManager {
     */
    public static final int OP_READ_WRITE_HEALTH_DATA = AppProtoEnums.APP_OP_READ_WRITE_HEALTH_DATA;

    /**
     * Use foreground service with the type
     * {@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_SPECIAL_USE}.
     *
     * @hide
     */
    public static final int OP_FOREGROUND_SERVICE_SPECIAL_USE =
            AppProtoEnums.APP_OP_FOREGROUND_SERVICE_SPECIAL_USE;

    /** @hide */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public static final int _NUM_OP = 127;
    public static final int _NUM_OP = 128;

    /** Access to coarse location information. */
    public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -1930,6 +1939,14 @@ public class AppOpsManager {
    public static final String OPSTR_SYSTEM_EXEMPT_FROM_FORCED_APP_STANDBY =
            "android:system_exempt_from_forced_app_standby";

    /**
     * Start a foreground service with the type "specialUse".
     *
     * @hide
     */
    public static final String OPSTR_FOREGROUND_SERVICE_SPECIAL_USE =
            "android:foreground_service_special_use";

    /** {@link #sAppOpsToNote} not initialized yet for this op */
    private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
    /** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
@@ -2026,6 +2043,7 @@ public class AppOpsManager {
            OP_TURN_SCREEN_ON,
            OP_RUN_LONG_JOBS,
            OP_READ_MEDIA_VISUAL_USER_SELECTED,
            OP_FOREGROUND_SERVICE_SPECIAL_USE,
    };

    static final AppOpInfo[] sAppOpInfos = new AppOpInfo[]{
@@ -2419,7 +2437,10 @@ public class AppOpsManager {
                OPSTR_SYSTEM_EXEMPT_FROM_FORCED_APP_STANDBY,
                "SYSTEM_EXEMPT_FROM_FORCED_APP_STANDBY").build(),
        new AppOpInfo.Builder(OP_READ_WRITE_HEALTH_DATA, OPSTR_READ_WRITE_HEALTH_DATA,
                "READ_WRITE_HEALTH_DATA").setDefaultMode(AppOpsManager.MODE_ALLOWED).build()
                "READ_WRITE_HEALTH_DATA").setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
        new AppOpInfo.Builder(OP_FOREGROUND_SERVICE_SPECIAL_USE,
                OPSTR_FOREGROUND_SERVICE_SPECIAL_USE, "FOREGROUND_SERVICE_SPECIAL_USE")
                .setPermission(Manifest.permission.FOREGROUND_SERVICE_SPECIAL_USE).build(),
    };

    // The number of longs needed to form a full bitmask of app ops
+1033 −0

File added.

Preview size limit exceeded, changes collapsed.

+93 −44
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentCallbacks2;
import android.content.ComponentName;
@@ -726,10 +727,32 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
     * for more details.
     * </div>
     *
     * <div class="caution">
     * <p><strong>Note:</strong>
     * Beginning with SDK Version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE},
     * apps targeting SDK Version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}
     * or higher are not allowed to start foreground services without specifying a valid
     * foreground service type in the manifest attribute
     * {@link android.R.attr#foregroundServiceType}.
     * See
     * <a href="{@docRoot}/about/versions/14/behavior-changes-14">
     * Behavior changes: Apps targeting Android 14
     * </a>
     * for more details.
     * </div>
     *
     * @throws ForegroundServiceStartNotAllowedException
     * If the app targeting API is
     * {@link android.os.Build.VERSION_CODES#S} or later, and the service is restricted from
     * becoming foreground service due to background restriction.
     * @throws ForegroundServiceTypeNotAllowedException
     * If the app targeting API is
     * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or later, and the manifest attribute
     * {@link android.R.attr#foregroundServiceType} is not set.
     * @throws SecurityException If the app targeting API is
     * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or later and doesn't have the
     * permission to start the foreground service with the specified type in the manifest attribute
     * {@link android.R.attr#foregroundServiceType}.
     *
     * @param id The identifier for this notification as per
     * {@link NotificationManager#notify(int, Notification)
@@ -757,9 +780,9 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
     * service element of manifest file. The value of attribute
     * {@link android.R.attr#foregroundServiceType} can be multiple flags ORed together.</p>
     *
   * <p>The foregroundServiceType parameter must be a subset flags of what is specified in manifest
   * attribute {@link android.R.attr#foregroundServiceType}, if not, an IllegalArgumentException is
   * thrown. Specify foregroundServiceType parameter as
     * <p>The foregroundServiceType parameter must be a subset flags of what is specified in
     * manifest attribute {@link android.R.attr#foregroundServiceType}, if not, an
     * IllegalArgumentException is thrown. Specify foregroundServiceType parameter as
     * {@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_MANIFEST} to use all flags that
     * is specified in manifest attribute foregroundServiceType.</p>
     *
@@ -775,12 +798,28 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
     * for more details.
     * </div>
     *
     * <div class="caution">
     * <p><strong>Note:</strong>
     * Beginning with SDK Version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE},
     * apps targeting SDK Version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}
     * or higher are not allowed to start foreground services without specifying a valid
     * foreground service type in the manifest attribute
     * {@link android.R.attr#foregroundServiceType}, and the parameter {@code foregroundServiceType}
     * here must not be the {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_NONE}.
     * See
     * <a href="{@docRoot}/about/versions/14/behavior-changes-14">
     * Behavior changes: Apps targeting Android 14
     * </a>
     * for more details.
     * </div>
     *
     * @param id The identifier for this notification as per
     * {@link NotificationManager#notify(int, Notification)
     * NotificationManager.notify(int, Notification)}; must not be 0.
     * @param notification The Notification to be displayed.
     * @param foregroundServiceType must be a subset flags of manifest attribute
   * {@link android.R.attr#foregroundServiceType} flags.
     * {@link android.R.attr#foregroundServiceType} flags; must not be
     * {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_NONE}.
     *
     * @throws IllegalArgumentException if param foregroundServiceType is not subset of manifest
     *     attribute {@link android.R.attr#foregroundServiceType}.
@@ -788,11 +827,21 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
     * If the app targeting API is
     * {@link android.os.Build.VERSION_CODES#S} or later, and the service is restricted from
     * becoming foreground service due to background restriction.
     * @throws ForegroundServiceTypeNotAllowedException
     * If the app targeting API is
     * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or later, and the manifest attribute
     * {@link android.R.attr#foregroundServiceType} is not set, or the param
     * {@code foregroundServiceType} is {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_NONE}.
     * @throws SecurityException If the app targeting API is
     * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or later and doesn't have the
     * permission to start the foreground service with the specified type in
     * {@code foregroundServiceType}.
     * {@link android.R.attr#foregroundServiceType}.
     *
     * @see android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_MANIFEST
     */
    public final void startForeground(int id, @NonNull Notification notification,
            @ForegroundServiceType int foregroundServiceType) {
            @RequiresPermission @ForegroundServiceType int foregroundServiceType) {
        try {
            mActivityManager.setServiceForeground(
                    new ComponentName(this, mClassName), mToken, id,
+15 −0
Original line number Diff line number Diff line
@@ -164,6 +164,21 @@ public abstract class PackageManager {
    public static final String PROPERTY_NO_APP_DATA_STORAGE =
            "android.internal.PROPERTY_NO_APP_DATA_STORAGE";

    /**
     * &lt;service&gt; level {@link android.content.pm.PackageManager.Property} tag specifying
     * the actual use case of the service if it's foreground service with the type
     * {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_SPECIAL_USE}.
     *
     * <p>
     * For example:
     * &lt;service&gt;
     *   &lt;property android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
     *     android:value="foo"/&gt;
     * &lt;/service&gt;
     */
    public static final String PROPERTY_SPECIAL_USE_FGS_SUBTYPE =
            "android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE";

    /**
     * A property value set within the manifest.
     * <p>
Loading