OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/update_client/ping_manager.h" | 5 #include "components/update_client/ping_manager.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <string> | 10 #include <string> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/bind_helpers.h" | 14 #include "base/bind_helpers.h" |
15 #include "base/compiler_specific.h" | 15 #include "base/compiler_specific.h" |
16 #include "base/location.h" | 16 #include "base/location.h" |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/macros.h" | 18 #include "base/macros.h" |
| 19 #include "base/memory/ptr_util.h" |
19 #include "base/sequenced_task_runner.h" | 20 #include "base/sequenced_task_runner.h" |
20 #include "base/strings/string_number_conversions.h" | 21 #include "base/strings/string_number_conversions.h" |
21 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" |
22 #include "base/strings/stringprintf.h" | 23 #include "base/strings/stringprintf.h" |
23 #include "base/threading/thread_checker.h" | 24 #include "components/update_client/component.h" |
24 #include "components/update_client/configurator.h" | 25 #include "components/update_client/configurator.h" |
25 #include "components/update_client/crx_update_item.h" | |
26 #include "components/update_client/request_sender.h" | 26 #include "components/update_client/request_sender.h" |
27 #include "components/update_client/updater_state.h" | 27 #include "components/update_client/updater_state.h" |
28 #include "components/update_client/utils.h" | 28 #include "components/update_client/utils.h" |
29 #include "net/url_request/url_fetcher.h" | 29 #include "net/url_request/url_fetcher.h" |
30 #include "url/gurl.h" | 30 #include "url/gurl.h" |
31 | 31 |
32 namespace update_client { | 32 namespace update_client { |
33 | 33 |
34 namespace { | 34 namespace { |
35 | 35 |
36 // Returns a string literal corresponding to the value of the downloader |d|. | 36 // Returns a string literal corresponding to the value of the downloader |d|. |
37 const char* DownloaderToString(CrxDownloader::DownloadMetrics::Downloader d) { | 37 const char* DownloaderToString(CrxDownloader::DownloadMetrics::Downloader d) { |
38 switch (d) { | 38 switch (d) { |
39 case CrxDownloader::DownloadMetrics::kUrlFetcher: | 39 case CrxDownloader::DownloadMetrics::kUrlFetcher: |
40 return "direct"; | 40 return "direct"; |
41 case CrxDownloader::DownloadMetrics::kBits: | 41 case CrxDownloader::DownloadMetrics::kBits: |
42 return "bits"; | 42 return "bits"; |
43 default: | 43 default: |
44 return "unknown"; | 44 return "unknown"; |
45 } | 45 } |
46 } | 46 } |
47 | 47 |
48 // Returns a string representing a sequence of download complete events | 48 // Returns a string representing a sequence of download complete events |
49 // corresponding to each download metrics in |item|. | 49 // corresponding to each download metrics in |item|. |
50 std::string BuildDownloadCompleteEventElements(const CrxUpdateItem* item) { | 50 std::string BuildDownloadCompleteEventElements(const Component& component) { |
51 using base::StringAppendF; | 51 using base::StringAppendF; |
52 std::string download_events; | 52 std::string download_events; |
53 for (size_t i = 0; i != item->download_metrics.size(); ++i) { | 53 for (const auto& metrics : component.download_metrics()) { |
54 const CrxDownloader::DownloadMetrics& metrics = item->download_metrics[i]; | |
55 std::string event("<event eventtype=\"14\""); | 54 std::string event("<event eventtype=\"14\""); |
56 StringAppendF(&event, " eventresult=\"%d\"", metrics.error == 0); | 55 StringAppendF(&event, " eventresult=\"%d\"", metrics.error == 0); |
57 StringAppendF(&event, " downloader=\"%s\"", | 56 StringAppendF(&event, " downloader=\"%s\"", |
58 DownloaderToString(metrics.downloader)); | 57 DownloaderToString(metrics.downloader)); |
59 if (metrics.error) { | 58 if (metrics.error) { |
60 StringAppendF(&event, " errorcode=\"%d\"", metrics.error); | 59 StringAppendF(&event, " errorcode=\"%d\"", metrics.error); |
61 } | 60 } |
62 StringAppendF(&event, " url=\"%s\"", metrics.url.spec().c_str()); | 61 StringAppendF(&event, " url=\"%s\"", metrics.url.spec().c_str()); |
63 | 62 |
64 // -1 means that the byte counts are not known. | 63 // -1 means that the byte counts are not known. |
(...skipping 10 matching lines...) Expand all Loading... |
75 StringAppendF(&event, " download_time_ms=\"%s\"", | 74 StringAppendF(&event, " download_time_ms=\"%s\"", |
76 base::Uint64ToString(metrics.download_time_ms).c_str()); | 75 base::Uint64ToString(metrics.download_time_ms).c_str()); |
77 } | 76 } |
78 StringAppendF(&event, "/>"); | 77 StringAppendF(&event, "/>"); |
79 | 78 |
80 download_events += event; | 79 download_events += event; |
81 } | 80 } |
82 return download_events; | 81 return download_events; |
83 } | 82 } |
84 | 83 |
85 // Returns a string representing one ping event for the update of an item. | 84 // Returns a string representing one ping event for the update of a component. |
86 // The event type for this ping event is 3. | 85 // The event type for this ping event is 3. |
87 std::string BuildUpdateCompleteEventElement(const CrxUpdateItem* item) { | 86 std::string BuildUpdateCompleteEventElement(const Component& component) { |
88 DCHECK(item->state == CrxUpdateItem::State::kNoUpdate || | 87 DCHECK(component.state() == ComponentState::kUpdateError || |
89 item->state == CrxUpdateItem::State::kUpdated); | 88 component.state() == ComponentState::kUpdated); |
90 | 89 |
91 using base::StringAppendF; | 90 using base::StringAppendF; |
92 | 91 |
93 std::string ping_event("<event eventtype=\"3\""); | 92 std::string ping_event("<event eventtype=\"3\""); |
94 const int event_result = item->state == CrxUpdateItem::State::kUpdated; | 93 const int event_result = component.state() == ComponentState::kUpdated; |
95 StringAppendF(&ping_event, " eventresult=\"%d\"", event_result); | 94 StringAppendF(&ping_event, " eventresult=\"%d\"", event_result); |
96 if (item->error_category) | 95 if (component.error_category()) |
97 StringAppendF(&ping_event, " errorcat=\"%d\"", item->error_category); | 96 StringAppendF(&ping_event, " errorcat=\"%d\"", component.error_category()); |
98 if (item->error_code) | 97 if (component.error_code()) |
99 StringAppendF(&ping_event, " errorcode=\"%d\"", item->error_code); | 98 StringAppendF(&ping_event, " errorcode=\"%d\"", component.error_code()); |
100 if (item->extra_code1) | 99 if (component.extra_code1()) |
101 StringAppendF(&ping_event, " extracode1=\"%d\"", item->extra_code1); | 100 StringAppendF(&ping_event, " extracode1=\"%d\"", component.extra_code1()); |
102 if (HasDiffUpdate(item)) | 101 if (HasDiffUpdate(component)) |
103 StringAppendF(&ping_event, " diffresult=\"%d\"", !item->diff_update_failed); | 102 StringAppendF(&ping_event, " diffresult=\"%d\"", |
104 if (item->diff_error_category) { | 103 !component.diff_update_failed()); |
| 104 if (component.diff_error_category()) { |
105 StringAppendF(&ping_event, " differrorcat=\"%d\"", | 105 StringAppendF(&ping_event, " differrorcat=\"%d\"", |
106 item->diff_error_category); | 106 component.diff_error_category()); |
107 } | 107 } |
108 if (item->diff_error_code) | 108 if (component.diff_error_code()) |
109 StringAppendF(&ping_event, " differrorcode=\"%d\"", item->diff_error_code); | 109 StringAppendF(&ping_event, " differrorcode=\"%d\"", |
110 if (item->diff_extra_code1) { | 110 component.diff_error_code()); |
| 111 if (component.diff_extra_code1()) { |
111 StringAppendF(&ping_event, " diffextracode1=\"%d\"", | 112 StringAppendF(&ping_event, " diffextracode1=\"%d\"", |
112 item->diff_extra_code1); | 113 component.diff_extra_code1()); |
113 } | 114 } |
114 if (!item->previous_fp.empty()) | 115 if (!component.previous_fp().empty()) |
115 StringAppendF(&ping_event, " previousfp=\"%s\"", item->previous_fp.c_str()); | 116 StringAppendF(&ping_event, " previousfp=\"%s\"", |
116 if (!item->next_fp.empty()) | 117 component.previous_fp().c_str()); |
117 StringAppendF(&ping_event, " nextfp=\"%s\"", item->next_fp.c_str()); | 118 if (!component.next_fp().empty()) |
| 119 StringAppendF(&ping_event, " nextfp=\"%s\"", component.next_fp().c_str()); |
118 StringAppendF(&ping_event, "/>"); | 120 StringAppendF(&ping_event, "/>"); |
119 return ping_event; | 121 return ping_event; |
120 } | 122 } |
121 | 123 |
122 // Returns a string representing one ping event for the uninstall of an item. | 124 // Returns a string representing one ping event for the uninstall of a |
123 // The event type for this ping event is 4. | 125 // component. The event type for this ping event is 4. |
124 std::string BuildUninstalledEventElement(const CrxUpdateItem* item) { | 126 std::string BuildUninstalledEventElement(const Component& component) { |
125 DCHECK(item->state == CrxUpdateItem::State::kUninstalled); | 127 DCHECK(component.state() == ComponentState::kUninstalled); |
126 | 128 |
127 using base::StringAppendF; | 129 using base::StringAppendF; |
128 | 130 |
129 std::string ping_event("<event eventtype=\"4\" eventresult=\"1\""); | 131 std::string ping_event("<event eventtype=\"4\" eventresult=\"1\""); |
130 if (item->extra_code1) | 132 if (component.extra_code1()) |
131 StringAppendF(&ping_event, " extracode1=\"%d\"", item->extra_code1); | 133 StringAppendF(&ping_event, " extracode1=\"%d\"", component.extra_code1()); |
132 StringAppendF(&ping_event, "/>"); | 134 StringAppendF(&ping_event, "/>"); |
133 return ping_event; | 135 return ping_event; |
134 } | 136 } |
135 | 137 |
136 // Builds a ping message for the specified update item. | 138 // Builds a ping message for the specified component. |
137 std::string BuildPing(const Configurator& config, const CrxUpdateItem* item) { | 139 std::string BuildPing(const Configurator& config, const Component& component) { |
138 const char app_element_format[] = | 140 const char app_element_format[] = |
139 "<app appid=\"%s\" version=\"%s\" nextversion=\"%s\">" | 141 "<app appid=\"%s\" version=\"%s\" nextversion=\"%s\">" |
140 "%s" | 142 "%s" |
141 "%s" | 143 "%s" |
142 "</app>"; | 144 "</app>"; |
143 | 145 |
144 std::string ping_event; | 146 std::string ping_event; |
145 switch (item->state) { | 147 switch (component.state()) { |
146 case CrxUpdateItem::State::kNoUpdate: // Fall through. | 148 case ComponentState::kUpdateError: // Fall through. |
147 case CrxUpdateItem::State::kUpdated: | 149 case ComponentState::kUpdated: |
148 ping_event = BuildUpdateCompleteEventElement(item); | 150 ping_event = BuildUpdateCompleteEventElement(component); |
149 break; | 151 break; |
150 case CrxUpdateItem::State::kUninstalled: | 152 case ComponentState::kUninstalled: |
151 ping_event = BuildUninstalledEventElement(item); | 153 ping_event = BuildUninstalledEventElement(component); |
152 break; | 154 break; |
153 default: | 155 default: |
154 NOTREACHED(); | 156 NOTREACHED(); |
155 break; | 157 break; |
156 } | 158 } |
157 | 159 |
158 const std::string app_element(base::StringPrintf( | 160 const std::string app_element(base::StringPrintf( |
159 app_element_format, | 161 app_element_format, |
160 item->id.c_str(), // "appid" | 162 component.id().c_str(), // "appid" |
161 item->previous_version.GetString().c_str(), // "version" | 163 component.previous_version().GetString().c_str(), // "version" |
162 item->next_version.GetString().c_str(), // "nextversion" | 164 component.next_version().GetString().c_str(), // "nextversion" |
163 ping_event.c_str(), // ping event | 165 ping_event.c_str(), // ping event |
164 BuildDownloadCompleteEventElements(item).c_str())); // download events | 166 BuildDownloadCompleteEventElements(component) |
| 167 .c_str())); // download events |
165 | 168 |
166 // The ping request does not include any updater state. | 169 // The ping request does not include any updater state. |
167 return BuildProtocolRequest( | 170 return BuildProtocolRequest( |
168 config.GetProdId(), config.GetBrowserVersion().GetString(), | 171 config.GetProdId(), config.GetBrowserVersion().GetString(), |
169 config.GetChannel(), config.GetLang(), config.GetOSLongName(), | 172 config.GetChannel(), config.GetLang(), config.GetOSLongName(), |
170 config.GetDownloadPreference(), app_element, "", nullptr); | 173 config.GetDownloadPreference(), app_element, "", nullptr); |
171 } | 174 } |
172 | 175 |
173 // Sends a fire and forget ping. The instances of this class have no | 176 // Sends a fire and forget ping. The instances of this class have no |
174 // ownership and they self-delete upon completion. One instance of this class | 177 // ownership and they self-delete upon completion. One instance of this class |
175 // can send only one ping. | 178 // can send only one ping. |
176 class PingSender { | 179 class PingSender { |
177 public: | 180 public: |
178 explicit PingSender(const scoped_refptr<Configurator>& config); | 181 explicit PingSender(const scoped_refptr<Configurator>& config); |
179 ~PingSender(); | 182 ~PingSender(); |
180 | 183 |
181 bool SendPing(const CrxUpdateItem* item); | 184 bool SendPing(const Component& component); |
182 | 185 |
183 private: | 186 private: |
184 void OnRequestSenderComplete(int error, | 187 void OnRequestSenderComplete(int error, |
185 const std::string& response, | 188 const std::string& response, |
186 int retry_after_sec); | 189 int retry_after_sec); |
187 | 190 |
188 const scoped_refptr<Configurator> config_; | 191 const scoped_refptr<Configurator> config_; |
189 std::unique_ptr<RequestSender> request_sender_; | 192 std::unique_ptr<RequestSender> request_sender_; |
190 base::ThreadChecker thread_checker_; | 193 base::ThreadChecker thread_checker_; |
191 | 194 |
192 DISALLOW_COPY_AND_ASSIGN(PingSender); | 195 DISALLOW_COPY_AND_ASSIGN(PingSender); |
193 }; | 196 }; |
194 | 197 |
195 PingSender::PingSender(const scoped_refptr<Configurator>& config) | 198 PingSender::PingSender(const scoped_refptr<Configurator>& config) |
196 : config_(config) {} | 199 : config_(config) {} |
197 | 200 |
198 PingSender::~PingSender() { | 201 PingSender::~PingSender() { |
199 DCHECK(thread_checker_.CalledOnValidThread()); | 202 DCHECK(thread_checker_.CalledOnValidThread()); |
200 } | 203 } |
201 | 204 |
202 void PingSender::OnRequestSenderComplete(int error, | 205 void PingSender::OnRequestSenderComplete(int error, |
203 const std::string& response, | 206 const std::string& response, |
204 int retry_after_sec) { | 207 int retry_after_sec) { |
205 DCHECK(thread_checker_.CalledOnValidThread()); | 208 DCHECK(thread_checker_.CalledOnValidThread()); |
206 delete this; | 209 delete this; |
207 } | 210 } |
208 | 211 |
209 bool PingSender::SendPing(const CrxUpdateItem* item) { | 212 bool PingSender::SendPing(const Component& component) { |
210 DCHECK(item); | |
211 DCHECK(thread_checker_.CalledOnValidThread()); | 213 DCHECK(thread_checker_.CalledOnValidThread()); |
212 | 214 |
213 auto urls(config_->PingUrl()); | 215 auto urls(config_->PingUrl()); |
214 if (item->component.requires_network_encryption) | 216 if (component.crx_component().requires_network_encryption) |
215 RemoveUnsecureUrls(&urls); | 217 RemoveUnsecureUrls(&urls); |
216 | 218 |
217 if (urls.empty()) | 219 if (urls.empty()) |
218 return false; | 220 return false; |
219 | 221 |
220 request_sender_.reset(new RequestSender(config_)); | 222 request_sender_.reset(new RequestSender(config_)); |
221 request_sender_->Send( | 223 request_sender_->Send( |
222 false, BuildPing(*config_, item), urls, | 224 false, BuildPing(*config_, component), urls, |
223 base::Bind(&PingSender::OnRequestSenderComplete, base::Unretained(this))); | 225 base::Bind(&PingSender::OnRequestSenderComplete, base::Unretained(this))); |
224 return true; | 226 return true; |
225 } | 227 } |
226 | 228 |
227 } // namespace | 229 } // namespace |
228 | 230 |
229 PingManager::PingManager(const scoped_refptr<Configurator>& config) | 231 PingManager::PingManager(const scoped_refptr<Configurator>& config) |
230 : config_(config) {} | 232 : config_(config) {} |
231 | 233 |
232 PingManager::~PingManager() { | 234 PingManager::~PingManager() { |
| 235 DCHECK(thread_checker_.CalledOnValidThread()); |
233 } | 236 } |
234 | 237 |
235 bool PingManager::SendPing(const CrxUpdateItem* item) { | 238 bool PingManager::SendPing(const Component& component) { |
236 std::unique_ptr<PingSender> ping_sender(new PingSender(config_)); | 239 DCHECK(thread_checker_.CalledOnValidThread()); |
237 if (!ping_sender->SendPing(item)) | 240 |
| 241 auto ping_sender = base::MakeUnique<PingSender>(config_); |
| 242 if (!ping_sender->SendPing(component)) |
238 return false; | 243 return false; |
239 | 244 |
240 // The ping sender object self-deletes after sending the ping asynchrously. | 245 // The ping sender object self-deletes after sending the ping asynchrously. |
241 ping_sender.release(); | 246 ping_sender.release(); |
242 return true; | 247 return true; |
243 } | 248 } |
244 | 249 |
245 } // namespace update_client | 250 } // namespace update_client |
OLD | NEW |