Loading core/java/android/companion/CompanionDeviceService.java +59 −17 Original line number Diff line number Diff line Loading @@ -31,29 +31,71 @@ import android.util.Log; import java.util.Objects; /** * Service to be implemented by apps that manage a companion device. * * System will keep this service bound whenever an associated device is nearby for Bluetooth * devices or companion app manages the connectivity and reports disappeared, ensuring app stays * alive * * An app must be {@link CompanionDeviceManager#associate associated} with at leas one device, * before it can take advantage of this service. * * You must declare this service in your manifest with an * intent-filter action of {@link #SERVICE_INTERFACE} and * permission of {@link android.Manifest.permission#BIND_COMPANION_DEVICE_SERVICE} * * <p>If you want to declare more than one of these services, you must declare the meta-data in the * service of your manifest with the corresponding name and value to true to indicate the * primary service. * Only the primary one will get the callback from * {@link #onDeviceAppeared(AssociationInfo associationInfo)}.</p> * * Example: * A service that receives calls from the system when the associated companion device appears * nearby or is connected, as well as when the device is no longer "present" or connected. * See {@link #onDeviceAppeared(AssociationInfo)}/{@link #onDeviceDisappeared(AssociationInfo)}. * * <p> * Additionally, the service will receive a call from the system, if and when the system needs to * transfer data to the companion device. * See {@link #dispatchMessage(int, int, byte[])}). * * <p> * Companion applications must create a service that {@code extends} * {@link CompanionDeviceService}, and declare it in their AndroidManifest.xml with the * "android.permission.BIND_COMPANION_DEVICE_SERVICE" permission * (see {@link android.Manifest.permission#BIND_COMPANION_DEVICE_SERVICE}), * as well as add an intent filter for the "android.companion.CompanionDeviceService" action * (see {@link #SERVICE_INTERFACE}). * * <p> * Following is an example of such declaration: * <pre>{@code * <service * android:name=".CompanionService" * android:label="@string/service_name" * android:exported="true" * android:permission="android.permission.BIND_COMPANION_DEVICE_SERVICE"> * <intent-filter> * <action android:name="android.companion.CompanionDeviceService" /> * </intent-filter> * </service> * }</pre> * * <p> * If the companion application has requested observing device presence (see * {@link CompanionDeviceManager#startObservingDevicePresence(String)}) the system will * <a href="https://developer.android.com/guide/components/bound-services"> bind the service</a> * when it detects the device nearby (for BLE devices) or when the device is connected * (for Bluetooth devices). * * <p> * The system binding {@link CompanionDeviceService} elevates the priority of the process that * the service is running in, and thus may prevent * <a href="https://developer.android.com/topic/performance/memory-management#low-memory_killer"> * the Low-memory killer</a> from killing the process at expense of other processes with lower * priority. * * <p> * It is possible for an application to declare multiple {@link CompanionDeviceService}-s. * In such case, the system will bind all declared services, but will deliver * {@link #onDeviceAppeared(AssociationInfo)}, {@link #onDeviceDisappeared(AssociationInfo)} and * {@link #dispatchMessage(int, int, byte[])} only to one "primary" services. * Applications that declare multiple {@link CompanionDeviceService}-s should indicate the "primary" * service using "android.companion.primary" tag. * <pre>{@code * <meta-data * android:name="primary" * android:name="android.companion.primary" * android:value="true" /> * }</pre> * * <p> * If the application declares multiple {@link CompanionDeviceService}-s, but does not indicate * the "primary" one, the system will pick one of the declared services to use as "primary". * * <p> * If the application declares multiple "primary" {@link CompanionDeviceService}-s, the system * will pick single one of them to use as "primary". */ public abstract class CompanionDeviceService extends Service { Loading services/companion/java/com/android/server/companion/CompanionDevicePresenceController.java +1 −1 Original line number Diff line number Diff line Loading @@ -48,7 +48,7 @@ import java.util.Objects; public class CompanionDevicePresenceController { private static final String LOG_TAG = "CompanionDevicePresenceController"; PerUser<ArrayMap<String, List<BoundService>>> mBoundServices; private static final String META_DATA_KEY_PRIMARY = "primary"; private static final String META_DATA_KEY_PRIMARY = "android.companion.primary"; private final CompanionDeviceManagerService mService; public CompanionDevicePresenceController(CompanionDeviceManagerService service) { Loading services/companion/java/com/android/server/companion/PackageUtils.java +2 −2 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ import java.util.Map; final class PackageUtils { private static final Intent COMPANION_SERVICE_INTENT = new Intent(CompanionDeviceService.SERVICE_INTERFACE); private static final String META_DATA_KEY_PRIMARY = "primary"; private static final String META_DATA_PRIMARY_TAG = "android.companion.primary"; static @Nullable PackageInfo getPackageInfo(@NonNull Context context, @UserIdInt int userId, @NonNull String packageName) { Loading Loading @@ -121,6 +121,6 @@ final class PackageUtils { } private static boolean isPrimaryCompanionDeviceService(ServiceInfo service) { return service.metaData != null && service.metaData.getBoolean(META_DATA_KEY_PRIMARY); return service.metaData != null && service.metaData.getBoolean(META_DATA_PRIMARY_TAG); } } Loading
core/java/android/companion/CompanionDeviceService.java +59 −17 Original line number Diff line number Diff line Loading @@ -31,29 +31,71 @@ import android.util.Log; import java.util.Objects; /** * Service to be implemented by apps that manage a companion device. * * System will keep this service bound whenever an associated device is nearby for Bluetooth * devices or companion app manages the connectivity and reports disappeared, ensuring app stays * alive * * An app must be {@link CompanionDeviceManager#associate associated} with at leas one device, * before it can take advantage of this service. * * You must declare this service in your manifest with an * intent-filter action of {@link #SERVICE_INTERFACE} and * permission of {@link android.Manifest.permission#BIND_COMPANION_DEVICE_SERVICE} * * <p>If you want to declare more than one of these services, you must declare the meta-data in the * service of your manifest with the corresponding name and value to true to indicate the * primary service. * Only the primary one will get the callback from * {@link #onDeviceAppeared(AssociationInfo associationInfo)}.</p> * * Example: * A service that receives calls from the system when the associated companion device appears * nearby or is connected, as well as when the device is no longer "present" or connected. * See {@link #onDeviceAppeared(AssociationInfo)}/{@link #onDeviceDisappeared(AssociationInfo)}. * * <p> * Additionally, the service will receive a call from the system, if and when the system needs to * transfer data to the companion device. * See {@link #dispatchMessage(int, int, byte[])}). * * <p> * Companion applications must create a service that {@code extends} * {@link CompanionDeviceService}, and declare it in their AndroidManifest.xml with the * "android.permission.BIND_COMPANION_DEVICE_SERVICE" permission * (see {@link android.Manifest.permission#BIND_COMPANION_DEVICE_SERVICE}), * as well as add an intent filter for the "android.companion.CompanionDeviceService" action * (see {@link #SERVICE_INTERFACE}). * * <p> * Following is an example of such declaration: * <pre>{@code * <service * android:name=".CompanionService" * android:label="@string/service_name" * android:exported="true" * android:permission="android.permission.BIND_COMPANION_DEVICE_SERVICE"> * <intent-filter> * <action android:name="android.companion.CompanionDeviceService" /> * </intent-filter> * </service> * }</pre> * * <p> * If the companion application has requested observing device presence (see * {@link CompanionDeviceManager#startObservingDevicePresence(String)}) the system will * <a href="https://developer.android.com/guide/components/bound-services"> bind the service</a> * when it detects the device nearby (for BLE devices) or when the device is connected * (for Bluetooth devices). * * <p> * The system binding {@link CompanionDeviceService} elevates the priority of the process that * the service is running in, and thus may prevent * <a href="https://developer.android.com/topic/performance/memory-management#low-memory_killer"> * the Low-memory killer</a> from killing the process at expense of other processes with lower * priority. * * <p> * It is possible for an application to declare multiple {@link CompanionDeviceService}-s. * In such case, the system will bind all declared services, but will deliver * {@link #onDeviceAppeared(AssociationInfo)}, {@link #onDeviceDisappeared(AssociationInfo)} and * {@link #dispatchMessage(int, int, byte[])} only to one "primary" services. * Applications that declare multiple {@link CompanionDeviceService}-s should indicate the "primary" * service using "android.companion.primary" tag. * <pre>{@code * <meta-data * android:name="primary" * android:name="android.companion.primary" * android:value="true" /> * }</pre> * * <p> * If the application declares multiple {@link CompanionDeviceService}-s, but does not indicate * the "primary" one, the system will pick one of the declared services to use as "primary". * * <p> * If the application declares multiple "primary" {@link CompanionDeviceService}-s, the system * will pick single one of them to use as "primary". */ public abstract class CompanionDeviceService extends Service { Loading
services/companion/java/com/android/server/companion/CompanionDevicePresenceController.java +1 −1 Original line number Diff line number Diff line Loading @@ -48,7 +48,7 @@ import java.util.Objects; public class CompanionDevicePresenceController { private static final String LOG_TAG = "CompanionDevicePresenceController"; PerUser<ArrayMap<String, List<BoundService>>> mBoundServices; private static final String META_DATA_KEY_PRIMARY = "primary"; private static final String META_DATA_KEY_PRIMARY = "android.companion.primary"; private final CompanionDeviceManagerService mService; public CompanionDevicePresenceController(CompanionDeviceManagerService service) { Loading
services/companion/java/com/android/server/companion/PackageUtils.java +2 −2 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ import java.util.Map; final class PackageUtils { private static final Intent COMPANION_SERVICE_INTENT = new Intent(CompanionDeviceService.SERVICE_INTERFACE); private static final String META_DATA_KEY_PRIMARY = "primary"; private static final String META_DATA_PRIMARY_TAG = "android.companion.primary"; static @Nullable PackageInfo getPackageInfo(@NonNull Context context, @UserIdInt int userId, @NonNull String packageName) { Loading Loading @@ -121,6 +121,6 @@ final class PackageUtils { } private static boolean isPrimaryCompanionDeviceService(ServiceInfo service) { return service.metaData != null && service.metaData.getBoolean(META_DATA_KEY_PRIMARY); return service.metaData != null && service.metaData.getBoolean(META_DATA_PRIMARY_TAG); } }