Browse Source

Rely on MLController for firing all events

vishnukvmd 1 year ago
parent
commit
c821d6e2a5
2 changed files with 55 additions and 40 deletions
  1. 1 25
      lib/app.dart
  2. 54 15
      lib/services/machine_learning/machine_learning_controller.dart

+ 1 - 25
lib/app.dart

@@ -43,12 +43,8 @@ class EnteApp extends StatefulWidget {
 }
 }
 
 
 class _EnteAppState extends State<EnteApp> with WidgetsBindingObserver {
 class _EnteAppState extends State<EnteApp> with WidgetsBindingObserver {
-  static const initialInteractionTimeout = Duration(seconds: 10);
-  static const defaultInteractionTimeout = Duration(seconds: 5);
-
   final _logger = Logger("EnteAppState");
   final _logger = Logger("EnteAppState");
   late Locale locale;
   late Locale locale;
-  late Timer _userInteractionTimer;
 
 
   @override
   @override
   void initState() {
   void initState() {
@@ -57,7 +53,6 @@ class _EnteAppState extends State<EnteApp> with WidgetsBindingObserver {
     locale = widget.locale;
     locale = widget.locale;
     setupIntentAction();
     setupIntentAction();
     WidgetsBinding.instance.addObserver(this);
     WidgetsBinding.instance.addObserver(this);
-    _setupInteractionTimer(timeout: initialInteractionTimeout);
   }
   }
 
 
   setLocale(Locale newLocale) {
   setLocale(Locale newLocale) {
@@ -76,30 +71,12 @@ class _EnteAppState extends State<EnteApp> with WidgetsBindingObserver {
     }
     }
   }
   }
 
 
-  void _resetTimer() {
-    _userInteractionTimer.cancel();
-    _setupInteractionTimer();
-  }
-
-  void _setupInteractionTimer({Duration timeout = defaultInteractionTimeout}) {
-    if (Platform.isAndroid || kDebugMode) {
-      _userInteractionTimer = Timer(timeout, () {
-        debugPrint("user is not interacting with the app");
-        MachineLearningController.instance.onUserInteractionEvent(false);
-      });
-    } else {
-      MachineLearningController.instance.onUserInteractionEvent(false);
-    }
-  }
-
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
     if (Platform.isAndroid || kDebugMode) {
     if (Platform.isAndroid || kDebugMode) {
       return Listener(
       return Listener(
         onPointerDown: (event) {
         onPointerDown: (event) {
-          MachineLearningController.instance.onUserInteractionEvent(true);
-          debugPrint("user is interacting with the app");
-          _resetTimer();
+          MachineLearningController.instance.onUserInteraction();
         },
         },
         child: AdaptiveTheme(
         child: AdaptiveTheme(
           light: lightThemeData,
           light: lightThemeData,
@@ -149,7 +126,6 @@ class _EnteAppState extends State<EnteApp> with WidgetsBindingObserver {
   @override
   @override
   void dispose() {
   void dispose() {
     WidgetsBinding.instance.removeObserver(this);
     WidgetsBinding.instance.removeObserver(this);
-    _userInteractionTimer.cancel();
     super.dispose();
     super.dispose();
   }
   }
 
 

+ 54 - 15
lib/services/machine_learning/machine_learning_controller.dart

@@ -1,7 +1,7 @@
+import "dart:async";
 import "dart:io";
 import "dart:io";
 
 
 import "package:battery_info/battery_info_plugin.dart";
 import "package:battery_info/battery_info_plugin.dart";
-import "package:battery_info/enums/charging_status.dart";
 import "package:battery_info/model/android_battery_info.dart";
 import "package:battery_info/model/android_battery_info.dart";
 import "package:logging/logging.dart";
 import "package:logging/logging.dart";
 import "package:photos/core/event_bus.dart";
 import "package:photos/core/event_bus.dart";
@@ -17,35 +17,70 @@ class MachineLearningController {
 
 
   static const kMaximumTemperature = 36; // 36 degree celsius
   static const kMaximumTemperature = 36; // 36 degree celsius
   static const kMinimumBatteryLevel = 20; // 20%
   static const kMinimumBatteryLevel = 20; // 20%
+  static const kInitialInteractionTimeout = Duration(seconds: 10);
+  static const kDefaultInteractionTimeout = Duration(seconds: 5);
+  static const kUnhealthyStates = ["over_heat", "over_voltage", "dead"];
+
+  bool _isDeviceHealthy = true;
+  bool _isUserInteracting = true;
+  bool _isRunningML = false;
+  late Timer _userInteractionTimer;
 
 
   void init() {
   void init() {
     if (Platform.isAndroid) {
     if (Platform.isAndroid) {
+      _startInteractionTimer(timeout: kInitialInteractionTimeout);
       BatteryInfoPlugin()
       BatteryInfoPlugin()
           .androidBatteryInfoStream
           .androidBatteryInfoStream
           .listen((AndroidBatteryInfo? batteryInfo) {
           .listen((AndroidBatteryInfo? batteryInfo) {
-        _logger.info("Battery info: ${batteryInfo!.toJson()}");
-        if (_shouldRunMachineLearning(batteryInfo)) {
-          Bus.instance.fire(MachineLearningControlEvent(true));
-        } else {
-          Bus.instance.fire(MachineLearningControlEvent(false));
-        }
+        _onBatteryStateUpdate(batteryInfo);
       });
       });
+    } else {
+      // Always run Machine Learning on iOS
+      Bus.instance.fire(MachineLearningControlEvent(true));
     }
     }
   }
   }
 
 
-  void onUserInteractionEvent(bool isUserInteracting) {
-    Bus.instance.fire(MachineLearningControlEvent(!isUserInteracting));
+  void onUserInteraction() {
+    _logger.info("User is interacting with the app");
+    _isUserInteracting = true;
+    _fireControlEvent();
+    _resetTimer();
   }
   }
 
 
-  bool _shouldRunMachineLearning(AndroidBatteryInfo info) {
-    if (info.chargingStatus == ChargingStatus.Charging ||
-        info.chargingStatus == ChargingStatus.Full) {
-      return _isAcceptableTemperature(
-        info.temperature ?? kMaximumTemperature,
+  void _fireControlEvent() {
+    final shouldRunML = _isDeviceHealthy && !_isUserInteracting;
+    if (shouldRunML != _isRunningML) {
+      _isRunningML = shouldRunML;
+      _logger.info(
+        "Firing event with device health: $_isDeviceHealthy and user interaction: $_isUserInteracting",
       );
       );
+      Bus.instance.fire(MachineLearningControlEvent(shouldRunML));
     }
     }
+  }
+
+  void _startInteractionTimer({Duration timeout = kDefaultInteractionTimeout}) {
+    _userInteractionTimer = Timer(timeout, () {
+      _logger.info("User is not interacting with the app");
+      _isUserInteracting = false;
+      _fireControlEvent();
+    });
+  }
+
+  void _resetTimer() {
+    _userInteractionTimer.cancel();
+    _startInteractionTimer();
+  }
+
+  void _onBatteryStateUpdate(AndroidBatteryInfo? batteryInfo) {
+    _logger.info("Battery info: ${batteryInfo!.toJson()}");
+    _isDeviceHealthy = _computeIsDeviceHealthy(batteryInfo);
+    _fireControlEvent();
+  }
+
+  bool _computeIsDeviceHealthy(AndroidBatteryInfo info) {
     return _hasSufficientBattery(info.batteryLevel ?? kMinimumBatteryLevel) &&
     return _hasSufficientBattery(info.batteryLevel ?? kMinimumBatteryLevel) &&
-        _isAcceptableTemperature(info.temperature ?? kMaximumTemperature);
+        _isAcceptableTemperature(info.temperature ?? kMaximumTemperature) &&
+        _isBatteryHealthy(info.health ?? "");
   }
   }
 
 
   bool _hasSufficientBattery(int batteryLevel) {
   bool _hasSufficientBattery(int batteryLevel) {
@@ -55,4 +90,8 @@ class MachineLearningController {
   bool _isAcceptableTemperature(int temperature) {
   bool _isAcceptableTemperature(int temperature) {
     return temperature <= kMaximumTemperature;
     return temperature <= kMaximumTemperature;
   }
   }
+
+  bool _isBatteryHealthy(String health) {
+    return !kUnhealthyStates.contains(health);
+  }
 }
 }