diff options
author | Evan Severson <evanseverson@google.com> | 2019-08-15 14:02:17 -0700 |
---|---|---|
committer | Evan Severson <evanseverson@google.com> | 2019-10-24 14:22:20 -0700 |
commit | 6fd44ac0a4f6579b72a0f617a9f437226e17e598 (patch) | |
tree | aa09760d3ee85d37f5e7a7613e43225e5c8717d5 | |
parent | e1a80af3de4c2b1a2b0e30fac9ad17fb0767c89d (diff) |
Add persistent permissions to `dumpsys usb`
Test: adb shell dumpsys usb
Change-Id: Iae909e359ac366bdb8d48479f5ff7100f6ae1747
4 files changed, 189 insertions, 66 deletions
diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto index 2e1de79b199f..40c5a85e1f24 100644 --- a/core/proto/android/service/usb.proto +++ b/core/proto/android/service/usb.proto @@ -32,6 +32,7 @@ message UsbServiceDumpProto { optional UsbPortManagerProto port_manager = 3; optional UsbAlsaManagerProto alsa_manager = 4; optional UsbSettingsManagerProto settings_manager = 5; + optional UsbPermissionsManagerProto permissions_manager = 6; } message UsbDeviceManagerProto { @@ -309,40 +310,83 @@ message UsbUserSettingsManagerProto { option (android.msg_privacy).dest = DEST_AUTOMATIC; optional int32 user_id = 1; - repeated UsbSettingsDevicePermissionProto device_permissions = 2; - repeated UsbSettingsAccessoryPermissionProto accessory_permissions = 3; + reserved 2; // previously device_permissions, now unused + reserved 3; // previously accessory_permissions, now unused repeated UsbDeviceAttachedActivities device_attached_activities = 4; repeated UsbAccessoryAttachedActivities accessory_attached_activities = 5; } -message UsbSettingsDevicePermissionProto { +message UsbProfileGroupSettingsManagerProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + // The user id of the personal profile if the device has a work profile. + optional int32 parent_user_id = 1; + repeated UsbSettingsDevicePreferenceProto device_preferences = 2; + repeated UsbSettingsAccessoryPreferenceProto accessory_preferences = 3; +} + +message UsbSettingsDevicePreferenceProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional UsbDeviceFilterProto filter = 1; + optional UserPackageProto user_package = 2; +} + +message UsbPermissionsManagerProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + repeated UsbUserPermissionsManagerProto user_permissions = 1; +} + +message UsbUserPermissionsManagerProto { option (android.msg_privacy).dest = DEST_AUTOMATIC; + optional int32 user_id = 1; + + repeated UsbDevicePermissionProto device_permissions = 2; + repeated UsbAccessoryPermissionProto accessory_permissions = 3; + + repeated UsbDevicePersistentPermissionProto device_persistent_permissions = 4; + repeated UsbAccessoryPersistentPermissionProto accessory_persistent_permissions = 5; +} + +message UsbDevicePermissionProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + // Name of device set by manufacturer + // All devices of the same model have the same name optional string device_name = 1; repeated int32 uids = 2; } -message UsbSettingsAccessoryPermissionProto { +message UsbAccessoryPermissionProto { option (android.msg_privacy).dest = DEST_AUTOMATIC; + // Description of accessory set by manufacturer + // All accessories of the same model have the same description optional string accessory_description = 1; repeated int32 uids = 2; } -message UsbProfileGroupSettingsManagerProto { +message UsbDevicePersistentPermissionProto { option (android.msg_privacy).dest = DEST_AUTOMATIC; - // The user id of the personal profile if the device has a work profile. - optional int32 parent_user_id = 1; - repeated UsbSettingsDevicePreferenceProto device_preferences = 2; - repeated UsbSettingsAccessoryPreferenceProto accessory_preferences = 3; + optional UsbDeviceFilterProto device_filter = 1; + repeated UsbUidPermissionProto permission_values = 2; } -message UsbSettingsDevicePreferenceProto { +message UsbAccessoryPersistentPermissionProto { option (android.msg_privacy).dest = DEST_AUTOMATIC; - optional UsbDeviceFilterProto filter = 1; - optional UserPackageProto user_package = 2; + optional UsbAccessoryFilterProto accessory_filter = 1; + repeated UsbUidPermissionProto permission_values = 2; +} + +message UsbUidPermissionProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional int32 uid = 1; + optional bool is_granted = 2; } message UsbDeviceFilterProto { diff --git a/services/usb/java/com/android/server/usb/UsbPermissionManager.java b/services/usb/java/com/android/server/usb/UsbPermissionManager.java index ef9ee73a9b68..1e46f981f117 100644 --- a/services/usb/java/com/android/server/usb/UsbPermissionManager.java +++ b/services/usb/java/com/android/server/usb/UsbPermissionManager.java @@ -20,14 +20,20 @@ import android.annotation.NonNull; import android.annotation.UserIdInt; import android.content.Context; import android.content.Intent; +import android.content.pm.UserInfo; import android.hardware.usb.UsbAccessory; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; import android.os.UserHandle; +import android.os.UserManager; +import android.service.usb.UsbSettingsManagerProto; import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; +import com.android.internal.util.dump.DualDumpOutputStream; + +import java.util.List; class UsbPermissionManager { private static final String LOG_TAG = UsbPermissionManager.class.getSimpleName(); @@ -112,4 +118,18 @@ class UsbPermissionManager { mContext.sendBroadcastAsUser(intent, UserHandle.ALL); } + void dump(@NonNull DualDumpOutputStream dump, String idName, long id) { + long token = dump.start(idName, id); + UserManager userManager = mContext.getSystemService(UserManager.class); + synchronized (mPermissionsByUser) { + List<UserInfo> users = userManager.getUsers(); + int numUsers = users.size(); + for (int i = 0; i < numUsers; i++) { + getPermissionsForUser(users.get(i).id).dump(dump, "user_permissions", + UsbSettingsManagerProto.USER_SETTINGS); + } + } + dump.end(token); + } + } diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java index ce6f592e2b0d..04936377bbfb 100644 --- a/services/usb/java/com/android/server/usb/UsbService.java +++ b/services/usb/java/com/android/server/usb/UsbService.java @@ -740,6 +740,8 @@ public class UsbService extends IUsbManager.Stub { mSettingsManager.dump(dump, "settings_manager", UsbServiceDumpProto.SETTINGS_MANAGER); + mPermissionManager.dump(dump, "permissions_manager", + UsbServiceDumpProto.PERMISSIONS_MANAGER); dump.flush(); } else if ("set-port-roles".equals(args[0]) && args.length == 4) { final String portId = args[1]; diff --git a/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java b/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java index 0cb64a37f9c1..e700f19adbd4 100644 --- a/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java +++ b/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java @@ -36,9 +36,12 @@ import android.os.Binder; import android.os.Environment; import android.os.Process; import android.os.UserHandle; -import android.service.usb.UsbSettingsAccessoryPermissionProto; -import android.service.usb.UsbSettingsDevicePermissionProto; -import android.service.usb.UsbUserSettingsManagerProto; +import android.service.usb.UsbAccessoryPermissionProto; +import android.service.usb.UsbAccessoryPersistentPermissionProto; +import android.service.usb.UsbDevicePermissionProto; +import android.service.usb.UsbDevicePersistentPermissionProto; +import android.service.usb.UsbUidPermissionProto; +import android.service.usb.UsbUserPermissionsManagerProto; import android.util.ArrayMap; import android.util.AtomicFile; import android.util.Slog; @@ -261,7 +264,7 @@ class UsbUserPermissionManager { } if (isChanged) { - scheduleWritePermissionLocked(); + scheduleWritePermissionsLocked(); } } } @@ -288,7 +291,7 @@ class UsbUserPermissionManager { } if (isChanged) { - scheduleWritePermissionLocked(); + scheduleWritePermissionsLocked(); } } } @@ -370,7 +373,7 @@ class UsbUserPermissionManager { } @GuardedBy("mLock") - private void scheduleWritePermissionLocked() { + private void scheduleWritePermissionsLocked() { if (mIsCopyPermissionsScheduled) { return; } @@ -393,15 +396,18 @@ class UsbUserPermissionManager { devices = new DeviceFilter[numDevices]; uidsForDevices = new int[numDevices][]; grantedValuesForDevices = new boolean[numDevices][]; - for (int i = 0; i < numDevices; i++) { - devices[i] = new DeviceFilter(mDevicePersistentPermissionMap.keyAt(i)); - SparseBooleanArray permissions = mDevicePersistentPermissionMap.valueAt(i); + for (int deviceIdx = 0; deviceIdx < numDevices; deviceIdx++) { + devices[deviceIdx] = + new DeviceFilter(mDevicePersistentPermissionMap.keyAt(deviceIdx)); + SparseBooleanArray permissions = + mDevicePersistentPermissionMap.valueAt(deviceIdx); int numPermissions = permissions.size(); - uidsForDevices[i] = new int[numPermissions]; - grantedValuesForDevices[i] = new boolean[numPermissions]; - for (int j = 0; j < numPermissions; j++) { - uidsForDevices[i][j] = permissions.keyAt(j); - grantedValuesForDevices[i][j] = permissions.valueAt(j); + uidsForDevices[deviceIdx] = new int[numPermissions]; + grantedValuesForDevices[deviceIdx] = new boolean[numPermissions]; + for (int permissionIdx = 0; permissionIdx < numPermissions; permissionIdx++) { + uidsForDevices[deviceIdx][permissionIdx] = permissions.keyAt(permissionIdx); + grantedValuesForDevices[deviceIdx][permissionIdx] = + permissions.valueAt(permissionIdx); } } @@ -409,16 +415,19 @@ class UsbUserPermissionManager { accessories = new AccessoryFilter[numAccessories]; uidsForAccessories = new int[numAccessories][]; grantedValuesForAccessories = new boolean[numAccessories][]; - for (int i = 0; i < numAccessories; i++) { - accessories[i] = - new AccessoryFilter(mAccessoryPersistentPermissionMap.keyAt(i)); - SparseBooleanArray permissions = mAccessoryPersistentPermissionMap.valueAt(i); + for (int accessoryIdx = 0; accessoryIdx < numAccessories; accessoryIdx++) { + accessories[accessoryIdx] = new AccessoryFilter( + mAccessoryPersistentPermissionMap.keyAt(accessoryIdx)); + SparseBooleanArray permissions = + mAccessoryPersistentPermissionMap.valueAt(accessoryIdx); int numPermissions = permissions.size(); - uidsForAccessories[i] = new int[numPermissions]; - grantedValuesForAccessories[i] = new boolean[numPermissions]; - for (int j = 0; j < numPermissions; j++) { - uidsForAccessories[i][j] = permissions.keyAt(j); - grantedValuesForAccessories[i][j] = permissions.valueAt(j); + uidsForAccessories[accessoryIdx] = new int[numPermissions]; + grantedValuesForAccessories[accessoryIdx] = new boolean[numPermissions]; + for (int permissionIdx = 0; permissionIdx < numPermissions; permissionIdx++) { + uidsForAccessories[accessoryIdx][permissionIdx] = + permissions.keyAt(permissionIdx); + grantedValuesForAccessories[accessoryIdx][permissionIdx] = + permissions.valueAt(permissionIdx); } } mIsCopyPermissionsScheduled = false; @@ -477,22 +486,22 @@ class UsbUserPermissionManager { * Creates UI dialog to request permission for the given package to access the device * or accessory. * - * @param device The USB device attached - * @param accessory The USB accessory attached + * @param device The USB device attached + * @param accessory The USB accessory attached * @param canBeDefault Whether the calling pacakge can set as default handler - * of the USB device or accessory - * @param packageName The package name of the calling package - * @param uid The uid of the calling package - * @param userContext The context to start the UI dialog - * @param pi PendingIntent for returning result + * of the USB device or accessory + * @param packageName The package name of the calling package + * @param uid The uid of the calling package + * @param userContext The context to start the UI dialog + * @param pi PendingIntent for returning result */ void requestPermissionDialog(@Nullable UsbDevice device, - @Nullable UsbAccessory accessory, - boolean canBeDefault, - @NonNull String packageName, - int uid, - @NonNull Context userContext, - @NonNull PendingIntent pi) { + @Nullable UsbAccessory accessory, + boolean canBeDefault, + @NonNull String packageName, + int uid, + @NonNull Context userContext, + @NonNull PendingIntent pi) { long identity = Binder.clearCallingIdentity(); Intent intent = new Intent(); if (device != null) { @@ -517,48 +526,96 @@ class UsbUserPermissionManager { } } - void dump(@NonNull DualDumpOutputStream dump) { + void dump(@NonNull DualDumpOutputStream dump, String idName, long id) { + long token = dump.start(idName, id); synchronized (mLock) { - for (String deviceName : mDevicePermissionMap.keySet()) { + dump.write("user_id", UsbUserPermissionsManagerProto.USER_ID, mUser.getIdentifier()); + int numMappings = mDevicePermissionMap.size(); + for (int mappingsIdx = 0; mappingsIdx < numMappings; mappingsIdx++) { + String deviceName = mDevicePermissionMap.keyAt(mappingsIdx); long devicePermissionToken = dump.start("device_permissions", - UsbUserSettingsManagerProto.DEVICE_PERMISSIONS); + UsbUserPermissionsManagerProto.DEVICE_PERMISSIONS); - dump.write("device_name", UsbSettingsDevicePermissionProto.DEVICE_NAME, deviceName); + dump.write("device_name", UsbDevicePermissionProto.DEVICE_NAME, deviceName); - SparseBooleanArray uidList = mDevicePermissionMap.get(deviceName); - int count = uidList.size(); - for (int i = 0; i < count; i++) { - dump.write("uids", UsbSettingsDevicePermissionProto.UIDS, uidList.keyAt(i)); + SparseBooleanArray uidList = mDevicePermissionMap.valueAt(mappingsIdx); + int numUids = uidList.size(); + for (int uidsIdx = 0; uidsIdx < numUids; uidsIdx++) { + dump.write("uids", UsbDevicePermissionProto.UIDS, uidList.keyAt(uidsIdx)); } dump.end(devicePermissionToken); } - for (UsbAccessory accessory : mAccessoryPermissionMap.keySet()) { + numMappings = mAccessoryPermissionMap.size(); + for (int mappingsIdx = 0; mappingsIdx < numMappings; ++mappingsIdx) { + UsbAccessory accessory = mAccessoryPermissionMap.keyAt(mappingsIdx); long accessoryPermissionToken = dump.start("accessory_permissions", - UsbUserSettingsManagerProto.ACCESSORY_PERMISSIONS); + UsbUserPermissionsManagerProto.ACCESSORY_PERMISSIONS); dump.write("accessory_description", - UsbSettingsAccessoryPermissionProto.ACCESSORY_DESCRIPTION, + UsbAccessoryPermissionProto.ACCESSORY_DESCRIPTION, accessory.getDescription()); - SparseBooleanArray uidList = mAccessoryPermissionMap.get(accessory); - int count = uidList.size(); - for (int i = 0; i < count; i++) { - dump.write("uids", UsbSettingsAccessoryPermissionProto.UIDS, uidList.keyAt(i)); + SparseBooleanArray uidList = mAccessoryPermissionMap.valueAt(mappingsIdx); + int numUids = uidList.size(); + for (int uidsIdx = 0; uidsIdx < numUids; uidsIdx++) { + dump.write("uids", UsbAccessoryPermissionProto.UIDS, uidList.keyAt(uidsIdx)); } dump.end(accessoryPermissionToken); } + + numMappings = mDevicePersistentPermissionMap.size(); + for (int mappingsIdx = 0; mappingsIdx < numMappings; mappingsIdx++) { + DeviceFilter filter = mDevicePersistentPermissionMap.keyAt(mappingsIdx); + long devicePermissionToken = dump.start("device_persistent_permissions", + UsbUserPermissionsManagerProto.DEVICE_PERSISTENT_PERMISSIONS); + filter.dump(dump, "device", + UsbDevicePersistentPermissionProto.DEVICE_FILTER); + SparseBooleanArray permissions = + mDevicePersistentPermissionMap.valueAt(mappingsIdx); + int numPermissions = permissions.size(); + for (int permissionsIdx = 0; permissionsIdx < numPermissions; permissionsIdx++) { + long uidPermissionToken = dump.start("uid_permission", + UsbDevicePersistentPermissionProto.PERMISSION_VALUES); + dump.write("uid", UsbUidPermissionProto.UID, permissions.keyAt(permissionsIdx)); + dump.write("is_granted", + UsbUidPermissionProto.IS_GRANTED, permissions.valueAt(permissionsIdx)); + dump.end(uidPermissionToken); + } + dump.end(devicePermissionToken); + } + + numMappings = mAccessoryPersistentPermissionMap.size(); + for (int mappingsIdx = 0; mappingsIdx < numMappings; mappingsIdx++) { + AccessoryFilter filter = mAccessoryPersistentPermissionMap.keyAt(mappingsIdx); + long accessoryPermissionToken = dump.start("accessory_persistent_permissions", + UsbUserPermissionsManagerProto.ACCESSORY_PERSISTENT_PERMISSIONS); + filter.dump(dump, "accessory", + UsbAccessoryPersistentPermissionProto.ACCESSORY_FILTER); + SparseBooleanArray permissions = + mAccessoryPersistentPermissionMap.valueAt(mappingsIdx); + int numPermissions = permissions.size(); + for (int permissionsIdx = 0; permissionsIdx < numPermissions; permissionsIdx++) { + long uidPermissionToken = dump.start("uid_permission", + UsbAccessoryPersistentPermissionProto.PERMISSION_VALUES); + dump.write("uid", UsbUidPermissionProto.UID, permissions.keyAt(permissionsIdx)); + dump.write("is_granted", + UsbUidPermissionProto.IS_GRANTED, permissions.valueAt(permissionsIdx)); + dump.end(uidPermissionToken); + } + dump.end(accessoryPermissionToken); + } } + dump.end(token); } /** * Check for camera permission of the calling process. * * @param packageName Package name of the caller. - * @param uid Linux uid of the calling process. - * + * @param uid Linux uid of the calling process. * @return True in case camera permission is available, False otherwise. */ private boolean isCameraPermissionGranted(String packageName, int uid) { @@ -677,7 +734,7 @@ class UsbUserPermissionManager { * * @param device The device that needs to get scanned * @return True in case a VIDEO device or interface is present, - * False otherwise. + * False otherwise. */ private boolean isCameraDevicePresent(UsbDevice device) { if (device.getDeviceClass() == UsbConstants.USB_CLASS_VIDEO) { |