1 // Copyright 2019 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 COMPONENTS_GUEST_OS_GUEST_OS_ENGAGEMENT_METRICS_H_ 6 #define COMPONENTS_GUEST_OS_GUEST_OS_ENGAGEMENT_METRICS_H_ 7 8 #include <memory> 9 10 #include "base/macros.h" 11 #include "base/time/time.h" 12 #include "base/timer/timer.h" 13 #include "chromeos/dbus/power/power_manager_client.h" 14 #include "components/session_manager/core/session_manager_observer.h" 15 #include "ui/wm/public/activation_change_observer.h" 16 17 class PrefService; 18 19 namespace aura { 20 class Window; 21 } // namespace aura 22 23 namespace base { 24 class Clock; 25 class TickClock; 26 } // namespace base 27 28 namespace guest_os { 29 30 // A class for recording engagement metrics. Calculates and reports daily 31 // totals for the following metrics: 32 // - Foo.EngagementTime.Total: Engaged session time, i.e. excluding when the 33 // screen is locked or dim due to user idle. To allow comparisons with the 34 // other metrics, this class should only be instantiated when the relevant 35 // Guest OS is supported. 36 // - Foo.EngagementTime.Foreground: Time when the user is engaged and focused 37 // on a matching window. 38 // - Foo.EngagementTime.Background: Time when the user is engaged and not 39 // focused on a matching window, but the Guest OS is otherwise active in the 40 // background. 41 // - Foo.Engagement.FooTotal: Total of Foreground and Background. 42 class GuestOsEngagementMetrics : public wm::ActivationChangeObserver, 43 public session_manager::SessionManagerObserver, 44 public chromeos::PowerManagerClient::Observer { 45 public: 46 using WindowMatcher = base::RepeatingCallback<bool(const aura::Window*)>; 47 48 GuestOsEngagementMetrics(PrefService* pref_service, 49 WindowMatcher window_matcher, 50 const std::string& pref_prefix, 51 const std::string& uma_name); 52 ~GuestOsEngagementMetrics() override; 53 54 // Instead of using |window_matcher_|, we let consumers define when the Guest 55 // OS is active in the background. This function should be called whenever 56 // changes. 57 void SetBackgroundActive(bool background_active); 58 59 void SetClocksForTesting(base::Clock* clock, base::TickClock* tick_clock); 60 61 // wm::ActivationChangeObserver: 62 void OnWindowActivated(wm::ActivationChangeObserver::ActivationReason reason, 63 aura::Window* gained_active, 64 aura::Window* lost_active) override; 65 66 // session_manager::SessionManagerObserver: 67 void OnSessionStateChanged() override; 68 69 // chromeos::PowerManagerClient::Observer: 70 void ScreenIdleStateChanged( 71 const power_manager::ScreenIdleState& proto) override; 72 73 private: 74 // Restores accumulated engagement time in previous sessions from profile 75 // preferences. 76 void RestoreEngagementTimeFromPrefs(); 77 78 // Called periodically to save accumulated results to profile preferences. 79 void SaveEngagementTimeToPrefs(); 80 81 // Called whenever engagement state is changed. Time spent in last state is 82 // accumulated to corresponding metrics. 83 void UpdateEngagementTime(); 84 85 // Records accumulated engagement time metrics to UMA if necessary (i.e. day 86 // has changed). 87 void RecordEngagementTimeToUmaIfNeeded(); 88 89 // Resets accumulated engagement times to zero, and updates both OS version 90 // and day ID. 91 void ResetEngagementTimePrefs(); 92 93 bool ShouldAccumulateEngagementTotalTime() const; 94 bool ShouldAccumulateEngagementForegroundTime() const; 95 bool ShouldAccumulateEngagementBackgroundTime() const; 96 97 bool ShouldRecordEngagementTimeToUma() const; 98 99 PrefService* const pref_service_; 100 101 WindowMatcher window_matcher_; 102 std::string pref_prefix_; 103 std::string uma_name_; 104 105 // |clock_| is used for determining when to log to UMA, while |tick_clock_| 106 // is used to calculate elapsed time. 107 const base::Clock* clock_; 108 const base::TickClock* tick_clock_; 109 base::RepeatingTimer update_engagement_time_timer_; 110 base::RepeatingTimer save_engagement_time_to_prefs_timer_; 111 base::TimeTicks last_update_ticks_; 112 113 // States for determining which engagement metrics should we accumulate to. 114 bool session_active_ = false; 115 bool screen_dimmed_ = false; 116 bool background_active_ = false; 117 bool matched_window_active_ = false; 118 119 // Accumulated results and associated state which are saved to profile 120 // preferences at fixed interval. 121 int day_id_ = 0; 122 base::TimeDelta engagement_time_total_; 123 base::TimeDelta engagement_time_foreground_; 124 base::TimeDelta engagement_time_background_; 125 126 DISALLOW_COPY_AND_ASSIGN(GuestOsEngagementMetrics); 127 }; 128 129 } // namespace guest_os 130 131 #endif // COMPONENTS_GUEST_OS_GUEST_OS_ENGAGEMENT_METRICS_H_ 132