Skip to content

Fatal SecurityException during USB enumeration on Android 10+ (Target SDK >= 29) prevents connecting to Flight Controllers #14190

@riverdotcodev

Description

@riverdotcodev

Have you checked the latest release for fixes?

  • Yes, I’ve tested on the latest release

Description

On Android devices with internal USB peripherals (such as integrated USB hubs, touch panels, or joysticks), QGroundControl crashes its USB enumeration thread when attempting to read the serial number of devices it hasn't been explicitly granted permission to access. This prevents QGC from discovering the actual Flight Controller (e.g., CubeOrange) if it happens to be enumerated after the internal peripherals in the USB device list.

Steps to reproduce the behavior:

  1. Run QGC on an Android 10+ device (API Level >= 29) that has other internal USB devices.
  2. Connect a Flight Controller via USB.
  3. QGC attempts to iterate through the UsbManager.getDeviceList().
  4. When QGC calls UsbDevice.getSerialNumber() on an internal device, Android throws a SecurityException.
  5. The unhandled exception breaks the enumeration loop, and the Flight Controller is never discovered.

QGC should catch the SecurityException during USB enumeration, gracefully ignore the device (or treat it as having no serial number), and continue scanning the rest of the USB devices.

Logcat Stack Trace:
01-01 00:04:29.898 6279 6303 W QGroundControl: 21.421 - warning: java.lang.SecurityException: User has not given 10116/org.mavlink.qgroundcontrol permission to access device /dev/bus/usb/003/003 01-01 00:04:29.898 6279 6303 W QGroundControl: at android.os.Parcel.createExceptionOrNull(Parcel.java:3011) 01-01 00:04:29.898 6279 6303 W QGroundControl: at android.os.Parcel.createException(Parcel.java:2995) ... 01-01 00:04:29.898 6279 6303 W QGroundControl: at android.hardware.usb.UsbDevice.getSerialNumber(UsbDevice.java:157) 01-01 00:04:29.898 6279 6303 W QGroundControl: at org.mavlink.qgroundcontrol.QGCUsbSerialManager.formatDeviceInfo(QGCUsbSerialManager.java:449) 01-01 00:04:29.898 6279 6303 W QGroundControl: at org.mavlink.qgroundcontrol.QGCUsbSerialManager.availableDevicesInfo(QGCUsbSerialManager.java:431)

I am a hardware supplier and we manufacture Android-based Ground Control Stations (GCS). We noticed issue #12477 where downgrading the targetSdkVersion to 28 acts as a workaround. I can confirm this works because Android 10 (API 29) introduced strict privacy restrictions on getSerialNumber().

However, as an OEM, we cannot force our end-users to use legacy builds of QGC, and Google Play policies require higher target SDKs.

Could the development team implement a proper try-catch block around the getSerialNumber() call inside QGCUsbSerialManager.java?
Catching the SecurityException and returning an empty string or null would make the USB enumeration robust against strict Android API 29+ security policies, allowing the loop to reach the actual MAVLink devices.

Are there any plans to fix this in the upcoming releases? We would heavily appreciate it!

Platform

Android

Flight Stack

None

System Information

.QGC Version: 5.0.8
.QGC build: stable, self-built from source
.Operating System: Android 13
.Flight Controller: CubePilot Cube Orange

Log Files and Screenshots

No response

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions