mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-04-07 21:50:11 +00:00
add A16QPR3 constructor
it's almost as if google is doing this deliberately doing this
This commit is contained in:
@@ -29,6 +29,7 @@ import android.app.NotificationManager
|
|||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.AppWidgetManager
|
||||||
|
import android.bluetooth.BluetoothAdapter
|
||||||
import android.bluetooth.BluetoothDevice
|
import android.bluetooth.BluetoothDevice
|
||||||
import android.bluetooth.BluetoothHeadset
|
import android.bluetooth.BluetoothHeadset
|
||||||
import android.bluetooth.BluetoothManager
|
import android.bluetooth.BluetoothManager
|
||||||
@@ -252,9 +253,10 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
if (device.connectionState == "Disconnected" && !config.bleOnlyMode) {
|
if (device.connectionState == "Disconnected" && !config.bleOnlyMode) {
|
||||||
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 bluetoothDevice = bluetoothManager.adapter.getRemoteDevice(sharedPreferences.getString(
|
val bluetoothAdapter = bluetoothManager.adapter
|
||||||
|
val bluetoothDevice = bluetoothAdapter.getRemoteDevice(sharedPreferences.getString(
|
||||||
"mac_address", "") ?: "")
|
"mac_address", "") ?: "")
|
||||||
connectToSocket(bluetoothDevice)
|
connectToSocket(bluetoothAdapter, bluetoothDevice)
|
||||||
}
|
}
|
||||||
Log.d(TAG, "Device status changed")
|
Log.d(TAG, "Device status changed")
|
||||||
if (isConnectedLocally) return
|
if (isConnectedLocally) return
|
||||||
@@ -607,7 +609,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
// if ((CrossDevice.isAvailable && !isConnectedLocally && earDetectionNotification.status.contains(0x00)) || leAvailableForAudio) CoroutineScope(
|
// if ((CrossDevice.isAvailable && !isConnectedLocally && earDetectionNotification.status.contains(0x00)) || leAvailableForAudio) CoroutineScope(
|
||||||
if (leAvailableForAudio) CoroutineScope(
|
if (leAvailableForAudio) CoroutineScope(
|
||||||
Dispatchers.IO).launch {
|
Dispatchers.IO).launch {
|
||||||
takeOver("call")
|
takeOver("call")
|
||||||
}
|
}
|
||||||
isInCall = true
|
isInCall = true
|
||||||
}
|
}
|
||||||
@@ -665,17 +667,18 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
|
|
||||||
// Log.d("AirPodsCrossDevice", CrossDevice.isAvailable.toString())
|
// Log.d("AirPodsCrossDevice", CrossDevice.isAvailable.toString())
|
||||||
// if (!CrossDevice.isAvailable) {
|
// if (!CrossDevice.isAvailable) {
|
||||||
Log.d(TAG, "${config.deviceName} connected")
|
Log.d(TAG, "${config.deviceName} connected")
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
connectToSocket(device!!)
|
val bluetoothManager = getSystemService(BluetoothManager::class.java)
|
||||||
}
|
connectToSocket(bluetoothManager.adapter, device!!)
|
||||||
Log.d(TAG, "Setting metadata")
|
}
|
||||||
setMetadatas(device!!)
|
Log.d(TAG, "Setting metadata")
|
||||||
isConnectedLocally = true
|
setMetadatas(device!!)
|
||||||
macAddress = device!!.address
|
isConnectedLocally = true
|
||||||
sharedPreferences.edit {
|
macAddress = device!!.address
|
||||||
putString("mac_address", macAddress)
|
sharedPreferences.edit {
|
||||||
}
|
putString("mac_address", macAddress)
|
||||||
|
}
|
||||||
// }
|
// }
|
||||||
|
|
||||||
} else if (intent?.action == AirPodsNotifications.AIRPODS_DISCONNECTED) {
|
} else if (intent?.action == AirPodsNotifications.AIRPODS_DISCONNECTED) {
|
||||||
@@ -688,7 +691,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val showIslandReceiver = object: BroadcastReceiver() {
|
val showIslandReceiver = object: BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context?, intent: Intent?) {
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
if (intent?.action == "me.kavishdevar.librepods.cross_device_island") {
|
if (intent?.action == "me.kavishdevar.librepods.cross_device_island") {
|
||||||
showIsland(this@AirPodsService, batteryNotification.getBattery().find { it.component == BatteryComponent.LEFT}?.level!!.coerceAtMost(batteryNotification.getBattery().find { it.component == BatteryComponent.RIGHT}?.level!!))
|
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
|
|||||||
val connectedDevices = proxy.connectedDevices
|
val connectedDevices = proxy.connectedDevices
|
||||||
if (connectedDevices.isNotEmpty()) {
|
if (connectedDevices.isNotEmpty()) {
|
||||||
// if (!CrossDevice.isAvailable) {
|
// if (!CrossDevice.isAvailable) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
connectToSocket(device)
|
connectToSocket(bluetoothAdapter, device)
|
||||||
}
|
}
|
||||||
setMetadatas(device)
|
setMetadatas(device)
|
||||||
macAddress = device.address
|
macAddress = device.address
|
||||||
sharedPreferences.edit {
|
sharedPreferences.edit {
|
||||||
putString("mac_address", macAddress)
|
putString("mac_address", macAddress)
|
||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
this@AirPodsService.sendBroadcast(
|
this@AirPodsService.sendBroadcast(
|
||||||
Intent(AirPodsNotifications.AIRPODS_CONNECTED)
|
Intent(AirPodsNotifications.AIRPODS_CONNECTED)
|
||||||
@@ -1555,7 +1558,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
.setContentText("Unable to connect to AirPods over L2CAP")
|
.setContentText("Unable to connect to AirPods over L2CAP")
|
||||||
.setStyle(NotificationCompat.BigTextStyle()
|
.setStyle(NotificationCompat.BigTextStyle()
|
||||||
.bigText("Your AirPods are connected via Bluetooth, but LibrePods couldn't connect to AirPods using L2CAP. " +
|
.bigText("Your AirPods are connected via Bluetooth, but LibrePods couldn't connect to AirPods using L2CAP. " +
|
||||||
"Error: $errorMessage"))
|
"Error: $errorMessage"))
|
||||||
.setContentIntent(pendingIntent)
|
.setContentIntent(pendingIntent)
|
||||||
.setCategory(Notification.CATEGORY_ERROR)
|
.setCategory(Notification.CATEGORY_ERROR)
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
@@ -2085,56 +2088,56 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
device.METADATA_MAIN_ICON,
|
device.METADATA_MAIN_ICON,
|
||||||
resToUri(instance.model.budCaseRes).toString().toByteArray()
|
resToUri(instance.model.budCaseRes).toString().toByteArray()
|
||||||
) &&
|
) &&
|
||||||
SystemApisUtils.setMetadata(
|
SystemApisUtils.setMetadata(
|
||||||
device,
|
device,
|
||||||
device.METADATA_MODEL_NAME,
|
device.METADATA_MODEL_NAME,
|
||||||
instance.model.name.toByteArray()
|
instance.model.name.toByteArray()
|
||||||
) &&
|
) &&
|
||||||
SystemApisUtils.setMetadata(
|
SystemApisUtils.setMetadata(
|
||||||
device,
|
device,
|
||||||
device.METADATA_DEVICE_TYPE,
|
device.METADATA_DEVICE_TYPE,
|
||||||
device.DEVICE_TYPE_UNTETHERED_HEADSET.toByteArray()
|
device.DEVICE_TYPE_UNTETHERED_HEADSET.toByteArray()
|
||||||
) &&
|
) &&
|
||||||
SystemApisUtils.setMetadata(
|
SystemApisUtils.setMetadata(
|
||||||
device,
|
device,
|
||||||
device.METADATA_UNTETHERED_CASE_ICON,
|
device.METADATA_UNTETHERED_CASE_ICON,
|
||||||
resToUri(instance.model.caseRes).toString().toByteArray()
|
resToUri(instance.model.caseRes).toString().toByteArray()
|
||||||
) &&
|
) &&
|
||||||
SystemApisUtils.setMetadata(
|
SystemApisUtils.setMetadata(
|
||||||
device,
|
device,
|
||||||
device.METADATA_UNTETHERED_RIGHT_ICON,
|
device.METADATA_UNTETHERED_RIGHT_ICON,
|
||||||
resToUri(instance.model.rightBudsRes).toString().toByteArray()
|
resToUri(instance.model.rightBudsRes).toString().toByteArray()
|
||||||
) &&
|
) &&
|
||||||
SystemApisUtils.setMetadata(
|
SystemApisUtils.setMetadata(
|
||||||
device,
|
device,
|
||||||
device.METADATA_UNTETHERED_LEFT_ICON,
|
device.METADATA_UNTETHERED_LEFT_ICON,
|
||||||
resToUri(instance.model.leftBudsRes).toString().toByteArray()
|
resToUri(instance.model.leftBudsRes).toString().toByteArray()
|
||||||
) &&
|
) &&
|
||||||
SystemApisUtils.setMetadata(
|
SystemApisUtils.setMetadata(
|
||||||
device,
|
device,
|
||||||
device.METADATA_MANUFACTURER_NAME,
|
device.METADATA_MANUFACTURER_NAME,
|
||||||
instance.model.manufacturer.toByteArray()
|
instance.model.manufacturer.toByteArray()
|
||||||
) &&
|
) &&
|
||||||
SystemApisUtils.setMetadata(
|
SystemApisUtils.setMetadata(
|
||||||
device,
|
device,
|
||||||
device.METADATA_COMPANION_APP,
|
device.METADATA_COMPANION_APP,
|
||||||
"me.kavishdevar.librepods".toByteArray()
|
"me.kavishdevar.librepods".toByteArray()
|
||||||
) &&
|
) &&
|
||||||
SystemApisUtils.setMetadata(
|
SystemApisUtils.setMetadata(
|
||||||
device,
|
device,
|
||||||
device.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD,
|
device.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD,
|
||||||
"20".toByteArray()
|
"20".toByteArray()
|
||||||
) &&
|
) &&
|
||||||
SystemApisUtils.setMetadata(
|
SystemApisUtils.setMetadata(
|
||||||
device,
|
device,
|
||||||
device.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD,
|
device.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD,
|
||||||
"20".toByteArray()
|
"20".toByteArray()
|
||||||
) &&
|
) &&
|
||||||
SystemApisUtils.setMetadata(
|
SystemApisUtils.setMetadata(
|
||||||
device,
|
device,
|
||||||
device.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD,
|
device.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD,
|
||||||
"20".toByteArray()
|
"20".toByteArray()
|
||||||
)
|
)
|
||||||
Log.d(TAG, "Metadata set: $metadataSet")
|
Log.d(TAG, "Metadata set: $metadataSet")
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "AirPods instance is not of type AirPodsInstance, skipping metadata setting")
|
Log.w(TAG, "AirPods instance is not of type AirPodsInstance, skipping metadata setting")
|
||||||
@@ -2325,7 +2328,9 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
Log.d(TAG, macAddress)
|
Log.d(TAG, macAddress)
|
||||||
|
|
||||||
// sharedPreferences.edit { putBoolean("CrossDeviceIsAvailable", false) }
|
// sharedPreferences.edit { putBoolean("CrossDeviceIsAvailable", false) }
|
||||||
device = getSystemService(BluetoothManager::class.java).adapter.bondedDevices.find {
|
val bluetoothManager = getSystemService(BluetoothManager::class.java)
|
||||||
|
val bluetoothAdapter = bluetoothManager.adapter
|
||||||
|
device = bluetoothAdapter.bondedDevices.find {
|
||||||
it.address == macAddress
|
it.address == macAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2341,7 +2346,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
// Set a temporary connecting state
|
// Set a temporary connecting state
|
||||||
isConnectedLocally = false // Keep as false since we're not actually connecting to L2CAP
|
isConnectedLocally = false // Keep as false since we're not actually connecting to L2CAP
|
||||||
} else {
|
} else {
|
||||||
connectToSocket(device!!)
|
connectToSocket(bluetoothAdapter, device!!)
|
||||||
connectAudio(this, device)
|
connectAudio(this, device)
|
||||||
isConnectedLocally = true
|
isConnectedLocally = true
|
||||||
}
|
}
|
||||||
@@ -2352,9 +2357,10 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
// CrossDevice.isAvailable = false
|
// CrossDevice.isAvailable = false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createBluetoothSocket(device: BluetoothDevice, uuid: ParcelUuid): BluetoothSocket {
|
private fun createBluetoothSocket(adapter: BluetoothAdapter, device: BluetoothDevice, uuid: ParcelUuid): BluetoothSocket {
|
||||||
val type = 3 // L2CAP
|
val type = 3 // L2CAP
|
||||||
val constructorSpecs = listOf(
|
val constructorSpecs = listOf(
|
||||||
|
arrayOf(adapter, device, type, true, true, 0x1001, uuid), // A16QPR3
|
||||||
arrayOf(device, type, true, true, 0x1001, uuid),
|
arrayOf(device, type, true, true, 0x1001, uuid),
|
||||||
arrayOf(device, type, 1, true, true, 0x1001, uuid),
|
arrayOf(device, type, 1, true, true, 0x1001, uuid),
|
||||||
arrayOf(type, 1, true, true, device, 0x1001, uuid),
|
arrayOf(type, 1, true, true, device, 0x1001, uuid),
|
||||||
@@ -2390,13 +2396,13 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("MissingPermission", "UnspecifiedRegisterReceiverFlag")
|
@SuppressLint("MissingPermission", "UnspecifiedRegisterReceiverFlag")
|
||||||
fun connectToSocket(device: BluetoothDevice, manual: Boolean = false) {
|
fun connectToSocket(adapter: BluetoothAdapter, device: BluetoothDevice, manual: Boolean = false) {
|
||||||
Log.d(TAG, "<LogCollector:Start> Connecting to socket")
|
Log.d(TAG, "<LogCollector:Start> Connecting to socket")
|
||||||
HiddenApiBypass.addHiddenApiExemptions("Landroid/bluetooth/BluetoothSocket;")
|
HiddenApiBypass.addHiddenApiExemptions("Landroid/bluetooth/BluetoothSocket;")
|
||||||
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 {
|
socket = try {
|
||||||
createBluetoothSocket(device, uuid)
|
createBluetoothSocket(adapter, device, uuid)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Failed to create BluetoothSocket: ${e.message}")
|
Log.e(TAG, "Failed to create BluetoothSocket: ${e.message}")
|
||||||
showSocketConnectionFailureNotification("Failed to create Bluetooth socket: ${e.localizedMessage}")
|
showSocketConnectionFailureNotification("Failed to create Bluetooth socket: ${e.localizedMessage}")
|
||||||
@@ -2812,7 +2818,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
}
|
}
|
||||||
if (device != null) {
|
if (device != null) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
connectToSocket(device!!, manual = true)
|
connectToSocket(bluetoothAdapter, device!!, manual = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user