Android USB Permissions
Suppose we’re writing a device driver for a USB device, implemented as an Android Service. Our driver checks to see if it has permission to access the device. If it doesn’t, it calls UsbManager.requestPermission, and a window like this pops up:
We click “Use by default for this USB device” and press “OK”.
Here’s what Android did in response:
Android gave our app temporary permission to access the USB device by updating UsbUserSettingsManager.mDevicePermissionMap.Android saved our app’s package name and the USB device’s information in the file “/data/system/users/0/usb_device_manager.xml”.
Now, if we reboot the Android device, we would expect Android to repopulate UsbUserSettingsManager.mDevicePermissionMap by reading the “usb_device_manager.xml” file for each user. But does it do this? No. Here’s what really happens.
During boot up, Android repopulates UsbUserSettingsManager.mDevicePermissionMap as a side-effect of sending USB_DEVICE_ATTACHED events to registered Activities. Our driver isn’t an Activity, so it is not granted permission to access the USB device.
To fix this, our driver must create a dummy Activity and register it to receive the USB_DEVICE_ATTACHED event by following the instructions found here.
We have now created an Activity that listens for USB_DEVICE_ATTACHED, so when we reboot Android our driver should automatically be granted permission to access the USB device, right? No, not if you’re running Android 7 or above. Android 7 has a new boot stage called “Direct Boot” that happens before the user unlocks the device. The USB_DEVICE_ATTACHED event is sent during Direct Boot, and since our app is not “Direct Boot aware” it doesn’t get the USB_DEVICE_ATTACHED message and it doesn’t receive permission to access the USB device.
To work around this Android bug, we need to add
to our dummy Activity’s manifest.
Update 10/25/19: These bugs have been reported to Google at https://issuetracker.google.com/issues/77658221, but Google has marked the status as “Won't Fix (Intended Behavior),” which means that the workarounds mentioned in this article will continue to be needed for USB-based device drivers.