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