diff --git a/core/api/current.txt b/core/api/current.txt index b89c3f7ffd956..b01afa4aa8d19 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -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; } diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 0f4644c63b8d3..e9796dba670ce 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -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 diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java index 7635138f6cdde..01e4b150fd7c6 100644 --- a/core/java/android/app/Service.java +++ b/core/java/android/app/Service.java @@ -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. * * + *
Note: + * 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 + * + * Behavior changes: Apps targeting Android 14 + * + * for more details. + *
Apps built with SDK version {@link android.os.Build.VERSION_CODES#Q} or later can specify - * the foreground service types using attribute {@link android.R.attr#foregroundServiceType} in - * service element of manifest file. The value of attribute - * {@link android.R.attr#foregroundServiceType} can be multiple flags ORed together.
- * - *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.
- * - *Note: - * Beginning with SDK Version {@link android.os.Build.VERSION_CODES#S}, - * apps targeting SDK Version {@link android.os.Build.VERSION_CODES#S} - * or higher are not allowed to start foreground services from the background. - * See - * - * Behavior changes: Apps targeting Android 12 - * - * for more details. - *
Apps built with SDK version {@link android.os.Build.VERSION_CODES#Q} or later can specify + * the foreground service types using attribute {@link android.R.attr#foregroundServiceType} in + * service element of manifest file. The value of attribute + * {@link android.R.attr#foregroundServiceType} can be multiple flags ORed together.
+ * + *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.
+ * + *Note: + * Beginning with SDK Version {@link android.os.Build.VERSION_CODES#S}, + * apps targeting SDK Version {@link android.os.Build.VERSION_CODES#S} + * or higher are not allowed to start foreground services from the background. + * See + * + * Behavior changes: Apps targeting Android 12 + * + * for more details. + *
Note: + * 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 + * + * Behavior changes: Apps targeting Android 14 + * + * for more details. + *
+ * For example: + * <service> + * <property android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE" + * android:value="foo"/> + * </service> + */ + public static final String PROPERTY_SPECIAL_USE_FGS_SUBTYPE = + "android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"; + /** * A property value set within the manifest. *
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java index 88d700432e8ae..ab20b6f7f9ccb 100644 --- a/core/java/android/content/pm/ServiceInfo.java +++ b/core/java/android/content/pm/ServiceInfo.java @@ -16,7 +16,9 @@ package android.content.pm; +import android.Manifest; import android.annotation.IntDef; +import android.annotation.RequiresPermission; import android.os.Parcel; import android.os.Parcelable; import android.util.Printer; @@ -100,7 +102,15 @@ public class ServiceInfo extends ComponentInfo /** * The default foreground service type if not been set in manifest file. + * + *
Apps targeting API level {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and + * later should NOT use this type, + * calling {@link android.app.Service#startForeground(int, android.app.Notification, int)} with + * this type will get a {@link android.app.ForegroundServiceTypeNotAllowedException}.
+ * + * @deprecated Do not use. */ + @Deprecated public static final int FOREGROUND_SERVICE_TYPE_NONE = 0; /** @@ -108,14 +118,36 @@ public class ServiceInfo extends ComponentInfo * the {@link android.R.attr#foregroundServiceType} attribute. * Data(photo, file, account) upload/download, backup/restore, import/export, fetch, * transfer over network between device and cloud. + * + *Apps targeting API level {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and + * later should NOT use this type: + * calling {@link android.app.Service#startForeground(int, android.app.Notification, int)} with + * this type on devices running {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} is still + * allowed, but calling it with this type on devices running future platform releases may get a + * {@link android.app.ForegroundServiceTypeNotAllowedException}.
+ * + * @deprecated Use {@link android.app.job.JobInfo.Builder} data transfer APIs instead. */ + @RequiresPermission( + value = Manifest.permission.FOREGROUND_SERVICE_DATA_SYNC, + conditional = true + ) + @Deprecated public static final int FOREGROUND_SERVICE_TYPE_DATA_SYNC = 1 << 0; /** * Constant corresponding tomediaPlayback in
* the {@link android.R.attr#foregroundServiceType} attribute.
* Music, video, news or other media playback.
+ *
+ * Starting foreground service with this type from apps targeting API level + * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and later, will require permission + * {@link android.Manifest.permission#FOREGROUND_SERVICE_MEDIA_PLAYBACK}. */ + @RequiresPermission( + value = Manifest.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK, + conditional = true + ) public static final int FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK = 1 << 1; /** @@ -123,28 +155,94 @@ public class ServiceInfo extends ComponentInfo * the {@link android.R.attr#foregroundServiceType} attribute. * Ongoing operations related to phone calls, video conferencing, * or similar interactive communication. + * + *
Starting foreground service with this type from apps targeting API level
+ * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and later, will require permission
+ * {@link android.Manifest.permission#FOREGROUND_SERVICE_PHONE_CALL} and
+ * {@link android.Manifest.permission#MANAGE_OWN_CALLS}.
*/
+ @RequiresPermission(
+ allOf = {
+ Manifest.permission.FOREGROUND_SERVICE_PHONE_CALL,
+ },
+ anyOf = {
+ Manifest.permission.MANAGE_OWN_CALLS,
+ },
+ conditional = true
+ )
public static final int FOREGROUND_SERVICE_TYPE_PHONE_CALL = 1 << 2;
/**
* Constant corresponding to location in
* the {@link android.R.attr#foregroundServiceType} attribute.
* GPS, map, navigation location update.
+ *
+ *
Starting foreground service with this type from apps targeting API level
+ * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and later, will require permission
+ * {@link android.Manifest.permission#FOREGROUND_SERVICE_LOCATION} and one of the
+ * following permissions:
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION},
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION}.
*/
+ @RequiresPermission(
+ allOf = {
+ Manifest.permission.FOREGROUND_SERVICE_LOCATION,
+ },
+ anyOf = {
+ Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION,
+ },
+ conditional = true
+ )
public static final int FOREGROUND_SERVICE_TYPE_LOCATION = 1 << 3;
/**
* Constant corresponding to connectedDevice in
* the {@link android.R.attr#foregroundServiceType} attribute.
* Auto, bluetooth, TV or other devices connection, monitoring and interaction.
+ *
+ *
Starting foreground service with this type from apps targeting API level + * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and later, will require permission + * {@link android.Manifest.permission#FOREGROUND_SERVICE_CONNECTED_DEVICE} and one of the + * following permissions: + * {@link android.Manifest.permission#BLUETOOTH_CONNECT}, + * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}, + * {@link android.Manifest.permission#CHANGE_WIFI_STATE}, + * {@link android.Manifest.permission#CHANGE_WIFI_MULTICAST_STATE}, + * {@link android.Manifest.permission#NFC}, + * {@link android.Manifest.permission#TRANSMIT_IR}, + * or has been granted the access to one of the attached USB devices/accessories. */ + @RequiresPermission( + allOf = { + Manifest.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE, + }, + anyOf = { + Manifest.permission.BLUETOOTH_CONNECT, + Manifest.permission.CHANGE_NETWORK_STATE, + Manifest.permission.CHANGE_WIFI_STATE, + Manifest.permission.CHANGE_WIFI_MULTICAST_STATE, + Manifest.permission.NFC, + Manifest.permission.TRANSMIT_IR, + }, + conditional = true + ) public static final int FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE = 1 << 4; /** * Constant corresponding to {@code mediaProjection} in * the {@link android.R.attr#foregroundServiceType} attribute. * Managing a media projection session, e.g for screen recording or taking screenshots. + * + *
Starting foreground service with this type from apps targeting API level + * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and later, will require permission + * {@link android.Manifest.permission#FOREGROUND_SERVICE_MEDIA_PROJECTION}, and the user must + * have allowed the screen capture request from this app. */ + @RequiresPermission( + value = Manifest.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION, + conditional = true + ) public static final int FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION = 1 << 5; /** @@ -155,7 +253,21 @@ public class ServiceInfo extends ComponentInfo * above, a foreground service will not be able to access the camera if this type is not * specified in the manifest and in * {@link android.app.Service#startForeground(int, android.app.Notification, int)}. + * + *
Starting foreground service with this type from apps targeting API level + * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and later, will require permission + * {@link android.Manifest.permission#FOREGROUND_SERVICE_CAMERA} and + * {@link android.Manifest.permission#CAMERA}. */ + @RequiresPermission( + allOf = { + Manifest.permission.FOREGROUND_SERVICE_CAMERA, + }, + anyOf = { + Manifest.permission.CAMERA, + }, + conditional = true + ) public static final int FOREGROUND_SERVICE_TYPE_CAMERA = 1 << 6; /** @@ -166,17 +278,148 @@ public class ServiceInfo extends ComponentInfo * above, a foreground service will not be able to access the microphone if this type is not * specified in the manifest and in * {@link android.app.Service#startForeground(int, android.app.Notification, int)}. + * + *
Starting foreground service with this type from apps targeting API level + * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and later, will require permission + * {@link android.Manifest.permission#FOREGROUND_SERVICE_MICROPHONE} and one of the following + * permissions: + * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT}, + * {@link android.Manifest.permission#RECORD_AUDIO}. */ + @RequiresPermission( + allOf = { + Manifest.permission.FOREGROUND_SERVICE_MICROPHONE, + }, + anyOf = { + Manifest.permission.CAPTURE_AUDIO_OUTPUT, + Manifest.permission.RECORD_AUDIO, + }, + conditional = true + ) public static final int FOREGROUND_SERVICE_TYPE_MICROPHONE = 1 << 7; /** - * The number of foreground service types, this doesn't include - * the {@link #FOREGROUND_SERVICE_TYPE_MANIFEST} and {@link #FOREGROUND_SERVICE_TYPE_NONE} - * as they're not real service types. + * Constant corresponding to {@code health} in + * the {@link android.R.attr#foregroundServiceType} attribute. + * Health, wellness and fitness. + * + *
The caller app is required to have the permissions + * {@link android.Manifest.permission#FOREGROUND_SERVICE_HEALTH} and one of the following + * permissions: + * {@link android.Manifest.permission#ACTIVITY_RECOGNITION}, + * {@link android.Manifest.permission#BODY_SENSORS}, + * {@link android.Manifest.permission#HIGH_SAMPLING_RATE_SENSORS}. + */ + @RequiresPermission( + allOf = { + Manifest.permission.FOREGROUND_SERVICE_HEALTH, + }, + anyOf = { + Manifest.permission.ACTIVITY_RECOGNITION, + Manifest.permission.BODY_SENSORS, + Manifest.permission.HIGH_SAMPLING_RATE_SENSORS, + }, + conditional = true + ) + public static final int FOREGROUND_SERVICE_TYPE_HEALTH = 1 << 8; + + /** + * Constant corresponding to {@code remoteMessaging} in + * the {@link android.R.attr#foregroundServiceType} attribute. + * Messaging use cases which host local server to relay messages across devices. + */ + @RequiresPermission( + value = Manifest.permission.FOREGROUND_SERVICE_REMOTE_MESSAGING, + conditional = true + ) + public static final int FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING = 1 << 9; + + /** + * Constant corresponding to {@code systemExempted} in + * the {@link android.R.attr#foregroundServiceType} attribute. + * The system exmpted foreground service use cases. + * + *
Note, apps are allowed to use this type only in the following cases: + *
The use of this foreground service type may be restricted. Additionally, apps must declare + * a service-level {@link PackageManager#PROPERTY_SPECIAL_USE_FGS_SUBTYPE <property>} in + * {@code AndroidManifest.xml} as a hint of what the exact use case here is. + * Here is an example: + *
+ * <uses-permission + * android:name="android.permissions.FOREGROUND_SERVICE_SPECIAL_USE" + * /> + * <service + * android:name=".MySpecialForegroundService" + * android:foregroundServiceType="specialUse"> + * <property + * android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE" + * android:value="foo" + * /> + * </service> + *+ * + * In a future release of Android, if the above foreground service type {@code foo} is supported + * by the platform, to offer the backward compatibility, the app could specify + * the {@code android:maxSdkVersion} attribute in the <uses-permission> section, + * and also add the foreground service type {@code foo} into + * the {@code android:foregroundServiceType}, therefore the same app could be installed + * in both platforms. + *
+ * <uses-permission + * android:name="android.permissions.FOREGROUND_SERVICE_SPECIAL_USE" + * android:maxSdkVersion="last_sdk_version_without_type_foo" + * /> + * <service + * android:name=".MySpecialForegroundService" + * android:foregroundServiceType="specialUse|foo"> + * <property + * android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"" + * android:value="foo" + * /> + * </service> + *+ */ + @RequiresPermission( + value = Manifest.permission.FOREGROUND_SERVICE_SPECIAL_USE, + conditional = true + ) + public static final int FOREGROUND_SERVICE_TYPE_SPECIAL_USE = 1 << 30; + + /** + * The max index being used in the definition of foreground service types. * * @hide */ - public static final int NUM_OF_FOREGROUND_SERVICE_TYPES = 8; + public static final int FOREGROUND_SERVICE_TYPES_MAX_INDEX = 30; /** * A special value indicates to use all types set in manifest file. @@ -199,7 +442,11 @@ public class ServiceInfo extends ComponentInfo FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE, FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION, FOREGROUND_SERVICE_TYPE_CAMERA, - FOREGROUND_SERVICE_TYPE_MICROPHONE + FOREGROUND_SERVICE_TYPE_MICROPHONE, + FOREGROUND_SERVICE_TYPE_HEALTH, + FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING, + FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED, + FOREGROUND_SERVICE_TYPE_SPECIAL_USE }) @Retention(RetentionPolicy.SOURCE) public @interface ForegroundServiceType {} @@ -275,6 +522,14 @@ public class ServiceInfo extends ComponentInfo return "camera"; case FOREGROUND_SERVICE_TYPE_MICROPHONE: return "microphone"; + case FOREGROUND_SERVICE_TYPE_HEALTH: + return "health"; + case FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING: + return "remoteMessaging"; + case FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED: + return "systemExempted"; + case FOREGROUND_SERVICE_TYPE_SPECIAL_USE: + return "specialUse"; default: return "unknown"; } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 7ada5483b92be..196ea59fe0f41 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -6184,6 +6184,116 @@ android:label="@string/permlab_foregroundService" android:protectionLevel="normal|instant" /> + +
For apps with targetSdkVersion
+ {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and above, this type should NOT
+ be used: calling
+ {@link android.app.Service#startForeground(int, android.app.Notification, int)} with
+ this type on devices running {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}
+ is still allowed, but calling it with this type on devices running future platform
+ releases may get a {@link android.app.ForegroundServiceTypeNotAllowedException}.
+ -->
For apps with targetSdkVersion
+ {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and above, starting a foreground
+ service with this type will require permission
+ {@link android.Manifest.permission#FOREGROUND_SERVICE_PHONE_CALL} and
+ {@link android.Manifest.permission#MANAGE_OWN_CALLS}.
+ -->
For apps with targetSdkVersion
+ {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and above, starting a foreground
+ service with this type will require permission
+ {@link android.Manifest.permission#FOREGROUND_SERVICE_MEDIA_PROJECTION}, and the user
+ must have allowed the screen capture request from this app.
+ -->