mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-14 18:26:11 -04:00
Manually flash batch cache, in low latency modes to achieve lower scan result delays.
This commit is contained in:
@@ -11,11 +11,15 @@ import eu.darken.capod.common.debug.autoreport.DebugSettings
|
||||
import eu.darken.capod.common.debug.logging.Logging.Priority.*
|
||||
import eu.darken.capod.common.debug.logging.log
|
||||
import eu.darken.capod.common.debug.logging.logTag
|
||||
import eu.darken.capod.main.core.ScannerMode
|
||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@@ -28,7 +32,7 @@ class BleScanner @Inject constructor(
|
||||
|
||||
fun scan(
|
||||
filter: Set<ScanFilter> = ProximityPairing.getBleScanFilter(),
|
||||
mode: Int = ScanSettings.SCAN_MODE_LOW_LATENCY,
|
||||
scannerMode: ScannerMode = ScannerMode.LOW_POWER,
|
||||
): Flow<List<BleScanResult>> = callbackFlow {
|
||||
val adapter = bluetoothManager.adapter
|
||||
val scanner = bluetoothManager.scanner
|
||||
@@ -59,14 +63,36 @@ class BleScanner @Inject constructor(
|
||||
}
|
||||
|
||||
val settings = ScanSettings.Builder().apply {
|
||||
setScanMode(mode)
|
||||
setScanMode(
|
||||
when (scannerMode) {
|
||||
ScannerMode.LOW_POWER -> ScanSettings.SCAN_MODE_LOW_POWER
|
||||
ScannerMode.BALANCED -> ScanSettings.SCAN_MODE_BALANCED
|
||||
ScannerMode.LOW_LATENCY -> ScanSettings.SCAN_MODE_LOW_LATENCY
|
||||
}
|
||||
)
|
||||
if (adapter.isOffloadedScanBatchingSupported) {
|
||||
setReportDelay(1000)
|
||||
when (scannerMode) {
|
||||
ScannerMode.LOW_POWER -> setReportDelay(5000)
|
||||
ScannerMode.BALANCED -> setReportDelay(2500)
|
||||
ScannerMode.LOW_LATENCY -> setReportDelay(500)
|
||||
}
|
||||
} else {
|
||||
log(TAG, WARN) { "isOffloadedScanBatchingSupported=false" }
|
||||
}
|
||||
}.build()
|
||||
|
||||
val flushJob = launch {
|
||||
while (isActive) {
|
||||
// Can undercut the minimum setReportDelay(), e.g. 5000ms on a Pixel5@12
|
||||
adapter.bluetoothLeScanner.flushPendingScanResults(callback)
|
||||
when (scannerMode) {
|
||||
ScannerMode.LOW_POWER -> break
|
||||
ScannerMode.BALANCED -> delay(2500)
|
||||
ScannerMode.LOW_LATENCY -> delay(500)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (adapter.isOffloadedFilteringSupported) {
|
||||
scanner.startScan(filter.toList(), settings, callback)
|
||||
log(TAG, VERBOSE) { "BleScanner started (filter=$filter, settings=$settings)" }
|
||||
@@ -77,8 +103,9 @@ class BleScanner @Inject constructor(
|
||||
}
|
||||
|
||||
awaitClose {
|
||||
log(TAG, INFO) { "BleScanner stopped" }
|
||||
flushJob.cancel()
|
||||
scanner.stopScan(callback)
|
||||
log(TAG, INFO) { "BleScanner stopped" }
|
||||
}
|
||||
}
|
||||
.map { origs ->
|
||||
|
||||
@@ -71,7 +71,7 @@ class BluetoothManager2 @Inject constructor(
|
||||
suspend fun getBluetoothProfile(
|
||||
profile: Int = BluetoothProfile.HEADSET
|
||||
): BluetoothProfile2 = withContext(dispatcherProvider.IO) {
|
||||
log(TAG) { "getBluetoothProfile(profile=$profile)" }
|
||||
log(TAG, VERBOSE) { "getBluetoothProfile(profile=$profile)" }
|
||||
|
||||
suspendCancellableCoroutine {
|
||||
val connectionState = AtomicBoolean(false)
|
||||
@@ -97,7 +97,7 @@ class BluetoothManager2 @Inject constructor(
|
||||
}
|
||||
|
||||
private fun connectedDevicesForProfile(profile: Int): Flow<Set<BluetoothDevice>> = callbackFlow {
|
||||
log(TAG) { "connectedDevices(profile=$profile) starting" }
|
||||
log(TAG, VERBOSE) { "connectedDevices(profile=$profile) starting" }
|
||||
trySend(getBluetoothProfile(profile).connectedDevices)
|
||||
|
||||
val filter = IntentFilter().apply {
|
||||
|
||||
@@ -29,7 +29,7 @@ class GeneralSettings @Inject constructor(
|
||||
|
||||
val scannerMode = preferences.createFlowPreference(
|
||||
"core.scanner.mode",
|
||||
ScannerMode.LOW_LATENCY,
|
||||
ScannerMode.LOW_POWER,
|
||||
moshi
|
||||
)
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package eu.darken.capod.monitor.core
|
||||
|
||||
import android.bluetooth.le.ScanSettings
|
||||
import eu.darken.capod.common.bluetooth.BleScanner
|
||||
import eu.darken.capod.common.bluetooth.BluetoothManager2
|
||||
import eu.darken.capod.common.coroutine.AppScope
|
||||
@@ -10,7 +9,6 @@ import eu.darken.capod.common.debug.logging.log
|
||||
import eu.darken.capod.common.debug.logging.logTag
|
||||
import eu.darken.capod.common.flow.replayingShare
|
||||
import eu.darken.capod.main.core.GeneralSettings
|
||||
import eu.darken.capod.main.core.ScannerMode
|
||||
import eu.darken.capod.pods.core.PodDevice
|
||||
import eu.darken.capod.pods.core.PodFactory
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -35,17 +33,10 @@ class PodMonitor @Inject constructor(
|
||||
private val cacheLock = Mutex()
|
||||
|
||||
val devices: Flow<List<PodDevice>> = generalSettings.scannerMode.flow
|
||||
.flatMapLatest {
|
||||
val mode = when (it) {
|
||||
ScannerMode.LOW_POWER -> ScanSettings.SCAN_MODE_LOW_POWER
|
||||
ScannerMode.BALANCED -> ScanSettings.SCAN_MODE_BALANCED
|
||||
ScannerMode.LOW_LATENCY -> ScanSettings.SCAN_MODE_LOW_LATENCY
|
||||
}
|
||||
.flatMapLatest { scannerMode ->
|
||||
bluetoothManager.isBluetoothEnabled.flatMapLatest { isBluetoothEnabled ->
|
||||
if (isBluetoothEnabled) {
|
||||
bleScanner.scan(
|
||||
mode = mode
|
||||
)
|
||||
bleScanner.scan(scannerMode = scannerMode)
|
||||
} else {
|
||||
log(TAG, WARN) { "Bluetooth is current disabled" }
|
||||
emptyFlow()
|
||||
|
||||
Reference in New Issue
Block a user