Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions omriusb/src/main/java/org/omri/radio/impl/UsbHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,29 @@ private UsbHelper(Context context) {

if(mContext != null) {
mUsbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
mUsbPermissionIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_USB_PERMISSION), 0);
// Android 12 (S, API 31) requires PendingIntent flags to explicitly declare mutability.
// UsbManager.requestPermission() needs to populate EXTRA_DEVICE and
// EXTRA_PERMISSION_GRANTED on the intent before broadcasting it back to us, which
// requires FLAG_MUTABLE. (FLAG_IMMUTABLE would deliver an empty broadcast and the
// permission flow would silently fail.)
int piFlags = PendingIntent.FLAG_UPDATE_CURRENT;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
piFlags |= PendingIntent.FLAG_MUTABLE;
}
mUsbPermissionIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_USB_PERMISSION), piFlags);

IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);

mContext.registerReceiver(mUsbBroadcastReceiver, filter);
// Android 13 (TIRAMISU, API 33) requires runtime-registered receivers to specify
// export-ness. ACTION_USB_PERMISSION is delivered by the system to our own process,
// so RECEIVER_NOT_EXPORTED is correct.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
mContext.registerReceiver(mUsbBroadcastReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
} else {
mContext.registerReceiver(mUsbBroadcastReceiver, filter);
}
created();
}
}
Expand Down Expand Up @@ -228,6 +244,20 @@ void removeDevice(UsbDevice remDev) {
public void onReceive(Context context, Intent intent) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
String action = intent.getAction();
if (action == null) {
if (DEBUG) Log.w(TAG, "Received broadcast with null action; ignoring");
return;
}
if (device == null) {
// Some Android builds deliver a USB_PERMISSION broadcast with EXTRA_DEVICE missing
// (e.g. when the system retracts a pending request). Without a device handle there
// is nothing meaningful to do; clearing pending state avoids getting stuck.
if (DEBUG) Log.w(TAG, "Received " + action + " with null EXTRA_DEVICE; ignoring");
if (ACTION_USB_PERMISSION.equals(action)) {
mPermissionPending = false;
}
return;
}
synchronized (this) {
if (ACTION_USB_PERMISSION.equals(action)) {
if(DEBUG)Log.d(TAG, "Received Permission request: " + action);
Expand Down