flutter_reactive_ble
flutter_reactive_ble copied to clipboard
Android: Connection is leaked when cancelling the connection soon after the connecting event is received
Describe the bug
I was testing out if the library handles cancelling the connection correctly if done before the connection completes. I've found that if I cancel the stream when receiving a connection update with DeviceConnectionState.connecting
, then it causes a bug on Android. This is meant to simulate the user closing the page that requires the connection with similar timing.
To Reproduce Steps to reproduce the behavior:
- Connect to one device using
connectToAdvertisingDevice()
- Listen to the global connection event stream. In the handler, cancel the connection stream in response to an update with state
DeviceConnectionState.connecting
- Observe events emitted in an unexpected order. Also the connection attempt is not cancelled correctly, and the phone is stuck connected to the device. Any subsequent
connectToAdvertisingDevice
fails, and we can't make the phone disonnect, as there is no longer a connection stream to cancel. The connected event is never received.
I/flutter (32163): INFO: 2023-06-05 15:45:42.133479: ble_connections: Connecting to 34:94:54:5D:51:8A
I/flutter (32163): ---
D/BluetoothAdapter(32163): isLeEnabled(): ON
D/BluetoothLeScanner(32163): onScannerRegistered() - status=0 scannerId=3 mScannerId=0
D/BluetoothAdapter(32163): isLeEnabled(): ON
D/BluetoothGatt(32163): connect() - device: 34:94:54:5D:51:8A, auto: false
D/BluetoothGatt(32163): registerApp()
I/flutter (32163): ---
D/BluetoothGatt(32163): registerApp() - UUID=e5fd0cfb-5271-4334-a985-23376d499022
I/flutter (32163): INFO: 2023-06-05 15:45:48.046516: ble_connections: Connection update for 34:94:54:5D:51:8A: DeviceConnectionState.connecting
I/flutter (32163): ---
D/BluetoothGatt(32163): onClientRegistered() - status=0 clientIf=6
I/flutter (32163): ---
I/flutter (32163): INFO: 2023-06-05 15:45:48.249214: ble_connections: Disconnecting from 34:94:54:5D:51:8A
I/flutter (32163): ---
I/flutter (32163): ---
I/flutter (32163): INFO: 2023-06-05 15:45:48.259584: ble_connections: Connection update for 34:94:54:5D:51:8A: DeviceConnectionState.disconnected
I/flutter (32163): ---
I/flutter (32163): ---
I/flutter (32163): INFO: 2023-06-05 15:45:48.260417: ble_connections: Connection update for 34:94:54:5D:51:8A: DeviceConnectionState.connecting
I/flutter (32163): ---
D/BluetoothGatt(32163): close()
D/BluetoothGatt(32163): unregisterApp() - mClientIf=6
I/flutter (32163): ---
Expected behavior A clear and concise description of what you expected to happen.
When I cancel the connection event stream, then the connection is cancelled regardless of the timing. The phone either disconnects from the peer or it stops the in progress connection to it.
- [x] I tried doing the same with a general BLE scanner application (e.g. nRF Connect) and it exhibits the expected behavior as described above. Mashing the connect/disonnect button, there is never a leaked connection while using nRF connect, and the UI always correctly represents the state of the connection.
Smartphone / tablet
- Device: Google Pixel 5
- OS: Android 13, security update 2023-04-05
- Package version: 5.0.3
Peripheral device
- Vendor, model: custom
- Does it run a custom firmware / software: yes
Additional context
iOS works fine. The only issue is that if the cancel happens before the first connecting event, then no disconnect event is emitted, but I can work around this. This is event is also missing on Android, and cancelling before the first connecting
event seems to work OK.
I expect that waiting for any in progress connection to finish before cancelling this stream will work around this bug.
Kind of similar to my case #745 except I am using connectToDevice and with autoConnect = true.
Any updates on this issue?