From 0f2adda03a722f2db77022760cb0f76ddfd42f3e Mon Sep 17 00:00:00 2001 From: Paul McLean Date: Thu, 17 Mar 2022 11:12:50 -0600 Subject: [PATCH] Filter out non-MIDI devices before attempting connection. Look for non-BLE transport devices Look for Service UUIDs indicative of non-MIDI devices Bug: 222388547 Bug: 216498842 Bug: 221079216 Test: Connect BT headset, examine log for no MIDI connect Conect BLE-MIDI devices, examine log for MIDI connect Listen in headphones, Play a MIDI synth with BLE-MIDI controller. Signature: MidiManager: openBluetoothDevice() XX:XX:XX:XX:XX:XX MidiService: openBluetoothDevice() Change-Id: Ibaadc26edb1ea9fdfab7891eda1f260fefb9757e --- .../com/android/server/midi/MidiService.java | 84 ++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java index 2d082e1576924..d7c9342fa342f 100644 --- a/services/midi/java/com/android/server/midi/MidiService.java +++ b/services/midi/java/com/android/server/midi/MidiService.java @@ -18,6 +18,7 @@ package com.android.server.midi; import android.annotation.NonNull; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothUuid; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -148,6 +149,8 @@ public class MidiService extends IMidiManager.Stub { private static final UUID MIDI_SERVICE = UUID.fromString( "03B80E5A-EDE8-4B33-A751-6CE34EC4C700"); + private final HashSet mNonMidiUUIDs = new HashSet(); + // PackageMonitor for listening to package changes private final PackageMonitor mPackageMonitor = new PackageMonitor() { @Override @@ -640,6 +643,55 @@ public class MidiService extends IMidiManager.Stub { return false; } + private static void dumpIntentExtras(Intent intent) { + String action = intent.getAction(); + Log.d(TAG, "Intent: " + action); + Bundle bundle = intent.getExtras(); + if (bundle != null) { + for (String key : bundle.keySet()) { + Log.d(TAG, " " + key + " : " + + (bundle.get(key) != null ? bundle.get(key) : "NULL")); + } + } + } + + private static boolean isBleTransport(Intent intent) { + Bundle bundle = intent.getExtras(); + boolean isBle = false; + if (bundle != null) { + isBle = bundle.getInt(BluetoothDevice.EXTRA_TRANSPORT, BluetoothDevice.TRANSPORT_AUTO) + == BluetoothDevice.TRANSPORT_LE; + } + return isBle; + } + + private void dumpUuids(BluetoothDevice btDevice) { + Log.d(TAG, "UUIDs for " + btDevice); + + ParcelUuid[] uuidParcels = btDevice.getUuids(); + if (uuidParcels == null) { + Log.d(TAG, "No UUID Parcels"); + return; + } + + for (ParcelUuid parcel : uuidParcels) { + UUID uuid = parcel.getUuid(); + Log.d(TAG, " uuid:" + uuid); + } + } + + private boolean hasNonMidiUuids(BluetoothDevice btDevice) { + ParcelUuid[] uuidParcels = btDevice.getUuids(); + // The assumption is that these services are indicative of devices that + // ARE NOT MIDI devices. + for (ParcelUuid parcel : uuidParcels) { + if (mNonMidiUUIDs.contains(parcel)) { + return true; + } + } + return false; + } + private final BroadcastReceiver mBleMidiReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -652,10 +704,27 @@ public class MidiService extends IMidiManager.Stub { switch (action) { case BluetoothDevice.ACTION_ACL_CONNECTED: { Log.d(TAG, "ACTION_ACL_CONNECTED"); + dumpIntentExtras(intent); + // BLE-MIDI controllers are by definition BLE, so if this device + // isn't, it CAN'T be a midi device + if (!isBleTransport(intent)) { + Log.i(TAG, "No BLE transport - NOT MIDI"); + break; + } + + Log.d(TAG, "BLE Device"); BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - // We can't determine here if this is a BLD-MIDI device, so go ahead and try - // to open as a MIDI device, further down it will get figured out. + dumpUuids(btDevice); + + // See if there are any service UUIDs and if so do any of them indicate a + // Non-MIDI device (headset, headphones, QWERTY keyboard....) + if (hasNonMidiUuids(btDevice)) { + Log.d(TAG, "Non-MIDI service UUIDs found. NOT MIDI"); + break; + } + + Log.d(TAG, "Potential MIDI Device."); openBluetoothDevice(btDevice); } break; @@ -686,6 +755,17 @@ public class MidiService extends IMidiManager.Stub { context.registerReceiver(mBleMidiReceiver, filter); mBluetoothServiceUid = -1; + + mNonMidiUUIDs.add(BluetoothUuid.A2DP_SINK); // Headphones? + mNonMidiUUIDs.add(BluetoothUuid.A2DP_SOURCE); // Headset? + mNonMidiUUIDs.add(BluetoothUuid.ADV_AUDIO_DIST); + mNonMidiUUIDs.add(BluetoothUuid.AVRCP_CONTROLLER); + mNonMidiUUIDs.add(BluetoothUuid.HFP); + mNonMidiUUIDs.add(BluetoothUuid.HSP); + mNonMidiUUIDs.add(BluetoothUuid.HID); + mNonMidiUUIDs.add(BluetoothUuid.LE_AUDIO); + mNonMidiUUIDs.add(BluetoothUuid.HOGP); + mNonMidiUUIDs.add(BluetoothUuid.HEARING_AID); } private void onUnlockUser() {