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

Commit 857d00ef authored by Evan Chen's avatar Evan Chen Committed by Android (Google) Code Review
Browse files

Merge "Companion App Manages Connectivity State Interfaces"

parents 456b39de 4698bcf0
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -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";
  }
+2 −0
Original line number Diff line number Diff line
@@ -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);
  }
+45 −0
Original line number Diff line number Diff line
@@ -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) {
+60 −16
Original line number Diff line number Diff line
@@ -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;
@@ -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.
@@ -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 {

@@ -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>
     *
@@ -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.
@@ -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
@@ -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) {
@@ -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) {
+5 −0
Original line number Diff line number Diff line
@@ -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