Loading core/java/android/companion/ObservingDevicePresenceRequest.java +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +4 −2 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java +46 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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"); Loading services/companion/java/com/android/server/companion/devicepresence/DevicePresenceProcessor.java +12 −8 Original line number Diff line number Diff line Loading @@ -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)) { Loading Loading @@ -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 + "]..."); Loading @@ -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=[" Loading Loading @@ -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) Loading @@ -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) Loading @@ -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); } /** Loading services/companion/java/com/android/server/companion/utils/PermissionsUtils.java +17 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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"); } Loading @@ -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; Loading Loading
core/java/android/companion/ObservingDevicePresenceRequest.java +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +4 −2 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading
services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java +46 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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"); Loading
services/companion/java/com/android/server/companion/devicepresence/DevicePresenceProcessor.java +12 −8 Original line number Diff line number Diff line Loading @@ -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)) { Loading Loading @@ -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 + "]..."); Loading @@ -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=[" Loading Loading @@ -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) Loading @@ -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) Loading @@ -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); } /** Loading
services/companion/java/com/android/server/companion/utils/PermissionsUtils.java +17 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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"); } Loading @@ -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; Loading