// Author: cirakg & claude ai // Summary: Application entry point (Connect IQ AppBase): lifecycle, first view, glance, locking on exit. // // Connect IQ lifecycle: initialize -> onStart -> getInitialView (or // getGlanceView in glance mode) -> views run -> onStop. // // The vault is opened in getInitialView, not onStart: onStart also runs in // glance mode, which has too little memory for it. // // Security: onStop locks the vault (keys and decrypted codes are wiped). It // runs when the user leaves the app, and also when Garmin's system passcode // shuts running apps down. // // getGlanceView is (:glance), so the compiler checks this class against the // glance scope too. The other methods never run in glance mode and use // non-glance code, so they opt out with (:typecheck(disableGlanceCheck)). import Toybox.Application; import Toybox.Lang; import Toybox.WatchUi; class OtpWalletApp extends Application.AppBase { // True once the full app (not the glance) has started. private var _started as Boolean = false; function initialize() { AppBase.initialize(); // Start of the start-up timer reported by `make perf` (debug builds only). Diag.markStart(); } function onStart(state as Dictionary?) as Void { } (:typecheck(disableGlanceCheck)) // onStop also runs after the glance, where AppState was never loaded. function onStop(state as Dictionary?) as Void { if (_started) { AppState.lock(); } } // The list, or a full-screen message when the data can't be used. (:typecheck(disableGlanceCheck)) function getInitialView() as [Views] or [Views, InputDelegates] { _started = true; AppState.start(); var error = AppState.startError; if (error != null) { return [new InfoView("OTP Wallet", [error], "error"), new InfoDelegate()]; } var list = new ListView(); return [list, new ListDelegate(list)]; } // The phone sent new settings (only while the full app runs). (:typecheck(disableGlanceCheck)) function onSettingsChanged() as Void { if (_started) { AppState.settingsChanged(); WatchUi.requestUpdate(); } } (:glance) function getGlanceView() as [WatchUi.GlanceView] or [WatchUi.GlanceView, WatchUi.GlanceViewDelegate] or Null { return [new OtpGlanceView()]; } }