Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,11 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
connectionReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action == AirPodsNotifications.AIRPODS_CONNECTION_DETECTED) {
if (::socket.isInitialized && socket.isConnected) {
Log.d(TAG, "Connection broadcast received but socket already connected, ignoring")
return
}

device = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
intent.getParcelableExtra("device", BluetoothDevice::class.java)!!
} else {
Expand Down Expand Up @@ -2360,6 +2365,13 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList

@Suppress("ClassName")
private object bluetoothReceiver : BroadcastReceiver() {
private fun sendDetected(context: Context?, name: String?, device: BluetoothDevice) {
val intent = Intent(AirPodsNotifications.AIRPODS_CONNECTION_DETECTED)
intent.putExtra("name", name)
intent.putExtra("device", device)
context?.sendBroadcast(intent)
}

@SuppressLint("MissingPermission")
override fun onReceive(context: Context?, intent: Intent) {
val bluetoothDevice = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
Expand All @@ -2375,16 +2387,20 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
?.getString("name", bluetoothDevice?.name)
if (bluetoothDevice != null && !action.isNullOrEmpty()) {
Log.d(TAG, "Received bluetooth connection broadcast: action=$action")
val uuid = ParcelUuid.fromString("74ec2172-0bad-4d01-8f77-997b2be0722a")
if (BluetoothDevice.ACTION_ACL_CONNECTED == action) {
val uuid = ParcelUuid.fromString("74ec2172-0bad-4d01-8f77-997b2be0722a")
bluetoothDevice.fetchUuidsWithSdp()
if (bluetoothDevice.uuids != null) {
if (bluetoothDevice.uuids.contains(uuid)) {
val intent = Intent(AirPodsNotifications.AIRPODS_CONNECTION_DETECTED)
intent.putExtra("name", name)
intent.putExtra("device", bluetoothDevice)
context?.sendBroadcast(intent)
}
if (bluetoothDevice.uuids?.contains(uuid) == true) {
sendDetected(context, name, bluetoothDevice)
} else {
bluetoothDevice.fetchUuidsWithSdp()
}
} else if ("android.bluetooth.device.action.UUID" == action) {
val savedMac = context?.getSharedPreferences("settings", MODE_PRIVATE)
?.getString("mac_address", "") ?: ""
val matchedByMac = savedMac.isNotEmpty() && bluetoothDevice.address == savedMac
val matchedByUuid = bluetoothDevice.uuids?.contains(uuid) == true
if (matchedByUuid || matchedByMac) {
sendDetected(context, name, bluetoothDevice)
}
}
}
Expand Down Expand Up @@ -2642,7 +2658,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList

@SuppressLint("MissingPermission", "UnspecifiedRegisterReceiverFlag")
fun connectToSocket(
adapter: BluetoothAdapter, device: BluetoothDevice, manual: Boolean = false
adapter: BluetoothAdapter, device: BluetoothDevice, manual: Boolean = false, retriesLeft: Int = if (manual) 0 else 3
) {
Log.d(TAG, "<LogCollector:Start> Connecting to socket")
val uuid: ParcelUuid = ParcelUuid.fromString("74ec2172-0bad-4d01-8f77-997b2be0722a")
Expand Down Expand Up @@ -2701,6 +2717,15 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
Log.d(
TAG, "<LogCollector:Complete:Failed> Socket not connected, ${e.message}"
)
if (retriesLeft > 0) {
Log.d(TAG, "Retrying socket connect, $retriesLeft attempts left")
try { socket.close() } catch (_: Exception) {}
CoroutineScope(Dispatchers.IO).launch {
delay(500L)
connectToSocket(adapter, device, manual, retriesLeft - 1)
}
return@withTimeout
}
if (manual) {
sendToast(
"Couldn't connect to socket: ${e.localizedMessage}"
Expand All @@ -2715,6 +2740,15 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
}
if (!socket.isConnected) {
Log.d(TAG, "<LogCollector:Complete:Failed> Socket not connected")
if (retriesLeft > 0) {
Log.d(TAG, "Retrying socket connect after timeout, $retriesLeft attempts left")
try { socket.close() } catch (_: Exception) {}
CoroutineScope(Dispatchers.IO).launch {
delay(500L)
connectToSocket(adapter, device, manual, retriesLeft - 1)
}
return
}
if (manual) {
sendToast(
"Couldn't connect to socket: timeout."
Expand Down
Loading