A Samsung One UI customisation app and Xposed module. System UI, the quick panel, lock screen lyrics, and tools that need no hooks at all.
Application ID: io.github.hongducdev.prism
Prism is an Android APK. The installable build lives on GitHub Releases. The green Code button on this page is source, not the app.
| Do this | Do not do this |
|---|---|
| Open Releases | Click Code → Download ZIP |
Under Assets, download the .apk (prism-x.y.z.apk) |
Download Source code (zip) or Source code (tar.gz) |
| Use the release marked Latest | Install an older tag because it appeared first in the list |
Official repository: github.com/hongducdev/prism
Before you install, check three things on that page:
- The owner is hongducdev and the repository name is prism.
- You are on Releases, not the source tree.
- The file you save ends in
.apk, and the version matches the tag (for example tagv1.0.5→prism-1.0.5.apk).
GitHub always attaches source archives to a release. Those zips are the code in this repo. They will not install on a phone.
Every release is signed with the same certificate. An APK that reports anything else was not built here, whatever the file name says.
SHA-256 5cdb102fe3fe1dc1b0f94d075356152d4d5d2638728da99c083fc2589f398fe7
SHA-1 3757b03167640982be9c299050520fa88280c9b8
Check a downloaded file with apksigner from the Android SDK build-tools:
apksigner verify --print-certs prism-1.0.5.apk
The Signer #1 certificate SHA-256 digest line must match the value above.
From 1.0.1 onwards Prism watches Releases itself — once a day when it starts, and whenever you ask it to under Settings → Check for updates — then downloads and installs the new APK for you.
Coming from 1.0.0 is the exception, because that build was published before any of this existed. Take the latest .apk from Releases and install it by hand this once; updates after that arrive on their own.
Tiếng Việt — tải đúng bản, đừng nhầm file
Chỉ tải Prism từ github.com/hongducdev/prism. Trước khi bấm Download, nhìn góc trái: chủ repo phải là hongducdev, tên repo phải là prism. Fork, mirror, hay file APK gửi qua chat không phải bản phát hành của project này.
Ứng dụng cài được nằm ở Releases → Latest. Nút xanh Code → Download ZIP trên trang repo chỉ là mã nguồn — giải nén ra không cài được trên điện thoại.
Trên trang release, kéo xuống mục Assets và tải file .apk (ví dụ prism-1.0.5.apk).
Đừng tải hai file GitHub tự gắn vào mọi release:
Source code (zip)Source code (tar.gz)
Đó là toàn bộ source của tag đó, không phải APK.
Trang Releases liệt kê mọi bản, bản cũ nằm phía dưới. Luôn vào bản có nhãn Latest, hoặc mở trực tiếp /releases/latest. Đối chiếu số version trên file APK với tag (tag v1.0.5 → file prism-1.0.5.apk). Nếu trong app thấy version khác với Latest trên GitHub, bạn đang chạy bản cũ hoặc bản không phải từ repo này.
Mọi bản phát hành đều ký bằng cùng một chứng chỉ. Nếu file bạn tải ra kết quả khác, đó không phải bản do tác giả build, bất kể tên file là gì.
SHA-256 5cdb102fe3fe1dc1b0f94d075356152d4d5d2638728da99c083fc2589f398fe7 SHA-1 3757b03167640982be9c299050520fa88280c9b8
Dùng apksigner trong Android SDK build-tools để đối chiếu:
apksigner verify --print-certs prism-1.0.5.apk
Dòng Signer #1 certificate SHA-256 digest phải trùng giá trị ở trên.
Từ 1.0.1 trở đi Prism tự theo dõi Releases — mỗi ngày một lần lúc mở app, và bất cứ khi nào bạn bấm Cài đặt → Kiểm tra cập nhật — rồi tải và cài bản mới giúp bạn.
Riêng khi đang ở bản 1.0.0 thì là ngoại lệ, vì bản đó ra đời trước khi có tính năng này. Bạn tải tệp .apk mới nhất ở Releases và cài tay một lần, từ đó về sau app tự lo.
| 📱 Device | Samsung, One UI 7 or 8 |
| 🤖 Android | 12 and newer (minSdk 31) |
| 🪝 Hooks | Vector or LSPosed |
| 🛠️ Tools | Shizuku or root — root covers everything Shizuku can do |
Every feature declares what it needs. The UI dims what this device cannot run rather than hiding it.
Around sixty tweaks, grouped by the process they change, plus eight standalone tools.
| Group | Examples |
|---|---|
🤖 Android (system_server) |
default USB mode, unlimited screen-on, lock screen timeout, app rotation, blockable system notification channels |
| 🎨 System UI | configurable Now Bar dashboards and media lyrics, lock screen lyrics, status bar padding, battery level text, network speed, custom carrier name, custom power menu, lunar calendar, physical eSIM adapter |
| ⚡ Quick panel | hide the rows under the tiles, clock style, brightness and volume readouts, always-expanded tiles |
| ⚙️ Settings | force peak refresh rate, outdoor mode, extra battery info, any font, scheduled power on/off |
| 📷 Phone and camera | call recording, caller location, all camera menus, no temperature gate |
| 🧩 Samsung apps | Galaxy Store ads, Gallery and Notes unlocks, Samsung Internet tweaks, watch pairing, no AI watermark |
The Tools tab includes:
- 🎵 Now Bar dashboards for network, battery, memory, charging, gaming, timers, tasks, downloads, and media lyrics with album artwork or a music icon.
- 📖 Reader Mode with two configurable E-ink/Reading profiles and manual control from the app or a Quick Settings tile through Xposed, Shizuku, or root. Per-app automation requires Xposed. This is an OLED color transform, not a physical E-ink display.
- 🖥️ Refresh rate controller — Standard/Adaptive/High mode plus min/max Hz for the current resolution (Shizuku or root for the one-time permission)
- 🖼️ Photo watermark from EXIF
- 💾 Configuration backup and restore
- 🌐 App language
- 🧊 App freezing (Shizuku or root)
- 💤 App standby buckets (Shizuku or root)
- ✍️ System font replacement (root)
- Confirm you are on hongducdev/prism and open Releases → Latest.
- Download the
.apkfrom Assets. Install it. - In Vector or LSPosed, enable Prism. Tick Prism itself in the module scope — that is how the app knows the module is active — plus the Samsung apps you actually want hooked.
- For the Tools tab, start Shizuku or use a rooted device.
- Restart System UI or reboot when a feature asks for it.
Vector activation is detected with a self-hook: PrismHookEntry rewrites PrismModuleStatus.isModuleActive inside the app. Looking for XposedBridge from app code does not work, because Vector loads it into a classloader the app cannot reach. The self-hook only runs when Prism is in its own scope, which is why xposed_scope lists the app's package first. Hooks in other apps work whether or not that box is ticked; without it the app just cannot tell that it is active.
app/src/main/java/io/github/hongducdev/prism/
├── core/designsystem/ theme and reusable components
├── core/model/ Capability, FeatureIds, SamsungPackages
├── data/preference/ DataStore and the SharedPreferences bridge for hooks
├── data/capability/ detection of Xposed, Shizuku and root
├── data/system/ privileged shell, restart control, system font, freeze, standby
├── data/watermark/ EXIF reading and the watermark renderer
├── feature/registry/ FeatureSpec, FeatureScope, FeatureRegistry and the catalogue
├── feature/{tweaks,tools,detail,settings,home}/
├── hook/ the Xposed layer, one package per hooked process
└── navigation/ the NavHost
Settings live in DataStore and are mirrored into one SharedPreferences entry as JSON, which is what the hooks read; a hook cannot reach DataStore. Both sides derive their keys from PreferenceKeys.
Add a FeatureSpec to a file under feature/registry/catalog/, then wire the hook into the aggregator for the process it belongs to (SystemUiHooks, AndroidHooks, SettingsHooks, …).
FeatureSpec(
id = "hide_battery_icon",
titleRes = R.string.feature_hide_battery_icon,
summaryRes = R.string.feature_hide_battery_icon_summary,
icon = Icons.Rounded.BatteryFull,
group = FeatureGroup.SYSTEM_UI,
capability = Capability.XPOSED,
restart = RestartRequirement.SYSTEM_UI,
detail = { scope ->
var value by scope.booleanState("some_option")
ToggleRow(title = "…", checked = value, onCheckedChange = { value = it })
},
)scope.booleanState, intState and stringState return write-through Compose state: reading gives the stored value, assigning persists it. Keys are namespaced by feature id, so two features cannot collide.
New target apps also need an entry in xposed_scope (res/values/arrays.xml) and, if the UI has to name the app, in the manifest's <queries>.
Requires the Android SDK and a JDK 21 or newer.
./gradlew.bat :app:assembleDebug
./gradlew.bat :app:testDebugUnitTest
./gradlew.bat :app:assembleReleaseAPKs land in app/build/outputs/apk/{debug,release}/.
Release builds are minified. R8 must not touch the hook layer, the power-menu view models, DexKit or Shizuku — the rules for that are in app/proguard-rules.pro, and they exist because those classes are called from other processes or by reflection, where a renamed symbol fails silently.
To sign a release with a real key, drop a keystore.properties next to settings.gradle.kts:
storeFile=/path/to/release.jks
storePassword=…
keyAlias=…
keyPassword=…Without that file the release build is signed with the debug key so it still installs. That is fine for a private build and not fine for anything published.
See THIRD_PARTY_NOTICES.md. The embedded Android Auto receiver comes from Open Headunit; the interface, three of the tools and the Shizuku handling come from Essentials by Sameera Sandakelum; the hook layer and the :stub module come from One UI X by SoClear.
Licensed under AGPL-3.0.



