Skip to content

Odin 2 mini support - #23

Open
iloveswiming909 wants to merge 96 commits into
AurelioB:mainfrom
iloveswiming909:jdwp_only
Open

Odin 2 mini support#23
iloveswiming909 wants to merge 96 commits into
AurelioB:mainfrom
iloveswiming909:jdwp_only

Conversation

@iloveswiming909

Copy link
Copy Markdown

I managed to find a workaround for the odin 2 mini No privledged execution method bug and have confirmed it works through testing it with another odin 2 mini owners device. Fair disclosure, this has been made with heavy use of Cluade Opus 4.8 and 5. Im very new to coding so this wouldnt be possible without it. Here is the summary it wrote, more information is availible in docs/wireless_debugging_execution


Summary

Adds an execution path for devices that can use neither su nor a callable PServer — the AYN Odin 2 Mini is the motivating example — by starting the privileged host through Android's own Wireless debugging, entirely on-device with no PC. It also includes the execution-layer correctness fixes the method depends on, which help root and PServer users too.

A note on the commits

This branch has a long, iterative commit history (developed over many rounds of device testing) and is not split into independently choosable pieces. Please squash-merge. Because of that I want to be equally clear about what is bundled in here, so nothing is a surprise on review — see "What's included" below. If any part is unwelcome I'm happy to pull it out into a follow-up rather than have it ride along silently.

How it works

com.odin2.gameassistant ships android:debuggable="true" while running as sharedUserId="android.uid.system" (uid 1000). A debuggable process accepts a JDWP debugger, and a debugger can make its target run code — so ClusterTune pairs with Wireless debugging, attaches to that app over the on-device adb connection, and has it launch the existing ClusterTuneHostEntry as uid 1000. ClusterTuneHostEntry already accepts uid 0 or 1000, so the host itself needed no change.

This is not an exploit of the vendor app: debuggable is a flag the vendor set, and JDWP is Android's ordinary debugging protocol. The only unusual part is that the debugger runs on the same device as its target.

Once the host is up it serves over Binder and needs no network, so profiles keep applying with Wi-Fi off until the next reboot. docs/wireless-debugging-execution.md documents the whole path for a reader new to the code.

What's included

Since the commits don't separate cleanly, here is the full contents by area. The first two are prerequisites for the method; the third is correctness work that stands on its own merit and also happens to be needed here.

The execution method — the vendored jdwp-injector module, JdwpHostExecutionMethod, connection management with active mDNS discovery, the pairing/setup UI, the host adoption lifecycle (a host survives an app restart with Wi-Fi off), and opt-in diagnostics.
PServer probe now verifies callability, not just presence (prerequisite). The probe does a real no-op transaction instead of trusting registration. On some devices PServerBinder is registered but every call is SELinux-denied, so the old presence check reported it available and it won auto-detection over a method that actually works — which also blocks this one from ever being selected.
GPU discovery gated on writability, not file existence (prerequisite). The host advertises a GPU domain only if it can actually write the node, decided at runtime; where it can't, GPU control is omitted rather than failing every apply. Root and PServer users are unaffected.
sysfs permission and robustness fixes (stand-alone correctness). Protection modes keep other-read so a capped node can't become 0440 (unreadable) on devices that ship 0660; chmod is non-fatal; writes retry to absorb the vendor's own perf/thermal services rewriting the same nodes; and a failing node reports itself and fails the transaction instead of silently taking unrelated policies down with it. These help every execution method, not just this one.

Disclosures

Vendored dependency. jdwp-injector/ is adapted from wuyr/jdwp-injector-for-android (Apache-2.0). ATTRIBUTION.md and the licence are retained in the module.
Scope. The method needs a debuggable system-uid app to attach to. Written generically, but the only confirmed target is com.odin2.gameassistant on the AYN Odin 2 Mini.

Limitations

Wireless debugging must be enabled once per boot — Android refuses to enable it without a network, so the first connection each boot needs Wi-Fi; everything after works offline. No GPU control at uid=system: every GPU node on this device is root:root with no world-write bit.
Diagnostics are opt-in and off by default, gated at a single point; a release build emits nothing until the user turns logging on.

New permissions

CHANGE_WIFI_MULTICAST_STATE and ACCESS_WIFI_STATE, used only for mDNS discovery of the local adb endpoint.

Testing

Field-tested on an AYN Odin 2 Mini across many iterations, including with remote testers: pairing, connect, apply on all clusters, apply with Wi-Fi off, app kill and relaunch offline (host adoption), reboot, and execution-method switching. Here is my reddit thread asking for testers. Root and PServer paths remain selected by auto-detection where available.

# Conflicts:
#	app/src/main/java/com/aure/clustertune/AppContainer.kt
#	app/src/main/java/com/aure/clustertune/MainActivity.kt
#	app/src/main/java/com/aure/clustertune/data/GpuPolicyDetector.kt
#	app/src/main/java/com/aure/clustertune/data/SettingsStorage.kt
#	app/src/main/java/com/aure/clustertune/model/AppSettings.kt
#	app/src/main/java/com/aure/clustertune/overlay/OverlayHostService.kt
#	app/src/main/java/com/aure/clustertune/root/PrivilegedExecutionMethod.kt
#	app/src/main/java/com/aure/clustertune/root/RootExec.kt
#	app/src/main/java/com/aure/clustertune/root/host/ClusterTuneHostClient.kt
#	app/src/main/java/com/aure/clustertune/root/host/ClusterTuneHostEntry.java
#	app/src/main/java/com/aure/clustertune/root/host/HostFilesystem.kt
#	app/src/main/java/com/aure/clustertune/root/host/HostRendezvous.kt
#	app/src/main/java/com/aure/clustertune/tile/PerformanceTileService.kt
#	app/src/main/java/com/aure/clustertune/ui/SettingsScreen.kt
#	app/src/main/java/com/aure/clustertune/ui/TunerScreen.kt
#	app/src/main/java/com/aure/clustertune/ui/settings/SettingsExecution.kt
#	app/src/main/res/values/strings.xml
#	app/src/test/java/com/aure/clustertune/root/PrivilegedExecutionResolverTest.kt
#	app/src/test/java/com/aure/clustertune/root/host/HostProtocolTest.kt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant