Launcher: reliable switch away from stock, one-click enable+default, live progress#83
Merged
Merged
Conversation
A disabled launcher's 'Set as default' was a dead button (gated on !enabled) even though the backend already runs pm enable first — so the user had to Enable, then Set as default. Drop the gate and relabel it 'Enable & set default' when disabled; one click now enables and switches. The multi-strategy switch (enable -> role -> set-home-activity -> verify, with stock-takeover as last resort) can take several seconds, so stream per-step progress over a Tauri Channel and show it inline in the row being acted on, including the verify polls and the final list refresh that otherwise left the spinner frozen on a stale label. Always re-read launcher state when the action finishes so the list and active-launcher line redraw without a manual Refresh.
Narrating 'Confirming…' before all three verify attempts (and the takeover flow runs the strategy chain twice) made it churn the same line over and over. Keep a single check, only in the takeover path.
Verified live on Shield/Android 11: an enabled stock launcher overrides both set-home-activity and the role API — they return 'Success' but HOME keeps resolving to stock. The only thing that hands HOME over is disabling stock (exactly what v1's Launcher Wizard does). Switching between two non-stock launchers via set-home-activity works fine. The old flow ran the full polite ladder first (role + set-home-activity, each with a ~1.6s verify back-off) before offering the disable-stock takeover, so leaving stock took ~4s of doomed attempts and a misleading 'press Home' message before the confirm even appeared. Now: when a stock launcher currently holds HOME, try the polite setters once, and if HOME still resolves to stock go straight to the opt-in disable-stock takeover. Other launchers are never touched. The takeover logic is extracted into one shared helper used by both the fast path and the ladder's last resort.
Foreground the now-default launcher with a HOME intent on the success paths that didn't already (role API, set-home-activity, stock fast path), so the TV actually shows the new launcher instead of sitting on the old screen until the user presses Home. Gated behind verify_active, so it only ever foregrounds the confirmed target. Status message now reads '<Name> is now your default launcher.' using the friendly launcher name instead of the raw package id, and drops the internal '(via role_api)' strategy detail that meant nothing to users.
- Launcher Disable now shows 'Disabling…', an inline status line, refreshes the list, and confirms '<Name> disabled.' (was a bare 'Disable' that gave no sign it worked). Enable gets the same inline status + friendly names. - Memory-table Force stop / Disable buttons show a spinner + 'Stopping…' / 'Disabling…' instead of a bare '…', with clearer result messages. - Generalize the spinner into a reusable .spinner / .busy pair.
safeDisableFromMemory updated the catalog state but never the health report's top_memory list that feeds the table, so a disabled app's row lingered until a full refresh. Remove the row on success — a disabled app isn't running, so it belongs out of the memory list immediately.
Each tab cached its own snapshot, so a change in one left the others stale — disabling a launcher from the Memory tab left the Launchers tab showing it as enabled. Add invalidateDeviceCaches(): a state change marks the other data tabs (Launchers, Memory report) for a fresh load on next visit, while the acting tab refreshes itself inline. Existing data stays on screen until each reload completes, so there's no flash. Wired into every package/launcher state change (enable/disable/uninstall, set-default, launcher enable/disable) plus the bulk paths (snapshot apply, panic recovery, Optimize wizard).
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.
Fixes the Launchers tab: switching the default launcher was slow, looked hung, and the 'Set as default' button did nothing on a disabled launcher.
Root cause (verified live on a Shield / Android 11, via adb)
An enabled stock launcher overrides
set-home-activityand the role API — both returnSuccessbut HOME keeps resolving to stock. The only thing that actually hands HOME over is disabling stock (exactly what v1's Launcher Wizard does). Switching between two non-stock launchers viaset-home-activityworks instantly. So the polite strategies are doomed when leaving stock, and the old flow ground through them (~1.6s verify back-off each, ~4s total) with a misleading 'press Home' message before even offering the disable-stock confirm.Changes
disabledwhenever the launcher wasn't enabled (looked clickable, did nothing — most visibly for disabled stock). The backend already runspm enablefirst, so the gate was pure friction. Dropped it; the button reads 'Enable & set default' when the target is disabled.Channel(Enabling → Assigning the Home role → Registering as the Home app → Disabling the stock launcher (…) → Checking whether Home switched over → Refreshing). Covers the verify polls and the final reload so the spinner never freezes on a stale label.Notes
cargo fmt/clippy/test (171 pass, +2 new launcher tests), npm run check (0/0), npm run build — all green. Backend mechanism validated directly against two Shields over adb.