Browse Source

Display the lock screen each time the app is brought to foreground

vishnukvmd 2 years ago
parent
commit
55afcb5484
1 changed files with 48 additions and 2 deletions
  1. 48 2
      lib/ui/tools/lock_screen.dart

+ 48 - 2
lib/ui/tools/lock_screen.dart

@@ -13,12 +13,17 @@ class LockScreen extends StatefulWidget {
   State<LockScreen> createState() => _LockScreenState();
 }
 
-class _LockScreenState extends State<LockScreen> {
+class _LockScreenState extends State<LockScreen> with WidgetsBindingObserver {
   final _logger = Logger("LockScreen");
+  bool _isShowingLockScreen = false;
+  bool _hasPlacedAppInBackground = false;
+  bool _hasAuthenticationFailed = false;
 
   @override
   void initState() {
+    _logger.info("initState");
     _showLockScreen();
+    WidgetsBinding.instance.addObserver(this);
     super.initState();
   }
 
@@ -55,14 +60,55 @@ class _LockScreenState extends State<LockScreen> {
     );
   }
 
+  @override
+  void didChangeAppLifecycleState(AppLifecycleState state) {
+    _logger.info(state.toString());
+    if (state == AppLifecycleState.resumed) {
+      // This is triggered either when the lock screen is dismissed or when
+      // the app is brought to foreground
+      _hasPlacedAppInBackground = false;
+      if (!_hasAuthenticationFailed) {
+        // Show the lock screen again only if the app is resuming from the
+        // background, and not when the lock screen was explicitly dismissed
+        _showLockScreen();
+      } else {
+        _hasAuthenticationFailed = false; // Reset failure state
+      }
+    } else if (state == AppLifecycleState.paused ||
+        state == AppLifecycleState.inactive) {
+      // This is triggered either when the lock screen pops up or when
+      // the app is pushed to background
+      if (!_isShowingLockScreen) {
+        _hasPlacedAppInBackground = true;
+        _hasAuthenticationFailed = false; // reset failure state
+      }
+    }
+  }
+
+  @override
+  void dispose() {
+    WidgetsBinding.instance.removeObserver(this);
+    super.dispose();
+  }
+
   Future<void> _showLockScreen() async {
-    _logger.info("Showing lockscreen");
+    _logger.info("Showing lock screen");
     try {
+      _isShowingLockScreen = true;
       final result = await requestAuthentication(
         "Please authenticate to view your memories",
       );
+      _isShowingLockScreen = false;
       if (result) {
         AppLock.of(context).didUnlock();
+      } else {
+        _logger.info("Dismissed");
+        if (!_hasPlacedAppInBackground) {
+          // Treat this as a failure only if user did not explicitly
+          // put the app in background
+          _hasAuthenticationFailed = true;
+          _logger.info("Authentication failed");
+        }
       }
     } catch (e, s) {
       _logger.severe(e, s);