Skip to content

Commit 53447f3

Browse files
committed
fix: Stop retrying auto-connect after SecurityException
BluetoothHeadset.connect() requires MODIFY_PHONE_STATE on modern Android, which is a system-only permission. Detect the SecurityException and stop further attempts instead of retrying every second.
1 parent db759ba commit 53447f3

File tree

3 files changed

+16
-1
lines changed

3 files changed

+16
-1
lines changed

app/src/main/java/eu/darken/capod/common/bluetooth/BluetoothManager2.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,9 @@ class BluetoothManager2 @Inject constructor(
304304
emit(wrappedDevices)
305305
}
306306

307+
private var _isNudgeAvailable: Boolean = true
308+
val isNudgeAvailable: Boolean get() = _isNudgeAvailable
309+
307310
suspend fun nudgeConnection(device: BluetoothDevice2): Boolean = getBluetoothProfile().map { bluetoothProfile ->
308311
try {
309312
log(TAG) { "Nudging Android connection to $device" }
@@ -317,6 +320,12 @@ class BluetoothManager2 @Inject constructor(
317320
log(TAG) { "Nudged connection to $device" }
318321
true
319322
} catch (e: Exception) {
323+
val isSecurityException = e is SecurityException ||
324+
(e is java.lang.reflect.InvocationTargetException && e.cause is SecurityException)
325+
if (isSecurityException) {
326+
log(TAG, ERROR) { "nudgeConnection is permanently unavailable: missing MODIFY_PHONE_STATE permission" }
327+
_isNudgeAvailable = false
328+
}
320329
Bugs.report(tag = TAG, "BluetoothHeadset.connect(device) is unavailable", exception = e)
321330
false
322331
}

app/src/main/java/eu/darken/capod/reaction/core/autoconnect/AutoConnect.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ class AutoConnect @Inject constructor(
9999
log(TAG) { "Auto connect condition ($condition) is not fullfilled: ${decision.reason}" }
100100
return@map
101101
}
102+
103+
if (!bluetoothManager.isNudgeAvailable) {
104+
log(TAG, WARN) { "nudgeConnection is not available on this device, skipping" }
105+
return@map
106+
}
107+
102108
val result = bluetoothManager.nudgeConnection(bondedDevice)
103109
log(TAG) { "nudgeConnection($bondedDevice) returned $result" }
104110
}

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
<string name="settings_signal_minimum_label">Minimum signal quality</string>
6262
<string name="settings_signal_minimum_description">The minimum signal quality that a device needs to have to be considered yours.</string>
6363
<string name="settings_autoconnect_label">Auto connect</string>
64-
<string name="settings_autoconnect_description">If Android does not automatically connect, we can ask it too. This will set the monitor mode setting to \'Always\'.</string>
64+
<string name="settings_autoconnect_description">If Android does not automatically connect, we can ask it too. This will set the monitor mode setting to \'Always\'. May not work on newer Android versions.</string>
6565
<string name="settings_autoconnect_condition_label">Auto connect condition</string>
6666
<string name="settings_autoconnect_condition_description">When should we try to connect to your device?</string>
6767
<string name="settings_devices_label">Devices</string>

0 commit comments

Comments
 (0)