| OLD | NEW |
| 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/update_client/protocol_builder.h" | 5 #include "components/update_client/protocol_builder.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include "base/guid.h" | 9 #include "base/guid.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/strings/string_util.h" |
| 12 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
| 13 #include "base/sys_info.h" | 14 #include "base/sys_info.h" |
| 14 #include "build/build_config.h" | 15 #include "build/build_config.h" |
| 15 #include "components/update_client/component.h" | 16 #include "components/update_client/component.h" |
| 16 #include "components/update_client/configurator.h" | 17 #include "components/update_client/configurator.h" |
| 17 #include "components/update_client/persisted_data.h" | 18 #include "components/update_client/persisted_data.h" |
| 18 #include "components/update_client/protocol_parser.h" | 19 #include "components/update_client/protocol_parser.h" |
| 19 #include "components/update_client/update_query_params.h" | 20 #include "components/update_client/update_query_params.h" |
| 20 #include "components/update_client/updater_state.h" | 21 #include "components/update_client/updater_state.h" |
| 21 #include "components/update_client/utils.h" | 22 #include "components/update_client/utils.h" |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 switch (d) { | 75 switch (d) { |
| 75 case CrxDownloader::DownloadMetrics::kUrlFetcher: | 76 case CrxDownloader::DownloadMetrics::kUrlFetcher: |
| 76 return "direct"; | 77 return "direct"; |
| 77 case CrxDownloader::DownloadMetrics::kBits: | 78 case CrxDownloader::DownloadMetrics::kBits: |
| 78 return "bits"; | 79 return "bits"; |
| 79 default: | 80 default: |
| 80 return "unknown"; | 81 return "unknown"; |
| 81 } | 82 } |
| 82 } | 83 } |
| 83 | 84 |
| 84 // Returns a string representing a sequence of download complete events | 85 } // namespace |
| 85 // corresponding to each download metrics in |item|. | 86 |
| 86 std::string BuildDownloadCompleteEventElements(const Component& component) { | 87 std::string BuildDownloadCompleteEventElement( |
| 88 const CrxDownloader::DownloadMetrics& metrics) { |
| 87 using base::StringAppendF; | 89 using base::StringAppendF; |
| 88 std::string download_events; | |
| 89 for (const auto& metrics : component.download_metrics()) { | |
| 90 std::string event("<event eventtype=\"14\""); | |
| 91 StringAppendF(&event, " eventresult=\"%d\"", metrics.error == 0); | |
| 92 StringAppendF(&event, " downloader=\"%s\"", | |
| 93 DownloaderToString(metrics.downloader)); | |
| 94 if (metrics.error) { | |
| 95 StringAppendF(&event, " errorcode=\"%d\"", metrics.error); | |
| 96 } | |
| 97 StringAppendF(&event, " url=\"%s\"", metrics.url.spec().c_str()); | |
| 98 | 90 |
| 99 // -1 means that the byte counts are not known. | 91 std::string event("<event eventtype=\"14\""); |
| 100 if (metrics.downloaded_bytes != -1) { | 92 StringAppendF(&event, " eventresult=\"%d\"", metrics.error == 0); |
| 101 StringAppendF(&event, " downloaded=\"%s\"", | 93 StringAppendF(&event, " downloader=\"%s\"", |
| 102 base::Int64ToString(metrics.downloaded_bytes).c_str()); | 94 DownloaderToString(metrics.downloader)); |
| 103 } | 95 if (metrics.error) { |
| 104 if (metrics.total_bytes != -1) { | 96 StringAppendF(&event, " errorcode=\"%d\"", metrics.error); |
| 105 StringAppendF(&event, " total=\"%s\"", | 97 } |
| 106 base::Int64ToString(metrics.total_bytes).c_str()); | 98 StringAppendF(&event, " url=\"%s\"", metrics.url.spec().c_str()); |
| 107 } | |
| 108 | 99 |
| 109 if (metrics.download_time_ms) { | 100 // -1 means that the byte counts are not known. |
| 110 StringAppendF(&event, " download_time_ms=\"%s\"", | 101 if (metrics.downloaded_bytes != -1) { |
| 111 base::Uint64ToString(metrics.download_time_ms).c_str()); | 102 StringAppendF(&event, " downloaded=\"%s\"", |
| 112 } | 103 base::Int64ToString(metrics.downloaded_bytes).c_str()); |
| 113 StringAppendF(&event, "/>"); | 104 } |
| 105 if (metrics.total_bytes != -1) { |
| 106 StringAppendF(&event, " total=\"%s\"", |
| 107 base::Int64ToString(metrics.total_bytes).c_str()); |
| 108 } |
| 114 | 109 |
| 115 download_events += event; | 110 if (metrics.download_time_ms) { |
| 111 StringAppendF(&event, " download_time_ms=\"%s\"", |
| 112 base::Uint64ToString(metrics.download_time_ms).c_str()); |
| 116 } | 113 } |
| 117 return download_events; | 114 StringAppendF(&event, "/>"); |
| 115 return event; |
| 118 } | 116 } |
| 119 | 117 |
| 120 // Returns a string representing one ping event for the update of a component. | |
| 121 // The event type for this ping event is 3. | |
| 122 std::string BuildUpdateCompleteEventElement(const Component& component) { | 118 std::string BuildUpdateCompleteEventElement(const Component& component) { |
| 123 DCHECK(component.state() == ComponentState::kUpdateError || | 119 DCHECK(component.state() == ComponentState::kUpdateError || |
| 124 component.state() == ComponentState::kUpdated); | 120 component.state() == ComponentState::kUpdated); |
| 125 | 121 |
| 126 using base::StringAppendF; | 122 using base::StringAppendF; |
| 127 | 123 |
| 128 std::string ping_event("<event eventtype=\"3\""); | 124 std::string event("<event eventtype=\"3\""); |
| 129 const int event_result = component.state() == ComponentState::kUpdated; | 125 const int event_result = component.state() == ComponentState::kUpdated; |
| 130 StringAppendF(&ping_event, " eventresult=\"%d\"", event_result); | 126 StringAppendF(&event, " eventresult=\"%d\"", event_result); |
| 131 if (component.error_category()) | 127 if (component.error_category()) |
| 132 StringAppendF(&ping_event, " errorcat=\"%d\"", component.error_category()); | 128 StringAppendF(&event, " errorcat=\"%d\"", component.error_category()); |
| 133 if (component.error_code()) | 129 if (component.error_code()) |
| 134 StringAppendF(&ping_event, " errorcode=\"%d\"", component.error_code()); | 130 StringAppendF(&event, " errorcode=\"%d\"", component.error_code()); |
| 135 if (component.extra_code1()) | 131 if (component.extra_code1()) |
| 136 StringAppendF(&ping_event, " extracode1=\"%d\"", component.extra_code1()); | 132 StringAppendF(&event, " extracode1=\"%d\"", component.extra_code1()); |
| 137 if (HasDiffUpdate(component)) | 133 if (HasDiffUpdate(component)) |
| 138 StringAppendF(&ping_event, " diffresult=\"%d\"", | 134 StringAppendF(&event, " diffresult=\"%d\"", |
| 139 !component.diff_update_failed()); | 135 !component.diff_update_failed()); |
| 140 if (component.diff_error_category()) { | 136 if (component.diff_error_category()) { |
| 141 StringAppendF(&ping_event, " differrorcat=\"%d\"", | 137 StringAppendF(&event, " differrorcat=\"%d\"", |
| 142 component.diff_error_category()); | 138 component.diff_error_category()); |
| 143 } | 139 } |
| 144 if (component.diff_error_code()) | 140 if (component.diff_error_code()) |
| 145 StringAppendF(&ping_event, " differrorcode=\"%d\"", | 141 StringAppendF(&event, " differrorcode=\"%d\"", component.diff_error_code()); |
| 146 component.diff_error_code()); | |
| 147 if (component.diff_extra_code1()) { | 142 if (component.diff_extra_code1()) { |
| 148 StringAppendF(&ping_event, " diffextracode1=\"%d\"", | 143 StringAppendF(&event, " diffextracode1=\"%d\"", |
| 149 component.diff_extra_code1()); | 144 component.diff_extra_code1()); |
| 150 } | 145 } |
| 151 if (!component.previous_fp().empty()) | 146 if (!component.previous_fp().empty()) |
| 152 StringAppendF(&ping_event, " previousfp=\"%s\"", | 147 StringAppendF(&event, " previousfp=\"%s\"", |
| 153 component.previous_fp().c_str()); | 148 component.previous_fp().c_str()); |
| 154 if (!component.next_fp().empty()) | 149 if (!component.next_fp().empty()) |
| 155 StringAppendF(&ping_event, " nextfp=\"%s\"", component.next_fp().c_str()); | 150 StringAppendF(&event, " nextfp=\"%s\"", component.next_fp().c_str()); |
| 156 StringAppendF(&ping_event, "/>"); | 151 StringAppendF(&event, "/>"); |
| 157 return ping_event; | 152 return event; |
| 158 } | 153 } |
| 159 | 154 |
| 160 // Returns a string representing one ping event for the uninstall of a | |
| 161 // component. The event type for this ping event is 4. | |
| 162 std::string BuildUninstalledEventElement(const Component& component) { | 155 std::string BuildUninstalledEventElement(const Component& component) { |
| 163 DCHECK(component.state() == ComponentState::kUninstalled); | 156 DCHECK(component.state() == ComponentState::kUninstalled); |
| 164 | 157 |
| 165 using base::StringAppendF; | 158 using base::StringAppendF; |
| 166 | 159 |
| 167 std::string ping_event("<event eventtype=\"4\" eventresult=\"1\""); | 160 std::string event("<event eventtype=\"4\" eventresult=\"1\""); |
| 168 if (component.extra_code1()) | 161 if (component.extra_code1()) |
| 169 StringAppendF(&ping_event, " extracode1=\"%d\"", component.extra_code1()); | 162 StringAppendF(&event, " extracode1=\"%d\"", component.extra_code1()); |
| 170 StringAppendF(&ping_event, "/>"); | 163 StringAppendF(&event, "/>"); |
| 171 return ping_event; | 164 return event; |
| 172 } | 165 } |
| 173 | 166 |
| 174 } // namespace | |
| 175 | |
| 176 std::string BuildProtocolRequest( | 167 std::string BuildProtocolRequest( |
| 177 const std::string& prod_id, | 168 const std::string& prod_id, |
| 178 const std::string& browser_version, | 169 const std::string& browser_version, |
| 179 const std::string& channel, | 170 const std::string& channel, |
| 180 const std::string& lang, | 171 const std::string& lang, |
| 181 const std::string& os_long_name, | 172 const std::string& os_long_name, |
| 182 const std::string& download_preference, | 173 const std::string& download_preference, |
| 183 const std::string& request_body, | 174 const std::string& request_body, |
| 184 const std::string& additional_attributes, | 175 const std::string& additional_attributes, |
| 185 const std::unique_ptr<UpdaterState::Attributes>& updater_state_attributes) { | 176 const std::unique_ptr<UpdaterState::Attributes>& updater_state_attributes) { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 // Include the updater state in the update check request. | 320 // Include the updater state in the update check request. |
| 330 return BuildProtocolRequest( | 321 return BuildProtocolRequest( |
| 331 config.GetProdId(), config.GetBrowserVersion().GetString(), | 322 config.GetProdId(), config.GetBrowserVersion().GetString(), |
| 332 config.GetChannel(), config.GetLang(), config.GetOSLongName(), | 323 config.GetChannel(), config.GetLang(), config.GetOSLongName(), |
| 333 config.GetDownloadPreference(), app_elements, additional_attributes, | 324 config.GetDownloadPreference(), app_elements, additional_attributes, |
| 334 updater_state_attributes); | 325 updater_state_attributes); |
| 335 } | 326 } |
| 336 | 327 |
| 337 std::string BuildEventPingRequest(const Configurator& config, | 328 std::string BuildEventPingRequest(const Configurator& config, |
| 338 const Component& component) { | 329 const Component& component) { |
| 330 DCHECK(component.state() == ComponentState::kUpdateError || |
| 331 component.state() == ComponentState::kUpdated || |
| 332 component.state() == ComponentState::kUninstalled); |
| 333 |
| 339 const char app_element_format[] = | 334 const char app_element_format[] = |
| 340 "<app appid=\"%s\" version=\"%s\" nextversion=\"%s\">" | 335 "<app appid=\"%s\" version=\"%s\" nextversion=\"%s\">" |
| 341 "%s" | 336 "%s" |
| 342 "%s" | |
| 343 "</app>"; | 337 "</app>"; |
| 344 | 338 |
| 345 std::string ping_event; | |
| 346 switch (component.state()) { | |
| 347 case ComponentState::kUpdateError: // Fall through. | |
| 348 case ComponentState::kUpdated: | |
| 349 ping_event = BuildUpdateCompleteEventElement(component); | |
| 350 break; | |
| 351 case ComponentState::kUninstalled: | |
| 352 ping_event = BuildUninstalledEventElement(component); | |
| 353 break; | |
| 354 default: | |
| 355 NOTREACHED(); | |
| 356 break; | |
| 357 } | |
| 358 | |
| 359 const std::string app_element(base::StringPrintf( | 339 const std::string app_element(base::StringPrintf( |
| 360 app_element_format, | 340 app_element_format, |
| 361 component.id().c_str(), // "appid" | 341 component.id().c_str(), // "appid" |
| 362 component.previous_version().GetString().c_str(), // "version" | 342 component.previous_version().GetString().c_str(), // "version" |
| 363 component.next_version().GetString().c_str(), // "nextversion" | 343 component.next_version().GetString().c_str(), // "nextversion" |
| 364 ping_event.c_str(), // ping event | 344 base::JoinString(component.events(), "").c_str())); // events |
| 365 BuildDownloadCompleteEventElements(component) | |
| 366 .c_str())); // download events | |
| 367 | 345 |
| 368 // The ping request does not include any updater state. | 346 // The ping request does not include any updater state. |
| 369 return BuildProtocolRequest( | 347 return BuildProtocolRequest( |
| 370 config.GetProdId(), config.GetBrowserVersion().GetString(), | 348 config.GetProdId(), config.GetBrowserVersion().GetString(), |
| 371 config.GetChannel(), config.GetLang(), config.GetOSLongName(), | 349 config.GetChannel(), config.GetLang(), config.GetOSLongName(), |
| 372 config.GetDownloadPreference(), app_element, "", nullptr); | 350 config.GetDownloadPreference(), app_element, "", nullptr); |
| 373 } | 351 } |
| 374 | 352 |
| 375 } // namespace update_client | 353 } // namespace update_client |
| OLD | NEW |