1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_CHROMEOS_POWER_ML_ADAPTIVE_SCREEN_BRIGHTNESS_MANAGER_H_
6 #define CHROME_BROWSER_CHROMEOS_POWER_ML_ADAPTIVE_SCREEN_BRIGHTNESS_MANAGER_H_
7 
8 #include <memory>
9 
10 #include "base/macros.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/optional.h"
13 #include "base/scoped_observer.h"
14 #include "base/time/time.h"
15 #include "chrome/browser/chromeos/power/ml/boot_clock.h"
16 #include "chrome/browser/chromeos/power/ml/screen_brightness_event.pb.h"
17 #include "chromeos/dbus/power/power_manager_client.h"
18 #include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
19 #include "mojo/public/cpp/bindings/pending_receiver.h"
20 #include "mojo/public/cpp/bindings/receiver.h"
21 #include "services/viz/public/mojom/compositing/video_detector_observer.mojom.h"
22 #include "ui/base/user_activity/user_activity_detector.h"
23 #include "ui/base/user_activity/user_activity_observer.h"
24 
25 namespace base {
26 class RepeatingTimer;
27 }  // namespace base
28 
29 namespace chromeos {
30 
31 class AccessibilityManager;
32 class MagnificationManager;
33 
34 namespace power {
35 namespace ml {
36 
37 class AdaptiveScreenBrightnessUkmLogger;
38 class RecentEventsCounter;
39 
40 // AdaptiveScreenBrightnessManager logs screen brightness and other features
41 // periodically and also when the screen brightness changes.
42 class AdaptiveScreenBrightnessManager
43     : public ui::UserActivityObserver,
44       public PowerManagerClient::Observer,
45       public viz::mojom::VideoDetectorObserver {
46  public:
47   // Duration of inactivity that marks the end of an activity.
48   static constexpr base::TimeDelta kInactivityDuration =
49       base::TimeDelta::FromSeconds(20);
50 
51   // Interval at which data should be logged.
52   static constexpr base::TimeDelta kLoggingInterval =
53       base::TimeDelta::FromMinutes(10);
54 
55   AdaptiveScreenBrightnessManager(
56       std::unique_ptr<AdaptiveScreenBrightnessUkmLogger> ukm_logger,
57       ui::UserActivityDetector* detector,
58       chromeos::PowerManagerClient* power_manager_client,
59       AccessibilityManager* accessibility_manager,
60       MagnificationManager* magnification_manager,
61       mojo::PendingReceiver<viz::mojom::VideoDetectorObserver> receiver,
62       std::unique_ptr<base::RepeatingTimer> periodic_timer);
63 
64   ~AdaptiveScreenBrightnessManager() override;
65 
66   // Returns a new instance of AdaptiveScreenBrightnessManager.
67   static std::unique_ptr<AdaptiveScreenBrightnessManager> CreateInstance();
68 
69   // ui::UserActivityObserver overrides:
70   void OnUserActivity(const ui::Event* event) override;
71 
72   // chromeos::PowerManagerClient::Observer overrides:
73   void ScreenBrightnessChanged(
74       const power_manager::BacklightBrightnessChange& change) override;
75   void PowerChanged(const power_manager::PowerSupplyProperties& proto) override;
76   void LidEventReceived(chromeos::PowerManagerClient::LidState state,
77                         const base::TimeTicks& timestamp) override;
78   void TabletModeEventReceived(chromeos::PowerManagerClient::TabletMode mode,
79                                const base::TimeTicks& timestamp) override;
80 
81   // viz::mojom::VideoDetectorObserver overrides:
82   void OnVideoActivityStarted() override;
83   void OnVideoActivityEnded() override;
84 
85  private:
86   friend class AdaptiveScreenBrightnessManagerTest;
87 
88   // Called when the periodic timer triggers.
89   void OnTimerFired();
90 
91   // Updates lid state and tablet mode from received switch states.
92   void OnReceiveSwitchStates(
93       base::Optional<chromeos::PowerManagerClient::SwitchStates> switch_states);
94 
95   // Updates screen brightness percent from received value.
96   void OnReceiveScreenBrightnessPercent(
97       base::Optional<double> screen_brightness_percent);
98 
99   // Returns the night light temperature as a percentage in the range [0, 100].
100   // Returns nullopt when the night light is not enabled.
101   const base::Optional<int> GetNightLightTemperaturePercent() const;
102 
103   void LogEvent();
104 
105   BootClock boot_clock_;
106 
107   // Timer to trigger periodically for logging data.
108   const std::unique_ptr<base::RepeatingTimer> periodic_timer_;
109 
110   const std::unique_ptr<AdaptiveScreenBrightnessUkmLogger> ukm_logger_;
111 
112   ScopedObserver<ui::UserActivityDetector, ui::UserActivityObserver>
113       user_activity_observer_{this};
114   ScopedObserver<chromeos::PowerManagerClient,
115                  chromeos::PowerManagerClient::Observer>
116       power_manager_client_observer_{this};
117 
118   AccessibilityManager* const accessibility_manager_;
119   MagnificationManager* const magnification_manager_;
120 
121   const mojo::Receiver<viz::mojom::VideoDetectorObserver> receiver_;
122 
123   // Counters for user events.
124   const std::unique_ptr<RecentEventsCounter> mouse_counter_;
125   const std::unique_ptr<RecentEventsCounter> key_counter_;
126   const std::unique_ptr<RecentEventsCounter> stylus_counter_;
127   const std::unique_ptr<RecentEventsCounter> touch_counter_;
128 
129   chromeos::PowerManagerClient::LidState lid_state_ =
130       chromeos::PowerManagerClient::LidState::NOT_PRESENT;
131 
132   chromeos::PowerManagerClient::TabletMode tablet_mode_ =
133       chromeos::PowerManagerClient::TabletMode::UNSUPPORTED;
134 
135   base::Optional<power_manager::PowerSupplyProperties::ExternalPower>
136       external_power_;
137 
138   // Battery percent. This is in the range [0.0, 100.0].
139   base::Optional<float> battery_percent_;
140 
141   // Both |screen_brightness_percent_| and |previous_screen_brightness_percent_|
142   // are values reported directly by powerd. They are percentages as double but
143   // are in the range of [0, 100]. When we convert these values to the fields in
144   // ScreenBrightnessEvent, we cast them to ints.
145   base::Optional<double> screen_brightness_percent_;
146   base::Optional<double> previous_screen_brightness_percent_;
147   base::Optional<base::TimeDelta> last_event_time_since_boot_;
148 
149   // The time (since boot) of the most recent active event. This is the end of
150   // the most recent period of activity.
151   base::Optional<base::TimeDelta> last_activity_time_since_boot_;
152   // The time (since boot) of the start of the most recent period of activity.
153   base::Optional<base::TimeDelta> start_activity_time_since_boot_;
154   base::Optional<bool> is_video_playing_;
155   base::Optional<ScreenBrightnessEvent_Event_Reason> reason_;
156 
157   base::WeakPtrFactory<AdaptiveScreenBrightnessManager> weak_ptr_factory_{this};
158 
159   DISALLOW_COPY_AND_ASSIGN(AdaptiveScreenBrightnessManager);
160 };
161 
162 }  // namespace ml
163 }  // namespace power
164 }  // namespace chromeos
165 
166 #endif  // CHROME_BROWSER_CHROMEOS_POWER_ML_ADAPTIVE_SCREEN_BRIGHTNESS_MANAGER_H_
167