Skip to content

Commit 4015f19

Browse files
sdonn3cedrickcooke
andauthored
Improve Advertising Robustness (#187)
* Scanner robustness improvements Co-authored-by: Cedrick Cooke <development@cedrickc.net>
1 parent 8e33c10 commit 4015f19

1 file changed

Lines changed: 27 additions & 12 deletions

File tree

core/src/androidMain/kotlin/Scanner.kt

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ import android.os.ParcelUuid
99
import com.benasher44.uuid.Uuid
1010
import com.juul.kable.logs.Logger
1111
import com.juul.kable.logs.Logging
12+
import kotlinx.coroutines.Dispatchers
1213
import kotlinx.coroutines.cancel
1314
import kotlinx.coroutines.channels.awaitClose
1415
import kotlinx.coroutines.channels.onFailure
1516
import kotlinx.coroutines.channels.trySendBlocking
1617
import kotlinx.coroutines.flow.Flow
1718
import kotlinx.coroutines.flow.callbackFlow
19+
import kotlinx.coroutines.flow.flowOn
1820

1921
public class ScanFailedException internal constructor(
2022
public val errorCode: Int,
@@ -32,7 +34,7 @@ public class AndroidScanner internal constructor(
3234
?: error("Bluetooth not supported")
3335

3436
public override val advertisements: Flow<Advertisement> = callbackFlow {
35-
check(bluetoothAdapter.isEnabled) { "Bluetooth is disabled" }
37+
val scanner = checkNotNull(bluetoothAdapter.bluetoothLeScanner) { "Bluetooth disabled." }
3638

3739
val callback = object : ScanCallback() {
3840
override fun onScanResult(callbackType: Int, result: ScanResult) {
@@ -53,22 +55,35 @@ public class AndroidScanner internal constructor(
5355
}
5456

5557
override fun onScanFailed(errorCode: Int) {
58+
logger.error { message = "Scan could not be started, error code $errorCode." }
5659
cancel("Bluetooth scan failed", ScanFailedException(errorCode))
5760
}
5861
}
5962

60-
val scanFilter =
61-
filterServices
62-
?.map { ScanFilter.Builder().setServiceUuid(ParcelUuid(it)).build() }
63-
?.toList()
64-
bluetoothAdapter.bluetoothLeScanner.startScan(
65-
scanFilter,
66-
scanSettings,
67-
callback,
68-
)
63+
val scanFilter = filterServices
64+
?.map { ScanFilter.Builder().setServiceUuid(ParcelUuid(it)).build() }
65+
?.toList()
66+
logger.info {
67+
message = when (filterServices) {
68+
null -> "Starting scan with no service filter."
69+
else -> "Starting scan for services ${filterServices.joinToString()}."
70+
}
71+
}
72+
scanner.startScan(scanFilter, scanSettings, callback)
6973

7074
awaitClose {
71-
bluetoothAdapter.bluetoothLeScanner.stopScan(callback)
75+
logger.info {
76+
message = when (filterServices) {
77+
null -> "Stopping scan with no service filter."
78+
else -> "Stopping scan for services ${filterServices.joinToString()}."
79+
}
80+
}
81+
// Can't check BLE state here, only Bluetooth, but should assume `IllegalStateException` means BLE has been disabled.
82+
try {
83+
scanner.stopScan(callback)
84+
} catch (e: IllegalStateException) {
85+
logger.warn(e) { message = "Failed to stop scan. " }
86+
}
7287
}
73-
}
88+
}.flowOn(Dispatchers.Main.immediate)
7489
}

0 commit comments

Comments
 (0)