OLD | NEW |
| (Empty) |
1 // Copyright 2016 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 #include "chrome/browser/metrics/desktop_engagement/desktop_engagement_service.h
" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/metrics/histogram_macros.h" | |
9 #include "base/strings/string_number_conversions.h" | |
10 #include "components/variations/variations_associated_data.h" | |
11 | |
12 namespace metrics { | |
13 | |
14 namespace { | |
15 | |
16 DesktopEngagementService* g_instance = nullptr; | |
17 | |
18 } // namespace | |
19 | |
20 // static | |
21 void DesktopEngagementService::Initialize() { | |
22 g_instance = new DesktopEngagementService; | |
23 } | |
24 | |
25 // static | |
26 bool DesktopEngagementService::IsInitialized() { | |
27 return g_instance != nullptr; | |
28 } | |
29 | |
30 // static | |
31 DesktopEngagementService* DesktopEngagementService::Get() { | |
32 DCHECK(g_instance); | |
33 return g_instance; | |
34 } | |
35 | |
36 void DesktopEngagementService::StartTimer(base::TimeDelta duration) { | |
37 timer_.Start(FROM_HERE, duration, | |
38 base::Bind(&DesktopEngagementService::OnTimerFired, | |
39 weak_factory_.GetWeakPtr())); | |
40 } | |
41 | |
42 void DesktopEngagementService::OnVisibilityChanged(bool visible) { | |
43 is_visible_ = visible; | |
44 if (is_visible_ && !is_first_session_) { | |
45 OnUserEvent(); | |
46 } else if (in_session_ && !is_audio_playing_) { | |
47 DVLOG(4) << "Ending session due to visibility change"; | |
48 EndSession(); | |
49 } | |
50 } | |
51 | |
52 void DesktopEngagementService::OnUserEvent() { | |
53 if (!is_visible_) | |
54 return; | |
55 | |
56 last_user_event_ = base::TimeTicks::Now(); | |
57 // This may start session. | |
58 if (!in_session_) { | |
59 DVLOG(4) << "Starting session due to user event"; | |
60 StartSession(); | |
61 } | |
62 } | |
63 | |
64 void DesktopEngagementService::OnAudioStart() { | |
65 // This may start session. | |
66 is_audio_playing_ = true; | |
67 if (!in_session_) { | |
68 DVLOG(4) << "Starting session due to audio start"; | |
69 StartSession(); | |
70 } | |
71 } | |
72 | |
73 void DesktopEngagementService::OnAudioEnd() { | |
74 is_audio_playing_ = false; | |
75 | |
76 // If the timer is not running, this means that no user events happened in the | |
77 // last 5 minutes so the session can be terminated. | |
78 if (!timer_.IsRunning()) { | |
79 DVLOG(4) << "Ending session due to audio ending"; | |
80 EndSession(); | |
81 } | |
82 } | |
83 | |
84 DesktopEngagementService::DesktopEngagementService() | |
85 : session_start_(base::TimeTicks::Now()), | |
86 last_user_event_(session_start_), | |
87 audio_tracker_(this), | |
88 weak_factory_(this) { | |
89 InitInactivityTimeout(); | |
90 } | |
91 | |
92 DesktopEngagementService::~DesktopEngagementService() {} | |
93 | |
94 void DesktopEngagementService::OnTimerFired() { | |
95 base::TimeDelta remaining = | |
96 inactivity_timeout_ - (base::TimeTicks::Now() - last_user_event_); | |
97 if (remaining.ToInternalValue() > 0) { | |
98 StartTimer(remaining); | |
99 return; | |
100 } | |
101 | |
102 // No user events happened in the last 5 min. Terminate the session now. | |
103 if (!is_audio_playing_) { | |
104 DVLOG(4) << "Ending session after delay"; | |
105 EndSession(); | |
106 } | |
107 } | |
108 | |
109 void DesktopEngagementService::StartSession() { | |
110 in_session_ = true; | |
111 is_first_session_ = false; | |
112 session_start_ = base::TimeTicks::Now(); | |
113 StartTimer(inactivity_timeout_); | |
114 } | |
115 | |
116 void DesktopEngagementService::EndSession() { | |
117 in_session_ = false; | |
118 | |
119 base::TimeDelta delta = base::TimeTicks::Now() - session_start_; | |
120 | |
121 // If timer is not running then session ended because of inactivity. | |
122 if (!timer_.IsRunning()) | |
123 delta -= inactivity_timeout_; | |
124 | |
125 DVLOG(4) << "Logging session length of " << delta.InSeconds() << " seconds."; | |
126 | |
127 // Note: This metric is recorded separately for Android in | |
128 // UmaSessionStats::UmaEndSession. | |
129 UMA_HISTOGRAM_LONG_TIMES("Session.TotalDuration", delta); | |
130 } | |
131 | |
132 void DesktopEngagementService::InitInactivityTimeout() { | |
133 const int kDefaultInactivityTimeoutMinutes = 5; | |
134 | |
135 int timeout_minutes = kDefaultInactivityTimeoutMinutes; | |
136 std::string param_value = variations::GetVariationParamValue( | |
137 "DesktopEngagement", "inactivity_timeout"); | |
138 if (!param_value.empty()) | |
139 base::StringToInt(param_value, &timeout_minutes); | |
140 | |
141 inactivity_timeout_ = base::TimeDelta::FromMinutes(timeout_minutes); | |
142 } | |
143 | |
144 } // namespace metrics | |
OLD | NEW |