/* * Copyright (C) 2007 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.content.pm; import android.Manifest; import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.RequiresPermission; import android.os.Parcel; import android.os.Parcelable; import android.util.Printer; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Information you can retrieve about a particular application * service. This corresponds to information collected from the * AndroidManifest.xml's <service> tags. */ @android.ravenwood.annotation.RavenwoodKeepWholeClass public class ServiceInfo extends ComponentInfo implements Parcelable { /** * Optional name of a permission required to be able to access this * Service. From the "permission" attribute. */ public String permission; /** * Bit in {@link #flags}: If set, the service will automatically be * stopped by the system if the user removes a task that is rooted * in one of the application's activities. Set from the * {@link android.R.attr#stopWithTask} attribute. */ public static final int FLAG_STOP_WITH_TASK = 0x0001; /** * Bit in {@link #flags}: If set, the service will run in its own * isolated process. Set from the * {@link android.R.attr#isolatedProcess} attribute. */ public static final int FLAG_ISOLATED_PROCESS = 0x0002; /** * Bit in {@link #flags}: If set, the service can be bound and run in the * calling application's package, rather than the package in which it is * declared. Set from {@link android.R.attr#externalService} attribute. */ public static final int FLAG_EXTERNAL_SERVICE = 0x0004; /** * Bit in {@link #flags}: If set, the service (which must be isolated) * will be spawned from an Application Zygote, instead of the regular Zygote. * The Application Zygote will pre-initialize the application's class loader, * and call a static callback into the application to allow it to perform * application-specific preloads (such as loading a shared library). Therefore, * spawning from the Application Zygote will typically reduce the service * launch time and reduce its memory usage. The downside of using this flag * is that you will have an additional process (the app zygote itself) that * is taking up memory. Whether actual memory usage is improved therefore * strongly depends on the number of isolated services that an application * starts, and how much memory those services save by preloading. Therefore, * it is recommended to measure memory usage under typical workloads to * determine whether it makes sense to use this flag. */ public static final int FLAG_USE_APP_ZYGOTE = 0x0008; /** * Bit in {@link #flags}: If set, and this is an {@link android.R.attr#isolatedProcess} * service, the service is allowed to be bound in a shared isolated process with other * isolated services. Note that these other isolated services can also belong to other * apps from different vendors. * * Shared isolated processes are created when using the * {@link android.content.Context#BIND_SHARED_ISOLATED_PROCESS) during service binding. * * Note that when this flag is used, the {@link android.R.attr#process} attribute is * ignored when the process is bound into a shared isolated process by a client. */ public static final int FLAG_ALLOW_SHARED_ISOLATED_PROCESS = 0x0010; /** * Bit in {@link #flags} indicating if the service is visible to ephemeral applications. * @hide */ public static final int FLAG_VISIBLE_TO_INSTANT_APP = 0x100000; /** * @hide Bit in {@link #flags}: If set, this service will only be available * for the system user. * Set from the android.R.attr#systemUserOnly attribute. * In Sync with {@link ActivityInfo#FLAG_SYSTEM_USER_ONLY} */ public static final int FLAG_SYSTEM_USER_ONLY = ActivityInfo.FLAG_SYSTEM_USER_ONLY; /** * Bit in {@link #flags}: If set, a single instance of the service will * run for all users on the device. Set from the * {@link android.R.attr#singleUser} attribute. */ public static final int FLAG_SINGLE_USER = 0x40000000; /** * Options that have been set in the service declaration in the * manifest. * These include: * {@link #FLAG_STOP_WITH_TASK}, {@link #FLAG_ISOLATED_PROCESS}, * {@link #FLAG_SINGLE_USER}. */ public int flags; /** * 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.InvalidForegroundServiceTypeException}.
* * @deprecated Do not use. */ @Deprecated public static final int FOREGROUND_SERVICE_TYPE_NONE = 0; /** * Constant corresponding todataSync
in
* 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.
*
* This type has time limit of 6 hours starting from Android version * {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}. * A foreground service of this type must be stopped within the timeout by * {@link android.app.Service#stopSelf()}, * {@link android.content.Context#stopService(android.content.Intent)} or their overloads). * {@link android.app.Service#stopForeground(int)} will also work, which will demote the * service to a "background" service, which will soon be stopped by the system. * *
If the service isn't stopped within the timeout, * {@link android.app.Service#onTimeout(int, int)} will be called. * *
Also note, even though
* {@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_DATA_SYNC} can be used on
* Android versions prior to {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}, since
* {@link android.app.Service#onTimeout(int, int)} did not exist on such versions, it will
* never be called.
*
* Because of this, developers must make sure to stop the foreground service even if
* {@link android.app.Service#onTimeout(int, int)} is not called on such versions.
*
* @see android.app.Service#onTimeout(int, int)
*/
@RequiresPermission(
value = Manifest.permission.FOREGROUND_SERVICE_DATA_SYNC,
conditional = true
)
public static final int FOREGROUND_SERVICE_TYPE_DATA_SYNC = 1 << 0;
/**
* Constant corresponding to mediaPlayback
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;
/**
* Constant corresponding to phoneCall
in
* 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} or holding the default
* {@link android.app.role.RoleManager#ROLE_DIALER dialer role}.
*/
@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_ADVERTISE}, * {@link android.Manifest.permission#BLUETOOTH_CONNECT}, * {@link android.Manifest.permission#BLUETOOTH_SCAN}, * {@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}, * {@link android.Manifest.permission#UWB_RANGING}, * 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_ADVERTISE, Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.CHANGE_NETWORK_STATE, Manifest.permission.CHANGE_WIFI_STATE, Manifest.permission.CHANGE_WIFI_MULTICAST_STATE, Manifest.permission.NFC, Manifest.permission.TRANSMIT_IR, Manifest.permission.UWB_RANGING, }, 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 foregroundServiceType} attribute. * *
* To capture through {@link android.media.projection.MediaProjection}, an app must start a * foreground service with the type corresponding to this constant. This type should only be * used for {@link android.media.projection.MediaProjection}. Capturing screen contents via * {@link android.media.projection.MediaProjection#createVirtualDisplay(String, int, int, int, * int, android.view.Surface, android.hardware.display.VirtualDisplay.Callback, * android.os.Handler) createVirtualDisplay} conveniently allows recording, presenting screen * contents into a meeting, taking screenshots, or several other scenarios. *
* *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;
/**
* Constant corresponding to {@code camera} in
* the {@link android.R.attr#foregroundServiceType} attribute.
* Use the camera device or record video.
* For apps with targetSdkVersion
{@link android.os.Build.VERSION_CODES#R} and
* 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;
/**
* Constant corresponding to {@code microphone} in
* the {@link android.R.attr#foregroundServiceType} attribute.
* Use the microphone device or record audio.
* For apps with targetSdkVersion
{@link android.os.Build.VERSION_CODES#R} and
* 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; /** * 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, } ) 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 ) 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 exempted foreground service use cases. * *
Note, apps are allowed to use this type only in the following cases: *
Unlike other foreground service types, this type is not associated with a specific use * case, and it will not require any special permissions * (besides {@link android.Manifest.permission#FOREGROUND_SERVICE}). * * However, this type has the following restrictions. * *
If the service isn't stopped within the timeout, * {@link android.app.Service#onTimeout(int)} will be called. Note, even when the * system calls this callback, it will not stop the service automatically. * You still need to stop the service using one of the aforementioned * ways even when you get this callback. * *
If the service is still not stopped after the callback, * the app will be declared an ANR, after a short grace period of several seconds. *
Also note, even though * {@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_MEDIA_PROCESSING} was added in * Android version {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}, it can be also used * on prior android versions (just like other new foreground service types can be used). * However, because {@link android.app.Service#onTimeout(int, int)} did not exist on prior * versions, it will never be called on such versions. * Because of this, developers must make sure to stop the foreground service even if * {@link android.app.Service#onTimeout(int, int)} is not called on such versions. * * @see android.app.Service#onTimeout(int, int) */ @RequiresPermission( value = Manifest.permission.FOREGROUND_SERVICE_MEDIA_PROCESSING ) @FlaggedApi(Flags.FLAG_INTRODUCE_MEDIA_PROCESSING_TYPE) public static final int FOREGROUND_SERVICE_TYPE_MEDIA_PROCESSING = 1 << 13; /** * Constant corresponding to {@code specialUse} in * the {@link android.R.attr#foregroundServiceType} attribute. * Use cases that can't be categorized into any other foreground service types, but also * can't use {@link android.app.job.JobInfo.Builder} APIs. * *
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.permission.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.permission.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 ) 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 FOREGROUND_SERVICE_TYPES_MAX_INDEX = 30; /** * A special value indicates to use all types set in manifest file. */ public static final int FOREGROUND_SERVICE_TYPE_MANIFEST = -1; /** * The set of flags for foreground service type. * The foreground service type is set in {@link android.R.attr#foregroundServiceType} * attribute. * @hide */ @IntDef(flag = true, prefix = { "FOREGROUND_SERVICE_TYPE_" }, value = { FOREGROUND_SERVICE_TYPE_MANIFEST, FOREGROUND_SERVICE_TYPE_NONE, FOREGROUND_SERVICE_TYPE_DATA_SYNC, FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK, FOREGROUND_SERVICE_TYPE_PHONE_CALL, FOREGROUND_SERVICE_TYPE_LOCATION, FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE, FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION, FOREGROUND_SERVICE_TYPE_CAMERA, FOREGROUND_SERVICE_TYPE_MICROPHONE, FOREGROUND_SERVICE_TYPE_HEALTH, FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING, FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED, FOREGROUND_SERVICE_TYPE_SHORT_SERVICE, FOREGROUND_SERVICE_TYPE_FILE_MANAGEMENT, FOREGROUND_SERVICE_TYPE_MEDIA_PROCESSING, FOREGROUND_SERVICE_TYPE_SPECIAL_USE, }) @Retention(RetentionPolicy.SOURCE) public @interface ForegroundServiceType {} /** * The type of foreground service, set in * {@link android.R.attr#foregroundServiceType} attribute by ORing flags in * {@link ForegroundServiceType} * @hide */ public @ForegroundServiceType int mForegroundServiceType = FOREGROUND_SERVICE_TYPE_NONE; public ServiceInfo() { } public ServiceInfo(ServiceInfo orig) { super(orig); permission = orig.permission; flags = orig.flags; mForegroundServiceType = orig.mForegroundServiceType; } /** * Return foreground service type specified in the manifest.. * @return foreground service type specified in the manifest. */ public @ForegroundServiceType int getForegroundServiceType() { return mForegroundServiceType; } public void dump(Printer pw, String prefix) { dump(pw, prefix, DUMP_FLAG_ALL); } /** @hide */ void dump(Printer pw, String prefix, int dumpFlags) { super.dumpFront(pw, prefix); pw.println(prefix + "permission=" + permission); pw.println(prefix + "flags=0x" + Integer.toHexString(flags)); super.dumpBack(pw, prefix, dumpFlags); } public String toString() { return "ServiceInfo{" + Integer.toHexString(System.identityHashCode(this)) + " " + name + "}"; } /** * @return The label for the given foreground service type. * * @hide */ public static String foregroundServiceTypeToLabel(@ForegroundServiceType int type) { switch (type) { case FOREGROUND_SERVICE_TYPE_MANIFEST: return "manifest"; case FOREGROUND_SERVICE_TYPE_NONE: return "none"; case FOREGROUND_SERVICE_TYPE_DATA_SYNC: return "dataSync"; case FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK: return "mediaPlayback"; case FOREGROUND_SERVICE_TYPE_PHONE_CALL: return "phoneCall"; case FOREGROUND_SERVICE_TYPE_LOCATION: return "location"; case FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE: return "connectedDevice"; case FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION: return "mediaProjection"; case FOREGROUND_SERVICE_TYPE_CAMERA: 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_SHORT_SERVICE: return "shortService"; case FOREGROUND_SERVICE_TYPE_FILE_MANAGEMENT: return "fileManagement"; case FOREGROUND_SERVICE_TYPE_MEDIA_PROCESSING: return "mediaProcessing"; case FOREGROUND_SERVICE_TYPE_SPECIAL_USE: return "specialUse"; default: return "unknown"; } } public int describeContents() { return 0; } public void writeToParcel(Parcel dest, int parcelableFlags) { super.writeToParcel(dest, parcelableFlags); dest.writeString8(permission); dest.writeInt(flags); dest.writeInt(mForegroundServiceType); } public static final @android.annotation.NonNull Creator