diff options
Diffstat (limited to 'source/app/OtpWalletApp.mc')
| -rw-r--r-- | source/app/OtpWalletApp.mc | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/source/app/OtpWalletApp.mc b/source/app/OtpWalletApp.mc index 8858878..7419433 100644 --- a/source/app/OtpWalletApp.mc +++ b/source/app/OtpWalletApp.mc @@ -1,17 +1,19 @@ // Author: cirakg & claude ai -// Summary: Application entry point (Connect IQ AppBase): lifecycle and first view. +// Summary: Application entry point (Connect IQ AppBase): lifecycle, first view, glance, locking on exit. // -// OtpWalletApp: the application entry point (Connect IQ AppBase). +// Connect IQ lifecycle: initialize -> onStart -> getInitialView (or +// getGlanceView in glance mode) -> views run -> onStop. // -// M0 skeleton: the app shows a home screen with its name and version. Later -// milestones add the vault, settings processing, locking and the glance. +// The vault is opened in getInitialView, not onStart: onStart also runs in +// glance mode, which has too little memory for it. // -// Connect IQ lifecycle: initialize -> onStart -> getInitialView -> (views run) -// -> onStop. +// 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. // -// Security note for later milestones: onStop is where every key and decrypted -// secret gets 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; @@ -19,22 +21,41 @@ 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(); } - // Called after the app is loaded, before the first view is shown. function onStart(state as Dictionary?) as Void { } - // Called when the app exits, for any reason. + (: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 first screen and its input handler. + // The list, or a full-screen message when the data can't be used. + (:typecheck(disableGlanceCheck)) function getInitialView() as [Views] or [Views, InputDelegates] { - return [new HomeView(), new HomeDelegate()]; + _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)]; + } + + (:glance) + function getGlanceView() as [WatchUi.GlanceView] or [WatchUi.GlanceView, WatchUi.GlanceViewDelegate] or Null { + return [new OtpGlanceView()]; } } |
