Skip to content

Commit 141f1e7

Browse files
authored
android(fix): do not require phone's MAC for service start (#253)
This makes the app run without issues on OxygenOS/ColorOS16 without root. * android(fix): add missing HEAD_GESTURES capability on app2 * android(fix): catch att initial read exceptions in toggle * android(refactor): remove navcontroller from head gestures screen * android(fix): do not crash when connected devices list is sent empty had never seen this before, this was the first time airpods saying zero connected devices * android(fix): do not crash if phone's MAC not available also removed crossdevice code * android: skip sdp hook check if setup skipped
1 parent 1dbb36a commit 141f1e7

File tree

7 files changed

+110
-61
lines changed

7 files changed

+110
-61
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ fun Main() {
381381
TroubleshootingScreen(navController)
382382
}
383383
composable("head_tracking") {
384-
HeadTrackingScreen(navController)
384+
HeadTrackingScreen()
385385
}
386386
composable("onboarding") {
387387
Onboarding(navController, context)

android/app/src/main/java/me/kavishdevar/librepods/composables/StyledToggle.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,12 @@ fun StyledToggle(
472472
val attManager = ServiceManager.getService()?.attManager ?: return
473473
val isDarkTheme = isSystemInDarkTheme()
474474
val textColor = if (isDarkTheme) Color.White else Color.Black
475-
val checkedValue = attManager.read(attHandle).getOrNull(0)?.toInt()
475+
val checkedValue = try {
476+
attManager.read(attHandle).getOrNull(0)?.toInt()
477+
} catch (e: Exception) {
478+
Log.w("StyledToggle", "Error reading initial value for $label: ${e.message}")
479+
null
480+
} ?: 0
476481
var checked by remember { mutableStateOf(checkedValue !=0) }
477482
var backgroundColor by remember { mutableStateOf(if (isDarkTheme) Color(0xFF1C1C1E) else Color(0xFFFFFFFF)) }
478483
val animatedBackgroundColor by animateColorAsState(targetValue = backgroundColor, animationSpec = tween(durationMillis = 500))

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
*/
1818

19+
20+
// this is absolutely unnecessary, why did I make this. a simple toggle would've sufficed
21+
1922
@file:OptIn(ExperimentalEncodingApi::class)
2023

2124
package me.kavishdevar.librepods.screens
@@ -83,7 +86,6 @@ import androidx.compose.ui.text.style.TextAlign
8386
import androidx.compose.ui.tooling.preview.Preview
8487
import androidx.compose.ui.unit.dp
8588
import androidx.compose.ui.unit.sp
86-
import androidx.navigation.NavController
8789
import com.kyant.backdrop.backdrops.layerBackdrop
8890
import com.kyant.backdrop.backdrops.rememberLayerBackdrop
8991
import dev.chrisbanes.haze.hazeSource
@@ -108,7 +110,7 @@ import kotlin.random.Random
108110
@RequiresApi(Build.VERSION_CODES.Q)
109111
@OptIn(ExperimentalMaterial3Api::class, ExperimentalAnimationApi::class)
110112
@Composable
111-
fun HeadTrackingScreen(navController: NavController) {
113+
fun HeadTrackingScreen() {
112114
DisposableEffect(Unit) {
113115
ServiceManager.getService()?.startHeadTracking()
114116
onDispose {
@@ -743,5 +745,5 @@ private fun AccelerationPlot() {
743745
@Preview
744746
@Composable
745747
fun HeadTrackingScreenPreview() {
746-
HeadTrackingScreen(navController = NavController(LocalContext.current))
748+
HeadTrackingScreen()
747749
}

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

Lines changed: 84 additions & 50 deletions
Large diffs are not rendered by default.

android/app/src/main/java/me/kavishdevar/librepods/utils/AACPManager.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ class AACPManager {
596596
eqData = FloatArray(8) { i -> eq1.get(i) }
597597
Log.d(TAG, "EQ Data set to: ${eqData.toList()}, eqOnPhone: $eqOnPhone, eqOnMedia: $eqOnMedia")
598598
}
599-
599+
600600
Opcodes.INFORMATION -> {
601601
Log.e(TAG, "Parsing Information Packet")
602602
val information = parseInformationPacket(packet)
@@ -1201,7 +1201,8 @@ class AACPManager {
12011201
var offset = 9
12021202
for (i in 0 until deviceCount) {
12031203
if (offset + 8 > data.size) {
1204-
throw IllegalArgumentException("Data array too short to parse all connected devices")
1204+
Log.w(TAG, "Data array too short to parse all connected devices, returning what we have")
1205+
break
12051206
}
12061207
val macBytes = data.sliceArray(offset until offset + 6)
12071208
val mac = macBytes.joinToString(":") { "%02X".format(it) }

android/app/src/main/java/me/kavishdevar/librepods/utils/AirPods.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ class AirPodsPro2Lightning: AirPodsBase(
149149
Capability.HEARING_AID,
150150
Capability.ADAPTIVE_AUDIO,
151151
Capability.ADAPTIVE_VOLUME,
152-
Capability.SWIPE_FOR_VOLUME
152+
Capability.SWIPE_FOR_VOLUME,
153+
Capability.HEAD_GESTURES
153154
)
154155
)
155156

@@ -171,7 +172,8 @@ class AirPodsPro2USBC: AirPodsBase(
171172
Capability.HEARING_AID,
172173
Capability.ADAPTIVE_AUDIO,
173174
Capability.ADAPTIVE_VOLUME,
174-
Capability.SWIPE_FOR_VOLUME
175+
Capability.SWIPE_FOR_VOLUME,
176+
Capability.HEAD_GESTURES
175177
)
176178
)
177179

@@ -230,4 +232,4 @@ object AirPodsModels {
230232
fun getModelByModelNumber(modelNumber: String): AirPodsBase? {
231233
return models.find { modelNumber in it.modelNumber }
232234
}
233-
}
235+
}

android/app/src/main/java/me/kavishdevar/librepods/utils/RadareOffsetFinder.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ class RadareOffsetFinder(context: Context) {
115115
}
116116

117117
fun isSdpOffsetAvailable(): Boolean {
118+
val sharedPreferences = ServiceManager.getService()?.applicationContext?.getSharedPreferences("settings", Context.MODE_PRIVATE) // ik not good practice- too lazy
119+
if (sharedPreferences?.getBoolean("skip_setup", false) == true) {
120+
Log.d(TAG, "Setup skipped, returning true for SDP offset.")
121+
return true
122+
}
118123
try {
119124
val process = Runtime.getRuntime().exec(arrayOf("/system/bin/getprop", SDP_OFFSET_PROP))
120125
val reader = BufferedReader(InputStreamReader(process.inputStream))
@@ -462,7 +467,7 @@ class RadareOffsetFinder(context: Context) {
462467
// findAndSaveL2cuProcessCfgReqOffset(libraryPath, envSetup)
463468
// findAndSaveL2cCsmConfigOffset(libraryPath, envSetup)
464469
// findAndSaveL2cuSendPeerInfoReqOffset(libraryPath, envSetup)
465-
470+
466471
// findAndSaveSdpOffset(libraryPath, envSetup) Should not be run by default, only when user asks for it.
467472

468473
} catch (e: Exception) {

0 commit comments

Comments
 (0)