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

Side by Side Diff: components/doodle/doodle_service.cc

Issue 2760253003: [Doodle] Record UMA for DoodleConfig download outcome and time (Closed)
Patch Set: review 1 Created 3 years, 9 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
1 // Copyright 2017 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/doodle/doodle_service.h" 5 #include "components/doodle/doodle_service.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/metrics/histogram_macros.h"
10 #include "base/time/time.h" 11 #include "base/time/time.h"
11 #include "base/values.h" 12 #include "base/values.h"
12 #include "components/doodle/pref_names.h" 13 #include "components/doodle/pref_names.h"
13 #include "components/prefs/pref_registry.h" 14 #include "components/prefs/pref_registry.h"
14 #include "components/prefs/pref_registry_simple.h" 15 #include "components/prefs/pref_registry_simple.h"
15 #include "components/prefs/pref_service.h" 16 #include "components/prefs/pref_service.h"
16 17
17 namespace doodle { 18 namespace doodle {
18 19
19 // static 20 // static
20 void DoodleService::RegisterProfilePrefs(PrefRegistrySimple* pref_registry) { 21 void DoodleService::RegisterProfilePrefs(PrefRegistrySimple* pref_registry) {
21 pref_registry->RegisterDictionaryPref(prefs::kCachedConfig, 22 pref_registry->RegisterDictionaryPref(prefs::kCachedConfig,
22 new base::DictionaryValue(), 23 new base::DictionaryValue(),
23 PrefRegistry::LOSSY_PREF); 24 PrefRegistry::LOSSY_PREF);
24 pref_registry->RegisterInt64Pref(prefs::kCachedConfigExpiry, 0, 25 pref_registry->RegisterInt64Pref(prefs::kCachedConfigExpiry, 0,
25 PrefRegistry::LOSSY_PREF); 26 PrefRegistry::LOSSY_PREF);
26 } 27 }
27 28
28 DoodleService::DoodleService(PrefService* pref_service, 29 DoodleService::DoodleService(PrefService* pref_service,
29 std::unique_ptr<DoodleFetcher> fetcher, 30 std::unique_ptr<DoodleFetcher> fetcher,
30 std::unique_ptr<base::OneShotTimer> expiry_timer, 31 std::unique_ptr<base::OneShotTimer> expiry_timer,
31 std::unique_ptr<base::Clock> clock) 32 std::unique_ptr<base::Clock> clock,
33 std::unique_ptr<base::TickClock> tick_clock)
32 : pref_service_(pref_service), 34 : pref_service_(pref_service),
33 fetcher_(std::move(fetcher)), 35 fetcher_(std::move(fetcher)),
34 expiry_timer_(std::move(expiry_timer)), 36 expiry_timer_(std::move(expiry_timer)),
35 clock_(std::move(clock)) { 37 clock_(std::move(clock)),
38 tick_clock_(std::move(tick_clock)) {
36 DCHECK(pref_service_); 39 DCHECK(pref_service_);
37 DCHECK(fetcher_); 40 DCHECK(fetcher_);
38 DCHECK(expiry_timer_); 41 DCHECK(expiry_timer_);
39 DCHECK(clock_); 42 DCHECK(clock_);
43 DCHECK(tick_clock_);
40 44
41 base::Time expiry_date = base::Time::FromInternalValue( 45 base::Time expiry_date = base::Time::FromInternalValue(
42 pref_service_->GetInt64(prefs::kCachedConfigExpiry)); 46 pref_service_->GetInt64(prefs::kCachedConfigExpiry));
43 base::Optional<DoodleConfig> config = DoodleConfig::FromDictionary( 47 base::Optional<DoodleConfig> config = DoodleConfig::FromDictionary(
44 *pref_service_->GetDictionary(prefs::kCachedConfig), base::nullopt); 48 *pref_service_->GetDictionary(prefs::kCachedConfig), base::nullopt);
45 UpdateCachedConfig(expiry_date - clock_->Now(), config); 49 DoodleState state =
50 config.has_value() ? DoodleState::AVAILABLE : DoodleState::NO_DOODLE;
51 UpdateCachedConfig(state, expiry_date - clock_->Now(), config);
46 } 52 }
47 53
48 DoodleService::~DoodleService() = default; 54 DoodleService::~DoodleService() = default;
49 55
50 void DoodleService::Shutdown() {} 56 void DoodleService::Shutdown() {}
51 57
52 void DoodleService::AddObserver(Observer* observer) { 58 void DoodleService::AddObserver(Observer* observer) {
53 observers_.AddObserver(observer); 59 observers_.AddObserver(observer);
54 } 60 }
55 61
56 void DoodleService::RemoveObserver(Observer* observer) { 62 void DoodleService::RemoveObserver(Observer* observer) {
57 observers_.RemoveObserver(observer); 63 observers_.RemoveObserver(observer);
58 } 64 }
59 65
60 void DoodleService::Refresh() { 66 void DoodleService::Refresh() {
61 fetcher_->FetchDoodle( 67 fetcher_->FetchDoodle(base::BindOnce(&DoodleService::DoodleFetched,
62 base::BindOnce(&DoodleService::DoodleFetched, base::Unretained(this))); 68 base::Unretained(this),
69 tick_clock_->NowTicks()));
70 }
71
72 // static
73 bool DoodleService::DownloadOutcomeIsSuccess(DownloadOutcome outcome) {
74 switch (outcome) {
75 case OUTCOME_NEW_DOODLE:
76 case OUTCOME_REVALIDATED_DOODLE:
77 case OUTCOME_CHANGED_DOODLE:
78 case OUTCOME_NO_DOODLE:
79 return true;
80 case OUTCOME_EXPIRED:
81 case OUTCOME_DOWNLOAD_ERROR:
82 case OUTCOME_PARSING_ERROR:
83 return false;
84 case OUTCOME_COUNT:
85 NOTREACHED();
86 }
87 return false;
88 }
89
90 // static
91 void DoodleService::RecordDownloadMetrics(DownloadOutcome outcome,
92 base::TimeDelta download_time) {
93 UMA_HISTOGRAM_ENUMERATION("Doodle.ConfigDownloadOutcome", outcome,
94 OUTCOME_COUNT);
95
96 if (DownloadOutcomeIsSuccess(outcome)) {
97 UMA_HISTOGRAM_MEDIUM_TIMES("Doodle.ConfigDownloadTime", download_time);
98 }
63 } 99 }
64 100
65 void DoodleService::DoodleFetched( 101 void DoodleService::DoodleFetched(
102 base::TimeTicks start_time,
66 DoodleState state, 103 DoodleState state,
67 base::TimeDelta time_to_live, 104 base::TimeDelta time_to_live,
68 const base::Optional<DoodleConfig>& doodle_config) { 105 const base::Optional<DoodleConfig>& doodle_config) {
69 UpdateCachedConfig(time_to_live, doodle_config); 106 base::TimeDelta download_time = tick_clock_->NowTicks() - start_time;
107 DownloadOutcome outcome =
108 UpdateCachedConfig(state, time_to_live, doodle_config);
109 RecordDownloadMetrics(outcome, download_time);
70 } 110 }
71 111
72 void DoodleService::UpdateCachedConfig( 112 DoodleService::DownloadOutcome DoodleService::UpdateCachedConfig(
113 DoodleState state,
73 base::TimeDelta time_to_live, 114 base::TimeDelta time_to_live,
74 const base::Optional<DoodleConfig>& doodle_config) { 115 const base::Optional<DoodleConfig>& doodle_config) {
75 // Handle the case where the new config is already expired. 116 // Handle the case where the new config is already expired.
76 bool expired = time_to_live <= base::TimeDelta(); 117 bool expired = time_to_live <= base::TimeDelta();
77 const base::Optional<DoodleConfig>& new_config = 118 const base::Optional<DoodleConfig>& new_config =
78 expired ? base::nullopt : doodle_config; 119 expired ? base::nullopt : doodle_config;
79 120
121 DownloadOutcome outcome = OUTCOME_COUNT;
122
80 // If the config changed, update our cache and notify observers. 123 // If the config changed, update our cache and notify observers.
81 // Note that this checks both for existence changes as well as changes of the 124 // Note that this checks both for existence changes as well as changes of the
82 // configs themselves. 125 // configs themselves.
83 if (cached_config_ != new_config) { 126 if (cached_config_ != new_config) {
127 bool had_config_before = cached_config_.has_value();
128
84 cached_config_ = new_config; 129 cached_config_ = new_config;
85 130
86 if (cached_config_.has_value()) { 131 if (cached_config_.has_value()) {
132 outcome = had_config_before ? OUTCOME_CHANGED_DOODLE : OUTCOME_NEW_DOODLE;
133
87 pref_service_->Set(prefs::kCachedConfig, *cached_config_->ToDictionary()); 134 pref_service_->Set(prefs::kCachedConfig, *cached_config_->ToDictionary());
88 base::Time expiry_date = clock_->Now() + time_to_live; 135 base::Time expiry_date = clock_->Now() + time_to_live;
89 pref_service_->SetInt64(prefs::kCachedConfigExpiry, 136 pref_service_->SetInt64(prefs::kCachedConfigExpiry,
90 expiry_date.ToInternalValue()); 137 expiry_date.ToInternalValue());
91 } else { 138 } else {
139 outcome = OUTCOME_NO_DOODLE;
140
92 pref_service_->ClearPref(prefs::kCachedConfig); 141 pref_service_->ClearPref(prefs::kCachedConfig);
93 pref_service_->ClearPref(prefs::kCachedConfigExpiry); 142 pref_service_->ClearPref(prefs::kCachedConfigExpiry);
94 } 143 }
95 144
96 for (auto& observer : observers_) { 145 for (auto& observer : observers_) {
97 observer.OnDoodleConfigUpdated(cached_config_); 146 observer.OnDoodleConfigUpdated(cached_config_);
98 } 147 }
148 } else {
149 outcome = cached_config_.has_value() ? OUTCOME_REVALIDATED_DOODLE
150 : OUTCOME_NO_DOODLE;
151 }
152
153 DCHECK(outcome != OUTCOME_COUNT);
154 // Determine the final outcome. ERROR or EXPIRED override NO_DOODLE.
155 switch (state) {
156 case DoodleState::AVAILABLE:
157 case DoodleState::NO_DOODLE:
158 if (expired) {
159 outcome = OUTCOME_EXPIRED;
160 }
161 break;
162
163 case DoodleState::DOWNLOAD_ERROR:
164 outcome = OUTCOME_DOWNLOAD_ERROR;
165 break;
166
167 case DoodleState::PARSING_ERROR:
168 outcome = OUTCOME_PARSING_ERROR;
169 break;
99 } 170 }
100 171
101 // Even if the configs are identical, the time-to-live might have changed. 172 // Even if the configs are identical, the time-to-live might have changed.
102 // (Re-)schedule the cache expiry. 173 // (Re-)schedule the cache expiry.
103 if (cached_config_.has_value()) { 174 if (cached_config_.has_value()) {
104 expiry_timer_->Start( 175 expiry_timer_->Start(
105 FROM_HERE, time_to_live, 176 FROM_HERE, time_to_live,
106 base::Bind(&DoodleService::DoodleExpired, base::Unretained(this))); 177 base::Bind(&DoodleService::DoodleExpired, base::Unretained(this)));
107 } else { 178 } else {
108 expiry_timer_->Stop(); 179 expiry_timer_->Stop();
109 } 180 }
181
182 return outcome;
110 } 183 }
111 184
112 void DoodleService::DoodleExpired() { 185 void DoodleService::DoodleExpired() {
113 DCHECK(cached_config_.has_value()); 186 DCHECK(cached_config_.has_value());
114 UpdateCachedConfig(base::TimeDelta(), base::nullopt); 187 UpdateCachedConfig(DoodleState::NO_DOODLE, base::TimeDelta(), base::nullopt);
115 } 188 }
116 189
117 } // namespace doodle 190 } // namespace doodle
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698