mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-01-29 06:10:52 +00:00
android: improve ble-based autoconnection
This commit is contained in:
@@ -213,6 +213,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
||||
this@AirPodsService,
|
||||
getSharedPreferences("settings", MODE_PRIVATE).getString("name", "AirPods Pro") ?: "AirPods"
|
||||
)
|
||||
if (isConnectedLocally) return
|
||||
val leftLevel = bleManager.getMostRecentStatus()?.leftBattery?: 0
|
||||
val rightLevel = bleManager.getMostRecentStatus()?.rightBattery?: 0
|
||||
val caseLevel = bleManager.getMostRecentStatus()?.caseBattery?: 0
|
||||
@@ -243,24 +244,23 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
||||
}
|
||||
|
||||
override fun onBatteryChanged(device: BLEManager.AirPodsStatus) {
|
||||
// if (!isConnectedLocally) {
|
||||
// val leftLevel = bleManager.getMostRecentStatus()?.leftBattery?: 0
|
||||
// val rightLevel = bleManager.getMostRecentStatus()?.rightBattery?: 0
|
||||
// val caseLevel = bleManager.getMostRecentStatus()?.caseBattery?: 0
|
||||
// val leftCharging = bleManager.getMostRecentStatus()?.isLeftCharging
|
||||
// val rightCharging = bleManager.getMostRecentStatus()?.isRightCharging
|
||||
// val caseCharging = bleManager.getMostRecentStatus()?.isCaseCharging
|
||||
if (isConnectedLocally) return
|
||||
val leftLevel = bleManager.getMostRecentStatus()?.leftBattery?: 0
|
||||
val rightLevel = bleManager.getMostRecentStatus()?.rightBattery?: 0
|
||||
val caseLevel = bleManager.getMostRecentStatus()?.caseBattery?: 0
|
||||
val leftCharging = bleManager.getMostRecentStatus()?.isLeftCharging
|
||||
val rightCharging = bleManager.getMostRecentStatus()?.isRightCharging
|
||||
val caseCharging = bleManager.getMostRecentStatus()?.isCaseCharging
|
||||
|
||||
// batteryNotification.setBatteryDirect(
|
||||
// leftLevel = leftLevel,
|
||||
// leftCharging = leftCharging == true,
|
||||
// rightLevel = rightLevel,
|
||||
// rightCharging = rightCharging == true,
|
||||
// caseLevel = caseLevel,
|
||||
// caseCharging = caseCharging == true
|
||||
// )
|
||||
// updateBattery()
|
||||
// }
|
||||
batteryNotification.setBatteryDirect(
|
||||
leftLevel = leftLevel,
|
||||
leftCharging = leftCharging == true,
|
||||
rightLevel = rightLevel,
|
||||
rightCharging = rightCharging == true,
|
||||
caseLevel = caseLevel,
|
||||
caseCharging = caseCharging == true
|
||||
)
|
||||
updateBattery()
|
||||
Log.d("AirPodsBLEService", "Battery changed")
|
||||
}
|
||||
|
||||
@@ -413,6 +413,9 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
||||
connectAudio(this@AirPodsService, device)
|
||||
justEnabledA2dp = true
|
||||
registerA2dpConnectionReceiver()
|
||||
if (MediaController.getMusicActive()) {
|
||||
MediaController.userPlayedTheMedia = true
|
||||
}
|
||||
} else if (newInEarData == listOf(false, false)) {
|
||||
MediaController.sendPause(force = true)
|
||||
if (config.disconnectWhenNotWearing) {
|
||||
@@ -434,7 +437,6 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
||||
|
||||
if (newInEarData.sorted() != inEarData.sorted()) {
|
||||
inEarData = newInEarData
|
||||
|
||||
if (inEar == true) {
|
||||
if (!justEnabledA2dp) {
|
||||
justEnabledA2dp = false
|
||||
@@ -1674,8 +1676,19 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
||||
@RequiresApi(Build.VERSION_CODES.R)
|
||||
@SuppressLint("MissingPermission")
|
||||
fun takeOver(takingOverFor: String) {
|
||||
if (isConnectedLocally || !CrossDevice.isAvailable || bleManager.getMostRecentStatus()?.isLeftInEar == true || bleManager.getMostRecentStatus()?.isRightInEar == true) {
|
||||
Log.d("AirPodsService", "Already connected or not available for takeover")
|
||||
if (isConnectedLocally) {
|
||||
Log.d("AirPodsService", "Already connected locally, skipping")
|
||||
return
|
||||
}
|
||||
|
||||
if (CrossDevice.isAvailable) {
|
||||
Log.d("AirPodsService", "CrossDevice is available, continuing")
|
||||
}
|
||||
else if (bleManager.getMostRecentStatus()?.isLeftInEar == true || bleManager.getMostRecentStatus()?.isRightInEar == true) {
|
||||
Log.d("AirPodsService", "At least one AirPod is in ear, continuing")
|
||||
}
|
||||
else {
|
||||
Log.d("AirPodsService", "CrossDevice not available and AirPods not in ear, skipping")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1684,6 +1697,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
||||
"call" -> config.takeoverWhenRingingCall
|
||||
else -> false
|
||||
}
|
||||
|
||||
if (!shouldTakeOverPState) {
|
||||
Log.d("AirPodsService", "Not taking over audio, phone state takeover disabled")
|
||||
return
|
||||
@@ -1704,6 +1718,12 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
||||
return
|
||||
}
|
||||
|
||||
if (takingOverFor == "music") {
|
||||
Log.d("AirPodsService", "Pausing music so that it doesn't play through speakers")
|
||||
MediaController.pausedForCrossDevice = true
|
||||
MediaController.sendPause(true)
|
||||
}
|
||||
|
||||
Log.d("AirPodsService", "Taking over audio")
|
||||
CrossDevice.sendRemotePacket(CrossDevicePackets.REQUEST_DISCONNECT.packet)
|
||||
Log.d("AirPodsService", macAddress)
|
||||
@@ -1810,7 +1830,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
||||
aacpManager.sendSetFeatureFlagsPacket()
|
||||
aacpManager.sendNotificationRequest()
|
||||
Log.d("AirPodsService", "Requesting proximity keys")
|
||||
aacpManager.sendRequestProximityKeys(AACPManager.Companion.ProximityKeyType.IRK.value)
|
||||
aacpManager.sendRequestProximityKeys((AACPManager.Companion.ProximityKeyType.IRK.value + AACPManager.Companion.ProximityKeyType.ENC_KEY.value).toByte())
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
aacpManager.sendPacket(aacpManager.createHandshakePacket())
|
||||
delay(200)
|
||||
@@ -1818,7 +1838,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
||||
delay(200)
|
||||
aacpManager.sendNotificationRequest()
|
||||
delay(200)
|
||||
aacpManager.sendRequestProximityKeys(AACPManager.Companion.ProximityKeyType.IRK.value)
|
||||
aacpManager.sendRequestProximityKeys((AACPManager.Companion.ProximityKeyType.IRK.value+AACPManager.Companion.ProximityKeyType.ENC_KEY.value).toByte())
|
||||
startHeadTracking()
|
||||
Handler(Looper.getMainLooper()).postDelayed({
|
||||
aacpManager.sendPacket(aacpManager.createHandshakePacket())
|
||||
|
||||
@@ -336,14 +336,16 @@ class BLEManager(private val context: Context) {
|
||||
val isLeftInEar = if (xorFactor) (status and 0x08) != 0 else (status and 0x02) != 0
|
||||
val isRightInEar = if (xorFactor) (status and 0x02) != 0 else (status and 0x08) != 0
|
||||
|
||||
val leftBatteryNibble = if (xorFactor) (podsBattery shr 4) and 0x0F else podsBattery and 0x0F
|
||||
val rightBatteryNibble = if (xorFactor) podsBattery and 0x0F else (podsBattery shr 4) and 0x0F
|
||||
val isFlipped = !primaryLeft
|
||||
|
||||
val leftBatteryNibble = if (isFlipped) (podsBattery shr 4) and 0x0F else podsBattery and 0x0F
|
||||
val rightBatteryNibble = if (isFlipped) podsBattery and 0x0F else (podsBattery shr 4) and 0x0F
|
||||
|
||||
val caseBattery = flagsCase and 0x0F
|
||||
val flags = (flagsCase shr 4) and 0x0F
|
||||
|
||||
val caseBattery = (flagsCase shr 4) and 0x0F
|
||||
val flags = flagsCase and 0x0F
|
||||
|
||||
val isRightCharging = if (xorFactor) (flags and 0x02) != 0 else (flags and 0x01) != 0
|
||||
val isLeftCharging = if (xorFactor) (flags and 0x01) != 0 else (flags and 0x02) != 0
|
||||
val isLeftCharging = if (isFlipped) (flags and 0x02) != 0 else (flags and 0x01) != 0
|
||||
val isRightCharging = if (isFlipped) (flags and 0x01) != 0 else (flags and 0x02) != 0
|
||||
val isCaseCharging = (flags and 0x04) != 0
|
||||
|
||||
val lidOpen = ((lid shr 3) and 0x01) == 0
|
||||
|
||||
@@ -88,11 +88,8 @@ object MediaController {
|
||||
userPlayedTheMedia = audioManager.isMusicActive
|
||||
}, 7) // i have no idea why android sends an event a hundred times after the user does something.
|
||||
}
|
||||
Log.d("MediaController", "pausedforcrossdevice: $pausedForCrossDevice Ear detection status: ${ServiceManager.getService()?.earDetectionNotification?.status}, music active: ${audioManager.isMusicActive} and cross device available: ${CrossDevice.isAvailable}")
|
||||
Log.d("MediaController", "pausedforcrossdevice: $pausedForCrossDevice")
|
||||
if (!pausedForCrossDevice && audioManager.isMusicActive) {
|
||||
Log.d("MediaController", "Pausing for cross device and taking over.")
|
||||
sendPause(true)
|
||||
pausedForCrossDevice = true
|
||||
ServiceManager.getService()?.takeOver("music")
|
||||
}
|
||||
}
|
||||
@@ -143,6 +140,14 @@ object MediaController {
|
||||
)
|
||||
)
|
||||
}
|
||||
if (!audioManager.isMusicActive) {
|
||||
Log.d("MediaController", "Setting iPausedTheMedia to false")
|
||||
iPausedTheMedia = false
|
||||
}
|
||||
if (pausedForCrossDevice) {
|
||||
Log.d("MediaController", "Setting pausedForCrossDevice to false")
|
||||
pausedForCrossDevice = false
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
|
||||
Reference in New Issue
Block a user