mirror of
https://github.com/oliexdev/openScale.git
synced 2025-08-15 05:04:22 +02:00
Refactor ScaleFactory and BluetoothScannerManager to use ScannedDeviceInfo
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
package com.health.openscale.core.bluetooth
|
||||
|
||||
import android.R.attr.identifier
|
||||
import android.R.attr.name
|
||||
import android.content.Context
|
||||
import android.util.SparseArray
|
||||
import com.health.openscale.core.bluetooth.scales.DummyScaleHandler
|
||||
@@ -77,9 +79,7 @@ class ScaleFactory(
|
||||
// List of modern Kotlin-based device handlers.
|
||||
// These are checked first for device compatibility.
|
||||
private val modernKotlinHandlers: List<ScaleDeviceHandler> = listOf(
|
||||
DummyScaleHandler("Mi Scale"), // Recognizes devices with "Mi Scale" in their name
|
||||
DummyScaleHandler("Beurer"), // Recognizes devices with "Beurer" in their name
|
||||
DummyScaleHandler("BF700") // Recognizes devices with "BF700" in their name
|
||||
DummyScaleHandler("Test") // Recognizes devices with "Test" in their name
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -87,11 +87,20 @@ class ScaleFactory(
|
||||
* This method contains the logic to map device names to specific Java driver classes.
|
||||
*
|
||||
* @param context The application context.
|
||||
* @param deviceName The name of the Bluetooth device.
|
||||
* @param deviceInfo Information about the scanned Bluetooth device.
|
||||
* @return A [BluetoothCommunication] instance if a matching driver is found, otherwise null.
|
||||
*/
|
||||
private fun createLegacyJavaDriver(context: Context?, deviceName: String): BluetoothCommunication? {
|
||||
val name = deviceName.lowercase()
|
||||
private fun createLegacyJavaDriver(context: Context?, deviceInfo: ScannedDeviceInfo): BluetoothCommunication? {
|
||||
val deviceName : String
|
||||
val name : String
|
||||
|
||||
if (deviceInfo.name != null) {
|
||||
deviceName = deviceInfo.name
|
||||
name = deviceInfo.name.lowercase()
|
||||
} else {
|
||||
deviceName = deviceInfo.determinedHandlerDisplayName ?: "UnknownDevice"
|
||||
name = deviceInfo.determinedHandlerDisplayName?.lowercase() ?: "UnknownDevice"
|
||||
}
|
||||
|
||||
if (name.startsWith("BEURER BF700".lowercase())
|
||||
|| name.startsWith("BEURER BF800".lowercase())
|
||||
@@ -256,11 +265,11 @@ class ScaleFactory(
|
||||
* Creates a [ScaleCommunicator] using the legacy Java driver approach.
|
||||
* It wraps a [BluetoothCommunication] instance (Java driver) in a [LegacyScaleAdapter].
|
||||
*
|
||||
* @param identifier The device name or other identifier used to find a legacy Java driver.
|
||||
* @param deviceInfo The device information used to find a legacy Java driver.
|
||||
* @return A [LegacyScaleAdapter] instance if a suitable Java driver is found, otherwise null.
|
||||
*/
|
||||
private fun createLegacyCommunicator(identifier: String): ScaleCommunicator? {
|
||||
val javaDriverInstance = createLegacyJavaDriver(applicationContext, identifier)
|
||||
private fun createLegacyCommunicator(deviceInfo: ScannedDeviceInfo): ScaleCommunicator? {
|
||||
val javaDriverInstance = createLegacyJavaDriver(applicationContext, deviceInfo)
|
||||
return if (javaDriverInstance != null) {
|
||||
LogManager.i(TAG, "Creating LegacyScaleAdapter with Java driver '${javaDriverInstance.javaClass.simpleName}'.")
|
||||
LegacyScaleAdapter(
|
||||
@@ -269,7 +278,7 @@ class ScaleFactory(
|
||||
databaseRepository = databaseRepository
|
||||
)
|
||||
} else {
|
||||
LogManager.w(TAG, "Could not create LegacyScaleAdapter: No Java driver found for '$identifier'.")
|
||||
LogManager.w(TAG, "Could not create LegacyScaleAdapter: No Java driver found for '${deviceInfo.name}'.")
|
||||
null
|
||||
}
|
||||
}
|
||||
@@ -332,12 +341,10 @@ class ScaleFactory(
|
||||
LogManager.d(TAG, "No modern Kotlin handler actively claimed '${primaryIdentifier}' or could create a communicator.")
|
||||
|
||||
// 2. Fallback to legacy adapter if no modern handler matched or created a communicator.
|
||||
// The device name (or a specific legacy handler name, if known from `determinedHandlerDisplayName`) is used.
|
||||
val identifierForLegacy = deviceInfo.determinedHandlerDisplayName ?: primaryIdentifier
|
||||
LogManager.i(TAG, "Attempting fallback to legacy adapter for identifier '${identifierForLegacy}'.")
|
||||
val legacyCommunicator = createLegacyCommunicator(identifierForLegacy)
|
||||
LogManager.i(TAG, "Attempting fallback to legacy adapter for identifier '${deviceInfo.name}'.")
|
||||
val legacyCommunicator = createLegacyCommunicator(deviceInfo)
|
||||
if (legacyCommunicator != null) {
|
||||
LogManager.i(TAG, "Legacy communicator '${legacyCommunicator.javaClass.simpleName}' created for device (identifier: '${identifierForLegacy}').")
|
||||
LogManager.i(TAG, "Legacy communicator '${legacyCommunicator.javaClass.simpleName}' created for device ('${deviceInfo.name}').")
|
||||
return legacyCommunicator
|
||||
}
|
||||
|
||||
@@ -349,39 +356,26 @@ class ScaleFactory(
|
||||
* Checks if any known handler (modern Kotlin or legacy Java-based) can theoretically support the given device.
|
||||
* This can be used by the UI to indicate if a device is potentially recognizable.
|
||||
*
|
||||
* @param deviceName The name of the Bluetooth device.
|
||||
* @param deviceAddress The MAC address of the device.
|
||||
* @param serviceUuids A list of advertised service UUIDs.
|
||||
* @param manufacturerData Manufacturer-specific data from the advertisement.
|
||||
* @param deviceInfo Information about the scanned Bluetooth device.
|
||||
* @return A Pair where `first` is true if a handler is found, and `second` is the name of the handler/driver, or null.
|
||||
*/
|
||||
fun getSupportingHandlerInfo(
|
||||
deviceName: String?,
|
||||
deviceAddress: String,
|
||||
serviceUuids: List<UUID>,
|
||||
manufacturerData: SparseArray<ByteArray>?
|
||||
): Pair<Boolean, String?> {
|
||||
val primaryIdentifier = deviceName ?: "UnknownDevice"
|
||||
// LogManager.d(TAG, "getSupportingHandlerInfo for: '$primaryIdentifier', Addr: $deviceAddress, UUIDs: ${serviceUuids.size}, ManuData: ${manufacturerData != null}")
|
||||
|
||||
fun getSupportingHandlerInfo(deviceInfo : ScannedDeviceInfo): Pair<Boolean, String?> {
|
||||
// Check modern handlers first
|
||||
for (handler in modernKotlinHandlers) {
|
||||
if (handler.canHandleDevice(deviceName, deviceAddress, serviceUuids, manufacturerData)) {
|
||||
// LogManager.d(TAG, "getSupportingHandlerInfo: Modern handler '${handler.getDriverName()}' matches '$primaryIdentifier'.")
|
||||
if (handler.canHandleDevice(deviceInfo.name, deviceInfo.address, deviceInfo.serviceUuids, deviceInfo.manufacturerData)) {
|
||||
return true to handler.getDriverName() // The "driver name" of the modern handler
|
||||
}
|
||||
}
|
||||
|
||||
// Then check if a legacy driver would exist based on the name
|
||||
if (deviceName != null) {
|
||||
val legacyJavaDriver = createLegacyJavaDriver(applicationContext, deviceName)
|
||||
if (deviceInfo.name != null) {
|
||||
val legacyJavaDriver = createLegacyJavaDriver(applicationContext, deviceInfo)
|
||||
if (legacyJavaDriver != null) {
|
||||
// LogManager.d(TAG, "getSupportingHandlerInfo: Legacy driver '${legacyJavaDriver.javaClass.simpleName}' matches '$deviceName'.")
|
||||
// Return the driver name from the BluetoothCommunication interface if available and meaningful.
|
||||
return true to legacyJavaDriver.driverName() // Assumes BluetoothCommunication has a driverName() method.
|
||||
}
|
||||
}
|
||||
LogManager.d(TAG, "getSupportingHandlerInfo: No supporting handler found for '$primaryIdentifier'.")
|
||||
LogManager.d(TAG, "getSupportingHandlerInfo: No supporting handler found for ${deviceInfo.name}.")
|
||||
return false to null
|
||||
}
|
||||
}
|
||||
|
@@ -250,23 +250,21 @@ class BluetoothScannerManager(
|
||||
val serviceUuids: List<UUID> = scanResult.scanRecord?.serviceUuids?.mapNotNull { it?.uuid } ?: emptyList()
|
||||
val manufacturerData: SparseArray<ByteArray>? = scanResult.scanRecord?.manufacturerSpecificData
|
||||
|
||||
val (isSupported, handlerName) = scaleFactory.getSupportingHandlerInfo(
|
||||
deviceName = deviceName,
|
||||
deviceAddress = deviceAddress,
|
||||
serviceUuids = serviceUuids,
|
||||
manufacturerData = manufacturerData
|
||||
)
|
||||
|
||||
val newDevice = ScannedDeviceInfo(
|
||||
name = deviceName,
|
||||
address = deviceAddress,
|
||||
rssi = rssi,
|
||||
serviceUuids = serviceUuids,
|
||||
manufacturerData = manufacturerData,
|
||||
isSupported = isSupported,
|
||||
determinedHandlerDisplayName = handlerName
|
||||
isSupported = false, // will be determined in the next getSupportingHandlerInfo
|
||||
determinedHandlerDisplayName = null // // will be determined in the next getSupportingHandlerInfo
|
||||
)
|
||||
|
||||
val (isSupported, handlerName) = scaleFactory.getSupportingHandlerInfo(newDevice)
|
||||
|
||||
newDevice.isSupported = isSupported
|
||||
newDevice.determinedHandlerDisplayName = handlerName
|
||||
|
||||
val existingDevice = deviceMap[newDevice.address]
|
||||
var listShouldBeUpdated = false
|
||||
|
||||
|
@@ -344,12 +344,6 @@ class BluetoothViewModel(
|
||||
// For a saved device, we need to re-evaluate its support status using ScaleFactory,
|
||||
// as supported handlers might change with app updates.
|
||||
LogManager.d(TAG, "Re-evaluating support for saved device '$name' ($address) using ScaleFactory.")
|
||||
val (isPotentiallySupported, handlerNameFromFactory) = scaleFactory.getSupportingHandlerInfo(
|
||||
deviceName = name,
|
||||
deviceAddress = address,
|
||||
serviceUuids = emptyList(), // Service UUIDs are unknown without a fresh scan.
|
||||
manufacturerData = null // Manufacturer data is unknown without a fresh scan.
|
||||
)
|
||||
|
||||
val deviceInfoForConnect = ScannedDeviceInfo(
|
||||
name = name,
|
||||
@@ -357,10 +351,14 @@ class BluetoothViewModel(
|
||||
rssi = 0, // RSSI is not relevant for a direct connection attempt to a saved device.
|
||||
serviceUuids = emptyList(),
|
||||
manufacturerData = null,
|
||||
isSupported = isPotentiallySupported, // Use current support assessment.
|
||||
determinedHandlerDisplayName = handlerNameFromFactory
|
||||
isSupported = false, // will be determined by getSupportingHandlerInfo
|
||||
determinedHandlerDisplayName = null // will be determined by getSupportingHandlerInfo
|
||||
)
|
||||
|
||||
val (isPotentiallySupported, handlerNameFromFactory) = scaleFactory.getSupportingHandlerInfo(deviceInfoForConnect)
|
||||
deviceInfoForConnect.isSupported = isPotentiallySupported
|
||||
deviceInfoForConnect.determinedHandlerDisplayName = handlerNameFromFactory
|
||||
|
||||
if (!deviceInfoForConnect.isSupported) {
|
||||
LogManager.w(TAG, "Saved device '$name' ($address) is currently not supported by ScaleFactory. Connection aborted.")
|
||||
// This error is specific to connecting to a *saved* device that's no longer supported.
|
||||
|
Reference in New Issue
Block a user