File: smart_charging_manager.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (211 lines) | stat: -rw-r--r-- 8,409 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
// 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 <optional>

#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 "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(
      std::optional<double> screen_brightness_percent);

  // Updates lid state and tablet mode from received switch states.
  void OnReceiveSwitchStates(
      std::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(
      std::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/40109338): 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_;

  std::optional<double> battery_percent_;
  std::optional<double> screen_brightness_percent_;
  std::optional<power_manager::PowerSupplyProperties::ExternalPower>
      external_power_;
  power_manager::ChargeHistoryState charge_history_;
  std::optional<bool> is_charging_;

  std::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_