@@ -29,6 +29,7 @@ import android.app.NotificationManager
2929import android.app.PendingIntent
3030import android.app.Service
3131import android.appwidget.AppWidgetManager
32+ import android.bluetooth.BluetoothAdapter
3233import android.bluetooth.BluetoothDevice
3334import android.bluetooth.BluetoothHeadset
3435import android.bluetooth.BluetoothManager
@@ -252,9 +253,10 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
252253 if (device.connectionState == " Disconnected" && ! config.bleOnlyMode) {
253254 Log .d(TAG , " Seems no device has taken over, we will." )
254255 val bluetoothManager = getSystemService(BluetoothManager ::class .java)
255- val bluetoothDevice = bluetoothManager.adapter.getRemoteDevice(sharedPreferences.getString(
256+ val bluetoothAdapter = bluetoothManager.adapter
257+ val bluetoothDevice = bluetoothAdapter.getRemoteDevice(sharedPreferences.getString(
256258 " mac_address" , " " ) ? : " " )
257- connectToSocket(bluetoothDevice)
259+ connectToSocket(bluetoothAdapter, bluetoothDevice)
258260 }
259261 Log .d(TAG , " Device status changed" )
260262 if (isConnectedLocally) return
@@ -607,7 +609,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
607609// if ((CrossDevice.isAvailable && !isConnectedLocally && earDetectionNotification.status.contains(0x00)) || leAvailableForAudio) CoroutineScope(
608610 if (leAvailableForAudio) CoroutineScope (
609611 Dispatchers .IO ).launch {
610- takeOver(" call" )
612+ takeOver(" call" )
611613 }
612614 isInCall = true
613615 }
@@ -665,17 +667,18 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
665667
666668// Log.d("AirPodsCrossDevice", CrossDevice.isAvailable.toString())
667669// if (!CrossDevice.isAvailable) {
668- Log .d(TAG , " ${config.deviceName} connected" )
669- CoroutineScope (Dispatchers .IO ).launch {
670- connectToSocket(device!! )
671- }
672- Log .d(TAG , " Setting metadata" )
673- setMetadatas(device!! )
674- isConnectedLocally = true
675- macAddress = device!! .address
676- sharedPreferences.edit {
677- putString(" mac_address" , macAddress)
678- }
670+ Log .d(TAG , " ${config.deviceName} connected" )
671+ CoroutineScope (Dispatchers .IO ).launch {
672+ val bluetoothManager = getSystemService(BluetoothManager ::class .java)
673+ connectToSocket(bluetoothManager.adapter, device!! )
674+ }
675+ Log .d(TAG , " Setting metadata" )
676+ setMetadatas(device!! )
677+ isConnectedLocally = true
678+ macAddress = device!! .address
679+ sharedPreferences.edit {
680+ putString(" mac_address" , macAddress)
681+ }
679682// }
680683
681684 } else if (intent?.action == AirPodsNotifications .AIRPODS_DISCONNECTED ) {
@@ -688,7 +691,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
688691 }
689692 }
690693 }
691- val showIslandReceiver = object : BroadcastReceiver () {
694+ val showIslandReceiver = object : BroadcastReceiver () {
692695 override fun onReceive (context : Context ? , intent : Intent ? ) {
693696 if (intent?.action == " me.kavishdevar.librepods.cross_device_island" ) {
694697 showIsland(this @AirPodsService, batteryNotification.getBattery().find { it.component == BatteryComponent .LEFT }?.level!! .coerceAtMost(batteryNotification.getBattery().find { it.component == BatteryComponent .RIGHT }?.level!! ))
@@ -743,14 +746,14 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
743746 val connectedDevices = proxy.connectedDevices
744747 if (connectedDevices.isNotEmpty()) {
745748// if (!CrossDevice.isAvailable) {
746- CoroutineScope (Dispatchers .IO ).launch {
747- connectToSocket(device)
748- }
749- setMetadatas(device)
750- macAddress = device.address
751- sharedPreferences.edit {
752- putString(" mac_address" , macAddress)
753- }
749+ CoroutineScope (Dispatchers .IO ).launch {
750+ connectToSocket(bluetoothAdapter, device)
751+ }
752+ setMetadatas(device)
753+ macAddress = device.address
754+ sharedPreferences.edit {
755+ putString(" mac_address" , macAddress)
756+ }
754757// }
755758 this @AirPodsService.sendBroadcast(
756759 Intent (AirPodsNotifications .AIRPODS_CONNECTED )
@@ -1555,7 +1558,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
15551558 .setContentText(" Unable to connect to AirPods over L2CAP" )
15561559 .setStyle(NotificationCompat .BigTextStyle ()
15571560 .bigText(" Your AirPods are connected via Bluetooth, but LibrePods couldn't connect to AirPods using L2CAP. " +
1558- " Error: $errorMessage " ))
1561+ " Error: $errorMessage " ))
15591562 .setContentIntent(pendingIntent)
15601563 .setCategory(Notification .CATEGORY_ERROR )
15611564 .setPriority(NotificationCompat .PRIORITY_HIGH )
@@ -2085,56 +2088,56 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
20852088 device.METADATA_MAIN_ICON ,
20862089 resToUri(instance.model.budCaseRes).toString().toByteArray()
20872090 ) &&
2088- SystemApisUtils .setMetadata(
2089- device,
2090- device.METADATA_MODEL_NAME ,
2091- instance.model.name.toByteArray()
2092- ) &&
2093- SystemApisUtils .setMetadata(
2094- device,
2095- device.METADATA_DEVICE_TYPE ,
2096- device.DEVICE_TYPE_UNTETHERED_HEADSET .toByteArray()
2097- ) &&
2098- SystemApisUtils .setMetadata(
2099- device,
2100- device.METADATA_UNTETHERED_CASE_ICON ,
2101- resToUri(instance.model.caseRes).toString().toByteArray()
2102- ) &&
2103- SystemApisUtils .setMetadata(
2104- device,
2105- device.METADATA_UNTETHERED_RIGHT_ICON ,
2106- resToUri(instance.model.rightBudsRes).toString().toByteArray()
2107- ) &&
2108- SystemApisUtils .setMetadata(
2109- device,
2110- device.METADATA_UNTETHERED_LEFT_ICON ,
2111- resToUri(instance.model.leftBudsRes).toString().toByteArray()
2112- ) &&
2113- SystemApisUtils .setMetadata(
2114- device,
2115- device.METADATA_MANUFACTURER_NAME ,
2116- instance.model.manufacturer.toByteArray()
2117- ) &&
2118- SystemApisUtils .setMetadata(
2119- device,
2120- device.METADATA_COMPANION_APP ,
2121- " me.kavishdevar.librepods" .toByteArray()
2122- ) &&
2123- SystemApisUtils .setMetadata(
2124- device,
2125- device.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD ,
2126- " 20" .toByteArray()
2127- ) &&
2128- SystemApisUtils .setMetadata(
2129- device,
2130- device.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD ,
2131- " 20" .toByteArray()
2132- ) &&
2133- SystemApisUtils .setMetadata(
2134- device,
2135- device.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD ,
2136- " 20" .toByteArray()
2137- )
2091+ SystemApisUtils .setMetadata(
2092+ device,
2093+ device.METADATA_MODEL_NAME ,
2094+ instance.model.name.toByteArray()
2095+ ) &&
2096+ SystemApisUtils .setMetadata(
2097+ device,
2098+ device.METADATA_DEVICE_TYPE ,
2099+ device.DEVICE_TYPE_UNTETHERED_HEADSET .toByteArray()
2100+ ) &&
2101+ SystemApisUtils .setMetadata(
2102+ device,
2103+ device.METADATA_UNTETHERED_CASE_ICON ,
2104+ resToUri(instance.model.caseRes).toString().toByteArray()
2105+ ) &&
2106+ SystemApisUtils .setMetadata(
2107+ device,
2108+ device.METADATA_UNTETHERED_RIGHT_ICON ,
2109+ resToUri(instance.model.rightBudsRes).toString().toByteArray()
2110+ ) &&
2111+ SystemApisUtils .setMetadata(
2112+ device,
2113+ device.METADATA_UNTETHERED_LEFT_ICON ,
2114+ resToUri(instance.model.leftBudsRes).toString().toByteArray()
2115+ ) &&
2116+ SystemApisUtils .setMetadata(
2117+ device,
2118+ device.METADATA_MANUFACTURER_NAME ,
2119+ instance.model.manufacturer.toByteArray()
2120+ ) &&
2121+ SystemApisUtils .setMetadata(
2122+ device,
2123+ device.METADATA_COMPANION_APP ,
2124+ " me.kavishdevar.librepods" .toByteArray()
2125+ ) &&
2126+ SystemApisUtils .setMetadata(
2127+ device,
2128+ device.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD ,
2129+ " 20" .toByteArray()
2130+ ) &&
2131+ SystemApisUtils .setMetadata(
2132+ device,
2133+ device.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD ,
2134+ " 20" .toByteArray()
2135+ ) &&
2136+ SystemApisUtils .setMetadata(
2137+ device,
2138+ device.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD ,
2139+ " 20" .toByteArray()
2140+ )
21382141 Log .d(TAG , " Metadata set: $metadataSet " )
21392142 } else {
21402143 Log .w(TAG , " AirPods instance is not of type AirPodsInstance, skipping metadata setting" )
@@ -2325,7 +2328,9 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
23252328 Log .d(TAG , macAddress)
23262329
23272330// sharedPreferences.edit { putBoolean("CrossDeviceIsAvailable", false) }
2328- device = getSystemService(BluetoothManager ::class .java).adapter.bondedDevices.find {
2331+ val bluetoothManager = getSystemService(BluetoothManager ::class .java)
2332+ val bluetoothAdapter = bluetoothManager.adapter
2333+ device = bluetoothAdapter.bondedDevices.find {
23292334 it.address == macAddress
23302335 }
23312336
@@ -2341,7 +2346,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
23412346 // Set a temporary connecting state
23422347 isConnectedLocally = false // Keep as false since we're not actually connecting to L2CAP
23432348 } else {
2344- connectToSocket(device!! )
2349+ connectToSocket(bluetoothAdapter, device!! )
23452350 connectAudio(this , device)
23462351 isConnectedLocally = true
23472352 }
@@ -2352,9 +2357,10 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
23522357// CrossDevice.isAvailable = false
23532358 }
23542359
2355- private fun createBluetoothSocket (device : BluetoothDevice , uuid : ParcelUuid ): BluetoothSocket {
2360+ private fun createBluetoothSocket (adapter : BluetoothAdapter , device : BluetoothDevice , uuid : ParcelUuid ): BluetoothSocket {
23562361 val type = 3 // L2CAP
23572362 val constructorSpecs = listOf (
2363+ arrayOf(adapter, device, type, true , true , 0x1001 , uuid), // A16QPR3
23582364 arrayOf(device, type, true , true , 0x1001 , uuid),
23592365 arrayOf(device, type, 1 , true , true , 0x1001 , uuid),
23602366 arrayOf(type, 1 , true , true , device, 0x1001 , uuid),
@@ -2390,13 +2396,13 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
23902396 }
23912397
23922398 @SuppressLint(" MissingPermission" , " UnspecifiedRegisterReceiverFlag" )
2393- fun connectToSocket (device : BluetoothDevice , manual : Boolean = false) {
2399+ fun connectToSocket (adapter : BluetoothAdapter , device : BluetoothDevice , manual : Boolean = false) {
23942400 Log .d(TAG , " <LogCollector:Start> Connecting to socket" )
23952401 HiddenApiBypass .addHiddenApiExemptions(" Landroid/bluetooth/BluetoothSocket;" )
23962402 val uuid: ParcelUuid = ParcelUuid .fromString(" 74ec2172-0bad-4d01-8f77-997b2be0722a" )
23972403 if (! isConnectedLocally) {
23982404 socket = try {
2399- createBluetoothSocket(device, uuid)
2405+ createBluetoothSocket(adapter, device, uuid)
24002406 } catch (e: Exception ) {
24012407 Log .e(TAG , " Failed to create BluetoothSocket: ${e.message} " )
24022408 showSocketConnectionFailureNotification(" Failed to create Bluetooth socket: ${e.localizedMessage} " )
@@ -2812,7 +2818,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
28122818 }
28132819 if (device != null ) {
28142820 CoroutineScope (Dispatchers .IO ).launch {
2815- connectToSocket(device!! , manual = true )
2821+ connectToSocket(bluetoothAdapter, device!! , manual = true )
28162822 }
28172823 }
28182824 }
0 commit comments