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

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

Merge "[V] Introduce new CDM present" into main

parents d921b37e 116b7b54
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -9635,9 +9635,16 @@ package android.companion {
    method @RequiresPermission(android.Manifest.permission.DELIVER_COMPANION_MESSAGES) public final void detachSystemDataTransport(int) throws android.companion.DeviceNotAssociatedException;
    method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
    method @Deprecated @MainThread public void onDeviceAppeared(@NonNull String);
    method @MainThread public void onDeviceAppeared(@NonNull android.companion.AssociationInfo);
    method @Deprecated @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 @Deprecated @MainThread public void onDeviceDisappeared(@NonNull android.companion.AssociationInfo);
    method @MainThread public void onDeviceEvent(@NonNull android.companion.AssociationInfo, int);
    field public static final int DEVICE_EVENT_BLE_APPEARED = 0; // 0x0
    field public static final int DEVICE_EVENT_BLE_DISAPPEARED = 1; // 0x1
    field public static final int DEVICE_EVENT_BT_CONNECTED = 2; // 0x2
    field public static final int DEVICE_EVENT_BT_DISCONNECTED = 3; // 0x3
    field public static final int DEVICE_EVENT_SELF_MANAGED_APPEARED = 4; // 0x4
    field public static final int DEVICE_EVENT_SELF_MANAGED_DISAPPEARED = 5; // 0x5
    field public static final String SERVICE_INTERFACE = "android.companion.CompanionDeviceService";
  }
+92 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@

package android.companion;

import android.annotation.IntDef;
import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -31,13 +32,14 @@ import android.util.Log;

import java.io.InputStream;
import java.io.OutputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
import java.util.concurrent.Executor;

