mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-07-06 12:19:55 +00:00
android: refactor AACP socket handling
This commit is contained in:
@@ -118,6 +118,7 @@ import com.kyant.backdrop.backdrops.rememberLayerBackdrop
|
|||||||
import dev.chrisbanes.haze.hazeSource
|
import dev.chrisbanes.haze.hazeSource
|
||||||
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
|
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
|
||||||
import dev.chrisbanes.haze.rememberHazeState
|
import dev.chrisbanes.haze.rememberHazeState
|
||||||
|
import me.kavishdevar.librepods.bluetooth.BluetoothConnectionManager
|
||||||
import me.kavishdevar.librepods.data.AirPodsNotifications
|
import me.kavishdevar.librepods.data.AirPodsNotifications
|
||||||
import me.kavishdevar.librepods.data.ControlCommandRepository
|
import me.kavishdevar.librepods.data.ControlCommandRepository
|
||||||
import me.kavishdevar.librepods.presentation.components.AppInfoCard
|
import me.kavishdevar.librepods.presentation.components.AppInfoCard
|
||||||
@@ -541,7 +542,7 @@ fun Main() {
|
|||||||
Context.BIND_AUTO_CREATE
|
Context.BIND_AUTO_CREATE
|
||||||
)
|
)
|
||||||
|
|
||||||
if (airPodsService.value?.isConnected() == true) {
|
if (BluetoothConnectionManager.getAACPSocket()?.isConnected == true) {
|
||||||
isConnected.value = true
|
isConnected.value = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -31,9 +31,8 @@ import kotlin.io.encoding.ExperimentalEncodingApi
|
|||||||
* constructing and parsing packets for communication with AirPods.
|
* constructing and parsing packets for communication with AirPods.
|
||||||
*/
|
*/
|
||||||
class AACPManager {
|
class AACPManager {
|
||||||
|
private val TAG = "AACPManager[${System.identityHashCode(this)}]"
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "AACPManager"
|
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object Opcodes {
|
object Opcodes {
|
||||||
const val SET_FEATURE_FLAGS: Byte = 0x4D
|
const val SET_FEATURE_FLAGS: Byte = 0x4D
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import android.content.Intent
|
|||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
@@ -40,6 +41,7 @@ import me.kavishdevar.librepods.bluetooth.AACPManager
|
|||||||
import me.kavishdevar.librepods.bluetooth.AACPManager.Companion.ControlCommandIdentifiers
|
import me.kavishdevar.librepods.bluetooth.AACPManager.Companion.ControlCommandIdentifiers
|
||||||
import me.kavishdevar.librepods.bluetooth.ATTCCCDHandles
|
import me.kavishdevar.librepods.bluetooth.ATTCCCDHandles
|
||||||
import me.kavishdevar.librepods.bluetooth.ATTHandles
|
import me.kavishdevar.librepods.bluetooth.ATTHandles
|
||||||
|
import me.kavishdevar.librepods.bluetooth.BluetoothConnectionManager
|
||||||
import me.kavishdevar.librepods.data.AirPodsInstance
|
import me.kavishdevar.librepods.data.AirPodsInstance
|
||||||
import me.kavishdevar.librepods.data.AirPodsModels
|
import me.kavishdevar.librepods.data.AirPodsModels
|
||||||
import me.kavishdevar.librepods.data.AirPodsNotifications
|
import me.kavishdevar.librepods.data.AirPodsNotifications
|
||||||
@@ -352,7 +354,7 @@ class AirPodsViewModel(
|
|||||||
service.let { service ->
|
service.let { service ->
|
||||||
_uiState.update {
|
_uiState.update {
|
||||||
it.copy(
|
it.copy(
|
||||||
isLocallyConnected = service.isConnected(), battery = service.getBattery()
|
isLocallyConnected = BluetoothConnectionManager.getAACPSocket()?.isConnected == true, battery = service.getBattery()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -382,7 +384,6 @@ class AirPodsViewModel(
|
|||||||
|
|
||||||
val connectionSuccessful = sharedPreferences.getBoolean("connection_successful", false)
|
val connectionSuccessful = sharedPreferences.getBoolean("connection_successful", false)
|
||||||
|
|
||||||
val fossUpgraded = sharedPreferences.getBoolean("foss_upgraded", false)
|
|
||||||
_uiState.update {
|
_uiState.update {
|
||||||
it.copy(
|
it.copy(
|
||||||
offListeningMode = offListeningModeEnabled,
|
offListeningMode = offListeningModeEnabled,
|
||||||
@@ -398,8 +399,8 @@ class AirPodsViewModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// faulty update on Play caused PLAY_BUILD to be false and resulted in use of FOSS billing in Play. since FOSS is not verified, we need to give 2 weeks to verify the purchase
|
// faulty update on Play caused PLAY_BUILD to be false and resulted in use of FOSS billing in Play. since FOSS is not verified, we need to give 2 weeks to verify the purchase
|
||||||
|
|
||||||
if (BuildConfig.PLAY_BUILD) {
|
if (BuildConfig.PLAY_BUILD) {
|
||||||
|
val fossUpgraded = sharedPreferences.getBoolean("foss_upgraded", false)
|
||||||
val expiryTime = sharedPreferences.getLong("premium_expiry_time", 0L)
|
val expiryTime = sharedPreferences.getLong("premium_expiry_time", 0L)
|
||||||
val now = System.currentTimeMillis()
|
val now = System.currentTimeMillis()
|
||||||
|
|
||||||
|
|||||||
@@ -35,9 +35,10 @@ import android.util.Log
|
|||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import me.kavishdevar.librepods.QuickSettingsDialogActivity
|
import me.kavishdevar.librepods.QuickSettingsDialogActivity
|
||||||
import me.kavishdevar.librepods.R
|
import me.kavishdevar.librepods.R
|
||||||
|
import me.kavishdevar.librepods.bluetooth.AACPManager
|
||||||
|
import me.kavishdevar.librepods.bluetooth.BluetoothConnectionManager
|
||||||
import me.kavishdevar.librepods.data.AirPodsNotifications
|
import me.kavishdevar.librepods.data.AirPodsNotifications
|
||||||
import me.kavishdevar.librepods.data.NoiseControlMode
|
import me.kavishdevar.librepods.data.NoiseControlMode
|
||||||
import me.kavishdevar.librepods.bluetooth.AACPManager
|
|
||||||
import kotlin.io.encoding.ExperimentalEncodingApi
|
import kotlin.io.encoding.ExperimentalEncodingApi
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.Q)
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
@@ -98,7 +99,7 @@ class AirPodsQSService : TileService() {
|
|||||||
Log.d("AirPodsQSService", "onStartListening")
|
Log.d("AirPodsQSService", "onStartListening")
|
||||||
|
|
||||||
val service = ServiceManager.getService()
|
val service = ServiceManager.getService()
|
||||||
isAirPodsConnected = service?.isConnected() == true
|
isAirPodsConnected = BluetoothConnectionManager.getAACPSocket()?.isConnected == true
|
||||||
currentAncMode = service?.getANC() ?: (NoiseControlMode.OFF.ordinal + 1)
|
currentAncMode = service?.getANC() ?: (NoiseControlMode.OFF.ordinal + 1)
|
||||||
|
|
||||||
if (currentAncMode == NoiseControlMode.OFF.ordinal + 1 && !isOffModeEnabled()) {
|
if (currentAncMode == NoiseControlMode.OFF.ordinal + 1 && !isOffModeEnabled()) {
|
||||||
|
|||||||
@@ -233,8 +233,6 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
|
|
||||||
lateinit var bleManager: BLEManager
|
lateinit var bleManager: BLEManager
|
||||||
|
|
||||||
private lateinit var socket: BluetoothSocket
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
init {
|
init {
|
||||||
System.loadLibrary("bluetooth_socket")
|
System.loadLibrary("bluetooth_socket")
|
||||||
@@ -246,7 +244,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
override fun onDeviceStatusChanged(
|
override fun onDeviceStatusChanged(
|
||||||
device: BLEManager.AirPodsStatus, previousStatus: BLEManager.AirPodsStatus?
|
device: BLEManager.AirPodsStatus, previousStatus: BLEManager.AirPodsStatus?
|
||||||
) {
|
) {
|
||||||
if (device.connectionState == "Disconnected" && !isConnected()) { // should never happen unless android messes up and sends us a stale broadcast
|
if (device.connectionState == "Disconnected" && BluetoothConnectionManager.getAACPSocket()?.isConnected != true) { // should never happen unless android messes up and sends us a stale broadcast
|
||||||
Log.d(TAG, "Seems no device has taken over, we will.")
|
Log.d(TAG, "Seems no device has taken over, we will.")
|
||||||
val bluetoothManager = getSystemService(BluetoothManager::class.java)
|
val bluetoothManager = getSystemService(BluetoothManager::class.java)
|
||||||
val bluetoothAdapter = bluetoothManager.adapter
|
val bluetoothAdapter = bluetoothManager.adapter
|
||||||
@@ -258,7 +256,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
connectToSocket(bluetoothAdapter, bluetoothDevice)
|
connectToSocket(bluetoothAdapter, bluetoothDevice)
|
||||||
}
|
}
|
||||||
Log.d(TAG, "Device status changed")
|
Log.d(TAG, "Device status changed")
|
||||||
if (socket.isConnected) return
|
if (BluetoothConnectionManager.getAACPSocket()?.isConnected == true) return
|
||||||
val leftLevel = bleManager.getMostRecentStatus()?.leftBattery ?: 0
|
val leftLevel = bleManager.getMostRecentStatus()?.leftBattery ?: 0
|
||||||
val rightLevel = bleManager.getMostRecentStatus()?.rightBattery ?: 0
|
val rightLevel = bleManager.getMostRecentStatus()?.rightBattery ?: 0
|
||||||
val caseLevel = bleManager.getMostRecentStatus()?.caseBattery ?: 0
|
val caseLevel = bleManager.getMostRecentStatus()?.caseBattery ?: 0
|
||||||
@@ -291,7 +289,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
getSharedPreferences("settings", MODE_PRIVATE).getString("name", "AirPods Pro")
|
getSharedPreferences("settings", MODE_PRIVATE).getString("name", "AirPods Pro")
|
||||||
?: "AirPods"
|
?: "AirPods"
|
||||||
)
|
)
|
||||||
if (socket.isConnected) return
|
if (BluetoothConnectionManager.getAACPSocket()?.isConnected == true) return
|
||||||
val leftLevel = bleManager.getMostRecentStatus()?.leftBattery ?: 0
|
val leftLevel = bleManager.getMostRecentStatus()?.leftBattery ?: 0
|
||||||
val rightLevel = bleManager.getMostRecentStatus()?.rightBattery ?: 0
|
val rightLevel = bleManager.getMostRecentStatus()?.rightBattery ?: 0
|
||||||
val caseLevel = bleManager.getMostRecentStatus()?.caseBattery ?: 0
|
val caseLevel = bleManager.getMostRecentStatus()?.caseBattery ?: 0
|
||||||
@@ -325,7 +323,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onBatteryChanged(device: BLEManager.AirPodsStatus) {
|
override fun onBatteryChanged(device: BLEManager.AirPodsStatus) {
|
||||||
if (socket.isConnected) return
|
if (BluetoothConnectionManager.getAACPSocket()?.isConnected == true) return
|
||||||
val leftLevel = bleManager.getMostRecentStatus()?.leftBattery ?: 0
|
val leftLevel = bleManager.getMostRecentStatus()?.leftBattery ?: 0
|
||||||
val rightLevel = bleManager.getMostRecentStatus()?.rightBattery ?: 0
|
val rightLevel = bleManager.getMostRecentStatus()?.rightBattery ?: 0
|
||||||
val caseLevel = bleManager.getMostRecentStatus()?.caseBattery ?: 0
|
val caseLevel = bleManager.getMostRecentStatus()?.caseBattery ?: 0
|
||||||
@@ -1739,7 +1737,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
|
|
||||||
val socketFailureChannel = NotificationChannel(
|
val socketFailureChannel = NotificationChannel(
|
||||||
"socket_connection_failure",
|
"socket_connection_failure",
|
||||||
"AirPods Socket Connection Issues",
|
"AirPods BluetoothConnectionManager.getAACPSocket()? Connection Issues",
|
||||||
NotificationManager.IMPORTANCE_HIGH
|
NotificationManager.IMPORTANCE_HIGH
|
||||||
).apply {
|
).apply {
|
||||||
description = "Notifications about problems connecting to AirPods protocol"
|
description = "Notifications about problems connecting to AirPods protocol"
|
||||||
@@ -1785,7 +1783,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
if (BuildConfig.FLAVOR != "xposed") {
|
if (BuildConfig.FLAVOR != "xposed") {
|
||||||
Log.w(
|
Log.w(
|
||||||
TAG,
|
TAG,
|
||||||
"Not showing socket error notification to user, the service shouldn't be running if it isn't supported."
|
"Not showing BluetoothConnectionManager.getAACPSocket()? error notification to user, the service shouldn't be running if it isn't supported."
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -2040,10 +2038,10 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!::socket.isInitialized) {
|
if (BluetoothConnectionManager.getAACPSocket() == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (connected && (config.bleOnlyMode || socket.isConnected)) {
|
if (BluetoothConnectionManager.getAACPSocket()?.isConnected == true) {
|
||||||
val updatedNotificationBuilder =
|
val updatedNotificationBuilder =
|
||||||
NotificationCompat.Builder(this, "airpods_connection_status")
|
NotificationCompat.Builder(this, "airpods_connection_status")
|
||||||
.setSmallIcon(R.drawable.airpods)
|
.setSmallIcon(R.drawable.airpods)
|
||||||
@@ -2091,8 +2089,8 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
notificationManager.cancel(1)
|
notificationManager.cancel(1)
|
||||||
} else if (!connected) {
|
} else if (!connected) {
|
||||||
notificationManager.cancel(2)
|
notificationManager.cancel(2)
|
||||||
} else if (!config.bleOnlyMode && !socket.isConnected) {
|
} else if (!config.bleOnlyMode && BluetoothConnectionManager.getAACPSocket()?.isConnected != true) {
|
||||||
showSocketConnectionFailureNotification("Socket created, but not connected. Check logs")
|
showSocketConnectionFailureNotification("BluetoothConnectionManager.getAACPSocket()? created, but not connected. Check logs")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2467,8 +2465,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
Log.d(
|
Log.d(
|
||||||
TAG, "owns connection: $ownsConnection"
|
TAG, "owns connection: $ownsConnection"
|
||||||
)
|
)
|
||||||
if (!::socket.isInitialized) return
|
if (BluetoothConnectionManager.getAACPSocket()?.isConnected == true) {
|
||||||
if (socket.isConnected) {
|
|
||||||
if (!XposedRemotePrefProvider.create().getBoolean("vendor_id_hook", false) || ownsConnection == 0) {
|
if (!XposedRemotePrefProvider.create().getBoolean("vendor_id_hook", false) || ownsConnection == 0) {
|
||||||
Log.d(TAG, "not taking over, vendorid is probably not set to apple")
|
Log.d(TAG, "not taking over, vendorid is probably not set to apple")
|
||||||
return
|
return
|
||||||
@@ -2677,10 +2674,11 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
fun connectToSocket(
|
fun connectToSocket(
|
||||||
adapter: BluetoothAdapter, device: BluetoothDevice, manual: Boolean = false
|
adapter: BluetoothAdapter, device: BluetoothDevice, manual: Boolean = false
|
||||||
) {
|
) {
|
||||||
|
if (BluetoothConnectionManager.getAACPSocket() != null && BluetoothConnectionManager.getAACPSocket()?.isConnected == true) return
|
||||||
Log.d(TAG, "<LogCollector:Start> Connecting to socket")
|
Log.d(TAG, "<LogCollector:Start> Connecting to socket")
|
||||||
val uuid: ParcelUuid = ParcelUuid.fromString("74ec2172-0bad-4d01-8f77-997b2be0722a")
|
val uuid: ParcelUuid = ParcelUuid.fromString("74ec2172-0bad-4d01-8f77-997b2be0722a")
|
||||||
// if (!isConnectedLocally) {
|
// if (!isConnectedLocally) {
|
||||||
socket = try {
|
val socket = try {
|
||||||
createBluetoothSocket(adapter, device, uuid, 4097)
|
createBluetoothSocket(adapter, device, uuid, 4097)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Failed to create BluetoothSocket: ${e.message}")
|
Log.e(TAG, "Failed to create BluetoothSocket: ${e.message}")
|
||||||
@@ -2768,7 +2766,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!socket.isConnected) {
|
if (!socket.isConnected) {
|
||||||
Log.d(TAG, "<LogCollector:Complete:Failed> Socket not connected")
|
Log.d(TAG, "<LogCollector:Complete:Failed> socket not connected")
|
||||||
if (manual) {
|
if (manual) {
|
||||||
sendToast(
|
sendToast(
|
||||||
"Couldn't connect to socket: timeout."
|
"Couldn't connect to socket: timeout."
|
||||||
@@ -2779,13 +2777,14 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
this@AirPodsService.device = device
|
this@AirPodsService.device = device
|
||||||
socket.let {
|
BluetoothConnectionManager.getAACPSocket()?.let {
|
||||||
aacpManager.sendPacket(aacpManager.createHandshakePacket())
|
aacpManager.sendPacket(aacpManager.createHandshakePacket())
|
||||||
aacpManager.sendSetFeatureFlagsPacket()
|
aacpManager.sendSetFeatureFlagsPacket()
|
||||||
aacpManager.sendNotificationRequest()
|
aacpManager.sendNotificationRequest()
|
||||||
Log.d(TAG, "Requesting proximity keys")
|
Log.d(TAG, "Requesting proximity keys")
|
||||||
aacpManager.sendRequestProximityKeys((AACPManager.Companion.ProximityKeyType.IRK.value + AACPManager.Companion.ProximityKeyType.ENC_KEY.value).toByte())
|
aacpManager.sendRequestProximityKeys((AACPManager.Companion.ProximityKeyType.IRK.value + AACPManager.Companion.ProximityKeyType.ENC_KEY.value).toByte())
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
delay(200)
|
||||||
aacpManager.sendPacket(aacpManager.createHandshakePacket())
|
aacpManager.sendPacket(aacpManager.createHandshakePacket())
|
||||||
delay(200)
|
delay(200)
|
||||||
aacpManager.sendSetFeatureFlagsPacket()
|
aacpManager.sendSetFeatureFlagsPacket()
|
||||||
@@ -2813,55 +2812,53 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
setupStemActions()
|
setupStemActions()
|
||||||
|
|
||||||
while (socket.isConnected) {
|
while (socket.isConnected) {
|
||||||
socket.let { it ->
|
try {
|
||||||
try {
|
val buffer = ByteArray(1024)
|
||||||
val buffer = ByteArray(1024)
|
val bytesRead = it.inputStream.read(buffer)
|
||||||
val bytesRead = it.inputStream.read(buffer)
|
var data: ByteArray
|
||||||
var data: ByteArray
|
if (bytesRead > 0) {
|
||||||
if (bytesRead > 0) {
|
data = buffer.copyOfRange(0, bytesRead)
|
||||||
data = buffer.copyOfRange(0, bytesRead)
|
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DATA).apply {
|
||||||
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DATA).apply {
|
putExtra("data", buffer.copyOfRange(0, bytesRead))
|
||||||
putExtra("data", buffer.copyOfRange(0, bytesRead))
|
setPackage(packageName)
|
||||||
setPackage(packageName)
|
})
|
||||||
})
|
val bytes = buffer.copyOfRange(0, bytesRead)
|
||||||
val bytes = buffer.copyOfRange(0, bytesRead)
|
val formattedHex = bytes.joinToString(" ") { "%02X".format(it) }
|
||||||
val formattedHex = bytes.joinToString(" ") { "%02X".format(it) }
|
|
||||||
// CrossDevice.sendReceivedPacket(bytes)
|
// CrossDevice.sendReceivedPacket(bytes)
|
||||||
updateNotificationContent(
|
updateNotificationContent(
|
||||||
true,
|
true,
|
||||||
sharedPreferences.getString("name", device.name),
|
sharedPreferences.getString("name", device.name),
|
||||||
batteryNotification.getBattery()
|
batteryNotification.getBattery()
|
||||||
)
|
)
|
||||||
|
|
||||||
aacpManager.receivePacket(data)
|
aacpManager.receivePacket(data)
|
||||||
|
|
||||||
if (!isHeadTrackingData(data)) {
|
if (!isHeadTrackingData(data)) {
|
||||||
Log.d("AirPodsData", "Data received: $formattedHex")
|
Log.d("AirPodsData", "Data received: $formattedHex")
|
||||||
logPacket(data, "AirPods")
|
logPacket(data, "AirPods")
|
||||||
}
|
|
||||||
|
|
||||||
} else if (bytesRead == -1) {
|
|
||||||
Log.d("AirPods Service", "Socket closed (bytesRead = -1)")
|
|
||||||
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED).apply {
|
|
||||||
setPackage(packageName)
|
|
||||||
})
|
|
||||||
aacpManager.disconnected()
|
|
||||||
return@launch
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.w(TAG, "Error reading data, we have probably disconnected.")
|
} else if (bytesRead == -1) {
|
||||||
e.printStackTrace()
|
Log.d("AirPods Service", "BluetoothConnectionManager.getAACPSocket()? closed (bytesRead = -1)")
|
||||||
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED).apply {
|
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED).apply {
|
||||||
setPackage(packageName)
|
setPackage(packageName)
|
||||||
})
|
})
|
||||||
aacpManager.disconnected()
|
aacpManager.disconnected()
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Error reading data, we have probably disconnected.")
|
||||||
|
e.printStackTrace()
|
||||||
|
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED).apply {
|
||||||
|
setPackage(packageName)
|
||||||
|
})
|
||||||
|
aacpManager.disconnected()
|
||||||
|
return@launch
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Log.d("AirPods Service", "Socket closed")
|
Log.d("AirPods Service", "socket closed")
|
||||||
// isConnectedLocally = false
|
// isConnectedLocally = false
|
||||||
socket.close()
|
|
||||||
aacpManager.disconnected()
|
aacpManager.disconnected()
|
||||||
updateNotificationContent(false)
|
updateNotificationContent(false)
|
||||||
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED).apply {
|
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED).apply {
|
||||||
@@ -2871,20 +2868,19 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
Log.d(TAG, "Failed to connect to socket: ${e.message}")
|
Log.d(TAG, "Failed to connect to BluetoothConnectionManager.getAACPSocket()?: ${e.message}")
|
||||||
showSocketConnectionFailureNotification("Failed to establish connection: ${e.localizedMessage}")
|
showSocketConnectionFailureNotification("Failed to establish connection: ${e.localizedMessage}")
|
||||||
// isConnectedLocally = false
|
// isConnectedLocally = false
|
||||||
this@AirPodsService.device = device
|
this@AirPodsService.device = device
|
||||||
updateNotificationContent(false)
|
updateNotificationContent(false)
|
||||||
}
|
}
|
||||||
// } else {
|
// } else {
|
||||||
// Log.d(TAG, "Already connected locally, skipping socket connection (isConnectedLocally = $isConnectedLocally, socket.isConnected = ${this::socket.isInitialized && socket.isConnected})")
|
// Log.d(TAG, "Already connected locally, skipping BluetoothConnectionManager.getAACPSocket()? connection (isConnectedLocally = $isConnectedLocally, BluetoothConnectionManager.getAACPSocket()?.isConnected = ${this::BluetoothConnectionManager.getAACPSocket()?.isInitialized && BluetoothConnectionManager.getAACPSocket()?.isConnected})")
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun disconnectForCD() {
|
fun disconnectForCD() {
|
||||||
if (!this::socket.isInitialized) return
|
BluetoothConnectionManager.getAACPSocket()?.close()
|
||||||
socket.close()
|
|
||||||
MediaController.pausedWhileTakingOver = false
|
MediaController.pausedWhileTakingOver = false
|
||||||
Log.d(TAG, "Disconnected from AirPods, showing island.")
|
Log.d(TAG, "Disconnected from AirPods, showing island.")
|
||||||
showIsland(
|
showIsland(
|
||||||
@@ -2915,8 +2911,12 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun disconnectAirPods() {
|
fun disconnectAirPods() {
|
||||||
if (!this::socket.isInitialized) return
|
if (BluetoothConnectionManager.getAACPSocket() == null) return
|
||||||
socket.close()
|
try {
|
||||||
|
BluetoothConnectionManager.getAACPSocket()?.close()
|
||||||
|
} catch(e: Exception) {
|
||||||
|
Log.e(TAG, "error closing aacp socket ${e.message}")
|
||||||
|
}
|
||||||
// isConnectedLocally = false
|
// isConnectedLocally = false
|
||||||
aacpManager.disconnected()
|
aacpManager.disconnected()
|
||||||
attManager.disconnected()
|
attManager.disconnected()
|
||||||
@@ -3228,10 +3228,6 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isConnected(): Boolean {
|
|
||||||
return if (::socket.isInitialized) socket.isConnected else false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Int.dpToPx(): Int {
|
private fun Int.dpToPx(): Int {
|
||||||
|
|||||||
Reference in New Issue
Block a user