Skip to content

Commit

Permalink
Merge pull request #87 from Semper-Viventem/fix-ble-scanner-registration
Browse files Browse the repository at this point in the history
Fix ble scanner registration
  • Loading branch information
Semper-Viventem authored Jan 10, 2024
2 parents f64dfcf + 6c429a3 commit 8b68880
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 18 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@ class BleFiltersProvider(
}

suspend fun getBGFilters(): List<ScanFilter> {
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 {
Expand All @@ -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",
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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")
}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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")
}
}
}
}

0 comments on commit 8b68880

Please sign in to comment.