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

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

Merge "Additional permission for Device Presence UUID matching." into main

parents bb81654f f890cb39
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -180,6 +180,9 @@ public final class ObservingDevicePresenceRequest implements Parcelable {
         * <p>Calling apps must use either this API or {@link #setAssociationId(int)},
         * but not both.</p>
         *
         * <p>Calling app must hold the
         * {@link AssociationRequest#DEVICE_PROFILE_AUTOMOTIVE_PROJECTION} profile.</p>
         *
         * @param uuid The ParcelUuid for observing device presence.
         */
        @NonNull
+4 −2
Original line number Diff line number Diff line
@@ -532,7 +532,8 @@ public class CompanionDeviceManagerService extends SystemService {
                String packageName, int userId) {
            startObservingDevicePresence_enforcePermission();

            mDevicePresenceProcessor.startObservingDevicePresence(request, packageName, userId);
            mDevicePresenceProcessor.startObservingDevicePresence(
                    request, packageName, userId, /* enforcePermissions */ true);
        }

        @Override
@@ -541,7 +542,8 @@ public class CompanionDeviceManagerService extends SystemService {
                String packageName, int userId) {
            stopObservingDevicePresence_enforcePermission();

            mDevicePresenceProcessor.stopObservingDevicePresence(request, packageName, userId);
            mDevicePresenceProcessor.stopObservingDevicePresence(
                    request, packageName, userId, /* enforcePermissions */ true);
        }

        @Override
+46 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.companion.CompanionDeviceManager.MESSAGE_REQUEST_CONTEXT_S
import android.companion.AssociationInfo;
import android.companion.ContextSyncMessage;
import android.companion.Flags;
import android.companion.ObservingDevicePresenceRequest;
import android.companion.Telecom;
import android.companion.datatransfer.PermissionSyncRequest;
import android.net.MacAddress;
@@ -193,6 +194,43 @@ class CompanionDeviceShellCommand extends ShellCommand {
                    break;
                }

                case "start-observing-device-presence-uuid": {
                    if (Flags.devicePresence()) {
                        int userId = getNextIntArgRequired();
                        String packageName = getNextArgRequired();
                        String uuid = getNextArgRequired();
                        if ("null".equals(uuid)) {
                            out.println("UUID can not be null.");
                            break;
                        }
                        ParcelUuid parcelUuid = ParcelUuid.fromString(uuid);
                        ObservingDevicePresenceRequest request = new ObservingDevicePresenceRequest
                                .Builder().setUuid(parcelUuid).build();
                        mDevicePresenceProcessor.startObservingDevicePresence(
                                request, packageName, userId, /* enforcePermissions */ false);

                    }
                    break;
                }

                case "stop-observing-device-presence-uuid": {
                    if (Flags.devicePresence()) {
                        int userId = getNextIntArgRequired();
                        String packageName = getNextArgRequired();
                        String uuid = getNextArgRequired();
                        if ("null".equals(uuid)) {
                            out.println("UUID can not be null.");
                            break;
                        }
                        ParcelUuid parcelUuid = ParcelUuid.fromString(uuid);
                        ObservingDevicePresenceRequest request = new ObservingDevicePresenceRequest
                                .Builder().setUuid(parcelUuid).build();
                        mDevicePresenceProcessor.stopObservingDevicePresence(
                                request, packageName, userId, /* enforcePermissions */ false);
                    }
                    break;
                }

                case "get-backup-payload": {
                    final int userId = getNextIntArgRequired();
                    byte[] payload = mBackupRestoreProcessor.getBackupPayload(userId);
@@ -515,6 +553,14 @@ class CompanionDeviceShellCommand extends ShellCommand {
            pw.println("  callback after simulate-device-event-device-locked");
            pw.println("  command has been called.");
            pw.println("  USE FOR DEBUGGING AND/OR TESTING PURPOSES ONLY.");

            pw.println("  start-observing-device-presence-uuid USER_ID PACKAGE_NAME UUID");
            pw.println("  Start observing device presence base on the UUID.");
            pw.println("  USE FOR DEBUGGING AND/OR TESTING PURPOSES ONLY.");

            pw.println("  stop-observing-device-presence-uuid USER_ID PACKAGE_NAME UUID");
            pw.println("  Stop observing device presence base on the UUID.");
            pw.println("  USE FOR DEBUGGING AND/OR TESTING PURPOSES ONLY.");
        }

        pw.println("  remove-inactive-associations");
+12 −8
Original line number Diff line number Diff line
@@ -181,14 +181,16 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
     * Process device presence start request.
     */
    public void startObservingDevicePresence(ObservingDevicePresenceRequest request,
            String packageName, int userId) {
            String packageName, int userId, boolean enforcePermissions) {
        Slog.i(TAG,
                "Start observing request=[" + request + "] for userId=[" + userId + "], package=["
                        + packageName + "]...");
        final ParcelUuid requestUuid = request.getUuid();

        if (requestUuid != null) {
            enforceCallerCanObserveDevicePresenceByUuid(mContext);
            if (enforcePermissions) {
                enforceCallerCanObserveDevicePresenceByUuid(mContext, packageName, userId);
            }

            // If it's already being observed, then no-op.
            if (mObservableUuidStore.isUuidBeingObserved(requestUuid, userId, packageName)) {
@@ -236,7 +238,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
     * Process device presence stop request.
     */
    public void stopObservingDevicePresence(ObservingDevicePresenceRequest request,
            String packageName, int userId) {
            String packageName, int userId, boolean enforcePermissions) {
        Slog.i(TAG,
                "Stop observing request=[" + request + "] for userId=[" + userId + "], package=["
                        + packageName + "]...");
@@ -244,7 +246,9 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
        final ParcelUuid requestUuid = request.getUuid();

        if (requestUuid != null) {
            enforceCallerCanObserveDevicePresenceByUuid(mContext);
            if (enforcePermissions) {
                enforceCallerCanObserveDevicePresenceByUuid(mContext, packageName, userId);
            }

            if (!mObservableUuidStore.isUuidBeingObserved(requestUuid, userId, packageName)) {
                Slog.i(TAG, "UUID=[" + requestUuid + "], package=[" + packageName + "], userId=["
@@ -283,7 +287,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
     * For legacy device presence below Android V.
     *
     * @deprecated Use {@link #startObservingDevicePresence(ObservingDevicePresenceRequest, String,
     * int)}
     * int, boolean)}
     */
    @Deprecated
    public void startObservingDevicePresence(int userId, String packageName, String deviceAddress)
@@ -306,14 +310,14 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene

        startObservingDevicePresence(
                new ObservingDevicePresenceRequest.Builder().setAssociationId(association.getId())
                        .build(), packageName, userId);
                        .build(), packageName, userId, /* enforcePermissions */ true);
    }

    /**
     * For legacy device presence below Android V.
     *
     * @deprecated Use {@link #stopObservingDevicePresence(ObservingDevicePresenceRequest, String,
     * int)}
     * int, boolean)}
     */
    @Deprecated
    public void stopObservingDevicePresence(int userId, String packageName, String deviceAddress)
@@ -336,7 +340,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene

        stopObservingDevicePresence(
                new ObservingDevicePresenceRequest.Builder().setAssociationId(association.getId())
                        .build(), packageName, userId);
                        .build(), packageName, userId, /* enforcePermissions */ true);
    }

    /**
+17 −5
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ import static android.os.Binder.getCallingUid;
import static android.os.Process.SYSTEM_UID;
import static android.os.UserHandle.getCallingUserId;

import static com.android.server.companion.utils.RolesUtils.isRoleHolder;

import static java.util.Collections.unmodifiableMap;

import android.Manifest;
@@ -44,6 +46,7 @@ import android.annotation.UserIdInt;
import android.companion.AssociationRequest;
import android.companion.CompanionDeviceManager;
import android.content.Context;
import android.os.Binder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.ArrayMap;
@@ -203,11 +206,9 @@ public final class PermissionsUtils {
    /**
     * Require the caller to hold necessary permission to observe device presence by UUID.
     */
    public static void enforceCallerCanObserveDevicePresenceByUuid(@NonNull Context context) {
        if (context.checkCallingPermission(REQUEST_OBSERVE_DEVICE_UUID_PRESENCE)
                != PERMISSION_GRANTED
                || context.checkCallingPermission(BLUETOOTH_SCAN) != PERMISSION_GRANTED
                || context.checkCallingPermission(BLUETOOTH_CONNECT) != PERMISSION_GRANTED) {
    public static void enforceCallerCanObserveDevicePresenceByUuid(@NonNull Context context,
            String packageName, int userId) {
        if (!hasRequirePermissions(context, packageName, userId)) {
            throw new SecurityException("Caller (uid=" + getCallingUid() + ") does not have "
                    + "permissions to request observing device presence base on the UUID");
        }
@@ -234,6 +235,17 @@ public final class PermissionsUtils {
        return sAppOpsService;
    }

    private static boolean hasRequirePermissions(
            @NonNull Context context, String packageName, int userId) {
        return context.checkCallingPermission(
                REQUEST_OBSERVE_DEVICE_UUID_PRESENCE) == PERMISSION_GRANTED
                && context.checkCallingPermission(BLUETOOTH_SCAN) == PERMISSION_GRANTED
                && context.checkCallingPermission(BLUETOOTH_CONNECT) == PERMISSION_GRANTED
                && Boolean.TRUE.equals(Binder.withCleanCallingIdentity(
                        () -> isRoleHolder(context, userId, packageName,
                                DEVICE_PROFILE_AUTOMOTIVE_PROJECTION)));
    }

    // DO NOT USE DIRECTLY! Access via getAppOpsService().
    private static IAppOpsService sAppOpsService = null;