Skip to content

Commit 58dfed9

Browse files
committed
android: fix the xposed module
skip unecessary parsing the argument for debugging, just return true and hope that it works
1 parent 91675de commit 58dfed9

File tree

15 files changed

+406
-53
lines changed

15 files changed

+406
-53
lines changed

android/app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ android {
1313
applicationId = "me.kavishdevar.librepods"
1414
minSdk = 28
1515
targetSdk = 35
16-
versionCode = 4
17-
versionName = "0.1.0"
16+
versionCode = 5
17+
versionName = "0.1.0-rc.2"
1818
}
1919

2020
buildTypes {

android/app/src/main/AndroidManifest.xml

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3-
xmlns:tools="http://schemas.android.com/tools">
3+
xmlns:tools="http://schemas.android.com/tools"
4+
android:sharedUserId="android.uid.system"
5+
android:sharedUserMaxSdkVersion="32"
6+
tools:targetApi="33">
7+
8+
<uses-feature
9+
android:name="android.hardware.telephony"
10+
android:required="false" />
411

512
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
613
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
714
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
815
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"
916
tools:ignore="ProtectedPermissions" />
17+
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
1018
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
1119
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
1220
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
1321
<uses-permission
1422
android:name="android.permission.BLUETOOTH_PRIVILEGED"
1523
tools:ignore="ProtectedPermissions" />
16-
<uses-permission
17-
android:name="android.permission.BATTERY_STATS"
18-
tools:ignore="ProtectedPermissions" />
19-
<uses-permission
20-
android:name="android.permission.UPDATE_DEVICE_STATS"
21-
tools:ignore="ProtectedPermissions" />
2224
<uses-permission android:name="android.permission.BLUETOOTH" />
2325
<uses-permission
2426
android:name="android.permission.BLUETOOTH_SCAN"
@@ -30,6 +32,8 @@
3032
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
3133
<uses-permission android:name="android.permission.INTERNET" />
3234

35+
<protected-broadcast android:name="batterywidget.impl.action.update_bluetooth_data" />
36+
3337
<application
3438
android:allowBackup="true"
3539
android:dataExtractionRules="@xml/data_extraction_rules"

android/app/src/main/cpp/l2c_fcr_hook.cpp

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@
3232
static HookFunType hook_func = nullptr;
3333
#define L2CEVT_L2CAP_CONFIG_REQ 4
3434
#define L2CEVT_L2CAP_CONFIG_RSP 15
35-
// Define all necessary structures for the L2CAP stack
3635

37-
// Forward declarations for types needed by the new hook
3836
struct t_l2c_lcb;
3937
typedef struct _BT_HDR {
4038
uint16_t event;
@@ -44,7 +42,6 @@ typedef struct _BT_HDR {
4442
uint8_t data[];
4543
} BT_HDR;
4644

47-
// Define base FCR structures
4845
typedef struct {
4946
uint8_t mode;
5047
uint8_t tx_win_sz;
@@ -130,17 +127,7 @@ static void (*original_l2c_csm_config)(tL2C_CCB* p_ccb, uint8_t event, void* p_d
130127
static void (*original_l2cu_send_peer_info_req)(tL2C_LCB* p_lcb, uint16_t info_type) = nullptr;
131128

132129
uint8_t fake_l2c_fcr_chk_chan_modes(void* p_ccb) {
133-
LOGI("l2c_fcr_chk_chan_modes hooked");
134-
auto* ccb = static_cast<tL2C_CCB*>(p_ccb);
135-
LOGI("Original FCR mode: 0x%02x", ccb->our_cfg.fcr.mode);
136-
137-
ccb->our_cfg.fcr.mode = 0;
138-
ccb->our_cfg.fcr_present = true;
139-
ccb->peer_cfg.fcr.mode = 0;
140-
ccb->peer_cfg.fcr_present = true;
141-
142-
LOGI("FCR mode set to Basic Mode (0) for both local and peer config, here's the new desired FCR mode: 0x%02x, and the peer's FCR mode: 0x%02x", ccb->our_cfg.fcr.mode, ccb->peer_cfg.fcr.mode);
143-
130+
LOGI("l2c_fcr_chk_chan_modes hooked, returning true.");
144131
return 1;
145132
}
146133

android/app/src/main/java/me/kavishdevar/librepods/MainActivity.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ fun Main() {
186186
permissions = listOf(
187187
"android.permission.BLUETOOTH_CONNECT",
188188
"android.permission.BLUETOOTH_SCAN",
189+
"android.permission.BLUETOOTH",
190+
"android.permission.BLUETOOTH_ADMIN",
189191
"android.permission.BLUETOOTH_ADVERTISE",
190192
"android.permission.POST_NOTIFICATIONS",
191193
"android.permission.READ_PHONE_STATE",
@@ -517,16 +519,16 @@ fun PermissionsScreen(
517519
),
518520
)
519521
}
520-
522+
521523
if (!canDrawOverlays && basicPermissionsGranted) {
522524
Spacer(modifier = Modifier.height(12.dp))
523-
525+
524526
Button(
525527
onClick = {
526528
val editor = context.getSharedPreferences("settings", MODE_PRIVATE).edit()
527529
editor.putBoolean("overlay_permission_skipped", true)
528530
editor.apply()
529-
531+
530532
val intent = Intent(context, MainActivity::class.java)
531533
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
532534
context.startActivity(intent)

android/app/src/main/java/me/kavishdevar/librepods/screens/AppSettingsScreen.kt

Lines changed: 82 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ import androidx.compose.ui.text.TextStyle
7171
import androidx.compose.ui.text.font.Font
7272
import androidx.compose.ui.text.font.FontFamily
7373
import androidx.compose.ui.text.font.FontWeight
74+
import androidx.compose.ui.text.style.TextOverflow
7475
import androidx.compose.ui.unit.dp
7576
import androidx.compose.ui.unit.sp
7677
import androidx.navigation.NavController
@@ -106,6 +107,7 @@ fun AppSettingsScreen(navController: NavController) {
106107
navController.popBackStack()
107108
},
108109
shape = RoundedCornerShape(8.dp),
110+
modifier = Modifier.width(180.dp)
109111
) {
110112
Icon(
111113
Icons.AutoMirrored.Filled.KeyboardArrowLeft,
@@ -121,6 +123,9 @@ fun AppSettingsScreen(navController: NavController) {
121123
color = if (isDarkTheme) Color(0xFF007AFF) else Color(0xFF3C6DF5),
122124
fontFamily = FontFamily(Font(R.font.sf_pro))
123125
),
126+
maxLines = 1,
127+
overflow = TextOverflow.Ellipsis,
128+
modifier = Modifier.weight(1f)
124129
)
125130
}
126131
},
@@ -142,10 +147,22 @@ fun AppSettingsScreen(navController: NavController) {
142147

143148
val backgroundColor = if (isDarkTheme) Color(0xFF1C1C1E) else Color(0xFFFFFFFF)
144149
val textColor = if (isDarkTheme) Color.White else Color.Black
145-
val accentColor = if (isDarkTheme) Color(0xFF007AFF) else Color(0xFF3C6DF5)
146150

147151
IndependentToggle("Show phone battery in widget", ServiceManager.getService()!!, "setPhoneBatteryInWidget", sharedPreferences)
148152

153+
Text(
154+
text = stringResource(R.string.conversational_awareness_customization).uppercase(),
155+
style = TextStyle(
156+
fontSize = 14.sp,
157+
fontWeight = FontWeight.Light,
158+
color = (if (isSystemInDarkTheme()) Color.White else Color.Black).copy(alpha = 0.6f),
159+
fontFamily = FontFamily(Font(R.font.sf_pro))
160+
),
161+
modifier = Modifier.padding(8.dp, bottom = 2.dp)
162+
)
163+
164+
Spacer(modifier = Modifier.height(2.dp))
165+
149166
Column (
150167
modifier = Modifier
151168
.fillMaxWidth()
@@ -170,17 +187,6 @@ fun AppSettingsScreen(navController: NavController) {
170187
val thumbColor = if (isDarkTheme) Color(0xFFFFFFFF) else Color(0xFFFFFFFF)
171188
val labelTextColor = if (isDarkTheme) Color.White else Color.Black
172189

173-
Text(
174-
text = stringResource(R.string.conversational_awareness_customization),
175-
style = TextStyle(
176-
fontSize = 20.sp,
177-
color = textColor
178-
),
179-
modifier = Modifier
180-
.padding(top = 12.dp, bottom = 4.dp)
181-
)
182-
183-
184190
var conversationalAwarenessPauseMusicEnabled by remember {
185191
mutableStateOf(
186192
sharedPreferences.getBoolean("conversational_awareness_pause_music", true)
@@ -367,6 +373,70 @@ fun AppSettingsScreen(navController: NavController) {
367373

368374
Spacer(modifier = Modifier.height(24.dp))
369375

376+
Column(
377+
modifier = Modifier
378+
.fillMaxWidth()
379+
.background(
380+
backgroundColor,
381+
RoundedCornerShape(14.dp)
382+
)
383+
.padding(horizontal = 16.dp, vertical = 8.dp)
384+
) {
385+
var openDialogForControlling by remember {
386+
mutableStateOf(
387+
sharedPreferences.getString("qs_click_behavior", "dialog") == "dialog"
388+
)
389+
}
390+
391+
fun updateQsClickBehavior(enabled: Boolean) {
392+
openDialogForControlling = enabled
393+
sharedPreferences.edit().putString("qs_click_behavior", if (enabled) "dialog" else "cycle").apply()
394+
}
395+
396+
Row(
397+
modifier = Modifier
398+
.fillMaxWidth()
399+
.clickable(
400+
indication = null,
401+
interactionSource = remember { MutableInteractionSource() }
402+
) {
403+
updateQsClickBehavior(!openDialogForControlling)
404+
},
405+
verticalAlignment = Alignment.CenterVertically
406+
) {
407+
Column(
408+
modifier = Modifier
409+
.weight(1f)
410+
.padding(vertical = 16.dp)
411+
.padding(end = 4.dp)
412+
) {
413+
Text(
414+
text = "Open dialog for controlling",
415+
fontSize = 16.sp,
416+
color = textColor
417+
)
418+
Spacer(modifier = Modifier.height(4.dp))
419+
Text(
420+
text = if (openDialogForControlling)
421+
"If disabled, clicking on the QS will cycle through modes"
422+
else "If enabled, it will show a dialog for controlling noise control mode and conversational awareness",
423+
fontSize = 14.sp,
424+
color = textColor.copy(0.6f),
425+
lineHeight = 16.sp,
426+
)
427+
}
428+
429+
StyledSwitch(
430+
checked = openDialogForControlling,
431+
onCheckedChange = {
432+
updateQsClickBehavior(it)
433+
}
434+
)
435+
}
436+
}
437+
438+
Spacer(modifier = Modifier.height(24.dp))
439+
370440
Button(
371441
onClick = { showResetDialog = true },
372442
modifier = Modifier

android/app/src/main/java/me/kavishdevar/librepods/screens/HeadTrackingScreen.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import androidx.compose.foundation.layout.fillMaxSize
3939
import androidx.compose.foundation.layout.fillMaxWidth
4040
import androidx.compose.foundation.layout.height
4141
import androidx.compose.foundation.layout.padding
42+
import androidx.compose.foundation.layout.width
4243
import androidx.compose.foundation.shape.RoundedCornerShape
4344
import androidx.compose.material.icons.Icons
4445
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
@@ -92,6 +93,7 @@ import androidx.compose.ui.text.font.FontFamily
9293
import androidx.compose.ui.text.font.FontWeight
9394
import androidx.compose.ui.text.rememberTextMeasurer
9495
import androidx.compose.ui.text.style.TextAlign
96+
import androidx.compose.ui.text.style.TextOverflow
9597
import androidx.compose.ui.tooling.preview.Preview
9698
import androidx.compose.ui.unit.dp
9799
import androidx.compose.ui.unit.sp
@@ -138,6 +140,7 @@ fun HeadTrackingScreen(navController: NavController) {
138140
if (ServiceManager.getService()?.isHeadTrackingActive == true) ServiceManager.getService()?.stopHeadTracking()
139141
},
140142
shape = RoundedCornerShape(8.dp),
143+
modifier = Modifier.width(180.dp)
141144
) {
142145
Icon(
143146
Icons.AutoMirrored.Filled.KeyboardArrowLeft,
@@ -153,6 +156,9 @@ fun HeadTrackingScreen(navController: NavController) {
153156
color = if (isDarkTheme) Color(0xFF007AFF) else Color(0xFF3C6DF5),
154157
fontFamily = FontFamily(Font(R.font.sf_pro))
155158
),
159+
maxLines = 1,
160+
overflow = TextOverflow.Ellipsis,
161+
modifier = Modifier.weight(1f)
156162
)
157163
}
158164
},

android/app/src/main/java/me/kavishdevar/librepods/services/AirPodsQSService.kt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import android.service.quicksettings.Tile
3131
import android.service.quicksettings.TileService
3232
import android.util.Log
3333
import androidx.annotation.RequiresApi
34+
import androidx.compose.material3.ExperimentalMaterial3Api
35+
import me.kavishdevar.librepods.MainActivity
3436
import me.kavishdevar.librepods.QuickSettingsDialogActivity
3537
import me.kavishdevar.librepods.R
3638
import me.kavishdevar.librepods.utils.AirPodsNotifications
@@ -260,4 +262,42 @@ class AirPodsQSService : TileService() {
260262
else -> R.drawable.airpods
261263
}
262264
}
265+
266+
@ExperimentalMaterial3Api
267+
override fun onTileAdded() {
268+
super.onTileAdded()
269+
Log.d("AirPodsQSService", "Tile added")
270+
271+
val intent = Intent(this, MainActivity::class.java).apply {
272+
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
273+
}
274+
}
275+
276+
@ExperimentalMaterial3Api
277+
fun openMainActivity() {
278+
Log.d("AirPodsQSService", "Opening MainActivity")
279+
280+
try {
281+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
282+
val pendingIntent = PendingIntent.getActivity(
283+
this,
284+
0,
285+
Intent(this, MainActivity::class.java).apply {
286+
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
287+
},
288+
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
289+
)
290+
startActivityAndCollapse(pendingIntent)
291+
} else {
292+
@Suppress("DEPRECATION")
293+
val intent = Intent(this, MainActivity::class.java).apply {
294+
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
295+
}
296+
startActivityAndCollapse(intent)
297+
}
298+
Log.d("AirPodsQSService", "Called startActivityAndCollapse for MainActivity")
299+
} catch (e: Exception) {
300+
Log.e("AirPodsQSService", "Error launching MainActivity: $e")
301+
}
302+
}
263303
}

0 commit comments

Comments
 (0)