From b2693c6e573cc0a5821f6955f02fe4116555b3e0 Mon Sep 17 00:00:00 2001 From: darken Date: Mon, 31 Jan 2022 19:20:39 +0100 Subject: [PATCH] Add option for unfiltered BLE scan. --- .../capod/common/bluetooth/BleScanner.kt | 12 ++--- .../common/debug/autoreport/DebugSettings.kt | 3 ++ .../darken/capod/monitor/core/PodMonitor.kt | 46 +++++++++++++++++-- app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/preferences_debug.xml | 6 +++ 5 files changed, 59 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/eu/darken/capod/common/bluetooth/BleScanner.kt b/app/src/main/java/eu/darken/capod/common/bluetooth/BleScanner.kt index 5507748e..c4b8b9a6 100644 --- a/app/src/main/java/eu/darken/capod/common/bluetooth/BleScanner.kt +++ b/app/src/main/java/eu/darken/capod/common/bluetooth/BleScanner.kt @@ -1,5 +1,6 @@ package eu.darken.capod.common.bluetooth +import android.annotation.SuppressLint import android.bluetooth.le.ScanCallback import android.bluetooth.le.ScanFilter import android.bluetooth.le.ScanResult @@ -10,7 +11,6 @@ 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 @@ -28,9 +28,9 @@ class BleScanner @Inject constructor( private val fakeBleData: FakeBleData, ) { - fun scan( - filter: Set = ProximityPairing.getBleScanFilter(), - scannerMode: ScannerMode = ScannerMode.LOW_POWER, + @SuppressLint("MissingPermission") fun scan( + filters: Set, + scannerMode: ScannerMode, ): Flow> = callbackFlow { val adapter = bluetoothManager.adapter val scanner = bluetoothManager.scanner @@ -92,8 +92,8 @@ class BleScanner @Inject constructor( } if (adapter.isOffloadedFilteringSupported) { - scanner.startScan(filter.toList(), settings, callback) - log(TAG, VERBOSE) { "BleScanner started (filter=$filter, settings=$settings)" } + scanner.startScan(filters.toList(), settings, callback) + log(TAG, VERBOSE) { "BleScanner started (filters=$filters, settings=$settings)" } } else { log(TAG, WARN) { "isOffloadedFilteringSupported=false" } scanner.startScan(callback) diff --git a/app/src/main/java/eu/darken/capod/common/debug/autoreport/DebugSettings.kt b/app/src/main/java/eu/darken/capod/common/debug/autoreport/DebugSettings.kt index b2da0e3a..95e81403 100644 --- a/app/src/main/java/eu/darken/capod/common/debug/autoreport/DebugSettings.kt +++ b/app/src/main/java/eu/darken/capod/common/debug/autoreport/DebugSettings.kt @@ -23,9 +23,12 @@ class DebugSettings @Inject constructor( val showFakeData = preferences.createFlowPreference("debug.fakedata.enabled", false) + val showUnfiltered = preferences.createFlowPreference("debug.blescanner.unfiltered.enabled", false) + override val preferenceDataStore: PreferenceDataStore = PreferenceStoreMapper( isDebugModeEnabled, showFakeData, + showUnfiltered, ) } \ No newline at end of file diff --git a/app/src/main/java/eu/darken/capod/monitor/core/PodMonitor.kt b/app/src/main/java/eu/darken/capod/monitor/core/PodMonitor.kt index f04dc526..22434cb9 100644 --- a/app/src/main/java/eu/darken/capod/monitor/core/PodMonitor.kt +++ b/app/src/main/java/eu/darken/capod/monitor/core/PodMonitor.kt @@ -1,10 +1,13 @@ package eu.darken.capod.monitor.core +import android.bluetooth.le.ScanFilter import eu.darken.capod.common.bluetooth.BleScanResult import eu.darken.capod.common.bluetooth.BleScanner import eu.darken.capod.common.bluetooth.BluetoothManager2 import eu.darken.capod.common.coroutine.AppScope -import eu.darken.capod.common.debug.logging.Logging.Priority.* +import eu.darken.capod.common.debug.autoreport.DebugSettings +import eu.darken.capod.common.debug.logging.Logging.Priority.VERBOSE +import eu.darken.capod.common.debug.logging.Logging.Priority.WARN import eu.darken.capod.common.debug.logging.asLog import eu.darken.capod.common.debug.logging.log import eu.darken.capod.common.debug.logging.logTag @@ -13,6 +16,8 @@ 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 eu.darken.capod.pods.core.apple.protocol.ContinuityProtocol +import eu.darken.capod.pods.core.apple.protocol.ProximityPairing import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.* @@ -29,6 +34,7 @@ class PodMonitor @Inject constructor( private val podFactory: PodFactory, private val generalSettings: GeneralSettings, private val bluetoothManager: BluetoothManager2, + private val debugSettings: DebugSettings, @AppScope private val appScope: CoroutineScope ) { @@ -54,9 +60,20 @@ class PodMonitor @Inject constructor( .flatMapLatest { isBluetoothEnabled -> if (isBluetoothEnabled) { log(TAG) { "Bluetooth is enabled" } - generalSettings.scannerMode.flow - .flatMapLatest { mode -> - bleScanner.scan(scannerMode = mode).map { it.preFilterAndMap(mode) } + combine( + generalSettings.scannerMode.flow, + debugSettings.showUnfiltered.flow + ) { mode, unfiltered -> mode to unfiltered } + .flatMapLatest { (mode, unfiltered) -> + val filters = if (unfiltered) { + setOf(getUnfilteredFilter()) + } else { + ProximityPairing.getBleScanFilter() + } + bleScanner.scan( + filters = filters, + scannerMode = mode + ).map { it.preFilterAndMap(mode) } } } else { log(TAG, WARN) { "Bluetooth is currently disabled" } @@ -141,6 +158,27 @@ class PodMonitor @Inject constructor( } } + + private fun getUnfilteredFilter(): ScanFilter { + val manufacturerData = ByteArray(2).apply { + this[0] = 0 + this[1] = 0 + } + + val manufacturerDataMask = ByteArray(2).apply { + this[0] = 0 + this[1] = 0 + } + val builder = ScanFilter.Builder().apply { + setManufacturerData( + ContinuityProtocol.APPLE_COMPANY_IDENTIFIER, + manufacturerData, + manufacturerDataMask + ) + } + return builder.build() + } + companion object { private val TAG = logTag("Monitor", "PodMonitor") } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 50e6f3ee..74b91441 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -139,4 +139,6 @@ Allow CAPod to draw over other apps to make the feature \"Show PopUp\" possible. Last seen: %s First seen: %s + Unfiltered BLE data + Remove any filters from the BLE scanner to show all broadcasted BLE data. Useful to add support for new headphone types. \ No newline at end of file diff --git a/app/src/main/res/xml/preferences_debug.xml b/app/src/main/res/xml/preferences_debug.xml index bc1e8527..3ba4a05e 100644 --- a/app/src/main/res/xml/preferences_debug.xml +++ b/app/src/main/res/xml/preferences_debug.xml @@ -18,4 +18,10 @@ android:summary="@string/settings_fake_data_description" android:title="@string/settings_fake_data_label" /> + + \ No newline at end of file