Fix USB permission flow on Android 12+ - #1
Open
ross-p-smith wants to merge 1 commit into
Open
Conversation
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).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
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).