home-assistant / android

:iphone: Home Assistant Companion for Android
https://companion.home-assistant.io/
Apache License 2.0
2.26k stars 628 forks source link

Bluetooth Connection sensor incorrectly assumes connected devices are not paired #2736

Closed jpelgrom closed 2 years ago

jpelgrom commented 2 years ago

Home Assistant Android version: 2022.6.0-full, beta-2534-90a9a27e-full

Android version: 13

Phone model: Pixel 4a

Home Assistant version: not relevant

Last working Home Assistant release (if known): looking at the history of BluetoothUtils, it has always been broken

Description of problem: Discovered while reviewing a PR: paired devices that are connected via GATT will show up both in connected_paired_devices and connected_not_paired_devices because for connected_not_paired_devices it actually isn't checked if the device is paired or not:

https://github.com/home-assistant/android/blob/90a9a27e5e371445f75481e7a93609528357d3ff/common/src/main/java/io/homeassistant/companion/android/common/bluetooth/BluetoothUtils.kt#L34

https://github.com/home-assistant/android/blob/90a9a27e5e371445f75481e7a93609528357d3ff/common/src/main/java/io/homeassistant/companion/android/common/bluetooth/BluetoothUtils.kt#L39-L44

Traceback (if applicable, to get the logs you may refer to: https://companion.home-assistant.io/docs/troubleshooting/faqs/#android-crash-logs):

n/a

Screenshot of problem:

App settings showing sensor attributes, with one device showing up in both `connected_paired_devices` and `connected_not_paired_devices`

(the device addresses are the same, just blacked out for privacy)

Additional information: After adding debug logging into the app to check the bondState of the device, it shows up as BOND_BONDED in both cases. This makes sense because they share the same hardware address and the developer documentation says that it is: "(...) a thin wrapper for a Bluetooth hardware address".

dshokouhi commented 2 years ago

After adding debug logging into the app to check the bondState of the device, it shows up as BOND_BONDED in both cases.

ran a test myself on my Mi Band 7, still shows up as unpaired if we check the bondState instead of assuming its false

jpelgrom commented 2 years ago

ran a test myself on my Mi Band 7, still shows up as unpaired if we check the bondState instead of assuming its false

Hmm, does the bondState also show as not paired if you replace the assumed true in the list of paired devices?

I used the following check to determine if the device is paired: btDev.bondState == android.bluetooth.BluetoothDevice.BOND_BONDED

dshokouhi commented 2 years ago

Hmm, does the bondState also show as not paired if you replace the assumed true in the list of paired devices?

I decided not to test that originally only because we are getting the first list from bondedDevices 😂

Ran a test now and don't see any differences, although I wouldn't expect to only because of the method used to get the list

I used the following check to determine if the device is paired: btDev.bondState == android.bluetooth.BluetoothDevice.BOND_BONDED

That was exactly what I used in my testing, but only for getConnectedDevices() as that can contain devices not paired

jpelgrom commented 2 years ago

I decided not to test that originally only because we are getting the first list from bondedDevices 😂

In getConnectedDevices it is also still checking if the device is actually connected instead of assuming it.

Ran a test now and don't see any differences

This puzzles me but might be a device-specific issue, or at least not in the scope of this issue.