Files
nstefanelli 3293f438de Auto-activate kiosk mode on launch when previously enabled (#4609)
## Summary

Fixes #4608.

When kiosk mode is enabled and the Home Assistant app is then
force-quit, crashes, or the device reboots, kiosk mode does not
re-activate on the next launch. The persisted
`settings.isKioskModeEnabled = true` is loaded into memory by
`KioskModeManager.loadSettings()` but never acted on, so the user has to
manually re-toggle kiosk mode from settings each time. For the
wall-mounted iPad use case kiosk mode is designed for, this leaves an
unattended dashboard silently falling back to the normal UI after any
restart.

## What changed

In `KioskModeManager.setup(using:)` (called from
`WebViewController.viewDidLoad`), if `settings.isKioskModeEnabled` is
`true` and kiosk mode is not already active, call `enableKioskMode()` to
restore it.

`enableKioskMode()` is idempotent — it guards on `!isKioskModeActive` —
so this is safe to call from any path and existing flows are unaffected.

```swift
// Restore kiosk mode if it was enabled before the app was last closed
if settings.isKioskModeEnabled, !isKioskModeActive {
    Current.Log.info("Restoring kiosk mode from persisted settings")
    enableKioskMode()
    return
}
```

## Test plan

- [ ] Enable kiosk mode in the app
- [ ] Force-quit the app from the app switcher
- [ ] Re-launch
- [ ] Verify the screen comes back up in kiosk mode (status bar hidden,
screensaver active, secret exit gesture working)
- [ ] Reboot the device — verify kiosk mode is still on after launch
- [ ] Disable kiosk mode, force-quit, re-launch — verify it stays
disabled

## Notes

- `KioskModeManager` is a singleton with UIKit dependencies and no
existing tests, so I haven't added a unit test here. Happy to add one if
there's a preferred pattern for managers like this.
- Out of scope (per the issue): a "panic recovery" guard so a crash loop
inside kiosk mode does not trap the user. Worth a follow-up.
- Local `xcodebuild` was blocked by an unrelated
`BuildMaterialDesignIconsFont` script failure in my environment, but
`swiftformat --lint` passes and the change uses existing APIs that
mirror the adjacent code path.

---------

Co-authored-by: Nick Stefanelli <nstefanelli@users.noreply.github.com>
2026-05-26 16:15:13 +02:00
..