Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1267)

Side by Side Diff: chrome/installer/util/experiment.cc

Issue 2889323004: Win 10 Inactive toast experiment metrics and storage modifications. (Closed)
Patch Set: Apply comments from 2898843002 Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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/installer/util/experiment.h"
6
7 #include <cmath>
8
9 #include "base/logging.h"
10
11 namespace installer {
12
13 // Returns closest integer of logarithm of |x| with base |b|.
14 static double LogFloor(double x, double b) {
15 return round(log(x) / log(b));
grt (UTC plus 2) 2017/05/24 13:43:38 nit: std::round
nikunjb 2017/05/30 21:45:01 Done.
16 }
17
18 // Returns the base to use for exponential buckets so that buckets
19 // 0,1,.. 2^|bits|-1 cover range [0, max_val]. If this function return b
20 // then Bucket value i will store values from [b^i, b^(i+1)]
21 static double ExpBucketBase(int max_val, int bits) {
22 return exp(log(max_val - 1) / (1 << bits));
grt (UTC plus 2) 2017/05/24 13:43:38 std::exp, std::log
nikunjb 2017/05/30 21:45:01 Done.
23 }
24
25 Experiment::Experiment() = default;
26 Experiment::Experiment(Experiment&&) = default;
27 Experiment::Experiment(const Experiment&) = default;
28 Experiment::~Experiment() = default;
29
30 void Experiment::InitializeFromMetrics(const ExperimentMetrics& metrics) {
31 *this = Experiment();
32 metrics_ = metrics;
33 state_ = metrics.state;
34 group_ = metrics.group;
35 toast_location_ = metrics.toast_location;
36 toast_count_ = metrics.toast_count;
37 if (metrics_.last_used_bucket > 0) {
38 double log_base = ExpBucketBase(ExperimentMetrics::kMaxLastUsed,
39 ExperimentMetrics::kLastUsedBucketBits);
40 inactive_days_ =
41 static_cast<int>(round(pow(log_base, metrics_.last_used_bucket) - 1));
grt (UTC plus 2) 2017/05/24 13:43:38 std::pow
nikunjb 2017/05/30 21:45:01 Done.
42 if (inactive_days_ > ExperimentMetrics::kMaxLastUsed) {
43 inactive_days_ = ExperimentMetrics::kMaxLastUsed;
44 }
45 }
46 if (metrics_.session_length_bucket > 0) {
47 double log_base = ExpBucketBase(ExperimentMetrics::kMaxSessionLength,
48 ExperimentMetrics::kSessionLengthBits);
49 user_session_uptime_ = base::TimeDelta::FromMinutes(static_cast<int>(
50 round(pow(log_base, metrics_.session_length_bucket) - 1)));
51 if (user_session_uptime_.InMinutes() >
52 ExperimentMetrics::kMaxSessionLength) {
53 user_session_uptime_ =
54 base::TimeDelta::FromMinutes(ExperimentMetrics::kMaxSessionLength);
55 }
56 }
57
58 if (metrics_.display_time_bucket > 0) {
59 double log_base = ExpBucketBase(ExperimentMetrics::kMaxDisplayTime,
60 ExperimentMetrics::kDisplayTimeBucketBits);
61 action_delay_ = base::TimeDelta::FromSeconds(static_cast<int>(
62 round(pow(log_base, metrics_.display_time_bucket) - 1)));
63 if (action_delay_.InSeconds() > ExperimentMetrics::kMaxDisplayTime) {
64 action_delay_ =
65 base::TimeDelta::FromSeconds(ExperimentMetrics::kMaxDisplayTime);
66 }
67 }
68
69 if (metrics_.first_toast_offset > 0) {
70 // Accurate time information is not kept in |metrics|. Reconstruct
71 // the toast display time to the closest day.
72 first_display_time_ =
73 (base::Time::UnixEpoch() +
74 base::TimeDelta::FromSeconds(
75 ExperimentMetrics::kExperimentStartSeconds) +
76 base::TimeDelta::FromDays(metrics_.first_toast_offset));
77 DCHECK_LE(metrics_.first_toast_offset,
78 ExperimentMetrics::kExperimentStartSeconds);
79 }
80 // Latest display time is not stored in experiment metrics. So, it will
81 // be initialized to be same as |first_display_time_| for now.
82 latest_display_time_ = first_display_time_;
83 }
84
85 void Experiment::SetState(ExperimentMetrics::State state) {
86 state_ = state;
87 metrics_.SetState(state);
88 }
89
90 void Experiment::AssignGroup(int group) {
91 DCHECK_GE(group, 0);
92 DCHECK_LT(group, ExperimentMetrics::kNumGroups);
93 DCHECK(metrics_.InInitialState());
94
95 group_ = group;
96 metrics_.group = group;
97 SetState(ExperimentMetrics::kGroupAssigned);
98 }
99
100 void Experiment::SetToastLocation(ExperimentMetrics::ToastLocation location) {
101 DCHECK(!metrics_.InTerminalState());
102 DCHECK(!metrics_.InInitialState());
103 toast_location_ = location;
104 metrics_.toast_location = location;
105 }
106
107 void Experiment::SetInactiveDays(int days) {
108 DCHECK(!metrics_.InTerminalState());
109 DCHECK(!metrics_.InInitialState());
110 DCHECK_GE(days, 0);
111 inactive_days_ = days;
112 double log_base = ExpBucketBase(ExperimentMetrics::kMaxLastUsed,
113 ExperimentMetrics::kLastUsedBucketBits);
114 metrics_.last_used_bucket = LogFloor(1 + days, log_base);
115 if (days > ExperimentMetrics::kMaxLastUsed) {
116 metrics_.last_used_bucket =
117 LogFloor(1 + ExperimentMetrics::kMaxLastUsed, log_base);
118 }
119 }
120
121 void Experiment::SetToastCount(int count) {
122 DCHECK(!metrics_.InTerminalState());
123 DCHECK(!metrics_.InInitialState());
124 toast_count_ = count;
125 metrics_.toast_count = count;
126 if (count > ExperimentMetrics::kMaxToastCount) {
127 metrics_.toast_count = ExperimentMetrics::kMaxToastCount;
128 }
129 }
130
131 void Experiment::SetDisplayTime(const base::Time& time) {
132 DCHECK(!metrics_.InTerminalState());
133 DCHECK(!metrics_.InInitialState());
134 if (metrics_.first_toast_offset == 0) {
135 // This is the first time toast is shown so add user to today's cohort.
136 first_display_time_ = time;
137 metrics_.first_toast_offset =
138 (time - base::Time::UnixEpoch() -
139 base::TimeDelta::FromSeconds(
140 ExperimentMetrics::kExperimentStartSeconds))
141 .InDays();
142 if (metrics_.first_toast_offset > ExperimentMetrics::kMaxFirstToastOffset ||
143 metrics_.first_toast_offset < 0) {
144 // First display time is outside the experiment range. Invalid local time.
145 // Reset to highest value of first display time.
146 metrics_.first_toast_offset = ExperimentMetrics::kMaxFirstToastOffset;
147 }
148 }
149 latest_display_time_ = time;
150 metrics_.toast_hour = (time - time.LocalMidnight()).InHours();
151 DCHECK_LE(metrics_.toast_hour, 24);
152 DCHECK_GE(metrics_.toast_hour, 0);
153 }
154
155 void Experiment::SetUserSessionUptime(const base::TimeDelta& time_delta) {
156 DCHECK(!metrics_.InTerminalState());
157 DCHECK(!metrics_.InInitialState());
158 user_session_uptime_ = time_delta;
159 double log_base = ExpBucketBase(ExperimentMetrics::kMaxSessionLength,
160 ExperimentMetrics::kSessionLengthBits);
161 metrics_.session_length_bucket =
162 LogFloor(1 + time_delta.InMinutes(), log_base);
163 if (time_delta.InMinutes() > ExperimentMetrics::kMaxSessionLength) {
164 metrics_.session_length_bucket =
165 LogFloor(1 + ExperimentMetrics::kMaxSessionLength, log_base);
166 }
167 }
168
169 void Experiment::SetActionDelay(const base::TimeDelta& time_delta) {
170 DCHECK(!metrics_.InTerminalState());
171 DCHECK(!metrics_.InInitialState());
172 action_delay_ = time_delta;
173 double log_base = ExpBucketBase(ExperimentMetrics::kMaxDisplayTime,
174 ExperimentMetrics::kDisplayTimeBucketBits);
175 metrics_.display_time_bucket = LogFloor(1 + time_delta.InSeconds(), log_base);
176 if (time_delta.InSeconds() > ExperimentMetrics::kMaxDisplayTime) {
177 metrics_.display_time_bucket =
178 LogFloor(1 + ExperimentMetrics::kMaxDisplayTime, log_base);
179 }
180 }
181
182 } // namespace installer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698