Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: chrome/browser/component_updater/component_updater_service.cc

Issue 15908002: Differential updates for components. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/component_updater/component_updater_service.h" 5 #include "chrome/browser/component_updater/component_updater_service.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/at_exit.h" 11 #include "base/at_exit.h"
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/compiler_specific.h"
13 #include "base/file_util.h" 14 #include "base/file_util.h"
14 #include "base/files/file_path.h" 15 #include "base/files/file_path.h"
16 #include "base/guid.h"
15 #include "base/logging.h" 17 #include "base/logging.h"
16 #include "base/memory/scoped_ptr.h" 18 #include "base/memory/scoped_ptr.h"
17 #include "base/stl_util.h" 19 #include "base/stl_util.h"
18 #include "base/strings/string_number_conversions.h" 20 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/string_piece.h" 21 #include "base/strings/string_piece.h"
20 #include "base/strings/string_util.h" 22 #include "base/strings/string_util.h"
21 #include "base/strings/stringprintf.h" 23 #include "base/strings/stringprintf.h"
24 #include "base/sys_info.h"
22 #include "base/timer.h" 25 #include "base/timer.h"
23 #include "chrome/browser/browser_process.h" 26 #include "chrome/browser/browser_process.h"
27 #include "chrome/browser/component_updater/component_patcher.h"
24 #include "chrome/browser/component_updater/component_unpacker.h" 28 #include "chrome/browser/component_updater/component_unpacker.h"
25 #include "chrome/common/chrome_notification_types.h" 29 #include "chrome/common/chrome_notification_types.h"
26 #include "chrome/common/chrome_utility_messages.h" 30 #include "chrome/common/chrome_utility_messages.h"
27 #include "chrome/common/chrome_version_info.h" 31 #include "chrome/common/chrome_version_info.h"
28 #include "chrome/common/extensions/extension.h" 32 #include "chrome/common/extensions/extension.h"
33 #include "chrome/common/omaha_query_params/omaha_query_params.h"
29 #include "content/public/browser/browser_thread.h" 34 #include "content/public/browser/browser_thread.h"
30 #include "content/public/browser/notification_service.h" 35 #include "content/public/browser/notification_service.h"
31 #include "content/public/browser/utility_process_host.h" 36 #include "content/public/browser/utility_process_host.h"
32 #include "content/public/browser/utility_process_host_client.h" 37 #include "content/public/browser/utility_process_host_client.h"
33 #include "googleurl/src/gurl.h" 38 #include "googleurl/src/gurl.h"
34 #include "net/base/escape.h" 39 #include "net/base/escape.h"
35 #include "net/base/load_flags.h" 40 #include "net/base/load_flags.h"
36 #include "net/base/net_errors.h" 41 #include "net/base/net_errors.h"
37 #include "net/url_request/url_fetcher.h" 42 #include "net/url_request/url_fetcher.h"
38 #include "net/url_request/url_fetcher_delegate.h" 43 #include "net/url_request/url_fetcher_delegate.h"
39 #include "net/url_request/url_request_status.h" 44 #include "net/url_request/url_request_status.h"
40 45
41 using content::BrowserThread; 46 using content::BrowserThread;
42 using content::UtilityProcessHost; 47 using content::UtilityProcessHost;
43 using content::UtilityProcessHostClient; 48 using content::UtilityProcessHostClient;
44 using extensions::Extension; 49 using extensions::Extension;
45 50
46 // The component updater is designed to live until process shutdown, so 51 // The component updater is designed to live until process shutdown, so
47 // base::Bind() calls are not refcounted. 52 // base::Bind() calls are not refcounted.
48 53
49 namespace { 54 namespace {
55
50 // Manifest sources, from most important to least important. 56 // Manifest sources, from most important to least important.
51 const CrxComponent::UrlSource kManifestSources[] = { 57 const CrxComponent::UrlSource kManifestSources[] = {
52 CrxComponent::BANDAID, 58 CrxComponent::BANDAID,
53 CrxComponent::CWS_PUBLIC, 59 CrxComponent::CWS_PUBLIC,
54 CrxComponent::CWS_SANDBOX 60 CrxComponent::CWS_SANDBOX,
55 }; 61 };
56 62
57 // Extends an omaha compatible update check url |query| string. Does 63 // Extends an omaha compatible update check url |query| string. Does
58 // not mutate the string if it would be longer than |limit| chars. 64 // not mutate the string if it would be longer than |limit| chars.
59 bool AddQueryString(const std::string& id, 65 bool AddQueryString(const std::string& id,
60 const std::string& version, 66 const std::string& version,
67 const std::string& fingerprint,
61 size_t limit, 68 size_t limit,
62 std::string* query) { 69 std::string* query) {
63 std::string additional = 70 std::string additional =
64 base::StringPrintf("id=%s&v=%s&uc", id.c_str(), version.c_str()); 71 base::StringPrintf("id=%s&v=%s&fp=%s&uc",
72 id.c_str(), version.c_str(), fingerprint.c_str());
65 additional = "x=" + net::EscapeQueryParamValue(additional, true); 73 additional = "x=" + net::EscapeQueryParamValue(additional, true);
66 if ((additional.size() + query->size() + 1) > limit) 74 if ((additional.size() + query->size() + 1) > limit)
67 return false; 75 return false;
68 if (!query->empty()) 76 if (!query->empty())
69 query->append(1, '&'); 77 query->append(1, '&');
70 query->append(additional); 78 query->append(additional);
71 return true; 79 return true;
72 } 80 }
73 81
74 // Create the final omaha compatible query. The |extra| is optional and can 82 // Create the final omaha compatible query. The |extra| is optional and can
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 net::LOAD_DISABLE_CACHE); 164 net::LOAD_DISABLE_CACHE);
157 // TODO(cpu): Define our retry and backoff policy. 165 // TODO(cpu): Define our retry and backoff policy.
158 fetcher->SetAutomaticallyRetryOn5xx(false); 166 fetcher->SetAutomaticallyRetryOn5xx(false);
159 if (save_to_file) { 167 if (save_to_file) {
160 fetcher->SaveResponseToTemporaryFile( 168 fetcher->SaveResponseToTemporaryFile(
161 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); 169 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
162 } 170 }
163 fetcher->Start(); 171 fetcher->Start();
164 } 172 }
165 173
166 // Returs true if the url request of |fetcher| was succesful. 174 // Returns true if the url request of |fetcher| was succesful.
167 bool FetchSuccess(const net::URLFetcher& fetcher) { 175 bool FetchSuccess(const net::URLFetcher& fetcher) {
168 return (fetcher.GetStatus().status() == net::URLRequestStatus::SUCCESS) && 176 return (fetcher.GetStatus().status() == net::URLRequestStatus::SUCCESS) &&
169 (fetcher.GetResponseCode() == 200); 177 (fetcher.GetResponseCode() == 200);
170 } 178 }
171 179
180 // Returns the error code which occured during the fetch. This function
181 // is intended to be called for logging purposes only, since it folds different
182 // types of errors to fit them in the returned type. The function returns 0 if
183 // the fetch was successful. If errors happen, the function could return a
184 // network error, an http response code, or the status of the fetch, if the
185 // fetch is pending or canceled.
186 int GetFetchError(const net::URLFetcher& fetcher) {
187 if (FetchSuccess(fetcher))
188 return 0;
189
190 const net::URLRequestStatus::Status status(fetcher.GetStatus().status());
191 if (status == net::URLRequestStatus::FAILED)
192 return fetcher.GetStatus().error();
193
194 if (status == net::URLRequestStatus::IO_PENDING ||
195 status == net::URLRequestStatus::CANCELED)
196 return status;
197
198 const int response_code(fetcher.GetResponseCode());
199 if (status == net::URLRequestStatus::SUCCESS && response_code != 200)
200 return response_code;
201
202 return -1;
203 }
204
205
172 // This is the one and only per-item state structure. Designed to be hosted 206 // This is the one and only per-item state structure. Designed to be hosted
173 // in a std::vector or a std::list. The two main members are |component| 207 // in a std::vector or a std::list. The two main members are |component|
174 // which is supplied by the the component updater client and |status| which 208 // which is supplied by the the component updater client and |status| which
175 // is modified as the item is processed by the update pipeline. The expected 209 // is modified as the item is processed by the update pipeline. The expected
176 // transition graph is: 210 // transition graph is:
177 // error error error 211 //
178 // +--kNoUpdate<------<-------+------<------+------<------+ 212 // kNew
179 // | | | | 213 // |
180 // V yes | | | 214 // V
181 // kNew --->kChecking-->[update?]----->kCanUpdate-->kDownloading-->kUpdating 215 // +----------------------> kChecking -<---------+-----<-------+
182 // ^ | | 216 // | | | |
183 // | |no | 217 // | error V no | |
184 // |--kUpToDate<---+ | 218 // kNoUpdate <---------------- [update?] ->---- kUpToDate kUpdated
185 // | success | 219 // ^ | ^
186 // +--kUpdated<-------------------------------------------+ 220 // | yes | |
221 // | diff=false V |
222 // | +-----------> kCanUpdate |
223 // | | | |
224 // | | V no |
225 // | | [differential update?]->----+ |
226 // | | | | |
227 // | | yes | | |
228 // | | error V | |
229 // | +---------<- kDownloadingDiff | |
230 // | | | | |
231 // | | | | |
232 // | | error V | |
233 // | +---------<- kUpdatingDiff ->--------|-----------+ success
234 // | | |
235 // | error V |
236 // +----------------------------------------- kDownloading |
237 // | | |
238 // | error V |
239 // +------------------------------------------ kUpdating ->----+ success
187 // 240 //
188 struct CrxUpdateItem { 241 struct CrxUpdateItem {
189 enum Status { 242 enum Status {
190 kNew, 243 kNew,
191 kChecking, 244 kChecking,
192 kCanUpdate, 245 kCanUpdate,
246 kDownloadingDiff,
193 kDownloading, 247 kDownloading,
248 kUpdatingDiff,
194 kUpdating, 249 kUpdating,
195 kUpdated, 250 kUpdated,
196 kUpToDate, 251 kUpToDate,
197 kNoUpdate, 252 kNoUpdate,
198 kLastStatus 253 kLastStatus
199 }; 254 };
200 255
201 Status status; 256 Status status;
257 std::string id;
258 CrxComponent component;
259
260 base::Time last_check;
261
262 // True if the update response includes an update for this component.
263 bool is_update_available;
264
265 // These members are initialized with their corresponding values from the
266 // update server response.
202 GURL crx_url; 267 GURL crx_url;
203 std::string id; 268 GURL diff_crx_url;
204 base::Time last_check; 269 std::string package_hash;
205 CrxComponent component; 270 std::string diff_package_hash;
271 int size;
272 int diff_size;
273
274 // The from/to version and fingerprint values.
275 Version previous_version;
206 Version next_version; 276 Version next_version;
277 std::string previous_fp;
278 std::string next_fp;
207 279
208 CrxUpdateItem() : status(kNew) {} 280 // True if the differential update failed for any reason.
281 bool diff_update_failed;
282
283 // The error information for full and differential updates.
284 int error_code;
285 int extra_code1;
286 int diff_error_code;
287 int diff_extra_code1;
288
289 CrxUpdateItem()
290 : status(kNew),
291 is_update_available(false),
292 size(0),
293 diff_size(0),
294 diff_update_failed(false),
295 error_code(0),
296 extra_code1(0),
297 diff_error_code(0),
298 diff_extra_code1(0) {
299 }
209 300
210 // Function object used to find a specific component. 301 // Function object used to find a specific component.
211 class FindById { 302 class FindById {
212 public: 303 public:
213 explicit FindById(const std::string& id) : id_(id) {} 304 explicit FindById(const std::string& id) : id_(id) {}
214 305
215 bool operator() (CrxUpdateItem* item) const { 306 bool operator() (CrxUpdateItem* item) const {
216 return (item->id == id_); 307 return (item->id == id_);
217 } 308 }
218 private: 309 private:
219 const std::string& id_; 310 const std::string& id_;
220 }; 311 };
221 }; 312 };
222 313
314 // Returns true if a differential update is available for the update item.
315 bool IsDiffUpdateAvailable(const CrxUpdateItem* update_item) {
316 return update_item->diff_crx_url.is_valid();
317 }
318
319 // Returns true if a differential update is available, it has not failed yet,
320 // and the configuration allows it.
321 bool CanTryDiffUpdate(const CrxUpdateItem* update_item,
322 const ComponentUpdateService::Configurator& config) {
323 return IsDiffUpdateAvailable(update_item) &&
324 !update_item->diff_update_failed &&
325 config.DeltasEnabled();
326 }
327
223 } // namespace. 328 } // namespace.
224 329
225 typedef ComponentUpdateService::Configurator Config;
226
227 CrxComponent::CrxComponent() 330 CrxComponent::CrxComponent()
228 : installer(NULL), 331 : installer(NULL),
229 source(BANDAID) { 332 source(BANDAID) {
230 } 333 }
231 334
232 CrxComponent::~CrxComponent() { 335 CrxComponent::~CrxComponent() {
233 } 336 }
234 337
235 ////////////////////////////////////////////////////////////////////////////// 338 //////////////////////////////////////////////////////////////////////////////
236 // The one and only implementation of the ComponentUpdateService interface. In 339 // The one and only implementation of the ComponentUpdateService interface. In
237 // charge of running the show. The main method is ProcessPendingItems() which 340 // charge of running the show. The main method is ProcessPendingItems() which
238 // is called periodically to do the upgrades/installs or the update checks. 341 // is called periodically to do the upgrades/installs or the update checks.
239 // An important consideration here is to be as "low impact" as we can to the 342 // An important consideration here is to be as "low impact" as we can to the
240 // rest of the browser, so even if we have many components registered and 343 // rest of the browser, so even if we have many components registered and
241 // eligible for update, we only do one thing at a time with pauses in between 344 // eligible for update, we only do one thing at a time with pauses in between
242 // the tasks. Also when we do network requests there is only one |url_fetcher_| 345 // the tasks. Also when we do network requests there is only one |url_fetcher_|
243 // in flight at at a time. 346 // in flight at a time.
244 // There are no locks in this code, the main structure |work_items_| is mutated 347 // There are no locks in this code, the main structure |work_items_| is mutated
245 // only from the UI thread. The unpack and installation is done in the file 348 // only from the UI thread. The unpack and installation is done in the file
246 // thread and the network requests are done in the IO thread and in the file 349 // thread and the network requests are done in the IO thread and in the file
247 // thread. 350 // thread.
248 class CrxUpdateService : public ComponentUpdateService { 351 class CrxUpdateService : public ComponentUpdateService {
249 public: 352 public:
250 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); 353 explicit CrxUpdateService(ComponentUpdateService::Configurator* config);
251 354
252 virtual ~CrxUpdateService(); 355 virtual ~CrxUpdateService();
253 356
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 CrxUpdateService* service_; 395 CrxUpdateService* service_;
293 DISALLOW_COPY_AND_ASSIGN(ManifestParserBridge); 396 DISALLOW_COPY_AND_ASSIGN(ManifestParserBridge);
294 }; 397 };
295 398
296 // Context for a update check url request. See DelegateWithContext above. 399 // Context for a update check url request. See DelegateWithContext above.
297 struct UpdateContext { 400 struct UpdateContext {
298 base::Time start; 401 base::Time start;
299 UpdateContext() : start(base::Time::Now()) {} 402 UpdateContext() : start(base::Time::Now()) {}
300 }; 403 };
301 404
405 // Context for a completion ping. See DelegateWithContext above. The type
406 // is needed for template type deduction and it could be used in the
407 // future to pass arguments to the callback.
408 struct PingContext {
409 };
410
302 // Context for a crx download url request. See DelegateWithContext above. 411 // Context for a crx download url request. See DelegateWithContext above.
303 struct CRXContext { 412 struct CRXContext {
304 ComponentInstaller* installer; 413 ComponentInstaller* installer;
305 std::vector<uint8> pk_hash; 414 std::vector<uint8> pk_hash;
306 std::string id; 415 std::string id;
416 std::string fingerprint;
307 CRXContext() : installer(NULL) {} 417 CRXContext() : installer(NULL) {}
308 }; 418 };
309 419
310 void OnURLFetchComplete(const net::URLFetcher* source, 420 void OnURLFetchComplete(const net::URLFetcher* source,
311 UpdateContext* context); 421 UpdateContext* context);
312 422
313 void OnURLFetchComplete(const net::URLFetcher* source, 423 void OnURLFetchComplete(const net::URLFetcher* source,
314 CRXContext* context); 424 CRXContext* context);
315 425
426 void OnURLFetchComplete(const net::URLFetcher* source,
427 PingContext* context);
428
316 private: 429 private:
317 // See ManifestParserBridge. 430 // See ManifestParserBridge.
318 void OnParseUpdateManifestSucceeded( 431 void OnParseUpdateManifestSucceeded(
319 const UpdateManifest::Results& results); 432 const UpdateManifest::Results& results);
320 433
321 // See ManifestParserBridge. 434 // See ManifestParserBridge.
322 void OnParseUpdateManifestFailed( 435 void OnParseUpdateManifestFailed(const std::string& error_message);
323 const std::string& error_message);
324 436
325 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query); 437 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query);
326 438
327 void ProcessPendingItems(); 439 void ProcessPendingItems();
328 440
329 void ScheduleNextRun(bool step_delay); 441 void ScheduleNextRun(bool step_delay);
330 442
331 void ParseManifest(const std::string& xml); 443 void ParseManifest(const std::string& xml);
332 444
333 void Install(const CRXContext* context, const base::FilePath& crx_path); 445 void Install(const CRXContext* context, const base::FilePath& crx_path);
334 446
335 void DoneInstalling(const std::string& component_id, 447 void DoneInstalling(const std::string& component_id,
336 ComponentUnpacker::Error error); 448 ComponentUnpacker::Error error,
449 int extended_error);
337 450
338 size_t ChangeItemStatus(CrxUpdateItem::Status from, 451 size_t ChangeItemStatus(CrxUpdateItem::Status from,
339 CrxUpdateItem::Status to); 452 CrxUpdateItem::Status to);
340 453
341 CrxUpdateItem* FindUpdateItemById(const std::string& id); 454 CrxUpdateItem* FindUpdateItemById(const std::string& id);
342 455
343 scoped_ptr<Config> config_; 456 // Returns true if completion pings are enabled.
457 bool CanPing() const;
458
459 void SendPing(CrxUpdateItem* item);
460
461 std::string BuildPing(CrxUpdateItem* item) const;
462
463 static std::string BuildPingEvent(CrxUpdateItem* item);
464
465 scoped_ptr<ComponentUpdateService::Configurator> config_;
466
467 scoped_ptr<ComponentPatcher> component_patcher_;
344 468
345 scoped_ptr<net::URLFetcher> url_fetcher_; 469 scoped_ptr<net::URLFetcher> url_fetcher_;
346 470
471 scoped_ptr<net::URLFetcher> ping_sender_;
472
473 // A collection of every work item.
347 typedef std::vector<CrxUpdateItem*> UpdateItems; 474 typedef std::vector<CrxUpdateItem*> UpdateItems;
348 // A collection of every work item.
349 UpdateItems work_items_; 475 UpdateItems work_items_;
350 476
351 // A particular set of items from work_items_, which should be checked ASAP. 477 // A particular set of items from work_items_, which should be checked ASAP.
352 std::set<CrxUpdateItem*> requested_work_items_; 478 std::set<CrxUpdateItem*> requested_work_items_;
353 479
354 base::OneShotTimer<CrxUpdateService> timer_; 480 base::OneShotTimer<CrxUpdateService> timer_;
355 481
356 Version chrome_version_; 482 const Version chrome_version_;
483 const std::string prod_id_;
484 const std::string os_type_;
485 const std::string os_version_;
357 486
358 bool running_; 487 bool running_;
359 488
360 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); 489 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService);
361 }; 490 };
362 491
363 ////////////////////////////////////////////////////////////////////////////// 492 //////////////////////////////////////////////////////////////////////////////
364 493
365 CrxUpdateService::CrxUpdateService( 494 CrxUpdateService::CrxUpdateService(ComponentUpdateService::Configurator* config)
366 ComponentUpdateService::Configurator* config)
367 : config_(config), 495 : config_(config),
496 component_patcher_(config->CreateComponentPatcher()),
368 chrome_version_(chrome::VersionInfo().Version()), 497 chrome_version_(chrome::VersionInfo().Version()),
498 prod_id_(chrome::OmahaQueryParams::GetProdIdString(
499 chrome::OmahaQueryParams::CHROME)),
500 os_type_(chrome::VersionInfo().OSType()),
501 os_version_(base::SysInfo().OperatingSystemVersion()),
369 running_(false) { 502 running_(false) {
370 } 503 }
371 504
372 CrxUpdateService::~CrxUpdateService() { 505 CrxUpdateService::~CrxUpdateService() {
373 // Because we are a singleton, at this point only the UI thread should be 506 // Because we are a singleton, at this point only the UI thread should be
374 // alive, this simplifies the management of the work that could be in 507 // alive, this simplifies the management of the work that could be in
375 // flight in other threads. 508 // flight in other threads.
376 Stop(); 509 Stop();
377 STLDeleteElements(&work_items_); 510 STLDeleteElements(&work_items_);
378 } 511 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 CrxUpdateItem::FindById finder(id); 576 CrxUpdateItem::FindById finder(id);
444 UpdateItems::iterator it = std::find_if(work_items_.begin(), 577 UpdateItems::iterator it = std::find_if(work_items_.begin(),
445 work_items_.end(), 578 work_items_.end(),
446 finder); 579 finder);
447 if (it == work_items_.end()) 580 if (it == work_items_.end())
448 return NULL; 581 return NULL;
449 return (*it); 582 return (*it);
450 } 583 }
451 584
452 // Changes all the components in |work_items_| that have |from| status to 585 // Changes all the components in |work_items_| that have |from| status to
453 // |to| statatus and returns how many have been changed. 586 // |to| status and returns how many have been changed.
454 size_t CrxUpdateService::ChangeItemStatus(CrxUpdateItem::Status from, 587 size_t CrxUpdateService::ChangeItemStatus(CrxUpdateItem::Status from,
455 CrxUpdateItem::Status to) { 588 CrxUpdateItem::Status to) {
456 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 589 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
457 size_t count = 0; 590 size_t count = 0;
458 for (UpdateItems::iterator it = work_items_.begin(); 591 for (UpdateItems::iterator it = work_items_.begin();
459 it != work_items_.end(); ++it) { 592 it != work_items_.end(); ++it) {
460 CrxUpdateItem* item = *it; 593 CrxUpdateItem* item = *it;
461 if (item->status != from) 594 if (item->status != from)
462 continue; 595 continue;
463 item->status = to; 596 item->status = to;
(...skipping 20 matching lines...) Expand all
484 CrxUpdateItem* uit; 617 CrxUpdateItem* uit;
485 uit = FindUpdateItemById(id); 618 uit = FindUpdateItemById(id);
486 if (uit) { 619 if (uit) {
487 uit->component = component; 620 uit->component = component;
488 return kReplaced; 621 return kReplaced;
489 } 622 }
490 623
491 uit = new CrxUpdateItem; 624 uit = new CrxUpdateItem;
492 uit->id.swap(id); 625 uit->id.swap(id);
493 uit->component = component; 626 uit->component = component;
627
494 work_items_.push_back(uit); 628 work_items_.push_back(uit);
495 // If this is the first component registered we call Start to 629 // If this is the first component registered we call Start to
496 // schedule the first timer. 630 // schedule the first timer.
497 if (running_ && (work_items_.size() == 1)) 631 if (running_ && (work_items_.size() == 1))
498 Start(); 632 Start();
499 633
500 return kOk; 634 return kOk;
501 } 635 }
502 636
503 // Sets a component to be checked for updates. 637 // Sets a component to be checked for updates.
504 // The componet to add is |crxit| and the |query| string is modified with the 638 // The component to add is |crxit| and the |query| string is modified with the
505 // required omaha compatible query. Returns false when the query strings 639 // required omaha compatible query. Returns false when the query strings
506 // is longer than specified by UrlSizeLimit(). 640 // is longer than specified by UrlSizeLimit().
507 bool CrxUpdateService::AddItemToUpdateCheck(CrxUpdateItem* item, 641 bool CrxUpdateService::AddItemToUpdateCheck(CrxUpdateItem* item,
508 std::string* query) { 642 std::string* query) {
509 if (!AddQueryString(item->id, 643 if (!AddQueryString(item->id,
510 item->component.version.GetString(), 644 item->component.version.GetString(),
645 item->component.fingerprint,
511 config_->UrlSizeLimit(), query)) 646 config_->UrlSizeLimit(), query))
512 return false; 647 return false;
648
513 item->status = CrxUpdateItem::kChecking; 649 item->status = CrxUpdateItem::kChecking;
514 item->last_check = base::Time::Now(); 650 item->last_check = base::Time::Now();
651 item->is_update_available = false;
652 item->previous_version = item->component.version;
653 item->next_version = Version();
654 item->previous_fp = item->component.fingerprint;
655 item->next_fp = "";
656 item->diff_update_failed = false;
657 item->error_code = 0;
658 item->extra_code1 = 0;
659 item->diff_error_code = 0;
660 item->diff_extra_code1 = 0;
515 return true; 661 return true;
516 } 662 }
517 663
518 // Start the process of checking for an update, for a particular component 664 // Start the process of checking for an update, for a particular component
519 // that was previously registered. 665 // that was previously registered.
520 ComponentUpdateService::Status CrxUpdateService::CheckForUpdateSoon( 666 ComponentUpdateService::Status CrxUpdateService::CheckForUpdateSoon(
521 const CrxComponent& component) { 667 const CrxComponent& component) {
522 if (component.pk_hash.empty() || 668 if (component.pk_hash.empty() ||
523 !component.version.IsValid() || 669 !component.version.IsValid() ||
524 !component.installer) 670 !component.installer)
525 return kError; 671 return kError;
526 672
527 std::string id = 673 std::string id =
528 HexStringToID(StringToLowerASCII(base::HexEncode(&component.pk_hash[0], 674 HexStringToID(StringToLowerASCII(base::HexEncode(&component.pk_hash[0],
529 component.pk_hash.size()/2))); 675 component.pk_hash.size()/2)));
530 676
531 CrxUpdateItem* uit; 677 CrxUpdateItem* uit;
532 uit = FindUpdateItemById(id); 678 uit = FindUpdateItemById(id);
533 if (!uit) 679 if (!uit)
534 return kError; 680 return kError;
535 681
536 // Check if the request is too soon. 682 // Check if the request is too soon.
537 base::TimeDelta delta = base::Time::Now() - uit->last_check; 683 base::TimeDelta delta = base::Time::Now() - uit->last_check;
538 if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay())) { 684 if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay()))
539 return kError; 685 return kError;
540 }
541 686
542 switch (uit->status) { 687 switch (uit->status) {
543 // If the item is already in the process of being updated, there is 688 // If the item is already in the process of being updated, there is
544 // no point in this call, so return kInProgress. 689 // no point in this call, so return kInProgress.
545 case CrxUpdateItem::kChecking: 690 case CrxUpdateItem::kChecking:
546 case CrxUpdateItem::kCanUpdate: 691 case CrxUpdateItem::kCanUpdate:
692 case CrxUpdateItem::kDownloadingDiff:
547 case CrxUpdateItem::kDownloading: 693 case CrxUpdateItem::kDownloading:
694 case CrxUpdateItem::kUpdatingDiff:
548 case CrxUpdateItem::kUpdating: 695 case CrxUpdateItem::kUpdating:
549 return kInProgress; 696 return kInProgress;
550 // Otherwise the item was already checked a while back (or it is new), 697 // Otherwise the item was already checked a while back (or it is new),
551 // set its status to kNew to give it a slightly higher priority. 698 // set its status to kNew to give it a slightly higher priority.
552 case CrxUpdateItem::kNew: 699 case CrxUpdateItem::kNew:
553 case CrxUpdateItem::kUpdated: 700 case CrxUpdateItem::kUpdated:
554 case CrxUpdateItem::kUpToDate: 701 case CrxUpdateItem::kUpToDate:
555 case CrxUpdateItem::kNoUpdate: 702 case CrxUpdateItem::kNoUpdate:
556 uit->status = CrxUpdateItem::kNew; 703 uit->status = CrxUpdateItem::kNew;
557 requested_work_items_.insert(uit); 704 requested_work_items_.insert(uit);
(...skipping 18 matching lines...) Expand all
576 void CrxUpdateService::ProcessPendingItems() { 723 void CrxUpdateService::ProcessPendingItems() {
577 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 724 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
578 // First check for ready upgrades and do one. The first 725 // First check for ready upgrades and do one. The first
579 // step is to fetch the crx package. 726 // step is to fetch the crx package.
580 for (UpdateItems::const_iterator it = work_items_.begin(); 727 for (UpdateItems::const_iterator it = work_items_.begin();
581 it != work_items_.end(); ++it) { 728 it != work_items_.end(); ++it) {
582 CrxUpdateItem* item = *it; 729 CrxUpdateItem* item = *it;
583 if (item->status != CrxUpdateItem::kCanUpdate) 730 if (item->status != CrxUpdateItem::kCanUpdate)
584 continue; 731 continue;
585 // Found component to update, start the process. 732 // Found component to update, start the process.
586 item->status = CrxUpdateItem::kDownloading;
587 CRXContext* context = new CRXContext; 733 CRXContext* context = new CRXContext;
588 context->pk_hash = item->component.pk_hash; 734 context->pk_hash = item->component.pk_hash;
589 context->id = item->id; 735 context->id = item->id;
590 context->installer = item->component.installer; 736 context->installer = item->component.installer;
737 context->fingerprint = item->next_fp;
738 GURL package_url;
739 if (CanTryDiffUpdate(item, *config_)) {
740 package_url = item->diff_crx_url;
741 item->status = CrxUpdateItem::kDownloadingDiff;
742 } else {
743 package_url = item->crx_url;
744 item->status = CrxUpdateItem::kDownloading;
745 }
591 url_fetcher_.reset(net::URLFetcher::Create( 746 url_fetcher_.reset(net::URLFetcher::Create(
592 0, item->crx_url, net::URLFetcher::GET, 747 0, package_url, net::URLFetcher::GET,
593 MakeContextDelegate(this, context))); 748 MakeContextDelegate(this, context)));
594 StartFetch(url_fetcher_.get(), config_->RequestContext(), true); 749 StartFetch(url_fetcher_.get(), config_->RequestContext(), true);
595 return; 750 return;
596 } 751 }
597 752
598 for (size_t ix = 0; ix != arraysize(kManifestSources); ++ix) { 753 for (size_t ix = 0; ix != arraysize(kManifestSources); ++ix) {
599 const CrxComponent::UrlSource manifest_source = kManifestSources[ix]; 754 const CrxComponent::UrlSource manifest_source = kManifestSources[ix];
600 755
601 std::string query; 756 std::string query;
602 // If no pending upgrades, we check if there are new components we have not 757 // If no pending upgrades, we check if there are new components we have not
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 delete context; 848 delete context;
694 } 849 }
695 850
696 // Parsing the manifest is either done right now for tests or in a sandboxed 851 // Parsing the manifest is either done right now for tests or in a sandboxed
697 // process for the production environment. This mitigates the case where an 852 // process for the production environment. This mitigates the case where an
698 // attacker was able to feed us a malicious xml string. 853 // attacker was able to feed us a malicious xml string.
699 void CrxUpdateService::ParseManifest(const std::string& xml) { 854 void CrxUpdateService::ParseManifest(const std::string& xml) {
700 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 855 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
701 if (config_->InProcess()) { 856 if (config_->InProcess()) {
702 UpdateManifest manifest; 857 UpdateManifest manifest;
703 if (!manifest.Parse(xml)) { 858 if (!manifest.Parse(xml))
704 CrxUpdateService::OnParseUpdateManifestFailed(manifest.errors()); 859 CrxUpdateService::OnParseUpdateManifestFailed(manifest.errors());
705 } else { 860 else
706 CrxUpdateService::OnParseUpdateManifestSucceeded(manifest.results()); 861 CrxUpdateService::OnParseUpdateManifestSucceeded(manifest.results());
707 }
708 } else { 862 } else {
709 UtilityProcessHost* host = 863 UtilityProcessHost* host =
710 UtilityProcessHost::Create(new ManifestParserBridge(this), 864 UtilityProcessHost::Create(new ManifestParserBridge(this),
711 base::MessageLoopProxy::current().get()); 865 base::MessageLoopProxy::current().get());
712 host->EnableZygote(); 866 host->EnableZygote();
713 host->Send(new ChromeUtilityMsg_ParseUpdateManifest(xml)); 867 host->Send(new ChromeUtilityMsg_ParseUpdateManifest(xml));
714 } 868 }
715 } 869 }
716 870
717 // A valid Omaha update check has arrived, from only the list of components that 871 // A valid Omaha update check has arrived, from only the list of components that
(...skipping 27 matching lines...) Expand all
745 } 899 }
746 if (!it->browser_min_version.empty()) { 900 if (!it->browser_min_version.empty()) {
747 if (IsVersionNewer(chrome_version_, it->browser_min_version)) { 901 if (IsVersionNewer(chrome_version_, it->browser_min_version)) {
748 // Does not apply for this chrome version. 902 // Does not apply for this chrome version.
749 crx->status = CrxUpdateItem::kNoUpdate; 903 crx->status = CrxUpdateItem::kNoUpdate;
750 continue; 904 continue;
751 } 905 }
752 } 906 }
753 // All test passed. Queue an upgrade for this component and fire the 907 // All test passed. Queue an upgrade for this component and fire the
754 // notifications. 908 // notifications.
909 crx->is_update_available = true;
755 crx->crx_url = it->crx_url; 910 crx->crx_url = it->crx_url;
911 crx->package_hash = it->package_hash;
912 crx->size = it->size;
913 crx->diff_crx_url = it->diff_crx_url;
914 crx->diff_package_hash = it->diff_package_hash;
915 crx->diff_size = it->diff_size;
756 crx->status = CrxUpdateItem::kCanUpdate; 916 crx->status = CrxUpdateItem::kCanUpdate;
757 crx->next_version = Version(it->version); 917 crx->next_version = Version(it->version);
918 crx->next_fp = it->package_fingerprint;
758 ++update_pending; 919 ++update_pending;
759 920
760 content::NotificationService::current()->Notify( 921 content::NotificationService::current()->Notify(
761 chrome::NOTIFICATION_COMPONENT_UPDATE_FOUND, 922 chrome::NOTIFICATION_COMPONENT_UPDATE_FOUND,
762 content::Source<std::string>(&crx->id), 923 content::Source<std::string>(&crx->id),
763 content::NotificationService::NoDetails()); 924 content::NotificationService::NoDetails());
764 } 925 }
765 926
766 // All the components that are not mentioned in the manifest we 927 // All the components that are not mentioned in the manifest we
767 // consider them up to date. 928 // consider them up to date.
(...skipping 14 matching lines...) Expand all
782 } 943 }
783 944
784 // Called when the CRX package has been downloaded to a temporary location. 945 // Called when the CRX package has been downloaded to a temporary location.
785 // Here we fire the notifications and schedule the component-specific installer 946 // Here we fire the notifications and schedule the component-specific installer
786 // to be called in the file thread. 947 // to be called in the file thread.
787 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source, 948 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source,
788 CRXContext* context) { 949 CRXContext* context) {
789 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 950 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
790 int error_code = net::OK; 951 int error_code = net::OK;
791 952
953 CrxUpdateItem* crx = FindUpdateItemById(context->id);
954 DCHECK(crx->status == CrxUpdateItem::kDownloadingDiff ||
955 crx->status == CrxUpdateItem::kDownloading);
956
792 if (source->FileErrorOccurred(&error_code) || !FetchSuccess(*source)) { 957 if (source->FileErrorOccurred(&error_code) || !FetchSuccess(*source)) {
958 if (crx->status == CrxUpdateItem::kDownloadingDiff) {
959 crx->diff_error_code = GetFetchError(*source);
960 crx->diff_update_failed = true;
961 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff,
962 CrxUpdateItem::kCanUpdate);
963 DCHECK_EQ(count, 1ul);
964 ScheduleNextRun(true);
965 return;
966 }
967 crx->error_code = GetFetchError(*source);
793 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading, 968 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading,
794 CrxUpdateItem::kNoUpdate); 969 CrxUpdateItem::kNoUpdate);
795 DCHECK_EQ(count, 1ul); 970 DCHECK_EQ(count, 1ul);
796 config_->OnEvent(Configurator::kNetworkError, CrxIdtoUMAId(context->id)); 971 config_->OnEvent(Configurator::kNetworkError, CrxIdtoUMAId(context->id));
797 url_fetcher_.reset(); 972 url_fetcher_.reset();
973
974 if (CanPing())
975 SendPing(crx);
976
798 ScheduleNextRun(false); 977 ScheduleNextRun(false);
799 } else { 978 } else {
800 base::FilePath temp_crx_path; 979 base::FilePath temp_crx_path;
801 CHECK(source->GetResponseAsFilePath(true, &temp_crx_path)); 980 CHECK(source->GetResponseAsFilePath(true, &temp_crx_path));
802 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading, 981
803 CrxUpdateItem::kUpdating); 982 size_t count = 0;
983 if (crx->status == CrxUpdateItem::kDownloadingDiff) {
984 count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff,
985 CrxUpdateItem::kUpdatingDiff);
986 } else {
987 count = ChangeItemStatus(CrxUpdateItem::kDownloading,
988 CrxUpdateItem::kUpdating);
989 }
804 DCHECK_EQ(count, 1ul); 990 DCHECK_EQ(count, 1ul);
991
805 url_fetcher_.reset(); 992 url_fetcher_.reset();
806 993
807 content::NotificationService::current()->Notify( 994 content::NotificationService::current()->Notify(
808 chrome::NOTIFICATION_COMPONENT_UPDATE_READY, 995 chrome::NOTIFICATION_COMPONENT_UPDATE_READY,
809 content::Source<std::string>(&context->id), 996 content::Source<std::string>(&context->id),
810 content::NotificationService::NoDetails()); 997 content::NotificationService::NoDetails());
811 998
812 // Why unretained? See comment at top of file. 999 // Why unretained? See comment at top of file.
813 BrowserThread::PostDelayedTask( 1000 BrowserThread::PostDelayedTask(
814 BrowserThread::FILE, 1001 BrowserThread::FILE,
815 FROM_HERE, 1002 FROM_HERE,
816 base::Bind(&CrxUpdateService::Install, 1003 base::Bind(&CrxUpdateService::Install,
817 base::Unretained(this), 1004 base::Unretained(this),
818 context, 1005 context,
819 temp_crx_path), 1006 temp_crx_path),
820 base::TimeDelta::FromMilliseconds(config_->StepDelay())); 1007 base::TimeDelta::FromMilliseconds(config_->StepDelay()));
821 } 1008 }
822 } 1009 }
823 1010
824 // Install consists of digital signature verification, unpacking and then 1011 // Install consists of digital signature verification, unpacking and then
825 // calling the component specific installer. All that is handled by the 1012 // calling the component specific installer. All that is handled by the
826 // |unpacker|. If there is an error this function is in charge of deleting 1013 // |unpacker|. If there is an error this function is in charge of deleting
827 // the files created. 1014 // the files created.
828 void CrxUpdateService::Install(const CRXContext* context, 1015 void CrxUpdateService::Install(const CRXContext* context,
829 const base::FilePath& crx_path) { 1016 const base::FilePath& crx_path) {
830 // This function owns the |crx_path| and the |context| object. 1017 // This function owns the |crx_path| and the |context| object.
831 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 1018 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
832 ComponentUnpacker 1019 ComponentUnpacker unpacker(context->pk_hash,
833 unpacker(context->pk_hash, crx_path, context->installer); 1020 crx_path,
834 if (!file_util::Delete(crx_path, false)) { 1021 context->fingerprint,
1022 component_patcher_.get(),
1023 context->installer);
1024 if (!file_util::Delete(crx_path, false))
835 NOTREACHED() << crx_path.value(); 1025 NOTREACHED() << crx_path.value();
836 }
837 // Why unretained? See comment at top of file. 1026 // Why unretained? See comment at top of file.
838 BrowserThread::PostDelayedTask( 1027 BrowserThread::PostDelayedTask(
839 BrowserThread::UI, 1028 BrowserThread::UI,
840 FROM_HERE, 1029 FROM_HERE,
841 base::Bind(&CrxUpdateService::DoneInstalling, base::Unretained(this), 1030 base::Bind(&CrxUpdateService::DoneInstalling, base::Unretained(this),
842 context->id, unpacker.error()), 1031 context->id, unpacker.error(), unpacker.extended_error()),
843 base::TimeDelta::FromMilliseconds(config_->StepDelay())); 1032 base::TimeDelta::FromMilliseconds(config_->StepDelay()));
844 delete context; 1033 delete context;
845 } 1034 }
846 1035
847 // Installation has been completed. Adjust the component status and 1036 // Installation has been completed. Adjust the component status and
848 // schedule the next check. 1037 // schedule the next check.
849 void CrxUpdateService::DoneInstalling(const std::string& component_id, 1038 void CrxUpdateService::DoneInstalling(const std::string& component_id,
850 ComponentUnpacker::Error error) { 1039 ComponentUnpacker::Error error,
1040 int extra_code) {
851 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1041 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
852 1042
853 CrxUpdateItem* item = FindUpdateItemById(component_id); 1043 CrxUpdateItem* item = FindUpdateItemById(component_id);
1044 if (item->status == CrxUpdateItem::kUpdatingDiff) {
1045 if (error != ComponentUnpacker::kNone) {
1046 item->diff_error_code = error;
1047 item->diff_extra_code1 = extra_code;
1048 item->diff_update_failed = true;
1049 size_t count = ChangeItemStatus(CrxUpdateItem::kUpdatingDiff,
1050 CrxUpdateItem::kCanUpdate);
1051 DCHECK_EQ(count, 1ul);
1052 ScheduleNextRun(true);
1053 return;
1054 }
1055 }
1056
1057 if (error != ComponentUnpacker::kNone) {
1058 item->error_code = error;
1059 item->extra_code1 = extra_code;
1060 }
1061
854 item->status = (error == ComponentUnpacker::kNone) ? CrxUpdateItem::kUpdated : 1062 item->status = (error == ComponentUnpacker::kNone) ? CrxUpdateItem::kUpdated :
855 CrxUpdateItem::kNoUpdate; 1063 CrxUpdateItem::kNoUpdate;
856 if (item->status == CrxUpdateItem::kUpdated) 1064 if (item->status == CrxUpdateItem::kUpdated) {
857 item->component.version = item->next_version; 1065 item->component.version = item->next_version;
1066 item->component.fingerprint = item->next_fp;
1067 }
858 1068
859 Configurator::Events event; 1069 Configurator::Events event;
860 switch (error) { 1070 switch (error) {
861 case ComponentUnpacker::kNone: 1071 case ComponentUnpacker::kNone:
862 event = Configurator::kComponentUpdated; 1072 event = Configurator::kComponentUpdated;
863 break; 1073 break;
864 case ComponentUnpacker::kInstallerError: 1074 case ComponentUnpacker::kInstallerError:
865 event = Configurator::kInstallerError; 1075 event = Configurator::kInstallerError;
866 break; 1076 break;
867 default: 1077 default:
868 event = Configurator::kUnpackError; 1078 event = Configurator::kUnpackError;
869 break; 1079 break;
870 } 1080 }
871 1081
1082 if (CanPing())
1083 SendPing(item);
1084
872 config_->OnEvent(event, CrxIdtoUMAId(component_id)); 1085 config_->OnEvent(event, CrxIdtoUMAId(component_id));
873 ScheduleNextRun(false); 1086 ScheduleNextRun(false);
874 } 1087 }
875 1088
1089 bool CrxUpdateService::CanPing() const {
1090 return config_->PingUrl().is_valid();
1091 }
1092
1093 void CrxUpdateService::SendPing(CrxUpdateItem* item) {
1094 const std::string ping_url(config_->PingUrl().spec());
1095 ping_sender_.reset(net::URLFetcher::Create(
1096 0, GURL(ping_url), net::URLFetcher::POST,
1097 MakeContextDelegate(this, new PingContext())));
1098 ping_sender_->SetUploadData(std::string("application/xml"), BuildPing(item));
1099 StartFetch(ping_sender_.get(), config_->RequestContext(), false);
1100 }
1101
1102 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source,
1103 PingContext* context) {
1104 ping_sender_.reset();
1105 }
1106
1107 // Builds a ping message for the specified update item.
1108 std::string CrxUpdateService::BuildPing(CrxUpdateItem* item) const {
1109 const char response_format[] =
1110 "<o:gupdate xmlns:o=\"http://www.google.com/update2/request\" "
1111 "protocol=\"2.0\" version=\"%s-%s\" requestid=\"{%s}\"> "
1112 "<o:os platform=\"%s\" version=\"%s\"/> "
1113 "<o:app appid=\"%s\" version=\"%s\">"
1114 "%s"
1115 "</o:app></o:gupdate>";
1116 const std::string response_envelope(
1117 base::StringPrintf(response_format,
1118 prod_id_.c_str(),
1119 chrome_version_.GetString().c_str(),
1120 base::GenerateGUID().c_str(),
1121 os_type_.c_str(),
1122 os_version_.c_str(),
1123 item->id.c_str(),
1124 item->component.version.GetString().c_str(),
1125 BuildPingEvent(item).c_str()));
1126 return response_envelope;
1127 }
1128
1129 // Returns a string representing one ping event for an update item.
1130 std::string CrxUpdateService::BuildPingEvent(CrxUpdateItem* item) {
1131 DCHECK(item->status == CrxUpdateItem::kNoUpdate ||
1132 item->status == CrxUpdateItem::kUpdated);
1133 DCHECK(item->is_update_available);
1134
1135 using base::StringAppendF;
1136
1137 std::string ping_event("<o:event eventtype=\"3\"");
1138 const int event_result = item->status == CrxUpdateItem::kUpdated;
1139 StringAppendF(&ping_event, " eventresult=\"%d\"", event_result);
1140 StringAppendF(&ping_event, " previousversion=\"%s\"",
1141 item->previous_version.GetString().c_str());
1142 StringAppendF(&ping_event, " nextversion=\"%s\"",
1143 item->next_version.GetString().c_str());
1144 if (item->error_code)
1145 StringAppendF(&ping_event, " errorcode=\"%d\"", item->error_code);
1146 if (item->extra_code1)
1147 StringAppendF(&ping_event, " extracode1=\"%d\"", item->extra_code1);
1148 if (IsDiffUpdateAvailable(item))
1149 StringAppendF(&ping_event, " diffresult=\"%d\"", !item->diff_update_failed);
1150 if (item->diff_error_code)
1151 StringAppendF(&ping_event, " differrorcode=\"%d\"", item->diff_error_code);
1152 if (item->diff_extra_code1) {
1153 StringAppendF(&ping_event,
1154 " diffextracode1=\"%d\"",
1155 item->diff_extra_code1);
1156 }
1157 if (!item->previous_fp.empty())
1158 StringAppendF(&ping_event, " previousfp=\"%s\"", item->previous_fp.c_str());
1159 if (!item->next_fp.empty())
1160 StringAppendF(&ping_event, " nextfp=\"%s\"", item->next_fp.c_str());
1161 StringAppendF(&ping_event, "/>");
1162 return ping_event;
1163 }
1164
876 // The component update factory. Using the component updater as a singleton 1165 // The component update factory. Using the component updater as a singleton
877 // is the job of the browser process. 1166 // is the job of the browser process.
878 ComponentUpdateService* ComponentUpdateServiceFactory( 1167 ComponentUpdateService* ComponentUpdateServiceFactory(
879 ComponentUpdateService::Configurator* config) { 1168 ComponentUpdateService::Configurator* config) {
880 DCHECK(config); 1169 DCHECK(config);
881 return new CrxUpdateService(config); 1170 return new CrxUpdateService(config);
882 } 1171 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698