Skip to content

Commit 826e395

Browse files
authored
android: use setConnectionProfile instead of (dis)connect on BluetoothProfile (#313)
this prevents android from trying to reconnect to audio itself after we disconnect. this is essentially the same as toggling the 'Media Audio' and 'Phone Calls' settings in the android settings
1 parent 574c193 commit 826e395

File tree

1 file changed

+9
-30
lines changed

1 file changed

+9
-30
lines changed

android/app/src/main/java/me/kavishdevar/librepods/services/AirPodsService.kt

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2161,11 +2161,6 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
21612161
?.getString("name", bluetoothDevice?.name)
21622162
if (bluetoothDevice != null && action != null && !action.isEmpty()) {
21632163
Log.d(TAG, "Received bluetooth connection broadcast: action=$action")
2164-
if (ServiceManager.getService()?.isConnectedLocally == true) {
2165-
Log.d(TAG, "Device is already connected locally, checking if we should keep audio connected")
2166-
if (ServiceManager.getService()?.socket?.isConnected == true) ServiceManager.getService()?.manuallyCheckForAudioSource() else Log.d(TAG, "We're not connected, ignoring")
2167-
return
2168-
}
21692164
if (BluetoothDevice.ACTION_ACL_CONNECTED == action) {
21702165
val uuid = ParcelUuid.fromString("74ec2172-0bad-4d01-8f77-997b2be0722a")
21712166
bluetoothDevice.fetchUuidsWithSdp()
@@ -2200,19 +2195,6 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
22002195
return START_STICKY
22012196
}
22022197

2203-
fun manuallyCheckForAudioSource() {
2204-
val shouldResume = MediaController.getMusicActive() // todo: for some reason we lose this info after disconnecting, probably android dispatches some event. haven't investigated yet.
2205-
if (airpodsInstance == null) return
2206-
Log.d(TAG, "disconnectedBecauseReversed: $disconnectedBecauseReversed, otherDeviceTookOver: $otherDeviceTookOver")
2207-
if ((earDetectionNotification.status[0] != 0.toByte() && earDetectionNotification.status[1] != 0.toByte()) || disconnectedBecauseReversed || otherDeviceTookOver) {
2208-
Log.d(
2209-
TAG,
2210-
"For some reason, Android connected to the audio profile itself even after disconnecting. Disconnecting audio profile again! I will resume: $shouldResume"
2211-
)
2212-
disconnectAudio(this, device, shouldResume = shouldResume)
2213-
}
2214-
}
2215-
22162198
@RequiresApi(Build.VERSION_CODES.R)
22172199
@SuppressLint("MissingPermission", "HardwareIds")
22182200
fun takeOver(takingOverFor: String, manualTakeOverAfterReversed: Boolean = false, startHeadTrackingAgain: Boolean = false) {
@@ -2653,7 +2635,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
26532635
return ancNotification.status
26542636
}
26552637

2656-
fun disconnectAudio(context: Context, device: BluetoothDevice?, shouldResume: Boolean = false) {
2638+
fun disconnectAudio(context: Context, device: BluetoothDevice?) {
26572639
val bluetoothAdapter = context.getSystemService(BluetoothManager::class.java).adapter
26582640
bluetoothAdapter?.getProfileProxy(context, object : BluetoothProfile.ServiceListener {
26592641
override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
@@ -2664,13 +2646,8 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
26642646
return
26652647
}
26662648
val method =
2667-
proxy.javaClass.getMethod("disconnect", BluetoothDevice::class.java)
2668-
method.invoke(proxy, device)
2669-
if (shouldResume) {
2670-
Handler(Looper.getMainLooper()).postDelayed({
2671-
MediaController.sendPlay()
2672-
}, 150)
2673-
}
2649+
proxy.javaClass.getMethod("setConnectionPolicy", BluetoothDevice::class.java, Int::class.java)
2650+
method.invoke(proxy, device, 0)
26742651
} catch (e: Exception) {
26752652
e.printStackTrace()
26762653
} finally {
@@ -2687,8 +2664,8 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
26872664
if (profile == BluetoothProfile.HEADSET) {
26882665
try {
26892666
val method =
2690-
proxy.javaClass.getMethod("disconnect", BluetoothDevice::class.java)
2691-
method.invoke(proxy, device)
2667+
proxy.javaClass.getMethod("setConnectionPolicy", BluetoothDevice::class.java, Int::class.java)
2668+
method.invoke(proxy, device, 0)
26922669
} catch (e: Exception) {
26932670
e.printStackTrace()
26942671
} finally {
@@ -2708,9 +2685,11 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
27082685
override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
27092686
if (profile == BluetoothProfile.A2DP) {
27102687
try {
2711-
val method =
2688+
val policyMethod = proxy.javaClass.getMethod("setConnectionPolicy", BluetoothDevice::class.java, Int::class.java)
2689+
policyMethod.invoke(proxy, device, 100)
2690+
val connectMethod =
27122691
proxy.javaClass.getMethod("connect", BluetoothDevice::class.java)
2713-
method.invoke(proxy, device)
2692+
connectMethod.invoke(proxy, device) // reduces the slight delay between allowing and actually connecting
27142693
} catch (e: Exception) {
27152694
e.printStackTrace()
27162695
} finally {

0 commit comments

Comments
 (0)