Add Vue WebUI and harden Android package handling - #21
Closed
eltavine wants to merge 2 commits into
Closed
Conversation
Introduce a full WebUI-based management flow for OukaroManager and rework the module runtime so configuration is saved through okrmng and applied reliably during the next boot instead of depending on runtime hot reload. This change turns the project into a complete, documented, test-backed KernelSU module package with a dedicated frontend, stronger Android package introspection, safer config persistence, and a more reproducible CI pipeline. - add a dedicated `webui/` frontend built with Vue 3, TypeScript, Vite, Tailwind CSS, vue-i18n, vue-sonner, and shadcn-style UI primitives - build the frontend directly into `module/webroot/` with relative asset paths and a cleanup step so the output matches the KernelSU WebUI layout - implement a single-page console that loads module state, supports package search, provides mutually exclusive `None` / `System` / `Priv` selection, shows draft statistics, preserves stale config entries, and clearly tells the user that a reboot is required before changes take effect - add bilingual Chinese and English UI copy with automatic locale selection from `navigator.language` and manual language switching in the header - style the WebUI with a high-contrast black-and-white visual system, remove template-like placeholder wording and gradients, and embed the `karo.svg` brand asset into both the WebUI and the repository README - integrate the frontend with the official KernelSU JavaScript API through `exec`, `moduleInfo`, `toast`, and `enableEdgeToEdge`, while also adding compatibility for both `window.ksu` and `window.kernelsu` - make frontend state loading more resilient by allowing failed module metadata lookups to be retried instead of poisoning the cached promise - extend `okrmng` into a WebUI-ready management CLI with `inspect --json` and `replace --system ... --priv ...` commands - return a stable JSON payload that includes configured system packages, configured priv packages, installed user apps, and missing configured apps - validate that a package cannot exist in both groups at the same time and keep package ordering deterministic through sorted `BTreeSet` storage - write `config.toml` atomically through a temporary file and persist only fully written updates to avoid half-written config during save operations - add parser coverage and config persistence tests for CSV handling, JSON shape expectations, duplicate-group rejection, stale package detection, empty config handling, and sorted round-trip serialization - scope app discovery consistently to the Android primary user (`system user` / `user 0`) so WebUI visibility matches actual module behavior on multi-user and work-profile devices - switch package listing to `pm list packages -3 --user 0` and fall back to `packages.xml` plus `package-restrictions.xml` parsing when shell output is unavailable or incomplete - parse package install-state metadata from `/data/system/users/0/package-restrictions*.xml` and filter out packages that are not actually installed for the primary user - document this primary-user-only contract in the WebUI copy and README so the project no longer implies cross-user package management support - rework `oukaro` so saved configuration is applied during boot from `module/post-mount.sh`, which is a better match for KernelSU overlay timing than the previous service-stage approach - leave `service.sh` as an intentional no-op to make it explicit that runtime hot reload is disabled and that reboot is the activation boundary - mount overlayfs only when needed, reuse existing mount points safely, clean unmanaged package directories, and copy package trees through a staging directory before renaming them into place - harden package path discovery by preferring `packages.xml`, supporting both directory and `base.apk` code paths, and falling back to `pm path --user 0` only when necessary - gate package application on confirmed primary-user installation state so packages from other users or stale metadata are not silently mounted - add tests around package path parsing, stale backup handling, invalid XML, package-restrictions parsing, and unmanaged directory cleanup - tighten module packaging and installation behavior by verifying required payload files in `customize.sh` and explicitly fixing executable bits for `oukaro`, `okrmng`, `post-mount.sh`, and `service.sh` - update `module.prop` to describe the actual save-then-reboot workflow and keep `module/.gitignore` focused on generated module artifacts - add a root `.gitignore` and refine `webui/.gitignore` so Rust targets, `module/webroot`, frontend caches, and other generated outputs stay out of version control noise - refresh the README so it matches the real implementation instead of the old simplified description - document the new Vue WebUI, CLI usage, save/reboot behavior, stale-config preservation, WebUI access paths, and the limitations of `/system/priv-app` on modern Android when privileged-permission allowlists are required - include the project SVG logo in the README for consistency with the WebUI - improve CI reproducibility by pinning Node, Rust, and Android NDK inputs instead of scraping the latest NDK release dynamically - add formatting checks and keep Rust tests in the workflow before building Android release binaries and the frontend bundle - make the workflow produce a complete `module/` artifact containing the native binaries and static WebUI assets expected by KernelSU Validation: - `cargo fmt --all --check` in `okrmng` - `cargo fmt --all --check` in `oukaro` - `cargo test` in `okrmng` - `cargo test` in `oukaro` - `npm run build` in `webui`
…console Rework both the Rust backend and the Vue WebUI so the module behaves more predictably across modern Android package-manager states, early-boot timing windows, and mixed KernelSU/WebUIX hosts. The overall goal of this change is to remove optimistic assumptions from package discovery and WebUI runtime integration, then replace them with explicit fallbacks, stronger validation, and clearer user-facing diagnostics. Improve Android metadata decoding and shared parsing utilities. - Add shared helpers under `shared/` so both `okrmng` and `oukaro` consume the same Android-specific parsing rules instead of drifting independently. - Introduce `shared/android_xml.rs` to decode plain UTF-8 XML, UTF-8 with BOM, UTF-16 XML with or without BOM, Android binary XML (`ABX\0`), and modified-UTF / CESU-8 payloads commonly emitted by Android framework code. - Align binary XML decoding more closely with AOSP behavior by handling entity references, CDATA sections, base64-encoded byte payloads, string interning, and ART-style multi-byte modified-UTF sequences. - Add `shared/android_package.rs` to validate package names against Android application ID rules before they can enter persisted config or boot-time apply paths. - Add `shared/android_package_state.rs` to model Android user availability as `installed && !hidden`, matching the semantics used by package user state in Android rather than treating install state alone as sufficient. - Add `shared/android_install_path.rs` so fallback package classification and metadata-derived code path resolution share one strict understanding of legitimate user-app install roots. Make `okrmng inspect` substantially more resilient and more informative. - Keep the existing `config.toml` format and CLI surface area intact, but extend inspect output with `installedUserAppsSource`, `systemUserStateSource`, and `warnings` so callers can tell whether data came from `pm list packages`, `packages.xml + package-restrictions.xml`, or a best-effort metadata fallback. - Fall back from `pm list packages -3 --user 0` to package metadata instead of failing outright when the package service is unavailable, incomplete, or too early in boot to answer shell queries reliably. - Parse both `publicFlags` and legacy `flags` fields when inferring whether a package should be treated as a user app. - Mirror Android's package visibility semantics by treating `hidden="true"` and legacy `blocked="true"` restriction entries as unavailable for user 0 instead of only checking `installed`. - Tighten path-based user-app inference so fallback classification accepts only known Android user-app roots such as `/data/app`, legacy `/data/app-private`, and adopted-storage `/mnt/expand/<uuid>/app`. - Keep malformed configured package names visible in inspect output, but emit explicit warnings so callers understand that those entries will be ignored at apply time. - Validate package names for `system-app add`, `priv-app add`, and `replace --system/--priv` so invalid identifiers are rejected before they reach disk. Strengthen `okrmng` config persistence semantics. - Continue writing config atomically, but explicitly sync the temporary file before rename and sync the containing directory after persistence so writes more closely match Android `AtomicFile` durability expectations. - Preserve sorted output through `BTreeSet`-backed config storage so generated TOML remains deterministic and friendlier to review. Make `oukaro` more defensive during boot-time apply. - Reuse the shared Android XML decoder for `packages.xml` and `package-restrictions.xml`, which prevents failures on devices that store these files as UTF-16 or Android binary XML instead of plain UTF-8 text. - Resolve package code paths from `packages.xml` before relying on shell probes so the module can still operate in early boot phases where the package service is not yet ready. - Treat `pm path --user 0` failures with empty stderr as "package missing" when they match AOSP shell behavior, instead of escalating them into hard errors that would hide otherwise-usable metadata fallbacks. - Reuse the same `installed && !hidden` availability model that backs `okrmng inspect`, keeping boot-time apply behavior aligned with the WebUI's view of what user-0 can actually access. - Refuse metadata-derived code paths outside known Android user-app install roots, even if those paths exist on disk, so stale or malformed metadata cannot redirect mounts toward arbitrary filesystem locations. - Sanitize runtime config entries before applying them: skip malformed package names, log why they were ignored, and resolve duplicate membership deterministically in favor of `priv-app`. - Make `oukaro` honor `OUKARO_MANAGER_CONFIG_PATH` just like `okrmng`, which improves testability and keeps both binaries consistent in recovery and debugging workflows. Harden `oukaro` config creation and filesystem operations. - Replace the previous direct write path for first-run config creation with an atomic temp-file write plus sync, matching the stronger persistence model already used on the management side. - Keep overlay mount setup defensive by removing the production `unwrap()` around mount option construction and reporting a real error if encoding fails. - Preserve staging-directory cleanup in package sync flows so interrupted copy operations do not leave partially prepared trees behind. Upgrade the WebUI runtime layer for real-world host variability. - Expand `module-api.ts` so the frontend can tolerate callback-based, promise-based, and direct-return exec bridge implementations instead of assuming one KernelSU host contract. - Normalize `window.ksu` and `window.kernelsu` so the app can operate across bridge naming differences without special-case code in the view layer. - Add runtime detection for preview, KernelSU Manager, and WebUIX hosts. - Probe WebUIX-specific bridges such as `wx:module` and `wx:pm` when they are available, rather than limiting the UI to official KernelSU helpers only. - Fall back to `/.package/<name>/...` info and icon resources on compatible WebUIX hosts via the shipped `webui/public/config.json` capability flag. - Expose richer runtime capability information to the page so unsupported or partially supported environments can surface warnings instead of failing silently. Refine the WebUI experience and make state handling more robust. - Keep the page single-screen and mobile-first, but add clearer environment badges, warning alerts, reboot-required guidance, and more precise host/runtime status messaging. - Replace leftover generic template copy with Oukaro-specific wording such as "System app configuration console" / "系统应用配置控制台" so the interface reads like a real module console rather than a scaffold. - Persist the selected locale in local storage and restore it automatically on the next load. - Persist unsaved drafts and the active search term, restore them when the server-side base assignment set still matches, and notify the user with toasts when a draft was successfully recovered. - Limit the default visible package list and matching search results to 10 items at a time, then provide explicit expand/collapse controls instead of eagerly rendering the entire package set inside a mobile WebView. - Lazy-load package details only for the currently visible rows so large app lists do not immediately trigger full metadata fetches. - Preserve package-name-only operation when richer package metadata is not available, but show app labels, versions, icons, and fallback initials when the host can supply them. - Keep local draft state intact when save fails, allowing the user to inspect the error and retry without rebuilding their selections. Polish branding and mobile WebView integration. - Embed the Karo SVG as the favicon and in-page branding element so the WebUI no longer looks like a stock Vite starter. - Update the document title to `OukaroManager` and load `/internal/insets.css` with `viewport-fit=cover` so supported hosts can honor safe-area insets correctly. - Add `100dvh` and inset-aware page padding in CSS to improve layout stability on modern Android WebViews and edge-to-edge hosts. Keep documentation aligned with the implemented runtime behavior. - Update `README.md` to explicitly mention that the built WebUI now ships `webroot/config.json` in order to enable `/.package/...` package info and icon fetching on compatible WebUIX hosts. - Preserve the documented model that WebUI saves only update `config.toml`, while actual mounts are still applied during the next boot's post-mount phase. Expand regression coverage across both Rust binaries. - Add tests for Android binary XML decoding, UTF-16 XML decoding, modified-UTF handling, package-state availability semantics, package-name validation, and stricter install-root recognition. - Add tests for restriction parsing with `installed`, `hidden`, and legacy `blocked` states. - Add tests that verify current package metadata is preferred over stale backup files, invalid current XML still fails loudly, system-partition code paths are rejected during metadata fallback, and package-path parsing handles split APK output correctly. - Add coverage for atomic config creation on the `oukaro` side so default config materialization is exercised directly. Validation: - `cargo test` in `okrmng` - `cargo test` in `oukaro`
Collaborator
|
Please submit your PRs separately. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces a dedicated Vue-based WebUI for OukaroManager and hardens the Rust backend so package discovery, config persistence, and boot-time apply behavior are more reliable across modern Android environments and mixed KernelSU/WebUIX hosts.
What changed
added a standalone
webui/app built with Vue 3, TypeScript, Vite, Tailwind CSS, vue-i18n, and shadcn-style componentsimplemented a mobile-first single-page management console for browsing installed user apps, searching packages, selecting
None/System/Priv, reviewing the current draft, and saving config changesadded bilingual Chinese/English UI copy with automatic locale detection and manual language switching
refined the WebUI runtime bridge so it can work with
window.ksu,window.kernelsu, preview environments, KernelSU Manager, and compatible WebUIX hostsadded WebUIX-oriented capability handling, including package info/icon probing through
/.package/...when supportedimproved WebUI resilience with draft recovery, persisted locale/search state, limited default package rendering, lazy detail loading, clearer warnings, and reboot-required guidance
extended
okrmngwith WebUI-oriented commands such asinspect --jsonandreplace --system ... --priv ...kept the existing
config.tomlformat while improving config validation, duplicate-group rejection, deterministic ordering, and atomic writesexpanded
inspectoutput to better explain package discovery sources and warning conditionsadded package-name validation aligned with Android application ID rules before invalid entries can be persisted
hardened Android package discovery and apply logic in
oukaroimproved fallback behavior when
pmis unavailable or unreliable during early bootaligned package availability checks more closely with Android user state semantics such as
installed,hidden, and legacyblockedreused shared parsing helpers for Android XML, package state, package validation, and install-path checks
rejected unsafe metadata-derived paths outside expected Android user-app roots
made config creation and persistence more defensive with stronger atomic write behavior
updated module packaging and workflow integration
improved
customize.sh, module metadata,.gitignorecoverage, CI reproducibility, and documentation consistencyrefreshed the README so it matches the actual WebUI-based save-then-reboot workflow