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/component_updater/component_updater_ping_manager.h" | 5 #include "components/component_updater/component_updater_ping_manager.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | |
8 | 9 |
9 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
10 #include "base/guid.h" | 11 #include "base/location.h" |
11 #include "base/logging.h" | 12 #include "base/logging.h" |
12 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
14 #include "base/sequenced_task_runner.h" | |
13 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
14 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
15 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
16 #include "components/component_updater/component_updater_configurator.h" | 18 #include "components/component_updater/component_updater_configurator.h" |
17 #include "components/component_updater/component_updater_utils.h" | 19 #include "components/component_updater/component_updater_utils.h" |
18 #include "components/component_updater/crx_update_item.h" | 20 #include "components/component_updater/crx_update_item.h" |
19 #include "net/url_request/url_fetcher.h" | 21 #include "components/component_updater/request_sender.h" |
20 #include "net/url_request/url_fetcher_delegate.h" | |
21 #include "url/gurl.h" | 22 #include "url/gurl.h" |
22 | 23 |
23 namespace component_updater { | 24 namespace component_updater { |
24 | 25 |
26 namespace { | |
27 | |
25 // Returns a string literal corresponding to the value of the downloader |d|. | 28 // Returns a string literal corresponding to the value of the downloader |d|. |
26 const char* DownloaderToString(CrxDownloader::DownloadMetrics::Downloader d) { | 29 const char* DownloaderToString(CrxDownloader::DownloadMetrics::Downloader d) { |
27 switch (d) { | 30 switch (d) { |
28 case CrxDownloader::DownloadMetrics::kUrlFetcher: | 31 case CrxDownloader::DownloadMetrics::kUrlFetcher: |
29 return "direct"; | 32 return "direct"; |
30 case CrxDownloader::DownloadMetrics::kBits: | 33 case CrxDownloader::DownloadMetrics::kBits: |
31 return "bits"; | 34 return "bits"; |
32 default: | 35 default: |
33 return "unknown"; | 36 return "unknown"; |
34 } | 37 } |
35 } | 38 } |
36 | 39 |
37 // Sends a fire and forget ping. The instances of this class have no | |
38 // ownership and they self-delete upon completion. | |
39 class PingSender : public net::URLFetcherDelegate { | |
40 public: | |
41 PingSender(); | |
42 | |
43 void SendPing(const Configurator& config, | |
44 net::URLRequestContextGetter* url_request_context_getter, | |
45 const CrxUpdateItem* item); | |
46 | |
47 private: | |
48 virtual ~PingSender(); | |
49 | |
50 // Overrides for URLFetcherDelegate. | |
51 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; | |
52 | |
53 static std::string BuildPing(const Configurator& config, | |
54 const CrxUpdateItem* item); | |
55 static std::string BuildDownloadCompleteEventElements( | |
56 const CrxUpdateItem* item); | |
57 static std::string BuildUpdateCompleteEventElement(const CrxUpdateItem* item); | |
58 | |
59 scoped_ptr<net::URLFetcher> url_fetcher_; | |
60 | |
61 DISALLOW_COPY_AND_ASSIGN(PingSender); | |
62 }; | |
63 | |
64 PingSender::PingSender() { | |
65 } | |
66 | |
67 PingSender::~PingSender() { | |
68 } | |
69 | |
70 void PingSender::OnURLFetchComplete(const net::URLFetcher* source) { | |
71 delete this; | |
72 } | |
73 | |
74 void PingSender::SendPing( | |
75 const Configurator& config, | |
76 net::URLRequestContextGetter* url_request_context_getter, | |
77 const CrxUpdateItem* item) { | |
78 DCHECK(item); | |
79 | |
80 if (!config.PingUrl().is_valid()) | |
81 return; | |
82 | |
83 url_fetcher_.reset(SendProtocolRequest(config.PingUrl(), | |
84 BuildPing(config, item), | |
85 this, | |
86 url_request_context_getter)); | |
87 } | |
88 | |
89 // Builds a ping message for the specified update item. | |
90 std::string PingSender::BuildPing(const Configurator& config, | |
91 const CrxUpdateItem* item) { | |
92 const char app_element_format[] = | |
93 "<app appid=\"%s\" version=\"%s\" nextversion=\"%s\">" | |
94 "%s" | |
95 "%s" | |
96 "</app>"; | |
97 const std::string app_element(base::StringPrintf( | |
98 app_element_format, | |
99 item->id.c_str(), // "appid" | |
100 item->previous_version.GetString().c_str(), // "version" | |
101 item->next_version.GetString().c_str(), // "nextversion" | |
102 BuildUpdateCompleteEventElement(item).c_str(), // update event | |
103 BuildDownloadCompleteEventElements(item).c_str())); // download events | |
104 | |
105 return BuildProtocolRequest(config.GetBrowserVersion().GetString(), | |
106 config.GetChannel(), | |
107 config.GetLang(), | |
108 config.GetOSLongName(), | |
109 app_element, | |
110 ""); | |
111 } | |
112 | |
113 // Returns a string representing a sequence of download complete events | 40 // Returns a string representing a sequence of download complete events |
114 // corresponding to each download metrics in |item|. | 41 // corresponding to each download metrics in |item|. |
115 std::string PingSender::BuildDownloadCompleteEventElements( | 42 std::string BuildDownloadCompleteEventElements(const CrxUpdateItem* item) { |
116 const CrxUpdateItem* item) { | |
117 using base::StringAppendF; | 43 using base::StringAppendF; |
118 std::string download_events; | 44 std::string download_events; |
119 for (size_t i = 0; i != item->download_metrics.size(); ++i) { | 45 for (size_t i = 0; i != item->download_metrics.size(); ++i) { |
120 const CrxDownloader::DownloadMetrics& metrics = item->download_metrics[i]; | 46 const CrxDownloader::DownloadMetrics& metrics = item->download_metrics[i]; |
121 std::string event("<event eventtype=\"14\""); | 47 std::string event("<event eventtype=\"14\""); |
122 StringAppendF(&event, " eventresult=\"%d\"", metrics.error == 0); | 48 StringAppendF(&event, " eventresult=\"%d\"", metrics.error == 0); |
123 StringAppendF(&event, | 49 StringAppendF(&event, |
124 " downloader=\"%s\"", | 50 " downloader=\"%s\"", |
125 DownloaderToString(metrics.downloader)); | 51 DownloaderToString(metrics.downloader)); |
126 if (metrics.error) { | 52 if (metrics.error) { |
(...skipping 19 matching lines...) Expand all Loading... | |
146 base::Uint64ToString(metrics.download_time_ms).c_str()); | 72 base::Uint64ToString(metrics.download_time_ms).c_str()); |
147 } | 73 } |
148 StringAppendF(&event, "/>"); | 74 StringAppendF(&event, "/>"); |
149 | 75 |
150 download_events += event; | 76 download_events += event; |
151 } | 77 } |
152 return download_events; | 78 return download_events; |
153 } | 79 } |
154 | 80 |
155 // Returns a string representing one ping event xml element for an update item. | 81 // Returns a string representing one ping event xml element for an update item. |
156 std::string PingSender::BuildUpdateCompleteEventElement( | 82 std::string BuildUpdateCompleteEventElement(const CrxUpdateItem* item) { |
157 const CrxUpdateItem* item) { | |
158 DCHECK(item->status == CrxUpdateItem::kNoUpdate || | 83 DCHECK(item->status == CrxUpdateItem::kNoUpdate || |
159 item->status == CrxUpdateItem::kUpdated); | 84 item->status == CrxUpdateItem::kUpdated); |
160 | 85 |
161 using base::StringAppendF; | 86 using base::StringAppendF; |
162 | 87 |
163 std::string ping_event("<event eventtype=\"3\""); | 88 std::string ping_event("<event eventtype=\"3\""); |
164 const int event_result = item->status == CrxUpdateItem::kUpdated; | 89 const int event_result = item->status == CrxUpdateItem::kUpdated; |
165 StringAppendF(&ping_event, " eventresult=\"%d\"", event_result); | 90 StringAppendF(&ping_event, " eventresult=\"%d\"", event_result); |
166 if (item->error_category) | 91 if (item->error_category) |
167 StringAppendF(&ping_event, " errorcat=\"%d\"", item->error_category); | 92 StringAppendF(&ping_event, " errorcat=\"%d\"", item->error_category); |
(...skipping 14 matching lines...) Expand all Loading... | |
182 &ping_event, " diffextracode1=\"%d\"", item->diff_extra_code1); | 107 &ping_event, " diffextracode1=\"%d\"", item->diff_extra_code1); |
183 } | 108 } |
184 if (!item->previous_fp.empty()) | 109 if (!item->previous_fp.empty()) |
185 StringAppendF(&ping_event, " previousfp=\"%s\"", item->previous_fp.c_str()); | 110 StringAppendF(&ping_event, " previousfp=\"%s\"", item->previous_fp.c_str()); |
186 if (!item->next_fp.empty()) | 111 if (!item->next_fp.empty()) |
187 StringAppendF(&ping_event, " nextfp=\"%s\"", item->next_fp.c_str()); | 112 StringAppendF(&ping_event, " nextfp=\"%s\"", item->next_fp.c_str()); |
188 StringAppendF(&ping_event, "/>"); | 113 StringAppendF(&ping_event, "/>"); |
189 return ping_event; | 114 return ping_event; |
190 } | 115 } |
191 | 116 |
117 // Builds a ping message for the specified update item. | |
118 std::string BuildPing(const Configurator& config, const CrxUpdateItem* item) { | |
119 const char app_element_format[] = | |
120 "<app appid=\"%s\" version=\"%s\" nextversion=\"%s\">" | |
121 "%s" | |
122 "%s" | |
123 "</app>"; | |
124 const std::string app_element(base::StringPrintf( | |
125 app_element_format, | |
126 item->id.c_str(), // "appid" | |
127 item->previous_version.GetString().c_str(), // "version" | |
128 item->next_version.GetString().c_str(), // "nextversion" | |
129 BuildUpdateCompleteEventElement(item).c_str(), // update event | |
130 BuildDownloadCompleteEventElements(item).c_str())); // download events | |
131 | |
132 return BuildProtocolRequest(config.GetBrowserVersion().GetString(), | |
133 config.GetChannel(), | |
134 config.GetLang(), | |
135 config.GetOSLongName(), | |
136 app_element, | |
137 ""); | |
138 } | |
139 | |
140 // Sends a fire and forget ping. The instances of this class have no | |
141 // ownership and they self-delete upon completion. One instance of this class | |
142 // can send only one ping. | |
143 class PingSender { | |
144 public: | |
145 explicit PingSender(const Configurator& config); | |
146 ~PingSender(); | |
147 | |
148 bool SendPing(const CrxUpdateItem* item); | |
149 | |
150 private: | |
151 void OnRequestSenderComplete(const net::URLFetcher* source); | |
erikwright (departed)
2014/09/15 18:37:11
forward-decl required?
Sorin Jianu
2014/09/15 22:17:57
This function is part of the public interface for
erikwright (departed)
2014/09/16 17:38:11
Sure, but the only case where you are not required
Sorin Jianu
2014/09/16 19:53:31
Thank you. I declared the forward type.
| |
152 | |
153 const Configurator& config_; | |
154 scoped_ptr<RequestSender> request_sender_; | |
155 base::ThreadChecker thread_checker_; | |
erikwright (departed)
2014/09/15 18:37:11
missing include?
Sorin Jianu
2014/09/15 22:17:57
Done.
| |
156 | |
157 DISALLOW_COPY_AND_ASSIGN(PingSender); | |
158 }; | |
159 | |
160 PingSender::PingSender(const Configurator& config) : config_(config) { | |
161 } | |
162 | |
163 PingSender::~PingSender() { | |
164 DCHECK(thread_checker_.CalledOnValidThread()); | |
165 } | |
166 | |
167 void PingSender::OnRequestSenderComplete(const net::URLFetcher* source) { | |
168 DCHECK(thread_checker_.CalledOnValidThread()); | |
169 delete this; | |
170 } | |
171 | |
172 bool PingSender::SendPing(const CrxUpdateItem* item) { | |
173 DCHECK(item); | |
174 DCHECK(thread_checker_.CalledOnValidThread()); | |
175 | |
176 std::vector<GURL> urls(config_.PingUrl()); | |
177 | |
178 if (urls.empty()) | |
179 return false; | |
180 | |
181 request_sender_.reset(new RequestSender(config_)); | |
182 request_sender_->Send( | |
183 BuildPing(config_, item), | |
184 urls, | |
185 base::Bind(&PingSender::OnRequestSenderComplete, base::Unretained(this))); | |
erikwright (departed)
2014/09/15 18:37:11
base/bind.h and base/bind_helpers.h required
Sorin Jianu
2014/09/15 22:17:57
Done.
| |
186 return true; | |
187 } | |
188 | |
189 } // namespace | |
190 | |
192 PingManager::PingManager(const Configurator& config) : config_(config) { | 191 PingManager::PingManager(const Configurator& config) : config_(config) { |
193 } | 192 } |
194 | 193 |
195 PingManager::~PingManager() { | 194 PingManager::~PingManager() { |
196 } | 195 } |
197 | 196 |
198 // Sends a fire and forget ping when the updates are complete. The ping | 197 // Sends a fire and forget ping when the updates are complete. The ping |
199 // sender object self-deletes after sending the ping. | 198 // sender object self-deletes after sending the ping has completed asynchrously. |
200 void PingManager::OnUpdateComplete(const CrxUpdateItem* item) { | 199 void PingManager::OnUpdateComplete(const CrxUpdateItem* item) { |
201 PingSender* ping_sender(new PingSender); | 200 PingSender* ping_sender(new PingSender(config_)); |
202 ping_sender->SendPing(config_, config_.RequestContext(), item); | 201 if (!ping_sender->SendPing(item)) |
202 delete ping_sender; | |
203 } | 203 } |
204 | 204 |
205 } // namespace component_updater | 205 } // namespace component_updater |
OLD | NEW |