-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
fix(android): support non-rooted OnePlus 12 / OxygenOS 16 #450
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| .worktrees/ | ||
| root-module/radare2-5.9.9-android-aarch64.tar.gz | ||
| wak.toml | ||
| log.txt | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1587,6 +1587,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList | |||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| fun setBatteryMetadata() { | ||||||||||||||||||
| if (::sharedPreferences.isInitialized && sharedPreferences.getBoolean("skip_setup", false)) return | ||||||||||||||||||
| device?.let { it -> | ||||||||||||||||||
| SystemApisUtils.setMetadata( | ||||||||||||||||||
| it, | ||||||||||||||||||
|
|
@@ -2192,6 +2193,20 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList | |||||||||||||||||
| takeOver("music", manualTakeOverAfterReversed = true) | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| if (!isConnectedLocally && ::sharedPreferences.isInitialized) { | ||||||||||||||||||
| val savedMac = sharedPreferences.getString("mac_address", "") | ||||||||||||||||||
| if (!savedMac.isNullOrEmpty()) { | ||||||||||||||||||
| Log.d(TAG, "Service restarted, attempting L2CAP reconnect to $savedMac") | ||||||||||||||||||
| val bluetoothManager = getSystemService(BluetoothManager::class.java) | ||||||||||||||||||
| val bluetoothDevice = bluetoothManager?.adapter?.getRemoteDevice(savedMac) | ||||||||||||||||||
|
Comment on lines
+2198
to
+2201
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The Proposed fix val savedMac = sharedPreferences.getString("mac_address", "")
- if (!savedMac.isNullOrEmpty()) {
+ if (!savedMac.isNullOrEmpty() && BluetoothAdapter.checkBluetoothAddress(savedMac)) {📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
| if (bluetoothDevice != null) { | ||||||||||||||||||
| CoroutineScope(Dispatchers.IO).launch { | ||||||||||||||||||
| connectToSocket(bluetoothDevice) | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
Comment on lines
+2196
to
+2208
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unstructured coroutine scope risks duplicate reconnect attempts and leaked coroutines.
Consider using a service-scoped Proposed fix (sketch)Add a service-level scope and reconnect job: // Class-level fields
private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
private var reconnectJob: Job? = nullIn if (!isConnectedLocally && ::sharedPreferences.isInitialized) {
val savedMac = sharedPreferences.getString("mac_address", "")
if (!savedMac.isNullOrEmpty()) {
Log.d(TAG, "Service restarted, attempting L2CAP reconnect to $savedMac")
val bluetoothManager = getSystemService(BluetoothManager::class.java)
val bluetoothDevice = bluetoothManager?.adapter?.getRemoteDevice(savedMac)
if (bluetoothDevice != null) {
- CoroutineScope(Dispatchers.IO).launch {
+ reconnectJob?.cancel()
+ reconnectJob = serviceScope.launch {
connectToSocket(bluetoothDevice)
}
}
}
}In + serviceScope.cancel()
super.onDestroy()🤖 Prompt for AI Agents |
||||||||||||||||||
|
|
||||||||||||||||||
| return START_STICKY | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
startForegroundService()andbindService()are called on every recomposition — must be wrapped in a side-effect.These calls sit directly in the composable body without any side-effect wrapper. Composables can recompose many times (on any state change in the parent tree), so
startForegroundServiceand especiallybindServicewill fire repeatedly, leading to multiple bindings without corresponding unbinds.Wrap in
LaunchedEffect(Unit)(orDisposableEffect) so they execute only once:Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents