12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- import "dart:async";
- import "dart:io";
- import "package:battery_info/battery_info_plugin.dart";
- import "package:battery_info/model/android_battery_info.dart";
- import "package:logging/logging.dart";
- import "package:photos/core/event_bus.dart";
- import "package:photos/events/machine_learning_control_event.dart";
- class MachineLearningController {
- MachineLearningController._privateConstructor();
- static final MachineLearningController instance =
- MachineLearningController._privateConstructor();
- final _logger = Logger("MachineLearningController");
- static const kMaximumTemperature = 36; // 36 degree celsius
- 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() {
- if (Platform.isAndroid) {
- _startInteractionTimer(timeout: kInitialInteractionTimeout);
- BatteryInfoPlugin()
- .androidBatteryInfoStream
- .listen((AndroidBatteryInfo? batteryInfo) {
- _onBatteryStateUpdate(batteryInfo);
- });
- } else {
- // Always run Machine Learning on iOS
- Bus.instance.fire(MachineLearningControlEvent(true));
- }
- }
- void onUserInteraction() {
- _logger.info("User is interacting with the app");
- _isUserInteracting = true;
- _fireControlEvent();
- _resetTimer();
- }
- 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) &&
- _isAcceptableTemperature(info.temperature ?? kMaximumTemperature) &&
- _isBatteryHealthy(info.health ?? "");
- }
- bool _hasSufficientBattery(int batteryLevel) {
- return batteryLevel >= kMinimumBatteryLevel;
- }
- bool _isAcceptableTemperature(int temperature) {
- return temperature <= kMaximumTemperature;
- }
- bool _isBatteryHealthy(String health) {
- return !kUnhealthyStates.contains(health);
- }
- }
|