try to fix service, again

This commit is contained in:
Kavish Devar
2024-12-06 14:09:28 +05:30
parent 4374a81915
commit db8458be59
3 changed files with 240 additions and 198 deletions

View File

@@ -258,11 +258,8 @@ class AirPodsService: Service() {
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")
try { if (isConnected != true) {
socket.close()
} catch (e: Exception) {
e.printStackTrace()
}
try { try {
socket = HiddenApiBypass.newInstance( socket = HiddenApiBypass.newInstance(
@@ -274,8 +271,7 @@ class AirPodsService: Service() {
0x1001, 0x1001,
uuid uuid
) as BluetoothSocket ) as BluetoothSocket
} } catch (
catch (
e: Exception e: Exception
) { ) {
e.printStackTrace() e.printStackTrace()
@@ -290,8 +286,7 @@ class AirPodsService: Service() {
0x1001, 0x1001,
uuid uuid
) as BluetoothSocket ) as BluetoothSocket
} } catch (
catch (
e: Exception e: Exception
) { ) {
e.printStackTrace() e.printStackTrace()
@@ -317,7 +312,8 @@ class AirPodsService: Service() {
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
while (socket.isConnected == true) { while (socket.isConnected == true) {
socket.let { socket.let {
val audioManager = this@AirPodsService.getSystemService(AUDIO_SERVICE) as AudioManager val audioManager =
this@AirPodsService.getSystemService(AUDIO_SERVICE) as AudioManager
MediaController.initialize(audioManager) MediaController.initialize(audioManager)
val buffer = ByteArray(1024) val buffer = ByteArray(1024)
val bytesRead = it.inputStream.read(buffer) val bytesRead = it.inputStream.read(buffer)
@@ -330,8 +326,7 @@ class AirPodsService: Service() {
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) }
Log.d("AirPods Data", "Data received: $formattedHex") Log.d("AirPods Data", "Data received: $formattedHex")
} } else if (bytesRead == -1) {
else if (bytesRead == -1) {
Log.d("AirPods Service", "Socket closed (bytesRead = -1)") Log.d("AirPods Service", "Socket closed (bytesRead = -1)")
// socket.close() // socket.close()
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED)) sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED))
@@ -348,25 +343,40 @@ class AirPodsService: Service() {
bytes[1] = list[1] bytes[1] = list[1]
putExtra("data", bytes) putExtra("data", bytes)
}) })
Log.d("AirPods Parser", "Ear Detection: ${earDetectionNotification.status[0]} ${earDetectionNotification.status[1]}") Log.d(
"AirPods Parser",
"Ear Detection: ${earDetectionNotification.status[0]} ${earDetectionNotification.status[1]}"
)
var justEnabledA2dp = false var justEnabledA2dp = false
earReceiver = object : BroadcastReceiver() { earReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
val data = intent.getByteArrayExtra("data") val data = intent.getByteArrayExtra("data")
if (data != null && earDetectionEnabled) { if (data != null && earDetectionEnabled) {
inEar = if (data.find { it == 0x02.toByte() } != null || data.find { it == 0x03.toByte() } != null) { inEar =
if (data.find { it == 0x02.toByte() } != null || data.find { it == 0x03.toByte() } != null) {
data[0] == 0x00.toByte() || data[1] == 0x00.toByte() data[0] == 0x00.toByte() || data[1] == 0x00.toByte()
} else { } else {
data[0] == 0x00.toByte() && data[1] == 0x00.toByte() data[0] == 0x00.toByte() && data[1] == 0x00.toByte()
} }
val newInEarData = listOf(data[0] == 0x00.toByte(), data[1] == 0x00.toByte()) val newInEarData = listOf(
if (newInEarData.contains(true) && inEarData == listOf(false, false)) { data[0] == 0x00.toByte(),
data[1] == 0x00.toByte()
)
if (newInEarData.contains(true) && inEarData == listOf(
false,
false
)
) {
connectAudio(this@AirPodsService, device) connectAudio(this@AirPodsService, device)
justEnabledA2dp = true justEnabledA2dp = true
val bluetoothAdapter = this@AirPodsService.getSystemService(BluetoothManager::class.java).adapter val bluetoothAdapter =
this@AirPodsService.getSystemService(
BluetoothManager::class.java
).adapter
bluetoothAdapter.getProfileProxy( bluetoothAdapter.getProfileProxy(
this@AirPodsService, object : BluetoothProfile.ServiceListener { this@AirPodsService,
object : BluetoothProfile.ServiceListener {
override fun onServiceConnected( override fun onServiceConnected(
profile: Int, profile: Int,
proxy: BluetoothProfile proxy: BluetoothProfile
@@ -388,12 +398,11 @@ class AirPodsService: Service() {
profile: Int profile: Int
) { ) {
} }
} },
,BluetoothProfile.A2DP BluetoothProfile.A2DP
) )
} } else if (newInEarData == listOf(false, false)) {
else if (newInEarData == listOf(false, false)){
disconnectAudio(this@AirPodsService, device) disconnectAudio(this@AirPodsService, device)
} }
@@ -411,39 +420,56 @@ class AirPodsService: Service() {
} }
} }
val earIntentFilter = IntentFilter(AirPodsNotifications.EAR_DETECTION_DATA) val earIntentFilter =
IntentFilter(AirPodsNotifications.EAR_DETECTION_DATA)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
this@AirPodsService.registerReceiver(earReceiver, earIntentFilter, this@AirPodsService.registerReceiver(
earReceiver, earIntentFilter,
RECEIVER_EXPORTED RECEIVER_EXPORTED
) )
} else { } else {
this@AirPodsService.registerReceiver(earReceiver, earIntentFilter) this@AirPodsService.registerReceiver(
earReceiver,
earIntentFilter
)
} }
} } else if (ancNotification.isANCData(data)) {
else if (ancNotification.isANCData(data)) {
ancNotification.setStatus(data) ancNotification.setStatus(data)
sendBroadcast(Intent(AirPodsNotifications.ANC_DATA).apply { sendBroadcast(Intent(AirPodsNotifications.ANC_DATA).apply {
putExtra("data", ancNotification.status) putExtra("data", ancNotification.status)
}) })
Log.d("AirPods Parser", "ANC: ${ancNotification.status}") Log.d("AirPods Parser", "ANC: ${ancNotification.status}")
} } else if (batteryNotification.isBatteryData(data)) {
else if (batteryNotification.isBatteryData(data)) {
batteryNotification.setBattery(data) batteryNotification.setBattery(data)
sendBroadcast(Intent(AirPodsNotifications.BATTERY_DATA).apply { sendBroadcast(Intent(AirPodsNotifications.BATTERY_DATA).apply {
putParcelableArrayListExtra("data", ArrayList(batteryNotification.getBattery())) putParcelableArrayListExtra(
"data",
ArrayList(batteryNotification.getBattery())
)
}) })
updateNotificationContent(true, this@AirPodsService.getSharedPreferences("settings", MODE_PRIVATE).getString("name", device.name), batteryNotification.getBattery()) updateNotificationContent(
true,
this@AirPodsService.getSharedPreferences(
"settings",
MODE_PRIVATE
).getString("name", device.name),
batteryNotification.getBattery()
)
for (battery in batteryNotification.getBattery()) { for (battery in batteryNotification.getBattery()) {
Log.d("AirPods Parser", "${battery.getComponentName()}: ${battery.getStatusName()} at ${battery.level}% ") Log.d(
"AirPods Parser",
"${battery.getComponentName()}: ${battery.getStatusName()} at ${battery.level}% "
)
} }
if (batteryNotification.getBattery()[0].status == 1 && batteryNotification.getBattery()[1].status == 1) { if (batteryNotification.getBattery()[0].status == 1 && batteryNotification.getBattery()[1].status == 1) {
disconnectAudio(this@AirPodsService, device) disconnectAudio(this@AirPodsService, device)
} } else {
else {
connectAudio(this@AirPodsService, device) connectAudio(this@AirPodsService, device)
} }
} } else if (conversationAwarenessNotification.isConversationalAwarenessData(
else if (conversationAwarenessNotification.isConversationalAwarenessData(data)) { data
)
) {
conversationAwarenessNotification.setData(data) conversationAwarenessNotification.setData(data)
sendBroadcast(Intent(AirPodsNotifications.CA_DATA).apply { sendBroadcast(Intent(AirPodsNotifications.CA_DATA).apply {
putExtra("data", conversationAwarenessNotification.status) putExtra("data", conversationAwarenessNotification.status)
@@ -456,9 +482,12 @@ class AirPodsService: Service() {
MediaController.stopSpeaking() MediaController.stopSpeaking()
} }
Log.d("AirPods Parser", "Conversation Awareness: ${conversationAwarenessNotification.status}") Log.d(
"AirPods Parser",
"Conversation Awareness: ${conversationAwarenessNotification.status}"
)
} else {
} }
else { }
} }
} }
Log.d("AirPods Service", "Socket closed") Log.d("AirPods Service", "Socket closed")
@@ -467,12 +496,12 @@ class AirPodsService: Service() {
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED)) sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED))
} }
} }
} } catch (e: Exception) {
catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
Log.d("AirPodsService", "Failed to connect to socket") Log.d("AirPodsService", "Failed to connect to socket")
} }
} }
}
fun sendPacket(packet: String) { fun sendPacket(packet: String) {

View File

@@ -520,7 +520,7 @@ fun AirPodsSettingsScreen(dev: BluetoothDevice?, service: AirPodsService,
), ),
topBar = { topBar = {
val darkMode = MaterialTheme.colorScheme.surface.luminance() < 0.5 val darkMode = MaterialTheme.colorScheme.surface.luminance() < 0.5
val mdensity = remember { mutableFloatStateOf(1f) } val mDensity = remember { mutableFloatStateOf(1f) }
CenterAlignedTopAppBar( CenterAlignedTopAppBar(
title = { title = {
Text( Text(
@@ -530,14 +530,14 @@ fun AirPodsSettingsScreen(dev: BluetoothDevice?, service: AirPodsService,
modifier = Modifier modifier = Modifier
.hazeChild( .hazeChild(
state = hazeState, state = hazeState,
style = CupertinoMaterials.thin(), style = CupertinoMaterials.regular(),
block = { block = {
// make the background transparent when not scrolled yet // make the background transparent when not scrolled yet
alpha = if (verticalScrollState.value > 55.dp.value * mdensity.floatValue) 1f else 0f alpha = if (verticalScrollState.value > 55.dp.value * mDensity.floatValue) 1f else 0f
} }
) )
.drawBehind { .drawBehind {
mdensity.value = density mDensity.floatValue = density
val strokeWidth = 0.7.dp.value * density val strokeWidth = 0.7.dp.value * density
val y = size.height - strokeWidth / 2 val y = size.height - strokeWidth / 2
if (verticalScrollState.value > 55.dp.value * density) { if (verticalScrollState.value > 55.dp.value * density) {

View File

@@ -68,6 +68,10 @@ import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
@Composable @Composable
fun DebugScreen(navController: NavController) { fun DebugScreen(navController: NavController) {
val hazeState = remember { HazeState() } val hazeState = remember { HazeState() }
val text = remember { mutableStateListOf<String>("Log Start") }
val context = LocalContext.current
val listState = rememberLazyListState()
Scaffold( Scaffold(
topBar = { topBar = {
TopAppBar( TopAppBar(
@@ -82,7 +86,14 @@ fun DebugScreen(navController: NavController) {
modifier = Modifier modifier = Modifier
.hazeChild( .hazeChild(
state = hazeState, state = hazeState,
style = CupertinoMaterials.thin() style = CupertinoMaterials.thin(),
block = {
alpha = if (listState.firstVisibleItemIndex > 0) {
1f
} else {
0f
}
}
), ),
colors = TopAppBarDefaults.topAppBarColors( colors = TopAppBarDefaults.topAppBarColors(
containerColor = Color.Transparent containerColor = Color.Transparent
@@ -92,16 +103,11 @@ fun DebugScreen(navController: NavController) {
containerColor = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color(0xFF000000) containerColor = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color(0xFF000000)
else Color(0xFFF2F2F7), else Color(0xFFF2F2F7),
) { paddingValues -> ) { paddingValues ->
val text = remember { mutableStateListOf<String>("Log Start") }
val context = LocalContext.current
val listState = rememberLazyListState()
val receiver = object : BroadcastReceiver() { val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
val data = intent.getByteArrayExtra("data") val data = intent.getByteArrayExtra("data")
data?.let { data?.let {
text.add(">" + it.joinToString(" ") { byte -> "%02X".format(byte) }) // Use ">" for received packets text.add(">" + it.joinToString(" ") { byte -> "%02X".format(byte) })
} }
} }
} }
@@ -121,12 +127,10 @@ fun DebugScreen(navController: NavController) {
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
// .padding(paddingValues)
.imePadding() .imePadding()
.haze(hazeState) .haze(hazeState)
.padding(top = 0.dp) .padding(top = 0.dp)
) { ) {
Spacer(modifier = Modifier.height(55.dp))
LazyColumn( LazyColumn(
state = listState, state = listState,
modifier = Modifier modifier = Modifier
@@ -136,7 +140,12 @@ fun DebugScreen(navController: NavController) {
items(text.size) { index -> items(text.size) { index ->
val message = text[index] val message = text[index]
val isSent = message.startsWith(">") val isSent = message.startsWith(">")
val backgroundColor = if (isSent) Color(0xFFE1FFC7) else Color(0xFFD1D1D1) val backgroundColor =
if (isSent) Color(0xFFE1FFC7) else Color(0xFFD1D1D1)
if (message == "Log Start") {
Spacer(modifier = Modifier.height(115.dp))
}
Box( Box(
modifier = Modifier modifier = Modifier
@@ -155,11 +164,13 @@ fun DebugScreen(navController: NavController) {
} }
Text( Text(
text = if (isSent) message.substring(1) else message, // Remove the ">" from sent packets text = if (isSent) message.substring(1) else message,
fontFamily = FontFamily(Font(R.font.hack)), fontFamily = FontFamily(Font(R.font.hack)),
color = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color(0xFF000000) color = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color(
0xFF000000
)
else Color(0xFF000000), else Color(0xFF000000),
modifier = Modifier.weight(1f) // Allows text to take available space modifier = Modifier.weight(1f)
) )
if (isSent) { if (isSent) {
@@ -170,6 +181,7 @@ fun DebugScreen(navController: NavController) {
} }
} }
) )
Spacer(modifier = Modifier.height(8.dp))
val airPodsService = remember { mutableStateOf<AirPodsService?>(null) } val airPodsService = remember { mutableStateOf<AirPodsService?>(null) }
val serviceConnection = object : ServiceConnection { val serviceConnection = object : ServiceConnection {
@@ -200,13 +212,14 @@ fun DebugScreen(navController: NavController) {
label = { Text("Packet") }, label = { Text("Packet") },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 8.dp), // Padding for the input field .padding(horizontal = 8.dp)
.padding(bottom = 5.dp),
trailingIcon = { trailingIcon = {
IconButton( IconButton(
onClick = { onClick = {
airPodsService.value?.sendPacket(packet.value.text) airPodsService.value?.sendPacket(packet.value.text)
text.add(packet.value.text) // Add sent message directly without prefix text.add(packet.value.text)
packet.value = TextFieldValue("") // Clear input field after sending packet.value = TextFieldValue("")
} }
) { ) {
@Suppress("DEPRECATION") @Suppress("DEPRECATION")