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
This commit is contained in:
Paul McLean
2022-03-17 11:12:50 -06:00
parent e60fa2d099
commit 0f2adda03a

View File

@@ -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<ParcelUuid> mNonMidiUUIDs = new HashSet<ParcelUuid>();
// 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() {