WeWaffles / OneLineage
git clone https://github.com/WeWaffles/OneLineage.git
v1.0.0 · today
Hot-switch a rooted Samsung phone between One UI and a LineageOS 23.2 GSI via a userspace pivot_root container
+30
stars, 24h · #270
+30
stars, 7 days · #1,341
+30
stars, 30 days · #8,915
30
★ total · +30% this week
2
forks · 3 open issues
Star history starts 2026-10-20; the chart appears after the second daily snapshot.
LanguageShell
License—
Created2026-10-20 (today)
Last pushtoday
Watchers1
OwnerUser
Links
README excerpt
# OneLineage Hot-switch between stock **One UI** and a **LineageOS 23.2 (Android 16) GSI** on a rooted Samsung phone, with no reflashing and no second partition. OneLineage stages the GSI under `/data/local/tmp`, pivots into it as a container with its own zygote and system_server, and can hand the screen back to One UI. If something isn't working and you have a fix feel free to make a pr! > ## Disclaimer > **This has only been tested on a single device: a rooted Samsung Galaxy S26 Ultra running One UI 8.5.** > It may not work on other Samsung models, other One UI versions, or other devices at all. It is experimental, it replaces core parts of a running system, and it can crash, hang or soft-brick your phone, fill `/data`, or break radio/SMS. **Back up everything first. Use at your own risk.** > Also, I did use AI a fair bit in this project, it would have taken a LOT longer without it. ## Requirements - A rooted Samsung phone (the tested one is an S26 Ultra on One UI 8.5) - Enough free space on `/data` for the extracted GSI - Internet access for the GSI download (LineageOS 23.2 GSI, EXT4, VANILLA or GAPPS builds from SourceForge) ## What's in here | Path | What it is | | --- | --- | | `src/`, `res/`, `AndroidManifest.xml` | The Android app (`com.wewaffles.onelineage`) | | `assets/master_prepare.sh` | Stages the rootfs, binds the patched files, fixes labels/ownership | | `assets/master_inner.sh` | Runs inside the container, starts the guest zygote | | `assets/switch_to_lineage.sh` / `return_to_oneui.sh` | Switch in and back out | | `assets/zygote_exec` | Static aarch64 launcher for the guest zygote | | `build_apk.sh` | Builds and signs the APK | ## Patches ### Patched system files (bind-mounted over the GSI) - `services_patched.jar` over `system/framework/services.jar` - `framework_patched.jar` over `system/framework/framework.jar` - `PermissionController_patched.apk`: removes the `android.permission.RANGING` reference so runtime-permission dialogs stop crashing (Samsung's PermissionController needs a permission the LineageOS 23.2 platform doesn't define) - Optional bind-mounts when present: `framework-res_patched.apk`, `libaudio_aidl_conversion_common_cpp_patched.so`, `libaudioclient_aidl_conversion_patched.so` ### Boot and environment fixes 1. **APEX paths in the container.** Host `/system/apex` and `/system_ext/apex` are bound into the rootfs after the GSI payloads are extracted, so PackageManagerService stops dying in `scanApexPackages`. 2. **SELinux labels on the staged `/data`.** The tree is relabeled like a real `/data` (`system_data_file`, per-package `app_data_file`) instead of `shell_data_file`. Also `setenforce 0` during the takeover and `setenforce 1` on return. 3. **Audio hang.** Host `audioserver`/`cameraserver` are left running (they used to be stopped/frozen, which deadlocked `AudioService`). Only the host zygote is suppressed. 4. **Runaway `sf.log`.** SurfaceFlinger output goes to `/dev/null` (it was growing to hundreds of MB in mi