From 593977df002a43d8df648b913a2816cde2fca1e4 Mon Sep 17 00:00:00 2001 From: Semper-Viventem Date: Mon, 22 Jan 2024 18:09:18 +0200 Subject: [PATCH] Fix background ble scanner --- app/build.gradle.kts | 4 +- .../java/f/cking/software/data/DataModule.kt | 2 + .../data/helpers/BleFiltersProvider.kt | 40 ++++++++++++++----- .../software/data/helpers/BleScannerHelper.kt | 11 ++--- .../interactor/GetAllDevicesInteractor.kt | 13 ++++++ .../interactor/GetKnownDevicesInteractor.kt | 19 --------- .../domain/interactor/InteractorsModule.kt | 2 +- 7 files changed, 52 insertions(+), 39 deletions(-) create mode 100644 app/src/main/java/f/cking/software/domain/interactor/GetAllDevicesInteractor.kt delete mode 100644 app/src/main/java/f/cking/software/domain/interactor/GetKnownDevicesInteractor.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index fb6aa0c..63331f4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -26,8 +26,8 @@ android { // This version code will be applied only for F-Droid builds, for other builds version code will be generated by gradle dynamically // For some reason F-Droid requires version code to be hardcoded in the build.gradle file - versionCode = 1705859018 - versionName = "0.22.4-beta" + versionCode = 1705859020 + versionName = "0.22.5-beta" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/f/cking/software/data/DataModule.kt b/app/src/main/java/f/cking/software/data/DataModule.kt index fbbd444..5266f2e 100644 --- a/app/src/main/java/f/cking/software/data/DataModule.kt +++ b/app/src/main/java/f/cking/software/data/DataModule.kt @@ -4,6 +4,7 @@ import android.content.Context import android.content.Context.MODE_PRIVATE import f.cking.software.data.database.AppDatabase import f.cking.software.data.helpers.ActivityProvider +import f.cking.software.data.helpers.BleFiltersProvider import f.cking.software.data.helpers.BleScannerHelper import f.cking.software.data.helpers.IntentHelper import f.cking.software.data.helpers.LocationProvider @@ -24,6 +25,7 @@ class DataModule( ) { val module = module { single { BleScannerHelper(get(), get(), get()) } + single { BleFiltersProvider(get()) } single { get().getSharedPreferences(sharedPreferencesName, MODE_PRIVATE) } single { SettingsRepository(get()) } single { AppDatabase.build(get(), appDatabaseName) } diff --git a/app/src/main/java/f/cking/software/data/helpers/BleFiltersProvider.kt b/app/src/main/java/f/cking/software/data/helpers/BleFiltersProvider.kt index 6f3f0a7..ad4d65b 100644 --- a/app/src/main/java/f/cking/software/data/helpers/BleFiltersProvider.kt +++ b/app/src/main/java/f/cking/software/data/helpers/BleFiltersProvider.kt @@ -2,15 +2,21 @@ package f.cking.software.data.helpers import android.bluetooth.le.ScanFilter import android.os.ParcelUuid -import f.cking.software.domain.interactor.GetKnownDevicesInteractor +import f.cking.software.domain.interactor.GetAllDevicesInteractor import f.cking.software.domain.model.ManufacturerInfo +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext class BleFiltersProvider( - private val getKnownDevicesInteractor: GetKnownDevicesInteractor, + private val getAllDevicesInteractor: GetAllDevicesInteractor, ) { val previouslyNoticedServicesUUIDs = mutableSetOf() + suspend fun getBackgroundFilters(): List { + return getKnownDevicesFilters() + getPopularServiceUUIDS() + getManufacturerFilter() + } + fun getPopularServiceUUIDS(): List { return (popularServicesUUID + previouslyNoticedServicesUUIDs).map { uuid -> ScanFilter.Builder() @@ -39,14 +45,28 @@ class BleFiltersProvider( } - suspend fun getBGFilters(): List { - return getKnownDevicesInteractor.execute() - .take(KNOWN_DEVICES_LIMIT) // Limit filters to fit into android scan registerer limitations - .map { - ScanFilter.Builder() - .setDeviceAddress(it.address) - .build() - } + suspend fun getKnownDevicesFilters(): List { + return withContext(Dispatchers.Default) { + val allKnownDevices = getAllDevicesInteractor.execute() + + val lastSeenDevices = allKnownDevices + .sortedByDescending { it.lastDetectTimeMs } + .take(KNOWN_DEVICES_LIMIT) // Limit filters to fit into android scan registerer limitations + .map { it.address } + .toSet() + + val shouldBeIncluded = allKnownDevices + .filter { it.tags.isNotEmpty() || it.favorite } + .map { it.address } + .toSet() + + (lastSeenDevices + shouldBeIncluded) + .map { + ScanFilter.Builder() + .setDeviceAddress(it) + .build() + } + } } private object NearByData { diff --git a/app/src/main/java/f/cking/software/data/helpers/BleScannerHelper.kt b/app/src/main/java/f/cking/software/data/helpers/BleScannerHelper.kt index 95f5405..709fb57 100644 --- a/app/src/main/java/f/cking/software/data/helpers/BleScannerHelper.kt +++ b/app/src/main/java/f/cking/software/data/helpers/BleScannerHelper.kt @@ -7,7 +7,6 @@ import android.bluetooth.le.* import android.content.Context import android.os.Handler import android.os.Looper -import f.cking.software.domain.interactor.GetKnownDevicesInteractor import f.cking.software.domain.model.BleScanDevice import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow @@ -16,7 +15,7 @@ import timber.log.Timber import java.util.* class BleScannerHelper( - private val getKnownDevicesInteractor: GetKnownDevicesInteractor, + private val bleFiltersProvider: BleFiltersProvider, private val appContext: Context, private val powerModeHelper: PowerModeHelper, ) { @@ -26,7 +25,6 @@ class BleScannerHelper( private val handler: Handler = Handler(Looper.getMainLooper()) private val batch = hashMapOf() private var currentScanTimeMs: Long = System.currentTimeMillis() - private val bleFiltersProvider = BleFiltersProvider(getKnownDevicesInteractor) var inProgress = MutableStateFlow(false) @@ -84,10 +82,9 @@ class BleScannerHelper( inProgress.tryEmit(true) currentScanTimeMs = System.currentTimeMillis() - val scanFilters = if (powerModeHelper.powerMode().useRestrictedBleConfig) { - bleFiltersProvider.getBGFilters() + - bleFiltersProvider.getPopularServiceUUIDS() + - bleFiltersProvider.getManufacturerFilter() + val powerMode = powerModeHelper.powerMode() + val scanFilters = if (powerMode.useRestrictedBleConfig) { + bleFiltersProvider.getBackgroundFilters() } else { listOf(ScanFilter.Builder().build()) } diff --git a/app/src/main/java/f/cking/software/domain/interactor/GetAllDevicesInteractor.kt b/app/src/main/java/f/cking/software/domain/interactor/GetAllDevicesInteractor.kt new file mode 100644 index 0000000..673a223 --- /dev/null +++ b/app/src/main/java/f/cking/software/domain/interactor/GetAllDevicesInteractor.kt @@ -0,0 +1,13 @@ +package f.cking.software.domain.interactor + +import f.cking.software.data.repo.DevicesRepository +import f.cking.software.domain.model.DeviceData + +class GetAllDevicesInteractor( + private val devicesRepository: DevicesRepository, +) { + + suspend fun execute(): List { + return devicesRepository.getDevices() + } +} \ No newline at end of file diff --git a/app/src/main/java/f/cking/software/domain/interactor/GetKnownDevicesInteractor.kt b/app/src/main/java/f/cking/software/domain/interactor/GetKnownDevicesInteractor.kt deleted file mode 100644 index a9c5129..0000000 --- a/app/src/main/java/f/cking/software/domain/interactor/GetKnownDevicesInteractor.kt +++ /dev/null @@ -1,19 +0,0 @@ -package f.cking.software.domain.interactor - -import f.cking.software.data.repo.DevicesRepository -import f.cking.software.domain.model.DeviceData -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext - -class GetKnownDevicesInteractor( - private val devicesRepository: DevicesRepository, - private val isKnownDeviceInteractor: IsKnownDeviceInteractor, -) { - - suspend fun execute(): List { - return withContext(Dispatchers.Default) { - devicesRepository.getDevices() - .filter { device -> isKnownDeviceInteractor.execute(device) } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/f/cking/software/domain/interactor/InteractorsModule.kt b/app/src/main/java/f/cking/software/domain/interactor/InteractorsModule.kt index 35f86a1..df3466e 100644 --- a/app/src/main/java/f/cking/software/domain/interactor/InteractorsModule.kt +++ b/app/src/main/java/f/cking/software/domain/interactor/InteractorsModule.kt @@ -9,7 +9,7 @@ object InteractorsModule { factory { AnalyseScanBatchInteractor(get(), get()) } factory { ClearGarbageInteractor(get(), get(), get(), get()) } factory { GetKnownDevicesCountInteractor(get(), get()) } - factory { GetKnownDevicesInteractor(get(), get()) } + factory { GetAllDevicesInteractor(get()) } factory { IsKnownDeviceInteractor() } factory { SaveScanBatchInteractor(get(), get(), get(), get()) } factory { GetBleRecordFramesFromRawInteractor() }