disassociate devices when not bonded

(cherry picked from commit b6410dd162)
This commit is contained in:
andrekir 2022-04-29 23:34:03 -03:00
parent ce90db8258
commit 9682c41f2b

View file

@ -144,7 +144,7 @@ class BTScanModel(app: Application) : AndroidViewModel(app), Logging {
debug("BTScanModel cleared") debug("BTScanModel cleared")
} }
val bluetoothAdapter = context.bluetoothManager?.adapter private val bluetoothAdapter = context.bluetoothManager?.adapter
private val deviceManager get() = context.deviceManager private val deviceManager get() = context.deviceManager
val hasCompanionDeviceApi get() = context.hasCompanionDeviceApi() val hasCompanionDeviceApi get() = context.hasCompanionDeviceApi()
private val hasConnectPermission get() = context.hasConnectPermission() private val hasConnectPermission get() = context.hasConnectPermission()
@ -224,8 +224,6 @@ class BTScanModel(app: Application) : AndroidViewModel(app), Logging {
} }
} }
private fun addDevice(entry: DeviceListEntry) { private fun addDevice(entry: DeviceListEntry) {
val oldDevs = devices.value!! val oldDevs = devices.value!!
oldDevs[entry.address] = entry // Add/replace entry oldDevs[entry.address] = entry // Add/replace entry
@ -294,8 +292,8 @@ class BTScanModel(app: Application) : AndroidViewModel(app), Logging {
// Include a placeholder for "None" // Include a placeholder for "None"
addDevice(DeviceListEntry(context.getString(R.string.none), "n", true)) addDevice(DeviceListEntry(context.getString(R.string.none), "n", true))
if (hasCompanionDeviceApi && hasConnectPermission) // Include CompanionDeviceManager valid associations
addAssociations() addDeviceAssociations()
usbDrivers.forEach { d -> usbDrivers.forEach { d ->
addDevice( addDevice(
@ -335,18 +333,33 @@ class BTScanModel(app: Application) : AndroidViewModel(app), Logging {
} }
} }
@SuppressLint("MissingPermission", "NewApi") /**
private fun addAssociations() { * @return DeviceListEntry from Bluetooth Address.
deviceManager?.associations?.forEach { bleAddress -> * Only valid if name begins with "Meshtastic"...
bluetoothAdapter?.getRemoteDevice(bleAddress)?.let { device -> */
if (device.name.startsWith("Mesh")) { @SuppressLint("MissingPermission")
val entry = DeviceListEntry( fun bleDeviceFrom(bleAddress: String): DeviceListEntry {
device.name, val device =
"x${device.address}", // full address with the bluetooth prefix added if (hasConnectPermission) bluetoothAdapter?.getRemoteDevice(bleAddress) else null
device.bondState == BOND_BONDED
) return if (device != null && device.name != null) {
addDevice(entry) DeviceListEntry(
} device.name,
"x${device.address}", // full address with the bluetooth prefix added
device.bondState == BOND_BONDED
)
} else DeviceListEntry("", "", false)
}
@SuppressLint("NewApi")
private fun addDeviceAssociations() {
if (hasCompanionDeviceApi) deviceManager?.associations?.forEach { bleAddress ->
val bleDevice = bleDeviceFrom(bleAddress)
if (!bleDevice.bonded) { // Clean up associations after pairing is removed
debug("Forgetting old BLE association ${bleAddress.anonymize}")
deviceManager?.disassociate(bleAddress)
} else if (bleDevice.name.startsWith("Mesh")) {
addDevice(bleDevice)
} }
} }
} }
@ -366,7 +379,7 @@ class BTScanModel(app: Application) : AndroidViewModel(app), Logging {
*/ */
override fun onInactive() { override fun onInactive() {
super.onInactive() super.onInactive()
// stopScan() if (!hasCompanionDeviceApi) stopScan()
} }
} }
@ -781,8 +794,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
b.text = device.name b.text = device.name
b.id = View.generateViewId() b.id = View.generateViewId()
b.isEnabled = enabled b.isEnabled = enabled
b.isChecked = b.isChecked = device.address == scanModel.selectedNotNull
device.address == scanModel.selectedNotNull && device.bonded // Only show checkbox if device is still paired
binding.deviceRadioGroup.addView(b) binding.deviceRadioGroup.addView(b)
b.setOnClickListener { b.setOnClickListener {
@ -791,21 +803,15 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
b.isChecked = b.isChecked =
scanModel.onSelected(myActivity, device) scanModel.onSelected(myActivity, device)
if (!b.isSelected) {
binding.scanStatusText.text = getString(R.string.please_pair)
}
} }
} }
@SuppressLint("MissingPermission")
private fun updateDevicesButtons(devices: MutableMap<String, BTScanModel.DeviceListEntry>?) { private fun updateDevicesButtons(devices: MutableMap<String, BTScanModel.DeviceListEntry>?) {
// Remove the old radio buttons and repopulate // Remove the old radio buttons and repopulate
binding.deviceRadioGroup.removeAllViews() binding.deviceRadioGroup.removeAllViews()
if (devices == null) return if (devices == null) return
val adapter = scanModel.bluetoothAdapter
var hasShownOurDevice = false var hasShownOurDevice = false
devices.values.forEach { device -> devices.values.forEach { device ->
if (device.address == scanModel.selectedNotNull) if (device.address == scanModel.selectedNotNull)
@ -821,14 +827,14 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
// and before use // and before use
val bleAddr = scanModel.selectedBluetooth val bleAddr = scanModel.selectedBluetooth
if (bleAddr != null && adapter != null && myActivity.hasConnectPermission()) { if (bleAddr != null) {
val bDevice = debug("bleAddr= $bleAddr selected= ${scanModel.selectedAddress}")
adapter.getRemoteDevice(bleAddr) val bleDevice = scanModel.bleDeviceFrom(bleAddr)
if (bDevice.name != null) { // ignore nodes that node have a name, that means we've lost them since they appeared if (bleDevice.name.startsWith("Mesh")) { // ignore nodes that node have a name, that means we've lost them since they appeared
val curDevice = BTScanModel.DeviceListEntry( val curDevice = BTScanModel.DeviceListEntry(
bDevice.name, bleDevice.name,
scanModel.selectedAddress!!, bleDevice.address,
bDevice.bondState == BOND_BONDED bleDevice.bonded
) )
addDeviceButton( addDeviceButton(
curDevice, curDevice,
@ -1079,7 +1085,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
val hasUSB = SerialInterface.findDrivers(myActivity).isNotEmpty() val hasUSB = SerialInterface.findDrivers(myActivity).isNotEmpty()
if (!hasUSB) { if (!hasUSB) {
// Warn user if BLE is disabled // Warn user if BLE is disabled
if (scanModel.bluetoothAdapter?.isEnabled != true) { if (bluetoothViewModel.enabled.value == false) {
showSnackbar(getString(R.string.error_bluetooth)) showSnackbar(getString(R.string.error_bluetooth))
} else { } else {
if (binding.provideLocationCheckbox.isChecked) if (binding.provideLocationCheckbox.isChecked)