/**
 * 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)}.
 * A service that receives calls from the system with device events.
 * See {@link #onDeviceEvent(AssociationInfo, int)}.
 *
 * <p>
 * Companion applications must create a service that {@code extends}
@@ -121,6 +123,57 @@ public abstract class CompanionDeviceService extends Service {
     */
    public static final String SERVICE_INTERFACE = "android.companion.CompanionDeviceService";

    /** @hide */
    @IntDef(prefix = {"DEVICE_EVENT"}, value = {
            DEVICE_EVENT_BLE_APPEARED,
            DEVICE_EVENT_BLE_DISAPPEARED,
            DEVICE_EVENT_BT_CONNECTED,
            DEVICE_EVENT_BT_DISCONNECTED,
            DEVICE_EVENT_SELF_MANAGED_APPEARED,
            DEVICE_EVENT_SELF_MANAGED_DISAPPEARED
    })

    @Retention(RetentionPolicy.SOURCE)
    public @interface DeviceEvent {}

    /**
     * Companion app receives {@link #onDeviceEvent(AssociationInfo, int)} callback
     * with this event if the device comes into BLE range.
     */
    public static final int DEVICE_EVENT_BLE_APPEARED = 0;

    /**
     * Companion app receives {@link #onDeviceEvent(AssociationInfo, int)} callback
     * with this event if the device is no longer in BLE range.
     */
    public static final int DEVICE_EVENT_BLE_DISAPPEARED = 1;

    /**
     * Companion app receives {@link #onDeviceEvent(AssociationInfo, int)} callback
     * with this event when the bluetooth device is connected.
     */
    public static final int DEVICE_EVENT_BT_CONNECTED = 2;

    /**
     * Companion app receives {@link #onDeviceEvent(AssociationInfo, int)} callback
     * with this event if the bluetooth device is disconnected.
     */
    public static final int DEVICE_EVENT_BT_DISCONNECTED = 3;

    /**
     * A companion app for a {@link AssociationInfo#isSelfManaged() self-managed} device will
     * receive the callback {@link #onDeviceEvent(AssociationInfo, int)} if it reports that a
     * device has appeared on its own.
     */
    public static final int DEVICE_EVENT_SELF_MANAGED_APPEARED = 4;

    /**
     * A companion app for a {@link AssociationInfo#isSelfManaged() self-managed} device will
     * receive the callback {@link #onDeviceEvent(AssociationInfo, int)} if it reports that a
     * device has disappeared on its own.
     */
    public static final int DEVICE_EVENT_SELF_MANAGED_DISAPPEARED = 5;

    private final Stub mRemote = new Stub();

    /**
@@ -251,7 +304,10 @@ public abstract class CompanionDeviceService extends Service {
     * Called by system whenever a device associated with this app is connected.
     *
     * @param associationInfo A record for the companion device.
     *
     * @deprecated please override {@link #onDeviceEvent(AssociationInfo, int)} instead.
     */
    @Deprecated
    @MainThread
    public void onDeviceAppeared(@NonNull AssociationInfo associationInfo) {
        if (!associationInfo.isSelfManaged()) {
@@ -263,7 +319,10 @@ public abstract class CompanionDeviceService extends Service {
     * Called by system whenever a device associated with this app is disconnected.
     *
     * @param associationInfo A record for the companion device.
     *
     * @deprecated please override {@link #onDeviceEvent(AssociationInfo, int)} instead.
     */
    @Deprecated
    @MainThread
    public void onDeviceDisappeared(@NonNull AssociationInfo associationInfo) {
        if (!associationInfo.isSelfManaged()) {
@@ -271,6 +330,30 @@ public abstract class CompanionDeviceService extends Service {
        }
    }

    /**
     *  Called by the system during device events.
     *
     *  <p>E.g. Event {@link #DEVICE_EVENT_BLE_APPEARED} will be called when the associated
     *  companion device comes into BLE range.
     *  <p>Event {@link #DEVICE_EVENT_BLE_DISAPPEARED} will be called when the associated
     *  companion device is no longer in BLE range.
     *  <p> Event {@link #DEVICE_EVENT_BT_CONNECTED} will be called when the associated
     *  companion device is connected.
     *  <p>Event {@link #DEVICE_EVENT_BT_DISCONNECTED} will be called when the associated
     *  companion device is disconnected.
     *  Note that app must receive {@link #DEVICE_EVENT_BLE_APPEARED} first before
     *  {@link #DEVICE_EVENT_BLE_DISAPPEARED} and {@link #DEVICE_EVENT_BT_CONNECTED}
     *  before {@link #DEVICE_EVENT_BT_DISCONNECTED}.
     *
     * @param associationInfo A record for the companion device.
     * @param event Associated companion device's event.
     */
    @MainThread
    public void onDeviceEvent(@NonNull AssociationInfo associationInfo,
            @DeviceEvent int event) {
        // Do nothing. Companion apps can override this function.
    }

    @Nullable
    @Override
    public final IBinder onBind(@NonNull Intent intent) {
@@ -304,5 +387,11 @@ public abstract class CompanionDeviceService extends Service {
        public void onDeviceDisappeared(AssociationInfo associationInfo) {
            mMainHandler.postAtFrontOfQueue(() -> mService.onDeviceDisappeared(associationInfo));
        }

        @Override
        public void onDeviceEvent(AssociationInfo associationInfo, int event) {
            mMainHandler.postAtFrontOfQueue(
                    () -> mService.onDeviceEvent(associationInfo, event));
        }
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -22,4 +22,5 @@ import android.companion.AssociationInfo;
oneway interface ICompanionDeviceService {
    void onDeviceAppeared(in AssociationInfo associationInfo);
    void onDeviceDisappeared(in AssociationInfo associationInfo);
    void onDeviceEvent(in AssociationInfo associationInfo, int state);
}
+34 −19
Original line number Diff line number Diff line
@@ -44,8 +44,9 @@ import java.util.Map;
 * Manages communication with companion applications via
 * {@link android.companion.ICompanionDeviceService} interface, including "connecting" (binding) to
 * the services, maintaining the connection (the binding), and invoking callback methods such as
 * {@link CompanionDeviceService#onDeviceAppeared(AssociationInfo)} and
 * {@link CompanionDeviceService#onDeviceDisappeared(AssociationInfo)} in the application process.
 * {@link CompanionDeviceService#onDeviceAppeared(AssociationInfo)},
 * {@link CompanionDeviceService#onDeviceDisappeared(AssociationInfo)} and
 * {@link CompanionDeviceService#onDeviceEvent(AssociationInfo, int)} in the application process.
 *
 * <p>
 * The following is the list of the APIs provided by {@link CompanionApplicationController} (to be
@@ -53,8 +54,7 @@ import java.util.Map;
 * <ul>
 * <li> {@link #bindCompanionApplication(int, String, boolean)}
 * <li> {@link #unbindCompanionApplication(int, String)}
 * <li> {@link #notifyCompanionApplicationDeviceAppeared(AssociationInfo)}
 * <li> {@link #notifyCompanionApplicationDeviceDisappeared(AssociationInfo)}
 * <li> {@link #notifyCompanionApplicationDeviceEvent(AssociationInfo, int)} (AssociationInfo, int)}
 * <li> {@link #isCompanionApplicationBound(int, String)}
 * <li> {@link #isRebindingCompanionApplicationScheduled(int, String)}
 * </ul>
@@ -240,19 +240,16 @@ public class CompanionApplicationController {
    void notifyCompanionApplicationDeviceAppeared(AssociationInfo association) {
        final int userId = association.getUserId();
        final String packageName = association.getPackageName();
        if (DEBUG) {
            Log.i(TAG, "notifyDevice_Appeared() id=" + association.getId() + " u" + userId

        Slog.i(TAG, "notifyDevice_Appeared() id=" + association.getId() + " u" + userId
                    + "/" + packageName);
        }

        final CompanionDeviceServiceConnector primaryServiceConnector =
                getPrimaryServiceConnector(userId, packageName);
        if (primaryServiceConnector == null) {
            if (DEBUG) {
                Log.e(TAG, "notify_CompanionApplicationDevice_Appeared(): "
            Slog.e(TAG, "notify_CompanionApplicationDevice_Appeared(): "
                        + "u" + userId + "/" + packageName + " is NOT bound.");
                Log.d(TAG, "Stacktrace", new Throwable());
            }
            Slog.e(TAG, "Stacktrace", new Throwable());
            return;
        }

@@ -265,19 +262,16 @@ public class CompanionApplicationController {
    void notifyCompanionApplicationDeviceDisappeared(AssociationInfo association) {
        final int userId = association.getUserId();
        final String packageName = association.getPackageName();
        if (DEBUG) {
            Log.i(TAG, "notifyDevice_Disappeared() id=" + association.getId() + " u" + userId

        Slog.i(TAG, "notifyDevice_Disappeared() id=" + association.getId() + " u" + userId
                + "/" + packageName);
        }

        final CompanionDeviceServiceConnector primaryServiceConnector =
                getPrimaryServiceConnector(userId, packageName);
        if (primaryServiceConnector == null) {
            if (DEBUG) {
                Log.e(TAG, "notify_CompanionApplicationDevice_Disappeared(): "
            Slog.e(TAG, "notify_CompanionApplicationDevice_Disappeared(): "
                        + "u" + userId + "/" + packageName + " is NOT bound.");
                Log.d(TAG, "Stacktrace", new Throwable());
            }
            Slog.e(TAG, "Stacktrace", new Throwable());
            return;
        }

@@ -287,6 +281,27 @@ public class CompanionApplicationController {
        primaryServiceConnector.postOnDeviceDisappeared(association);
    }

    void notifyCompanionApplicationDeviceEvent(AssociationInfo association, int event) {
        final int userId = association.getUserId();
        final String packageName = association.getPackageName();
        final CompanionDeviceServiceConnector primaryServiceConnector =
                getPrimaryServiceConnector(userId, packageName);

        if (primaryServiceConnector == null) {
            Slog.e(TAG, "notifyCompanionApplicationDeviceEvent(): "
                        + "u" + userId + "/" + packageName
                        + " event=[ " + event  + " ] is NOT bound.");
            Slog.e(TAG, "Stacktrace", new Throwable());
            return;
        }

        Slog.i(TAG, "Calling onDeviceEvent() to userId=[" + userId + "] package=["
                + packageName + "] associationId=[" + association.getId()
                + "] state=[" + event + "]");

        primaryServiceConnector.postOnDeviceEvent(association, event);
    }

    void dump(@NonNull PrintWriter out) {
        out.append("Companion Device Application Controller: \n");

+71 −17
Original line number Diff line number Diff line
@@ -24,6 +24,12 @@ import static android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESE
import static android.Manifest.permission.USE_COMPANION_TRANSPORTS;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
import static android.companion.AssociationRequest.DEVICE_PROFILE_AUTOMOTIVE_PROJECTION;
import static android.companion.CompanionDeviceService.DEVICE_EVENT_BLE_APPEARED;
import static android.companion.CompanionDeviceService.DEVICE_EVENT_BLE_DISAPPEARED;
import static android.companion.CompanionDeviceService.DEVICE_EVENT_BT_CONNECTED;
import static android.companion.CompanionDeviceService.DEVICE_EVENT_BT_DISCONNECTED;
import static android.companion.CompanionDeviceService.DEVICE_EVENT_SELF_MANAGED_APPEARED;
import static android.companion.CompanionDeviceService.DEVICE_EVENT_SELF_MANAGED_DISAPPEARED;
import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Process.SYSTEM_UID;
@@ -383,17 +389,8 @@ public class CompanionDeviceManagerService extends SystemService {

        if (!association.shouldBindWhenPresent()) return;

        final int userId = association.getUserId();
        final String packageName = association.getPackageName();
        // Set bindImportant to true when the association is self-managed to avoid the target
        // service being killed.
        final boolean bindImportant = association.isSelfManaged();
        bindApplicationIfNeeded(association);

        if (!mCompanionAppController.isCompanionApplicationBound(userId, packageName)) {
            mCompanionAppController.bindCompanionApplication(userId, packageName, bindImportant);
        } else if (DEBUG) {
            Log.i(TAG, "u" + userId + "\\" + packageName + " is already bound");
        }
        mCompanionAppController.notifyCompanionApplicationDeviceAppeared(association);
    }

@@ -414,11 +411,57 @@ public class CompanionDeviceManagerService extends SystemService {
        if (association.shouldBindWhenPresent()) {
            mCompanionAppController.notifyCompanionApplicationDeviceDisappeared(association);
        }
    }

    private void onDeviceEventInternal(int associationId, int event) {
        Slog.i(TAG, "onDeviceEventInternal() id=" + associationId + " event= " + event);
        final AssociationInfo association = mAssociationStore.getAssociationById(associationId);
        final String packageName = association.getPackageName();
        final int userId = association.getUserId();
        switch (event) {
            case DEVICE_EVENT_BLE_APPEARED:
            case DEVICE_EVENT_BT_CONNECTED:
            case DEVICE_EVENT_SELF_MANAGED_APPEARED:
                if (!association.shouldBindWhenPresent()) return;

                bindApplicationIfNeeded(association);

                mCompanionAppController.notifyCompanionApplicationDeviceEvent(
                        association, event);
                break;
            case DEVICE_EVENT_BLE_DISAPPEARED:
            case DEVICE_EVENT_BT_DISCONNECTED:
            case DEVICE_EVENT_SELF_MANAGED_DISAPPEARED:
                if (!mCompanionAppController.isCompanionApplicationBound(userId, packageName)) {
                    if (DEBUG) Log.w(TAG, "u" + userId + "\\" + packageName + " is NOT bound");
                    return;
                }
                if (association.shouldBindWhenPresent()) {
                    mCompanionAppController.notifyCompanionApplicationDeviceEvent(
                            association, event);
                }
                // Check if there are other devices associated to the app that are present.
                if (shouldBindPackage(userId, packageName)) return;

                mCompanionAppController.unbindCompanionApplication(userId, packageName);
                break;
            default:
                Slog.e(TAG, "Event: " + event + "is not supported");
                break;
        }
    }

    private void bindApplicationIfNeeded(AssociationInfo association) {
        final String packageName = association.getPackageName();
        final int userId = association.getUserId();
        // Set bindImportant to true when the association is self-managed to avoid the target
        // service being killed.
        final boolean bindImportant = association.isSelfManaged();
        if (!mCompanionAppController.isCompanionApplicationBound(userId, packageName)) {
            mCompanionAppController.bindCompanionApplication(
                    userId, packageName, bindImportant);
        } else if (DEBUG) {
            Log.i(TAG, "u" + userId + "\\" + packageName + " is already bound");
        }
    }

    /**
@@ -883,7 +926,6 @@ public class CompanionDeviceManagerService extends SystemService {
                        + " active=" + active
                        + " deviceAddress=" + deviceAddress);
            }

            final int userId = getCallingUserId();
            enforceCallerIsSystemOr(userId, packageName);

@@ -912,10 +954,17 @@ public class CompanionDeviceManagerService extends SystemService {
            // an application sets/unsets the mNotifyOnDeviceNearby flag.
            mAssociationStore.updateAssociation(association);

            int associationId = association.getId();
            // If device is already present, then trigger callback.
            if (active && mDevicePresenceMonitor.isDevicePresent(association.getId())) {
                if (DEBUG) Log.d(TAG, "Device is already present. Triggering callback.");
                onDeviceAppearedInternal(association.getId());
            if (active && mDevicePresenceMonitor.isDevicePresent(associationId)) {
                Slog.i(TAG, "Device is already present. Triggering callback.");
                if (mDevicePresenceMonitor.isBlePresent(associationId)
                        || mDevicePresenceMonitor.isSimulatePresent(associationId)) {
                    onDeviceAppearedInternal(associationId);
                    onDeviceEventInternal(associationId, DEVICE_EVENT_BLE_APPEARED);
                } else if (mDevicePresenceMonitor.isBtConnected(associationId)) {
                    onDeviceEventInternal(associationId, DEVICE_EVENT_BT_CONNECTED);
                }
            }

            // If last listener is unregistered, then unbind application.
@@ -1380,6 +1429,11 @@ public class CompanionDeviceManagerService extends SystemService {
        public void onDeviceDisappeared(int associationId) {
            onDeviceDisappearedInternal(associationId);
        }

        @Override
        public void onDeviceEvent(int associationId, int event) {
            onDeviceEventInternal(associationId, event);
        }
    };

    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
Loading