From d4cd0b4b6f7606de1640e02bc7009cc0a6a1b3a3 Mon Sep 17 00:00:00 2001 From: Semper-Viventem Date: Wed, 10 Jan 2024 00:51:43 +0200 Subject: [PATCH 1/6] Improve ble errors logging --- app/src/main/AndroidManifest.xml | 2 +- .../data/helpers/BleScanErrorMapper.kt | 18 ++++++++++++++++++ .../software/data/helpers/BleScannerHelper.kt | 7 +++++-- 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/f/cking/software/data/helpers/BleScanErrorMapper.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8150c57..0cf0938 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,12 +5,12 @@ - + diff --git a/app/src/main/java/f/cking/software/data/helpers/BleScanErrorMapper.kt b/app/src/main/java/f/cking/software/data/helpers/BleScanErrorMapper.kt new file mode 100644 index 0000000..78fe27a --- /dev/null +++ b/app/src/main/java/f/cking/software/data/helpers/BleScanErrorMapper.kt @@ -0,0 +1,18 @@ +package f.cking.software.data.helpers + +import android.bluetooth.le.ScanCallback + +object BleScanErrorMapper { + + fun map(errorCode: Int): String { + return when (errorCode) { + ScanCallback.SCAN_FAILED_ALREADY_STARTED -> "Scan already started" + ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED -> "Application registration failed" + ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED -> "Feature unsupported" + ScanCallback.SCAN_FAILED_INTERNAL_ERROR -> "Internal error" + ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES -> "Out of hardware resources" + ScanCallback.SCAN_FAILED_SCANNING_TOO_FREQUENTLY -> "Scanning too frequently" + else -> "Unknown error" + } + } +} \ No newline at end of file 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 e8ab0ec..0b17400 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 @@ -119,9 +119,11 @@ class BleScannerHelper( Timber.d("BLE Scan finished ${batch.count()} devices found") scanListener?.onSuccess(batch.values.toList()) } + is ScanResultInternal.Failure -> { - scanListener?.onFailure(BLEScanFailure(scanResult.errorCode)) + scanListener?.onFailure(BLEScanFailure(scanResult.errorCode, BleScanErrorMapper.map(scanResult.errorCode))) } + is ScanResultInternal.Canceled -> { // do nothing } @@ -155,7 +157,8 @@ class BleScannerHelper( object Canceled : ScanResultInternal } - class BLEScanFailure(errorCode: Int) : RuntimeException("BLE Scan failed with error code: $errorCode") + class BLEScanFailure(errorCode: Int, errorDescription: String) : + RuntimeException("BLE Scan failed with error code: $errorCode (${errorDescription})") class BluetoothIsNotInitialized : RuntimeException("Bluetooth is turned off or not available on this device") } \ No newline at end of file From f5a6f13568076a6d7ed9b8ff2cf08da8ccb80363 Mon Sep 17 00:00:00 2001 From: Semper-Viventem Date: Wed, 10 Jan 2024 00:59:46 +0200 Subject: [PATCH 2/6] Add devices pagination --- .../java/f/cking/software/data/database/dao/DeviceDao.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/f/cking/software/data/database/dao/DeviceDao.kt b/app/src/main/java/f/cking/software/data/database/dao/DeviceDao.kt index de5a682..a18ef63 100644 --- a/app/src/main/java/f/cking/software/data/database/dao/DeviceDao.kt +++ b/app/src/main/java/f/cking/software/data/database/dao/DeviceDao.kt @@ -1,6 +1,9 @@ package f.cking.software.data.database.dao -import androidx.room.* +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query import f.cking.software.data.database.entity.DeviceEntity @Dao @@ -12,6 +15,9 @@ interface DeviceDao { @Query("SELECT * FROM device WHERE address LIKE :address") fun findByAddress(address: String): DeviceEntity? + @Query("SELECT * FROM device ORDER BY last_detect_time_ms DESC LIMIT :limit OFFSET :offset") + fun getPaginated(offset: Int, limit: Int): List + @Query("SELECT * FROM device WHERE address IN (:addresses)") fun findAllByAddresses(addresses: List): List From 986f1bd5e2d6e58c85d520ce948e4debebc80b3a Mon Sep 17 00:00:00 2001 From: Semper-Viventem Date: Wed, 10 Jan 2024 01:14:51 +0200 Subject: [PATCH 3/6] Revert "Add devices pagination" This reverts commit f5a6f13568076a6d7ed9b8ff2cf08da8ccb80363. --- .../java/f/cking/software/data/database/dao/DeviceDao.kt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/src/main/java/f/cking/software/data/database/dao/DeviceDao.kt b/app/src/main/java/f/cking/software/data/database/dao/DeviceDao.kt index a18ef63..de5a682 100644 --- a/app/src/main/java/f/cking/software/data/database/dao/DeviceDao.kt +++ b/app/src/main/java/f/cking/software/data/database/dao/DeviceDao.kt @@ -1,9 +1,6 @@ package f.cking.software.data.database.dao -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query +import androidx.room.* import f.cking.software.data.database.entity.DeviceEntity @Dao @@ -15,9 +12,6 @@ interface DeviceDao { @Query("SELECT * FROM device WHERE address LIKE :address") fun findByAddress(address: String): DeviceEntity? - @Query("SELECT * FROM device ORDER BY last_detect_time_ms DESC LIMIT :limit OFFSET :offset") - fun getPaginated(offset: Int, limit: Int): List - @Query("SELECT * FROM device WHERE address IN (:addresses)") fun findAllByAddresses(addresses: List): List From 4c18bd3c3114c5a97d3f642776f2c22946722169 Mon Sep 17 00:00:00 2001 From: Semper-Viventem Date: Wed, 10 Jan 2024 01:30:01 +0200 Subject: [PATCH 4/6] Add device filter limitation for background scans --- .../data/helpers/BleFiltersProvider.kt | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) 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 c81b248..6f3f0a7 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 @@ -40,11 +40,13 @@ class BleFiltersProvider( } suspend fun getBGFilters(): List { - return getKnownDevicesInteractor.execute().map { - ScanFilter.Builder() - .setDeviceAddress(it.address) - .build() - } + return getKnownDevicesInteractor.execute() + .take(KNOWN_DEVICES_LIMIT) // Limit filters to fit into android scan registerer limitations + .map { + ScanFilter.Builder() + .setDeviceAddress(it.address) + .build() + } } private object NearByData { @@ -58,15 +60,18 @@ class BleFiltersProvider( } private object AirdropData { - val bytes: ByteArray = listOf(0x05, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0B, 0x0D, 0xC1, 0xF6, 0xFA, 0xE3, 0x11, 0x00, 0x00) - .map { it.toUByte().toByte() } - .toByteArray() - val bytesMask: ByteArray = listOf(0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) - .map { it.toUByte().toByte() } - .toByteArray() + val bytes: ByteArray = + listOf(0x05, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0B, 0x0D, 0xC1, 0xF6, 0xFA, 0xE3, 0x11, 0x00, 0x00) + .map { it.toUByte().toByte() } + .toByteArray() + val bytesMask: ByteArray = + listOf(0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) + .map { it.toUByte().toByte() } + .toByteArray() } companion object { + private const val KNOWN_DEVICES_LIMIT = 3000 private val popularServicesUUID = setOf( "0000fe8f-0000-1000-8000-00805f9b34fb", "0000fe9f-0000-1000-8000-00805f9b34fb", From f5fe8a2be8770ec7b66fdcbbe14e43a7a99269f1 Mon Sep 17 00:00:00 2001 From: Semper-Viventem Date: Wed, 10 Jan 2024 01:36:25 +0200 Subject: [PATCH 5/6] Update the app version --- app/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 44be80c..57246a0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -23,8 +23,8 @@ android { applicationId = "f.cking.software" minSdk = 29 targetSdk = 34 - versionCode = 1704045673 - versionName = "0.21.5-beta" + versionCode = 1704045674 + versionName = "0.21.6-beta" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" From 6c429a362c1a3b393bf74416dba161138c93ba8a Mon Sep 17 00:00:00 2001 From: Semper-Viventem Date: Wed, 10 Jan 2024 01:56:42 +0200 Subject: [PATCH 6/6] Improve BootBroadcastReceiver --- .../software/service/BootBroadcastReceiver.kt | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/f/cking/software/service/BootBroadcastReceiver.kt b/app/src/main/java/f/cking/software/service/BootBroadcastReceiver.kt index 0f22358..e361591 100644 --- a/app/src/main/java/f/cking/software/service/BootBroadcastReceiver.kt +++ b/app/src/main/java/f/cking/software/service/BootBroadcastReceiver.kt @@ -5,12 +5,21 @@ import android.content.Context import android.content.Intent import f.cking.software.data.helpers.PermissionHelper import f.cking.software.data.repo.SettingsRepository +import f.cking.software.domain.interactor.SaveReportInteractor +import f.cking.software.domain.model.JournalEntry +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.launch import org.koin.java.KoinJavaComponent.inject +import timber.log.Timber class BootBroadcastReceiver : BroadcastReceiver() { private val permissionHelper: PermissionHelper by inject(PermissionHelper::class.java) private val settingsRepository: SettingsRepository by inject(SettingsRepository::class.java) + private val saveReportInteractor: SaveReportInteractor by inject(SaveReportInteractor::class.java) + private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main) override fun onReceive(context: Context, intent: Intent) { if (intent.action == Intent.ACTION_BOOT_COMPLETED) { @@ -19,8 +28,23 @@ class BootBroadcastReceiver : BroadcastReceiver() { } private fun tryToRunService(context: Context) { - if (settingsRepository.getRunOnStartup() && permissionHelper.checkAllPermissions()) { - BgScanService.start(context) + if (settingsRepository.getRunOnStartup()) { + if (permissionHelper.checkAllPermissions()) { + try { + BgScanService.start(context) + } catch (error: Exception) { + Timber.e(error, "Failed to start service from the boot receiver") + val report = JournalEntry.Report.Error( + title = "[Launch on system startup error]: ${error.message ?: error::class.java}", + stackTrace = error.stackTraceToString(), + ) + scope.launch { + saveReportInteractor.execute(report) + } + } + } else { + Timber.e("Not all permissions granted, can't start service from the boot receiver") + } } } } \ No newline at end of file