I’m debugging USB related issue due to upgrade to SDK34 and failure on Android 14. I don’t have a physical device so I resort to emulator.
I chmoded the usb device: such that the device is readable/writable from the host:
$ ls -l /dev/bus/usb/002/006
crw-rw-rw- 1 root root 189, 133 Sep 11 22:33 /dev/bus/usb/002/006
I attached the device per instructions to emulator
emulator -avd Pixel_5_API_34 -no-snapshot -usb-passthrough hostbus=2,hostaddr=6
I entered shell and checked that lsusb shows the device:
$ su
# lsusb
...
Bus 002 Device 002: ID 0547:e009
...
It is indeed the device I look for (correct vendor id/product id), but when I try to get the device list I always get an empty list (of course it works on physical devices prior to Android 14)
Here is the way I get the device list
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Log.i("OLS",String.format("Device count = %d",deviceList.size()));
Log show that the device count is 0.
Have anybody had experience with it? It seems that at virtual android Kernel level the device is visible but it isn’t propagated to the user
(The answers I find there are outdated or irrelevant to existing Android platforms)
3
One probably does not even have to use switch -usb-passthrough
, because the documentation does not have it (anymore): https://www.qemu.org/docs/master/system/devices/usb.html
Use lsusb -t
to determine the address and try different config switches. USB in an emulation can’t really be used to test all scenarios, which one can test with hardware; for example, connecting a bunch of USB sticks all at once via an USB hub, then disconnect and reconnect selectively.
As commented there, running Android on VMWare might provide better USB support, as this is not exactly being provided by the emulation itself, but by an auxiliary services, dealing with USB devices outside of the emulation, which permits to conveniently dispatch them.
My suspicion would be, that the system image used might eventually lack the required SE Linux policies, to even permit device access; eg. https://linux.die.net/man/8/usbmodules_selinux
semanage permissive -a usbmodules_t
would be the command, but there’s no semanage
.
However, this should at least log the AVC (Access Vector Cache) denial event to console. Despite that the Android emulator is rooted, the mere problem is that it has no semanage
; there’s just unofficial “SE Tools” for Android. It does not have to be the emulator
at fault, but it could be the system image as well – and on Android, the SE policies are being baked in at build time …which means, that even if QEMU can connect the device, this still might require to build or mod a custom image, including the proper SE policies, which ultimately permit to access the USB device/s.
6
With Android 14 you have to prompt the user for permission in order to access the USB device. If you don’t prompt via RequestPermission
, permission can’t be granted and your app won’t find anything there.
AFAIK this is a recent change that might explain why the update broke your app.
https://developer.android.com/reference/android/hardware/usb/UsbManager#requestPermission(android.hardware.usb.UsbDevice,%20android.app.PendingIntent)
This may or may not help you:
https://devcodef1.com/news/1108574/usb-permission-failure-in-android-14-xamarin
private void RequestUsbPermission(UsbDevice device)
{
UsbManager usbManager = (UsbManager)GetSystemService(Context.UsbService);
if (usbManager != null && device != null)
{
PendingIntent permissionIntent = PendingIntent.GetBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
usbManager.RequestPermission(device, permissionIntent);
}
}
5