Skip to content

Fix USB permission flow on Android 12+ - #1

Open
ross-p-smith wants to merge 1 commit into
hradio:masterfrom
ross-p-smith:fix/android-12-13-usb-permission
Open

Fix USB permission flow on Android 12+#1
ross-p-smith wants to merge 1 commit into
hradio:masterfrom
ross-p-smith:fix/android-12-13-usb-permission

Conversation

@ross-p-smith

Copy link
Copy Markdown

UsbHelper.requestPermission() relies on UsbManager mutating the PendingIntent it broadcasts back to us so we can read EXTRA_DEVICE and EXTRA_PERMISSION_GRANTED. On Android 12 (API 31) PendingIntents must declare mutability explicitly, and on Android 13 (API 33) runtime-registered receivers must declare export-ness. Without these, the PendingIntent registration is rejected on API 31+ with IllegalArgumentException, the receiver registration is rejected on API 33+ with SecurityException, and (when an immutable PendingIntent is used as a workaround) the permission broadcast arrives with a null EXTRA_DEVICE and the flow stalls silently.

This change:

  • Adds FLAG_MUTABLE to the USB_PERMISSION PendingIntent on Build.VERSION_CODES.S and above. FLAG_IMMUTABLE is wrong here: UsbManager needs to attach EXTRA_DEVICE and EXTRA_PERMISSION_GRANTED to the intent before broadcasting it back, which an immutable PendingIntent forbids.
  • Passes Context.RECEIVER_NOT_EXPORTED to registerReceiver on Build.VERSION_CODES.TIRAMISU and above. The USB_PERMISSION action is delivered by the system to our own process; not-exported is the correct choice and is required on API 33+.
  • Defensively ignores broadcasts whose action or EXTRA_DEVICE is null, and clears mPermissionPending in the USB_PERMISSION case so a swallowed grant cannot leave the helper stuck refusing further permission requests.

Verified on Android 13 (DUDU7 head unit, UNISOC UMS9620, SDK 33) with a 16C0:05DC USB DAB dongle: the USB permission grant path (USB_DEVICE_ATTACHED -> requestPermission -> permission granted -> openDevice) now completes without exception. Pre-fix, the same flow failed at the PendingIntent / registerReceiver call sites on Android 12+ / 13+ respectively.

File licence is unchanged (Apache-2.0, IRT GmbH 2018).

UsbHelper.requestPermission() relies on UsbManager mutating the
PendingIntent it broadcasts back to us so we can read EXTRA_DEVICE
and EXTRA_PERMISSION_GRANTED. On Android 12 (API 31) PendingIntents
must declare mutability explicitly, and on Android 13 (API 33)
runtime-registered receivers must declare export-ness. Without
these, the PendingIntent registration is rejected on API 31+ with
IllegalArgumentException, the receiver registration is rejected on
API 33+ with SecurityException, and (when an immutable PendingIntent
is used as a workaround) the permission broadcast arrives with a
null EXTRA_DEVICE and the flow stalls silently.

This change:

- Adds FLAG_MUTABLE to the USB_PERMISSION PendingIntent on
  Build.VERSION_CODES.S and above. FLAG_IMMUTABLE is wrong here:
  UsbManager needs to attach EXTRA_DEVICE and
  EXTRA_PERMISSION_GRANTED to the intent before broadcasting it
  back, which an immutable PendingIntent forbids.
- Passes Context.RECEIVER_NOT_EXPORTED to registerReceiver on
  Build.VERSION_CODES.TIRAMISU and above. The USB_PERMISSION action
  is delivered by the system to our own process; not-exported is
  the correct choice and is required on API 33+.
- Defensively ignores broadcasts whose action or EXTRA_DEVICE is
  null, and clears mPermissionPending in the USB_PERMISSION case
  so a swallowed grant cannot leave the helper stuck refusing
  further permission requests.

Verified on Android 13 (DUDU7 head unit, UNISOC UMS9620, SDK 33)
with a 16C0:05DC USB DAB dongle: the USB permission grant path
(USB_DEVICE_ATTACHED -> requestPermission -> permission granted ->
openDevice) now completes without exception. Pre-fix, the same
flow failed at the PendingIntent / registerReceiver call sites on
Android 12+ / 13+ respectively.

File licence is unchanged (Apache-2.0, IRT GmbH 2018).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant