Android - DemoRunner & AudioDeviceSelectorComponent: clicking Bluetooth MIDI crashes the app

This is with the latest juce/develop, Pixel 6, Android 13.

Bluetooth is on, and the permissions are enabled.

Stack trace from the debugger:

It looks like android.permission.BLUETOOTH_SCAN (and possibly android.permission.BLUETOOTH_CONNECT ?) need to be added.

@reuk You’re probably swamped as per the usual – I saw your changes on GitHub/develop and will check 'em out today/tomorrow.

Thanks!

It looks like you need to add the permissions on your DemoRunner + demos apps accordingly, and prompt for them all.

For example, if I use the Projucer and generate the MidiDemo project, it doesn’t have all of the necessary permissions. In turn this causes assertions about permissions:

Even when adding all of the required permissions from Android, I get crashes with logs like this:

runtime.cc:684] JNI DETECTED ERROR IN APPLICATION: JNI IsInstanceOf called with pending exception java.lang.SecurityException: Need android.permission.BLUETOOTH_SCAN permission for android.content.AttributionSource@9cf7f69c: GattService registerScanner

From what I can tell, “Nearby Devices” needs to be requested here as much as the rest (ie: android.permission.BLUETOOTH_SCAN as per the log I posted). According the Android Bluetooth permissions page, the app should prompt like this: https://developer.android.com/static/images/guide/topics/connectivity/bluetooth/nearby-devices.svg

If I manually allow the permission for “Nearby devices”, the app works as intended.

The complete solution is to properly add support for permissions checking across the board.

  • All of the Bluetooth and related demo code, as required, should be dynamically checking for permissions.
  • The JUCE PIP manifest, where many PIPs should be enabling a great many permissions, should be modified correctly to generate projects with all of these permissions.
  • The DemoRunner should have the assortment of Bluetooth permissions enabled by default.
1 Like

You have a good point about the PIPs.

The rest however could already be in order? All bluetooth permissions are requested by the DemoRunner

When pressing the Bluetooth button in the MidiDemo, the Nearby Devices permission request dialog pops up for me, just like in the material you linked.

The dynamic checking code has already been there though, the only thing that changed recently is that on Android 12+ RuntimePermissions::bluetoothMidi maps to a different Android permission.

Is there a JUCE example maybe where this check is missing?

Hm, just re-checked locally and it appears you’re right. I’ve a few JUCE projects with different JUCE repos going in parallel so I probably loaded the wrong DemoRunner project and mucked up what I needed to see. Sorry about that!

Yes, the missing checks are part of the same "MIDI Bluetooth devices..." button.

The moment I disable "Nearby devices" in the “App Info” permissions view, clicking the "MIDI Bluetooth devices..." button will crash the app because not all required permissions are available (specifically, according the logs, android.permission.BLUETOOTH_SCAN is not being prompted). See the screenshots here to understand what to test. Go from this:

To this:

And now hit that Bluetooth devices button in the MidiDemo to witness the crash (with no debugger attached)/exception being thrown with a debugger attached.

Just from a quick glance, is it possible that androidPermissionToJucePermission is giving the wrong permission to scan when code requests bluetoothMidi ?

Thanks for the screenshots. I did try this out but haven’t been able to repro the crash so far.

If the Nearby devices permission is disabled the button callback is called with wasGranted == false at MidiDemo.h:105, which is the expected behaviour and seems to be sufficient to avoid crashing.

Can you see this callback called with a true argument even though the permission is explicitly turned off? Did you enable all three permissions in the Projucer: Scan, Advertise and Connect?

I’ll double check using the DemoRunner so as to remove the variable of the generated MidiDemo project + any manually added permissions.

I can confirm that this works fine in the DemoRunner.

I’ll now build + run + test a newly generated MidiDemo project with all of the permissions.

PEBKAC is the answer: the module paths were using the global paths, which had an out of date JUCE!

Everything works here…

1 Like