| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_ASH_POWER_SMART_CHARGING_SMART_CHARGING_MANAGER_H_ |
| #define CHROME_BROWSER_ASH_POWER_SMART_CHARGING_SMART_CHARGING_MANAGER_H_ |
| |
| #include "base/files/file_path.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/scoped_observation.h" |
| #include "base/task/sequenced_task_runner.h" |
| #include "base/time/time.h" |
| #include "base/timer/timer.h" |
| #include "chrome/browser/ash/power/ml/boot_clock.h" |
| #include "chrome/browser/ash/power/smart_charging/smart_charging_ukm_logger.h" |
| #include "chromeos/dbus/power/power_manager_client.h" |
| #include "chromeos/dbus/power_manager/charge_history_state.pb.h" |
| #include "chromeos/dbus/power_manager/user_charging_event.pb.h" |
| #include "components/session_manager/core/session_manager.h" |
| #include "components/session_manager/core/session_manager_observer.h" |
| #include "mojo/public/cpp/bindings/receiver.h" |
| #include "services/viz/public/mojom/compositing/video_detector_observer.mojom.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| #include "ui/base/user_activity/user_activity_detector.h" |
| #include "ui/base/user_activity/user_activity_observer.h" |
| |
| namespace ash { |
| namespace power { |
| namespace ml { |
| class RecentEventsCounter; |
| } // namespace ml |
| |
| // SmartChargingManager logs battery percentage and other features related to |
| // user charging events. It is currently used to log data and will be |
| // extended to do inference in the future. |
| class SmartChargingManager : public ui::UserActivityObserver, |
| public chromeos::PowerManagerClient::Observer, |
| public viz::mojom::VideoDetectorObserver, |
| public session_manager::SessionManagerObserver { |
| public: |
| SmartChargingManager( |
| ui::UserActivityDetector* detector, |
| mojo::PendingReceiver<viz::mojom::VideoDetectorObserver> receiver, |
| session_manager::SessionManager* session_manager, |
| std::unique_ptr<base::RepeatingTimer> periodic_timer); |
| ~SmartChargingManager() override; |
| SmartChargingManager(const SmartChargingManager&) = delete; |
| SmartChargingManager& operator=(const SmartChargingManager&) = delete; |
| |
| // Stores start time and end time of events. |
| struct TimePeriod { |
| TimePeriod(base::TimeDelta start, base::TimeDelta end) { |
| start_time = start; |
| end_time = end; |
| } |
| base::TimeDelta start_time; |
| base::TimeDelta end_time; |
| }; |
| |
| static std::unique_ptr<SmartChargingManager> CreateInstance(); |
| |
| // ui::UserActivityObserver overrides: |
| void OnUserActivity(const ui::Event* event) override; |
| |
| // chromeos::PowerManagerClient::Observer overrides: |
| void ScreenBrightnessChanged( |
| const power_manager::BacklightBrightnessChange& change) override; |
| void PowerChanged(const power_manager::PowerSupplyProperties& proto) override; |
| void PowerManagerBecameAvailable(bool available) override; |
| void ShutdownRequested(power_manager::RequestShutdownReason reason) override; |
| void SuspendImminent(power_manager::SuspendImminent::Reason reason) override; |
| void LidEventReceived(chromeos::PowerManagerClient::LidState state, |
| base::TimeTicks timestamp) override; |
| void TabletModeEventReceived(chromeos::PowerManagerClient::TabletMode mode, |
| base::TimeTicks timestamp) override; |
| |
| // viz::mojom::VideoDetectorObserver overrides: |
| void OnVideoActivityStarted() override; |
| void OnVideoActivityEnded() override; |
| |
| // session_manager::SessionManagerObserver overrides: |
| void OnUserSessionStarted(bool is_primary_user) override; |
| |
| private: |
| friend class SmartChargingManagerTest; |
| |
| // Populates the UserChargingEvent proto for logging/inference. |
| void PopulateUserChargingEventProto(power_manager::UserChargingEvent* proto); |
| |
| // Log the event. |
| void LogEvent(const power_manager::UserChargingEvent::Event::Reason& reason); |
| |
| // Called when the periodic timer triggers. |
| void OnTimerFired(); |
| |
| // Get charge history from powerd and update it. |
| void UpdateChargeHistory(); |
| |
| // Updates screen brightness percent from received value. |
| void OnReceiveScreenBrightnessPercent( |
| absl::optional<double> screen_brightness_percent); |
| |
| // Updates lid state and tablet mode from received switch states. |
| void OnReceiveSwitchStates( |
| absl::optional<chromeos::PowerManagerClient::SwitchStates> switch_states); |
| |
| // Gets amount of time of video playing recently (e.g. in the last 30 |
| // minutes). |
| base::TimeDelta DurationRecentVideoPlaying(); |
| |
| // Tries to load data from user profile path. |
| void MaybeLoadFromDisk(const base::FilePath& profile_path); |
| |
| // Tries to save data to user profile path. |
| void MaybeSaveToDisk(const base::FilePath& profile_path); |
| |
| // Calls after saving from disk completes. |
| void OnLoadProtoFromDiskComplete( |
| std::unique_ptr<power_manager::PastChargingEvents> proto); |
| |
| // Adds a past events given it's reason to |past_events_|. |
| void AddPastEvent( |
| const power_manager::UserChargingEvent::Event::Reason& reason); |
| |
| // Updates and deletes events. |
| void UpdatePastEvents(); |
| |
| // Gets the "plug in" and "unplug" events of the last charge. |
| std::tuple<power_manager::PastChargingEvents::Event, |
| power_manager::PastChargingEvents::Event> |
| GetLastChargeEvents(); |
| |
| void OnChargeHistoryReceived( |
| absl::optional<power_manager::ChargeHistoryState> proto); |
| |
| base::ScopedObservation<ui::UserActivityDetector, ui::UserActivityObserver> |
| user_activity_observation_{this}; |
| |
| base::ScopedObservation<chromeos::PowerManagerClient, |
| chromeos::PowerManagerClient::Observer> |
| power_manager_client_observation_{this}; |
| base::ScopedObservation<session_manager::SessionManager, |
| session_manager::SessionManagerObserver> |
| session_manager_observation_{this}; |
| |
| // Timer to trigger periodically for logging data. |
| const std::unique_ptr<base::RepeatingTimer> periodic_timer_; |
| |
| // Timer to trigger the update of charge history periodically; |
| const std::unique_ptr<base::RepeatingTimer> charge_history_timer_ = |
| std::make_unique<base::RepeatingTimer>(); |
| |
| // Number of trials to get charge history again if failed. |
| int num_trials_getting_charge_history_ = 5; |
| const std::unique_ptr<base::OneShotTimer> |
| retry_getting_charge_history_timer_ = |
| std::make_unique<base::OneShotTimer>(); |
| |
| // Checks if data is loaded from disk yet. |
| bool loaded_from_disk_ = false; |
| |
| // Helper to return TimeSinceBoot. |
| ml::BootClock boot_clock_; |
| int event_id_ = -1; |
| |
| const mojo::Receiver<viz::mojom::VideoDetectorObserver> receiver_; |
| |
| // Counters for user events. |
| const std::unique_ptr<ml::RecentEventsCounter> mouse_counter_; |
| const std::unique_ptr<ml::RecentEventsCounter> key_counter_; |
| const std::unique_ptr<ml::RecentEventsCounter> stylus_counter_; |
| const std::unique_ptr<ml::RecentEventsCounter> touch_counter_; |
| |
| chromeos::PowerManagerClient::LidState lid_state_ = |
| chromeos::PowerManagerClient::LidState::NOT_PRESENT; |
| |
| chromeos::PowerManagerClient::TabletMode tablet_mode_ = |
| chromeos::PowerManagerClient::TabletMode::UNSUPPORTED; |
| |
| // A queue that stores recent video usage of the user. |
| base::circular_deque<TimePeriod> recent_video_usage_; |
| // Most recent time the user started playing video. |
| base::TimeDelta most_recent_video_start_time_; |
| bool is_video_playing_ = false; |
| |
| // TODO(crbug.com/1028853): This is for testing only. Need to remove when ukm |
| // logger is available. |
| power_manager::UserChargingEvent user_charging_event_for_test_; |
| std::vector<power_manager::PastChargingEvents::Event> past_events_; |
| |
| absl::optional<double> battery_percent_; |
| absl::optional<double> screen_brightness_percent_; |
| absl::optional<power_manager::PowerSupplyProperties::ExternalPower> |
| external_power_; |
| power_manager::ChargeHistoryState charge_history_; |
| absl::optional<bool> is_charging_; |
| |
| absl::optional<base::FilePath> profile_path_; |
| const std::unique_ptr<SmartChargingUkmLogger> ukm_logger_; |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; |
| base::WeakPtrFactory<SmartChargingManager> weak_ptr_factory_{this}; |
| }; |
| |
| } // namespace power |
| } // namespace ash |
| |
| #endif // CHROME_BROWSER_ASH_POWER_SMART_CHARGING_SMART_CHARGING_MANAGER_H_ |