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