Loading core/api/current.txt +4 −2 Original line number Diff line number Diff line Loading @@ -10127,8 +10127,10 @@ package android.companion { ctor public CompanionDeviceService(); method @RequiresPermission(android.Manifest.permission.DELIVER_COMPANION_MESSAGES) public final void dispatchMessage(int, int, @NonNull byte[]); method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent); method @MainThread public abstract void onDeviceAppeared(@NonNull String); method @MainThread public abstract void onDeviceDisappeared(@NonNull String); method @Deprecated @MainThread public void onDeviceAppeared(@NonNull String); method @MainThread public void onDeviceAppeared(@NonNull android.companion.AssociationInfo); method @Deprecated @MainThread public void onDeviceDisappeared(@NonNull String); method @MainThread public void onDeviceDisappeared(@NonNull android.companion.AssociationInfo); method @MainThread public void onDispatchMessage(int, int, @NonNull byte[]); field public static final String SERVICE_INTERFACE = "android.companion.CompanionDeviceService"; } core/api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -2428,6 +2428,8 @@ package android.companion { method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean canPairWithoutPrompt(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); method @NonNull @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public java.util.List<android.companion.AssociationInfo> getAllAssociations(); method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean isDeviceAssociatedForWifiConnection(@NonNull String, @NonNull android.net.MacAddress, @NonNull android.os.UserHandle); method @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED) public void notifyDeviceAppeared(int); method @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED) public void notifyDeviceDisappeared(int); method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public void removeOnAssociationsChangedListener(@NonNull android.companion.CompanionDeviceManager.OnAssociationsChangedListener); } core/java/android/companion/CompanionDeviceManager.java +45 −0 Original line number Diff line number Diff line Loading @@ -776,6 +776,51 @@ public final class CompanionDeviceManager { } } /** * Notify the system that the given self-managed association has just 'appeared'. * This causes the system to bind to the companion app to keep it running until the association * is reported as 'disappeared' * * <p>This API is only available for the companion apps that manage the connectivity by * themselves.</p> * * @param associationId the unique {@link AssociationInfo#getId ID} assigned to the Association * recorded by CompanionDeviceManager * * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED) public void notifyDeviceAppeared(int associationId) { try { mService.notifyDeviceAppeared(associationId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Notify the system that the given self-managed association has just 'disappeared'. * This causes the system to unbind to the companion app. * * <p>This API is only available for the companion apps that manage the connectivity by * themselves.</p> * * @param associationId the unique {@link AssociationInfo#getId ID} assigned to the Association * recorded by CompanionDeviceManager * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED) public void notifyDeviceDisappeared(int associationId) { try { mService.notifyDeviceDisappeared(associationId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } private boolean checkFeaturePresent() { boolean featurePresent = mService != null; if (!featurePresent && DEBUG) { Loading core/java/android/companion/CompanionDeviceService.java +60 −16 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.os.Handler; import android.os.IBinder; import android.util.Log; import com.android.internal.util.function.pooled.PooledLambda; import java.util.Objects; Loading @@ -34,8 +35,9 @@ 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, * ensuring app stays alive. * 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. Loading @@ -43,6 +45,17 @@ import java.util.Objects; * 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: * <meta-data * android:name="primary" * android:value="true" /> */ public abstract class CompanionDeviceService extends Service { Loading @@ -52,13 +65,14 @@ public abstract class CompanionDeviceService extends Service { * An intent action for a service to be bound whenever this app's companion device(s) * are nearby. * * <p>The app will be kept alive for as long as the device is nearby. * <p>The app will be kept alive for as long as the device is nearby or companion app reports * appeared. * If the app is not running at the time device gets connected, the app will be woken up.</p> * * <p>Shortly after the device goes out of range, the service will be unbound, and the * app will be eligible for cleanup, unless any other user-visible components are running.</p> * <p>Shortly after the device goes out of range or the companion app reports disappeared, * the service will be unbound, and the app will be eligible for cleanup, unless any other * user-visible components are running.</p> * * <p>An app shouldn't declare more than one of these services. * If running in background is not essential for the devices that this app can manage, * app should avoid declaring this service.</p> * Loading @@ -73,9 +87,13 @@ public abstract class CompanionDeviceService extends Service { * Called by system whenever a device associated with this app is available. * * @param address the MAC address of the device * @deprecated please override {@link #onDeviceAppeared(AssociationInfo)} instead. */ @Deprecated @MainThread public abstract void onDeviceAppeared(@NonNull String address); public void onDeviceAppeared(@NonNull String address) { // Do nothing. Companion apps can override this function. } /** * Called by system whenever a device associated with this app stops being available. Loading @@ -83,9 +101,13 @@ public abstract class CompanionDeviceService extends Service { * Usually this means the device goes out of range or is turned off. * * @param address the MAC address of the device * @deprecated please override {@link #onDeviceDisappeared(AssociationInfo)} instead. */ @Deprecated @MainThread public abstract void onDeviceDisappeared(@NonNull String address); public void onDeviceDisappeared(@NonNull String address) { // Do nothing. Companion apps can override this function. } /** * Called by system whenever the system dispatches a message to the app to send it to Loading Loading @@ -118,6 +140,30 @@ public abstract class CompanionDeviceService extends Service { companionDeviceManager.dispatchMessage(messageId, associationId, message); } /** * Called by system whenever a device associated with this app is connected. * * @param associationInfo A record for the companion device. */ @MainThread public void onDeviceAppeared(@NonNull AssociationInfo associationInfo) { if (!associationInfo.isSelfManaged()) { onDeviceAppeared(associationInfo.getDeviceMacAddressAsString()); } } /** * Called by system whenever a device associated with this app is disconnected. * * @param associationInfo A record for the companion device. */ @MainThread public void onDeviceDisappeared(@NonNull AssociationInfo associationInfo) { if (!associationInfo.isSelfManaged()) { onDeviceDisappeared(associationInfo.getDeviceMacAddressAsString()); } } @Nullable @Override public final IBinder onBind(@NonNull Intent intent) { Loading @@ -132,17 +178,15 @@ public abstract class CompanionDeviceService extends Service { class Stub extends ICompanionDeviceService.Stub { @Override public void onDeviceAppeared(String address) { Handler.getMain().sendMessage(PooledLambda.obtainMessage( CompanionDeviceService::onDeviceAppeared, CompanionDeviceService.this, address)); public void onDeviceAppeared(AssociationInfo associationInfo) { Handler.getMain().post( () -> CompanionDeviceService.this.onDeviceAppeared(associationInfo)); } @Override public void onDeviceDisappeared(String address) { Handler.getMain().sendMessage(PooledLambda.obtainMessage( CompanionDeviceService::onDeviceDisappeared, CompanionDeviceService.this, address)); public void onDeviceDisappeared(AssociationInfo associationInfo) { Handler.getMain().post( () -> CompanionDeviceService.this.onDeviceDisappeared(associationInfo)); } public void onDispatchMessage(int messageId, int associationId, @NonNull byte[] message) { Loading core/java/android/companion/ICompanionDeviceManager.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -65,5 +65,10 @@ interface ICompanionDeviceManager { void dispatchMessage(in int messageId, in int associationId, in byte[] message); void addOnAssociationsChangedListener(IOnAssociationsChangedListener listener, int userId); void removeOnAssociationsChangedListener(IOnAssociationsChangedListener listener, int userId); void notifyDeviceAppeared(int associationId); void notifyDeviceDisappeared(int associationId); } Loading
core/api/current.txt +4 −2 Original line number Diff line number Diff line Loading @@ -10127,8 +10127,10 @@ package android.companion { ctor public CompanionDeviceService(); method @RequiresPermission(android.Manifest.permission.DELIVER_COMPANION_MESSAGES) public final void dispatchMessage(int, int, @NonNull byte[]); method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent); method @MainThread public abstract void onDeviceAppeared(@NonNull String); method @MainThread public abstract void onDeviceDisappeared(@NonNull String); method @Deprecated @MainThread public void onDeviceAppeared(@NonNull String); method @MainThread public void onDeviceAppeared(@NonNull android.companion.AssociationInfo); method @Deprecated @MainThread public void onDeviceDisappeared(@NonNull String); method @MainThread public void onDeviceDisappeared(@NonNull android.companion.AssociationInfo); method @MainThread public void onDispatchMessage(int, int, @NonNull byte[]); field public static final String SERVICE_INTERFACE = "android.companion.CompanionDeviceService"; }
core/api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -2428,6 +2428,8 @@ package android.companion { method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean canPairWithoutPrompt(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); method @NonNull @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public java.util.List<android.companion.AssociationInfo> getAllAssociations(); method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean isDeviceAssociatedForWifiConnection(@NonNull String, @NonNull android.net.MacAddress, @NonNull android.os.UserHandle); method @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED) public void notifyDeviceAppeared(int); method @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED) public void notifyDeviceDisappeared(int); method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public void removeOnAssociationsChangedListener(@NonNull android.companion.CompanionDeviceManager.OnAssociationsChangedListener); }
core/java/android/companion/CompanionDeviceManager.java +45 −0 Original line number Diff line number Diff line Loading @@ -776,6 +776,51 @@ public final class CompanionDeviceManager { } } /** * Notify the system that the given self-managed association has just 'appeared'. * This causes the system to bind to the companion app to keep it running until the association * is reported as 'disappeared' * * <p>This API is only available for the companion apps that manage the connectivity by * themselves.</p> * * @param associationId the unique {@link AssociationInfo#getId ID} assigned to the Association * recorded by CompanionDeviceManager * * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED) public void notifyDeviceAppeared(int associationId) { try { mService.notifyDeviceAppeared(associationId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Notify the system that the given self-managed association has just 'disappeared'. * This causes the system to unbind to the companion app. * * <p>This API is only available for the companion apps that manage the connectivity by * themselves.</p> * * @param associationId the unique {@link AssociationInfo#getId ID} assigned to the Association * recorded by CompanionDeviceManager * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED) public void notifyDeviceDisappeared(int associationId) { try { mService.notifyDeviceDisappeared(associationId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } private boolean checkFeaturePresent() { boolean featurePresent = mService != null; if (!featurePresent && DEBUG) { Loading
core/java/android/companion/CompanionDeviceService.java +60 −16 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.os.Handler; import android.os.IBinder; import android.util.Log; import com.android.internal.util.function.pooled.PooledLambda; import java.util.Objects; Loading @@ -34,8 +35,9 @@ 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, * ensuring app stays alive. * 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. Loading @@ -43,6 +45,17 @@ import java.util.Objects; * 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: * <meta-data * android:name="primary" * android:value="true" /> */ public abstract class CompanionDeviceService extends Service { Loading @@ -52,13 +65,14 @@ public abstract class CompanionDeviceService extends Service { * An intent action for a service to be bound whenever this app's companion device(s) * are nearby. * * <p>The app will be kept alive for as long as the device is nearby. * <p>The app will be kept alive for as long as the device is nearby or companion app reports * appeared. * If the app is not running at the time device gets connected, the app will be woken up.</p> * * <p>Shortly after the device goes out of range, the service will be unbound, and the * app will be eligible for cleanup, unless any other user-visible components are running.</p> * <p>Shortly after the device goes out of range or the companion app reports disappeared, * the service will be unbound, and the app will be eligible for cleanup, unless any other * user-visible components are running.</p> * * <p>An app shouldn't declare more than one of these services. * If running in background is not essential for the devices that this app can manage, * app should avoid declaring this service.</p> * Loading @@ -73,9 +87,13 @@ public abstract class CompanionDeviceService extends Service { * Called by system whenever a device associated with this app is available. * * @param address the MAC address of the device * @deprecated please override {@link #onDeviceAppeared(AssociationInfo)} instead. */ @Deprecated @MainThread public abstract void onDeviceAppeared(@NonNull String address); public void onDeviceAppeared(@NonNull String address) { // Do nothing. Companion apps can override this function. } /** * Called by system whenever a device associated with this app stops being available. Loading @@ -83,9 +101,13 @@ public abstract class CompanionDeviceService extends Service { * Usually this means the device goes out of range or is turned off. * * @param address the MAC address of the device * @deprecated please override {@link #onDeviceDisappeared(AssociationInfo)} instead. */ @Deprecated @MainThread public abstract void onDeviceDisappeared(@NonNull String address); public void onDeviceDisappeared(@NonNull String address) { // Do nothing. Companion apps can override this function. } /** * Called by system whenever the system dispatches a message to the app to send it to Loading Loading @@ -118,6 +140,30 @@ public abstract class CompanionDeviceService extends Service { companionDeviceManager.dispatchMessage(messageId, associationId, message); } /** * Called by system whenever a device associated with this app is connected. * * @param associationInfo A record for the companion device. */ @MainThread public void onDeviceAppeared(@NonNull AssociationInfo associationInfo) { if (!associationInfo.isSelfManaged()) { onDeviceAppeared(associationInfo.getDeviceMacAddressAsString()); } } /** * Called by system whenever a device associated with this app is disconnected. * * @param associationInfo A record for the companion device. */ @MainThread public void onDeviceDisappeared(@NonNull AssociationInfo associationInfo) { if (!associationInfo.isSelfManaged()) { onDeviceDisappeared(associationInfo.getDeviceMacAddressAsString()); } } @Nullable @Override public final IBinder onBind(@NonNull Intent intent) { Loading @@ -132,17 +178,15 @@ public abstract class CompanionDeviceService extends Service { class Stub extends ICompanionDeviceService.Stub { @Override public void onDeviceAppeared(String address) { Handler.getMain().sendMessage(PooledLambda.obtainMessage( CompanionDeviceService::onDeviceAppeared, CompanionDeviceService.this, address)); public void onDeviceAppeared(AssociationInfo associationInfo) { Handler.getMain().post( () -> CompanionDeviceService.this.onDeviceAppeared(associationInfo)); } @Override public void onDeviceDisappeared(String address) { Handler.getMain().sendMessage(PooledLambda.obtainMessage( CompanionDeviceService::onDeviceDisappeared, CompanionDeviceService.this, address)); public void onDeviceDisappeared(AssociationInfo associationInfo) { Handler.getMain().post( () -> CompanionDeviceService.this.onDeviceDisappeared(associationInfo)); } public void onDispatchMessage(int messageId, int associationId, @NonNull byte[] message) { Loading
core/java/android/companion/ICompanionDeviceManager.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -65,5 +65,10 @@ interface ICompanionDeviceManager { void dispatchMessage(in int messageId, in int associationId, in byte[] message); void addOnAssociationsChangedListener(IOnAssociationsChangedListener listener, int userId); void removeOnAssociationsChangedListener(IOnAssociationsChangedListener listener, int userId); void notifyDeviceAppeared(int associationId); void notifyDeviceDisappeared(int associationId); }