Releases: jlgrimes/flipx
Release list
flipx v0.7
What's new
- No more reload on every flip. Route through each launcher's LAUNCHER activity (e.g. ES-DE's
MainActivity) instead of its HOME variant. Both launchers stay warm in their tasks; flipping back resumes instantly instead of cold-starting. - Per-direction rotation lock. With the rotation toggle on, hinge close locks landscape, hinge open locks 90° counter-clockwise of that. Matches the device's physical pivoted orientation in each hinge state.
Toggle behavior
| Toggle | Hinge close | Hinge open |
|---|---|---|
| ON | lock landscape (rotation 1) | lock 90° CCW (rotation 0) |
| OFF | flipx doesn't touch | flipx doesn't touch |
Known limitation (unchanged from v0.6)
ES-DE still renders at 648×720 inside the 720×720 panel because the Unisoc framework letterboxes landscape-locked apps. This is a device-level constraint we can't override without root. The cropping was the trade-off for keeping ES-DE warm — using the HOME variant fixed cropping but introduced reload-on-every-flip, which was worse.
Install / upgrade
adb install -r flipx-v0.7.apk over your existing install.
flipx v0.6
What's new
- Consolidated rotation handling into a single toggle. The v0.5 "RG Rotate fullscreen fix" is removed — both of its levers (wm set-ignore-orientation-request and policy_control immersive.full=*) were no-ops on this device, so they were dead code.
- Reworked rotation lock semantics. When the toggle is ON, flipx now only acts on hinge CLOSE (locks landscape). Hinge OPEN restores free rotation so the routed app (typically ES-DE) keeps its original behavior. Previously v0.3 also forced portrait on open, which was over-reach.
Behavior summary
| Toggle | Hinge close | Hinge open |
|---|---|---|
| ON | force landscape | free rotation (sensor + app) |
| OFF | flipx doesn't touch | flipx doesn't touch |
Install / upgrade
adb install -r flipx-v0.6.apk over your existing install.
flipx v0.5
What's new
- Shizuku-based launching. HomeRouterActivity now delegates to a new
launchComponentAIDL method on the UserService, which firesam start -n <component>as shell uid. Improves consistency of the launching path. - RG Rotate fullscreen toggle — new switch in the Rotation section. Applies both userspace levers for hiding system bars and ignoring per-app orientation locks (
wm set-ignore-orientation-request+policy_control immersive.full=*). Default off.
Known limitation: launcher pillarbox
On the RG Rotate, every launcher (and most apps) gets a 648×720 window inside the 720×720 panel — 36px of dead space on each side. We diagnosed this exhaustively: it's neither home-stack assignment, nor an app manifest aspect ratio, nor a launching-context propagation issue. It's an OEM-level navigation bar reservation enforced inside the Unisoc framework overlay, and no userspace lever (Shizuku-included) unlocks it. Fixing it requires root + a Magisk module that patches the framework resources.
The v0.5 fullscreen toggle is shipped anyway because (a) it's harmless when ineffective and (b) it may work on future Android builds or on differently-configured devices. If you toggle it on and your launchers fill the full 720×720, great. If not, this is the device's limit.
Install / upgrade
adb install -r flipx-v0.5.apk over your existing install.
flipx v0.4
What's new
Fixes ES-DE (and other targets) appearing pillarboxed with black bars on the sides.
On Android 12 — at least on the Unisoc T618 build the RG Rotate ships with — the home task stack applies an aspect-ratio compatibility constraint that shrinks activities to ~90% width. On the RG Rotate's 720×720 square display, this manifests as 36px of black bars on each side of whatever launcher flipx routed to.
Fix: HomeRouterActivity now prefers the regular LAUNCHER intent over the HOME-category intent when routing. The target launcher starts in a normal task stack with no aspect compat, getting the full panel.
For ES-DE specifically, this routes through its regular MainActivity instead of MainActivityHomeApp — visually the same UI, but no pillarbox.
Install / upgrade
adb install -r flipx-v0.4.apk over your existing install. Settings preserved.
flipx v0.3
What's new
Lock orientation to hinge state. Replaces the v0.2 global rotation hammer with a device-appropriate behavior: when the toggle is on, flipx binds the display rotation directly to the hinge — open → portrait, closed → landscape. Sensor-based auto-rotate is effectively disabled while locked.
Find it under the Rotation section of flipx's main screen. Default off in v0.3.
When the toggle is turned off, flipx calls wm user-rotation free to restore the system default (sensor-based rotation).
Install / upgrade
Same signing key — just adb install -r flipx-v0.3.apk over your existing install. Settings preserved.
Under the hood
- Implemented via
/system/bin/wm user-rotation lock <N>running as shell uid through the Shizuku UserService. - Hard-coded rotation values: 0 = portrait, 1 = landscape. If they come out backwards on your unit, the two constants in
HingeUserService.kt(ROTATION_PORTRAIT/ROTATION_LANDSCAPE) just need to be swapped. - Reapplied on every Shizuku bind because
wmflags reset across reboot.
v0.2 reverted
The "force auto-rotate everywhere" toggle from v0.2 has been removed — it was a global override that affected games too. The hinge-bound rotation lock here is the more targeted replacement.
flipx v0.2
What's new
Force auto-rotate everywhere. Many launchers lock themselves to portrait via android:screenOrientation in their manifest, which overrides Android's global auto-rotate setting. v0.2 adds a toggle that uses Shizuku to flip the WindowManager-level ignore-orientation-request flag — when on, every app (launchers included) rotates with the device sensor regardless of its own orientation lock.
Defaults to ON. Toggle in the Rotation section of flipx's main screen. Turn it off if a game you play needs to stay in a fixed orientation.
Install / upgrade
Same signing key as v0.1 — just adb install -r flipx-v0.2.apk (or sideload it) on top of your existing install. All your settings (launcher picks, home role) are preserved.
If you're installing flipx for the first time, see the README for the full setup walkthrough.
Under the hood
- New AIDL methods
setIgnoreOrientationRequest(boolean)/isIgnoringOrientationRequest()on the Shizuku UserService. - Implemented via
/system/bin/wm set-ignore-orientation-request <true|false>running as shell uid. - Reapplied on every Shizuku bind because the wm flag resets across reboot.
Compatibility note
The wm flag is Android 12+ (added for foldable/large-screen support, repurposed here). On Android 11 or earlier the command silently no-ops and the toggle becomes a no-op too.
flipx v0.1
First release. Working end-to-end on the Anbernic RG Rotate (Android 12, Unisoc T618).
What this is
Two home screens for the RG Rotate. Flip the hinge open → land on your gaming launcher. Flip it closed → land on your everyday launcher. Automatic.
Install
- Install Shizuku and start it (Wireless Debugging or ADB).
- Download
flipx-v0.1.apkfrom this release, sideload it. - Open flipx, grant the Shizuku permission, tap Start watcher.
- Pick your launchers — one for hinge OPEN, one for hinge CLOSE. The picker lists every installed app that declares
category.HOME. - Tap "Make flipx the home" — flipx silently becomes the default home and routes home button presses based on hinge state.
See the README for the full walkthrough and troubleshooting.
What's in this build
- Hinge state detection via the gpio-keys Hall sensor (KEY_F12 press/release on
/dev/input/event2). - Shizuku UserService streaming
geteventas shell uid — no root required. - Explicit broadcast from the UserService to a flipx manifest receiver, bypassing the Android 12 background-service-start restriction.
- HomeRouterActivity that reads hinge state on every home press and routes the HOME intent at the configured target launcher.
- Auto-switch on flip when you're already sitting on one of the configured launchers — no need to press home manually.
Compatibility
Hard-coded to the RG Rotate's /dev/input/event2 and KEY_F12/F9 scancodes. Other handhelds will not work without a manifest change — see hinge-findings.md for the reverse-engineering trail you'd need to adapt.