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

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

Issue 18516010: Implemented completion pings for component updates. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ChromeConfigurator owns the ping manager. Created 7 years, 5 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/compiler_specific.h"
14 #include "base/file_util.h" 14 #include "base/file_util.h"
15 #include "base/files/file_path.h" 15 #include "base/files/file_path.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/memory/scoped_ptr.h" 17 #include "base/memory/scoped_ptr.h"
18 #include "base/observer_list.h"
18 #include "base/stl_util.h" 19 #include "base/stl_util.h"
19 #include "base/strings/string_number_conversions.h" 20 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/string_piece.h" 21 #include "base/strings/string_piece.h"
21 #include "base/strings/string_util.h" 22 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h" 23 #include "base/strings/stringprintf.h"
23 #include "base/timer/timer.h" 24 #include "base/timer/timer.h"
24 #include "chrome/browser/browser_process.h" 25 #include "chrome/browser/browser_process.h"
25 #include "chrome/browser/chrome_notification_types.h" 26 #include "chrome/browser/chrome_notification_types.h"
26 #include "chrome/browser/component_updater/component_patcher.h" 27 #include "chrome/browser/component_updater/component_patcher.h"
27 #include "chrome/browser/component_updater/component_unpacker.h" 28 #include "chrome/browser/component_updater/component_unpacker.h"
29 #include "chrome/browser/component_updater/component_updater_service_observer.h"
30 #include "chrome/browser/component_updater/crx_update_item.h"
28 #include "chrome/common/chrome_utility_messages.h" 31 #include "chrome/common/chrome_utility_messages.h"
29 #include "chrome/common/chrome_version_info.h" 32 #include "chrome/common/chrome_version_info.h"
30 #include "chrome/common/extensions/extension.h" 33 #include "chrome/common/extensions/extension.h"
31 #include "chrome/common/omaha_query_params/omaha_query_params.h" 34 #include "chrome/common/omaha_query_params/omaha_query_params.h"
32 #include "content/public/browser/browser_thread.h" 35 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/notification_service.h" 36 #include "content/public/browser/notification_service.h"
34 #include "content/public/browser/utility_process_host.h" 37 #include "content/public/browser/utility_process_host.h"
35 #include "content/public/browser/utility_process_host_client.h" 38 #include "content/public/browser/utility_process_host_client.h"
36 #include "net/base/escape.h" 39 #include "net/base/escape.h"
37 #include "net/base/load_flags.h" 40 #include "net/base/load_flags.h"
38 #include "net/base/net_errors.h" 41 #include "net/base/net_errors.h"
39 #include "net/url_request/url_fetcher.h" 42 #include "net/url_request/url_fetcher.h"
40 #include "net/url_request/url_fetcher_delegate.h" 43 #include "net/url_request/url_fetcher_delegate.h"
41 #include "net/url_request/url_request_status.h" 44 #include "net/url_request/url_request_status.h"
42 #include "url/gurl.h" 45 #include "url/gurl.h"
43 46
47 using component_updater::ComponentUpdaterServiceObserver;
44 using content::BrowserThread; 48 using content::BrowserThread;
45 using content::UtilityProcessHost; 49 using content::UtilityProcessHost;
46 using content::UtilityProcessHostClient; 50 using content::UtilityProcessHostClient;
47 using extensions::Extension; 51 using extensions::Extension;
48 52
49 // The component updater is designed to live until process shutdown, so 53 // The component updater is designed to live until process shutdown, so
50 // base::Bind() calls are not refcounted. 54 // base::Bind() calls are not refcounted.
51 55
52 namespace { 56 namespace {
53 57
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 &val)) { 104 &val)) {
101 id.append(1, val + 'a'); 105 id.append(1, val + 'a');
102 } else { 106 } else {
103 id.append(1, 'a'); 107 id.append(1, 'a');
104 } 108 }
105 } 109 }
106 DCHECK(Extension::IdIsValid(id)); 110 DCHECK(Extension::IdIsValid(id));
107 return id; 111 return id;
108 } 112 }
109 113
110 // Returns given a crx id it returns a small number, less than 100, that has a
111 // decent chance of being unique among the registered components. It also has
112 // the nice property that can be trivially computed by hand.
113 static int CrxIdtoUMAId(const std::string& id) {
114 CHECK_GT(id.size(), 2U);
115 return id[0] + id[1] + id[2] - ('a' * 3);
116 }
117
118 // Helper to do version check for components. 114 // Helper to do version check for components.
119 bool IsVersionNewer(const Version& current, const std::string& proposed) { 115 bool IsVersionNewer(const Version& current, const std::string& proposed) {
120 Version proposed_ver(proposed); 116 Version proposed_ver(proposed);
121 if (!proposed_ver.IsValid()) 117 if (!proposed_ver.IsValid())
122 return false; 118 return false;
123 return (current.CompareTo(proposed_ver) < 0); 119 return (current.CompareTo(proposed_ver) < 0);
124 } 120 }
125 121
126 // Helper template class that allows our main class to have separate 122 // Helper template class that allows our main class to have separate
127 // OnURLFetchComplete() callbacks for different types of url requests 123 // OnURLFetchComplete() callbacks for different types of url requests
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 } 161 }
166 fetcher->Start(); 162 fetcher->Start();
167 } 163 }
168 164
169 // Returns true if the url request of |fetcher| was succesful. 165 // Returns true if the url request of |fetcher| was succesful.
170 bool FetchSuccess(const net::URLFetcher& fetcher) { 166 bool FetchSuccess(const net::URLFetcher& fetcher) {
171 return (fetcher.GetStatus().status() == net::URLRequestStatus::SUCCESS) && 167 return (fetcher.GetStatus().status() == net::URLRequestStatus::SUCCESS) &&
172 (fetcher.GetResponseCode() == 200); 168 (fetcher.GetResponseCode() == 200);
173 } 169 }
174 170
175 // This is the one and only per-item state structure. Designed to be hosted 171 // Returns the error code which occured during the fetch.The function returns 0
176 // in a std::vector or a std::list. The two main members are |component| 172 // if the fetch was successful. If errors happen, the function could return a
177 // which is supplied by the the component updater client and |status| which 173 // network error, an http response code, or the status of the fetch, if the
178 // is modified as the item is processed by the update pipeline. The expected 174 // fetch is pending or canceled.
179 // transition graph is: 175 int GetFetchError(const net::URLFetcher& fetcher) {
180 // 176 if (FetchSuccess(fetcher))
181 // kNew 177 return 0;
182 // |
183 // V
184 // +----------------------> kChecking -<---------+-----<-------+
185 // | | | |
186 // | error V no | |
187 // kNoUpdate <---------------- [update?] ->---- kUpToDate kUpdated
188 // ^ | ^
189 // | yes | |
190 // | diff=false V |
191 // | +-----------> kCanUpdate |
192 // | | | |
193 // | | V no |
194 // | | [differential update?]->----+ |
195 // | | | | |
196 // | | yes | | |
197 // | | error V | |
198 // | +---------<- kDownloadingDiff | |
199 // | | | | |
200 // | | | | |
201 // | | error V | |
202 // | +---------<- kUpdatingDiff ->--------|-----------+ success
203 // | | |
204 // | error V |
205 // +----------------------------------------- kDownloading |
206 // | | |
207 // | error V |
208 // +------------------------------------------ kUpdating ->----+ success
209 //
210 struct CrxUpdateItem {
211 enum Status {
212 kNew,
213 kChecking,
214 kCanUpdate,
215 kDownloadingDiff,
216 kDownloading,
217 kUpdatingDiff,
218 kUpdating,
219 kUpdated,
220 kUpToDate,
221 kNoUpdate,
222 kLastStatus
223 };
224 178
225 Status status; 179 const net::URLRequestStatus::Status status(fetcher.GetStatus().status());
226 std::string id; 180 if (status == net::URLRequestStatus::FAILED)
227 CrxComponent component; 181 return fetcher.GetStatus().error();
228 182
229 base::Time last_check; 183 if (status == net::URLRequestStatus::IO_PENDING ||
184 status == net::URLRequestStatus::CANCELED)
185 return status;
230 186
231 // These members are initialized with their corresponding values from the 187 const int response_code(fetcher.GetResponseCode());
232 // update server response. 188 if (status == net::URLRequestStatus::SUCCESS && response_code != 200)
233 GURL crx_url; 189 return response_code;
234 GURL diff_crx_url;
235 int size;
236 int diff_size;
237 190
238 // The from/to version and fingerprint values. 191 return -1;
239 Version previous_version;
240 Version next_version;
241 std::string previous_fp;
242 std::string next_fp;
243
244 // True if the differential update failed for any reason.
245 bool diff_update_failed;
246
247 CrxUpdateItem()
248 : status(kNew),
249 size(0),
250 diff_size(0),
251 diff_update_failed(false) {
252 } 192 }
253 193
254 // Function object used to find a specific component.
255 class FindById {
256 public:
257 explicit FindById(const std::string& id) : id_(id) {}
258
259 bool operator() (CrxUpdateItem* item) const {
260 return (item->id == id_);
261 }
262 private:
263 const std::string& id_;
264 };
265 };
266
267 // Returns true if a differential update is available for the update item. 194 // Returns true if a differential update is available for the update item.
268 bool IsDiffUpdateAvailable(const CrxUpdateItem* update_item) { 195 bool IsDiffUpdateAvailable(const CrxUpdateItem* update_item) {
269 return update_item->diff_crx_url.is_valid(); 196 return update_item->diff_crx_url.is_valid();
270 } 197 }
271 198
272 // Returns true if a differential update is available, it has not failed yet, 199 // Returns true if a differential update is available, it has not failed yet,
273 // and the configuration allows it. 200 // and the configuration allows it.
274 bool CanTryDiffUpdate(const CrxUpdateItem* update_item, 201 bool CanTryDiffUpdate(const CrxUpdateItem* update_item,
275 const ComponentUpdateService::Configurator& config) { 202 const ComponentUpdateService::Configurator& config) {
276 return IsDiffUpdateAvailable(update_item) && 203 return IsDiffUpdateAvailable(update_item) &&
277 !update_item->diff_update_failed && 204 !update_item->diff_update_failed &&
278 config.DeltasEnabled(); 205 config.DeltasEnabled();
279 } 206 }
280 207
281 } // namespace. 208 } // namespace
209
210 CrxUpdateItem::CrxUpdateItem()
211 : status(kNew),
212 diff_update_failed(false),
213 error_category(0),
214 error_code(0),
215 extra_code1(0),
216 diff_error_category(0),
217 diff_error_code(0),
218 diff_extra_code1(0) {
219 }
220
221 CrxUpdateItem::~CrxUpdateItem() {
222 }
282 223
283 CrxComponent::CrxComponent() 224 CrxComponent::CrxComponent()
284 : installer(NULL) { 225 : installer(NULL) {
285 } 226 }
286 227
287 CrxComponent::~CrxComponent() { 228 CrxComponent::~CrxComponent() {
288 } 229 }
289 230
290 ////////////////////////////////////////////////////////////////////////////// 231 //////////////////////////////////////////////////////////////////////////////
291 // The one and only implementation of the ComponentUpdateService interface. In 232 // The one and only implementation of the ComponentUpdateService interface. In
(...skipping 12 matching lines...) Expand all
304 public: 245 public:
305 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); 246 explicit CrxUpdateService(ComponentUpdateService::Configurator* config);
306 247
307 virtual ~CrxUpdateService(); 248 virtual ~CrxUpdateService();
308 249
309 // Overrides for ComponentUpdateService. 250 // Overrides for ComponentUpdateService.
310 virtual Status Start() OVERRIDE; 251 virtual Status Start() OVERRIDE;
311 virtual Status Stop() OVERRIDE; 252 virtual Status Stop() OVERRIDE;
312 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; 253 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE;
313 virtual Status CheckForUpdateSoon(const CrxComponent& component) OVERRIDE; 254 virtual Status CheckForUpdateSoon(const CrxComponent& component) OVERRIDE;
255 virtual Status AddObserver(
256 ComponentUpdaterServiceObserver* observer) OVERRIDE;
257 virtual Status RemoveObserver(
258 ComponentUpdaterServiceObserver* observer) OVERRIDE;
314 259
315 // The only purpose of this class is to forward the 260 // The only purpose of this class is to forward the
316 // UtilityProcessHostClient callbacks so CrxUpdateService does 261 // UtilityProcessHostClient callbacks so CrxUpdateService does
317 // not have to derive from it because that is refcounted. 262 // not have to derive from it because that is refcounted.
318 class ManifestParserBridge : public UtilityProcessHostClient { 263 class ManifestParserBridge : public UtilityProcessHostClient {
319 public: 264 public:
320 explicit ManifestParserBridge(CrxUpdateService* service) 265 explicit ManifestParserBridge(CrxUpdateService* service)
321 : service_(service) {} 266 : service_(service) {}
322 267
323 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { 268 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 CRXContext() : installer(NULL) {} 308 CRXContext() : installer(NULL) {}
364 }; 309 };
365 310
366 void OnURLFetchComplete(const net::URLFetcher* source, 311 void OnURLFetchComplete(const net::URLFetcher* source,
367 UpdateContext* context); 312 UpdateContext* context);
368 313
369 void OnURLFetchComplete(const net::URLFetcher* source, 314 void OnURLFetchComplete(const net::URLFetcher* source,
370 CRXContext* context); 315 CRXContext* context);
371 316
372 private: 317 private:
318 enum ErrorCategory {
319 kErrorNone = 0,
320 kNetworkError,
321 kUnpackError,
322 kInstallError,
323 };
324
373 // See ManifestParserBridge. 325 // See ManifestParserBridge.
374 void OnParseUpdateManifestSucceeded( 326 void OnParseUpdateManifestSucceeded(const UpdateManifest::Results& results);
375 const UpdateManifest::Results& results);
376 327
377 // See ManifestParserBridge. 328 // See ManifestParserBridge.
378 void OnParseUpdateManifestFailed(const std::string& error_message); 329 void OnParseUpdateManifestFailed(const std::string& error_message);
379 330
380 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query); 331 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query);
381 332
382 void ProcessPendingItems(); 333 void ProcessPendingItems();
383 334
384 void ScheduleNextRun(bool step_delay); 335 void ScheduleNextRun(bool step_delay);
385 336
386 void ParseManifest(const std::string& xml); 337 void ParseManifest(const std::string& xml);
387 338
388 void Install(const CRXContext* context, const base::FilePath& crx_path); 339 void Install(const CRXContext* context, const base::FilePath& crx_path);
389 340
390 void DoneInstalling(const std::string& component_id, 341 void DoneInstalling(const std::string& component_id,
391 ComponentUnpacker::Error error, 342 ComponentUnpacker::Error error,
392 int extended_error); 343 int extended_error);
393 344
394 size_t ChangeItemStatus(CrxUpdateItem::Status from, 345 size_t ChangeItemStatus(CrxUpdateItem::Status from,
395 CrxUpdateItem::Status to); 346 CrxUpdateItem::Status to);
396 347
397 CrxUpdateItem* FindUpdateItemById(const std::string& id); 348 CrxUpdateItem* FindUpdateItemById(const std::string& id);
398 349
399 scoped_ptr<ComponentUpdateService::Configurator> config_; 350 scoped_ptr<ComponentUpdateService::Configurator> config_;
400 351
401 scoped_ptr<ComponentPatcher> component_patcher_; 352 scoped_ptr<ComponentPatcher> component_patcher_;
402 353
403 scoped_ptr<net::URLFetcher> url_fetcher_; 354 scoped_ptr<net::URLFetcher> url_fetcher_;
404 355
356 ObserverList<component_updater::ComponentUpdaterServiceObserver> observers_;
357
405 // A collection of every work item. 358 // A collection of every work item.
406 typedef std::vector<CrxUpdateItem*> UpdateItems; 359 typedef std::vector<CrxUpdateItem*> UpdateItems;
407 UpdateItems work_items_; 360 UpdateItems work_items_;
408 361
409 // A particular set of items from work_items_, which should be checked ASAP. 362 // A particular set of items from work_items_, which should be checked ASAP.
410 std::set<CrxUpdateItem*> requested_work_items_; 363 std::set<CrxUpdateItem*> requested_work_items_;
411 364
412 base::OneShotTimer<CrxUpdateService> timer_; 365 base::OneShotTimer<CrxUpdateService> timer_;
413 366
414 const Version chrome_version_; 367 const Version chrome_version_;
415 const std::string prod_id_; 368 const std::string prod_id_;
416 369
417 bool running_; 370 bool running_;
418 371
419 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); 372 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService);
420 }; 373 };
421 374
422 ////////////////////////////////////////////////////////////////////////////// 375 //////////////////////////////////////////////////////////////////////////////
423 376
424 CrxUpdateService::CrxUpdateService(ComponentUpdateService::Configurator* config) 377 CrxUpdateService::CrxUpdateService(ComponentUpdateService::Configurator* config)
425 : config_(config), 378 : config_(config),
426 component_patcher_(config->CreateComponentPatcher()), 379 component_patcher_(config->CreateComponentPatcher()),
427 chrome_version_(chrome::VersionInfo().Version()), 380 chrome_version_(chrome::VersionInfo().Version()),
waffles 2013/07/16 22:47:13 Is this space accidental?
Sorin Jianu 2013/07/16 22:52:47 Yes
428 prod_id_(chrome::OmahaQueryParams::GetProdIdString( 381 prod_id_(chrome::OmahaQueryParams::GetProdIdString(
429 chrome::OmahaQueryParams::CHROME)), 382 chrome::OmahaQueryParams::CHROME)),
430 running_(false) { 383 running_(false) {
431 } 384 }
432 385
433 CrxUpdateService::~CrxUpdateService() { 386 CrxUpdateService::~CrxUpdateService() {
434 // Because we are a singleton, at this point only the UI thread should be 387 // Because we are a singleton, at this point only the UI thread should be
435 // alive, this simplifies the management of the work that could be in 388 // alive, this simplifies the management of the work that could be in
436 // flight in other threads. 389 // flight in other threads.
437 Stop(); 390 Stop();
438 STLDeleteElements(&work_items_); 391 STLDeleteElements(&work_items_);
392
393 // Destroying the configurator removes the observer that the configurator
394 // attaches to this object. The observer list must be empty when this
395 // object is destroyed.
396 config_.reset();
439 } 397 }
440 398
441 ComponentUpdateService::Status CrxUpdateService::Start() { 399 ComponentUpdateService::Status CrxUpdateService::Start() {
442 // Note that RegisterComponent will call Start() when the first 400 // Note that RegisterComponent will call Start() when the first
443 // component is registered, so it can be called twice. This way 401 // component is registered, so it can be called twice. This way
444 // we avoid scheduling the timer if there is no work to do. 402 // we avoid scheduling the timer if there is no work to do.
445 running_ = true; 403 running_ = true;
446 if (work_items_.empty()) 404 if (work_items_.empty())
447 return kOk; 405 return kOk;
448 406
449 content::NotificationService::current()->Notify( 407 content::NotificationService::current()->Notify(
450 chrome::NOTIFICATION_COMPONENT_UPDATER_STARTED, 408 chrome::NOTIFICATION_COMPONENT_UPDATER_STARTED,
451 content::Source<ComponentUpdateService>(this), 409 content::Source<ComponentUpdateService>(this),
452 content::NotificationService::NoDetails()); 410 content::NotificationService::NoDetails());
453 411
454 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(config_->InitialDelay()), 412 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(config_->InitialDelay()),
455 this, &CrxUpdateService::ProcessPendingItems); 413 this, &CrxUpdateService::ProcessPendingItems);
456 return kOk; 414 return kOk;
457 } 415 }
458 416
459 // Stop the main check + update loop. In flight operations will be 417 // Stop the main check + update loop. In flight operations will be
460 // completed. 418 // completed.
461 ComponentUpdateService::Status CrxUpdateService::Stop() { 419 ComponentUpdateService::Status CrxUpdateService::Stop() {
462 running_ = false; 420 running_ = false;
463 timer_.Stop(); 421 timer_.Stop();
464 return kOk; 422 return kOk;
465 } 423 }
466 424
425 ComponentUpdateService::Status CrxUpdateService::AddObserver(
426 ComponentUpdaterServiceObserver* observer) {
427 observers_.AddObserver(observer);
428 return kOk;
429 }
430
431 ComponentUpdateService::Status CrxUpdateService::RemoveObserver(
432 ComponentUpdaterServiceObserver* observer) {
433 observers_.RemoveObserver(observer);
434 return kOk;
435 }
436
467 // This function sets the timer which will call ProcessPendingItems() or 437 // This function sets the timer which will call ProcessPendingItems() or
468 // ProcessRequestedItem() if there is an important requested item. There 438 // ProcessRequestedItem() if there is an important requested item. There
469 // are two kinds of waits: a short step_delay (when step_status is 439 // are two kinds of waits: a short step_delay (when step_status is
470 // kPrevInProgress) and a long one when a full check/update cycle 440 // kPrevInProgress) and a long one when a full check/update cycle
471 // has completed either successfully or with an error. 441 // has completed either successfully or with an error.
472 void CrxUpdateService::ScheduleNextRun(bool step_delay) { 442 void CrxUpdateService::ScheduleNextRun(bool step_delay) {
473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 443 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
474 DCHECK(url_fetcher_.get() == NULL); 444 DCHECK(url_fetcher_.get() == NULL);
475 CHECK(!timer_.IsRunning()); 445 CHECK(!timer_.IsRunning());
476 // It could be the case that Stop() had been called while a url request 446 // It could be the case that Stop() had been called while a url request
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 query)) 549 query))
580 return false; 550 return false;
581 551
582 item->status = CrxUpdateItem::kChecking; 552 item->status = CrxUpdateItem::kChecking;
583 item->last_check = base::Time::Now(); 553 item->last_check = base::Time::Now();
584 item->previous_version = item->component.version; 554 item->previous_version = item->component.version;
585 item->next_version = Version(); 555 item->next_version = Version();
586 item->previous_fp = item->component.fingerprint; 556 item->previous_fp = item->component.fingerprint;
587 item->next_fp.clear(); 557 item->next_fp.clear();
588 item->diff_update_failed = false; 558 item->diff_update_failed = false;
559 item->error_category = 0;
560 item->error_code = 0;
561 item->extra_code1 = 0;
562 item->diff_error_category = 0;
563 item->diff_error_code = 0;
564 item->diff_extra_code1 = 0;
589 return true; 565 return true;
590 } 566 }
591 567
592 // Start the process of checking for an update, for a particular component 568 // Start the process of checking for an update, for a particular component
593 // that was previously registered. 569 // that was previously registered.
594 ComponentUpdateService::Status CrxUpdateService::CheckForUpdateSoon( 570 ComponentUpdateService::Status CrxUpdateService::CheckForUpdateSoon(
595 const CrxComponent& component) { 571 const CrxComponent& component) {
596 if (component.pk_hash.empty() || 572 if (component.pk_hash.empty() ||
597 !component.version.IsValid() || 573 !component.version.IsValid() ||
598 !component.installer) 574 !component.installer)
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 size_t update_pending = 0; 770 size_t update_pending = 0;
795 std::vector<UpdateManifest::Result>::const_iterator it; 771 std::vector<UpdateManifest::Result>::const_iterator it;
796 for (it = results.list.begin(); it != results.list.end(); ++it) { 772 for (it = results.list.begin(); it != results.list.end(); ++it) {
797 CrxUpdateItem* crx = FindUpdateItemById(it->extension_id); 773 CrxUpdateItem* crx = FindUpdateItemById(it->extension_id);
798 if (!crx) 774 if (!crx)
799 continue; 775 continue;
800 776
801 if (crx->status != CrxUpdateItem::kChecking) 777 if (crx->status != CrxUpdateItem::kChecking)
802 continue; // Not updating this component now. 778 continue; // Not updating this component now.
803 779
804 config_->OnEvent(Configurator::kManifestCheck, CrxIdtoUMAId(crx->id));
805
806 if (it->version.empty()) { 780 if (it->version.empty()) {
807 // No version means no update available. 781 // No version means no update available.
808 crx->status = CrxUpdateItem::kNoUpdate; 782 crx->status = CrxUpdateItem::kNoUpdate;
809 continue; 783 continue;
810 } 784 }
811 if (!IsVersionNewer(crx->component.version, it->version)) { 785 if (!IsVersionNewer(crx->component.version, it->version)) {
812 // Our component is up to date. 786 // Our component is up to date.
813 crx->status = CrxUpdateItem::kUpToDate; 787 crx->status = CrxUpdateItem::kUpToDate;
814 continue; 788 continue;
815 } 789 }
816 if (!it->browser_min_version.empty()) { 790 if (!it->browser_min_version.empty()) {
817 if (IsVersionNewer(chrome_version_, it->browser_min_version)) { 791 if (IsVersionNewer(chrome_version_, it->browser_min_version)) {
818 // Does not apply for this chrome version. 792 // Does not apply for this chrome version.
819 crx->status = CrxUpdateItem::kNoUpdate; 793 crx->status = CrxUpdateItem::kNoUpdate;
820 continue; 794 continue;
821 } 795 }
822 } 796 }
823 // All test passed. Queue an upgrade for this component and fire the 797 // All test passed. Queue an upgrade for this component and fire the
824 // notifications. 798 // notifications.
825 crx->crx_url = it->crx_url; 799 crx->crx_url = it->crx_url;
826 crx->size = it->size;
827 crx->diff_crx_url = it->diff_crx_url; 800 crx->diff_crx_url = it->diff_crx_url;
828 crx->diff_size = it->diff_size;
829 crx->status = CrxUpdateItem::kCanUpdate; 801 crx->status = CrxUpdateItem::kCanUpdate;
830 crx->next_version = Version(it->version); 802 crx->next_version = Version(it->version);
831 crx->next_fp = it->package_fingerprint; 803 crx->next_fp = it->package_fingerprint;
832 ++update_pending; 804 ++update_pending;
833 805
834 content::NotificationService::current()->Notify( 806 content::NotificationService::current()->Notify(
835 chrome::NOTIFICATION_COMPONENT_UPDATE_FOUND, 807 chrome::NOTIFICATION_COMPONENT_UPDATE_FOUND,
836 content::Source<std::string>(&crx->id), 808 content::Source<std::string>(&crx->id),
837 content::NotificationService::NoDetails()); 809 content::NotificationService::NoDetails());
838 } 810 }
839 811
840 // All the components that are not mentioned in the manifest we 812 // All the components that are not mentioned in the manifest we
841 // consider them up to date. 813 // consider them up to date.
842 ChangeItemStatus(CrxUpdateItem::kChecking, CrxUpdateItem::kUpToDate); 814 ChangeItemStatus(CrxUpdateItem::kChecking, CrxUpdateItem::kUpToDate);
843 815
844 // If there are updates pending we do a short wait. 816 // If there are updates pending we do a short wait.
845 ScheduleNextRun(update_pending > 0); 817 ScheduleNextRun(update_pending > 0);
846 } 818 }
847 819
848 void CrxUpdateService::OnParseUpdateManifestFailed( 820 void CrxUpdateService::OnParseUpdateManifestFailed(
849 const std::string& error_message) { 821 const std::string& error_message) {
850 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 822 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
851 size_t count = ChangeItemStatus(CrxUpdateItem::kChecking, 823 size_t count = ChangeItemStatus(CrxUpdateItem::kChecking,
852 CrxUpdateItem::kNoUpdate); 824 CrxUpdateItem::kNoUpdate);
853 config_->OnEvent(Configurator::kManifestError, static_cast<int>(count));
854 DCHECK_GT(count, 0ul); 825 DCHECK_GT(count, 0ul);
855 ScheduleNextRun(false); 826 ScheduleNextRun(false);
856 } 827 }
857 828
858 // Called when the CRX package has been downloaded to a temporary location. 829 // Called when the CRX package has been downloaded to a temporary location.
859 // Here we fire the notifications and schedule the component-specific installer 830 // Here we fire the notifications and schedule the component-specific installer
860 // to be called in the file thread. 831 // to be called in the file thread.
861 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source, 832 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source,
862 CRXContext* context) { 833 CRXContext* context) {
863 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 834 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
864 int error_code = net::OK; 835 int error_code = net::OK;
865 836
866 CrxUpdateItem* crx = FindUpdateItemById(context->id); 837 CrxUpdateItem* crx = FindUpdateItemById(context->id);
867 DCHECK(crx->status == CrxUpdateItem::kDownloadingDiff || 838 DCHECK(crx->status == CrxUpdateItem::kDownloadingDiff ||
868 crx->status == CrxUpdateItem::kDownloading); 839 crx->status == CrxUpdateItem::kDownloading);
869 840
870 if (source->FileErrorOccurred(&error_code) || !FetchSuccess(*source)) { 841 if (source->FileErrorOccurred(&error_code) || !FetchSuccess(*source)) {
871 if (crx->status == CrxUpdateItem::kDownloadingDiff) { 842 if (crx->status == CrxUpdateItem::kDownloadingDiff) {
843 crx->diff_error_category = kNetworkError;
844 crx->diff_error_code = GetFetchError(*source);
872 crx->diff_update_failed = true; 845 crx->diff_update_failed = true;
873 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff, 846 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff,
874 CrxUpdateItem::kCanUpdate); 847 CrxUpdateItem::kCanUpdate);
875 DCHECK_EQ(count, 1ul); 848 DCHECK_EQ(count, 1ul);
849 url_fetcher_.reset();
850
876 ScheduleNextRun(true); 851 ScheduleNextRun(true);
877 return; 852 return;
878 } 853 }
854 crx->error_category = kNetworkError;
855 crx->error_code = GetFetchError(*source);
879 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading, 856 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading,
880 CrxUpdateItem::kNoUpdate); 857 CrxUpdateItem::kNoUpdate);
881 DCHECK_EQ(count, 1ul); 858 DCHECK_EQ(count, 1ul);
882 config_->OnEvent(Configurator::kNetworkError, CrxIdtoUMAId(context->id));
883 url_fetcher_.reset(); 859 url_fetcher_.reset();
884 860
861 // At this point, since both the differential and the full downloads failed,
862 // the update for this component has finished with an error.
863 FOR_EACH_OBSERVER(component_updater::ComponentUpdaterServiceObserver,
864 observers_, OnUpdateComplete(crx));
865
885 ScheduleNextRun(false); 866 ScheduleNextRun(false);
886 } else { 867 } else {
887 base::FilePath temp_crx_path; 868 base::FilePath temp_crx_path;
888 CHECK(source->GetResponseAsFilePath(true, &temp_crx_path)); 869 CHECK(source->GetResponseAsFilePath(true, &temp_crx_path));
889 870
890 size_t count = 0; 871 size_t count = 0;
891 if (crx->status == CrxUpdateItem::kDownloadingDiff) { 872 if (crx->status == CrxUpdateItem::kDownloadingDiff) {
892 count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff, 873 count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff,
893 CrxUpdateItem::kUpdatingDiff); 874 CrxUpdateItem::kUpdatingDiff);
894 } else { 875 } else {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 BrowserThread::PostDelayedTask( 916 BrowserThread::PostDelayedTask(
936 BrowserThread::UI, 917 BrowserThread::UI,
937 FROM_HERE, 918 FROM_HERE,
938 base::Bind(&CrxUpdateService::DoneInstalling, base::Unretained(this), 919 base::Bind(&CrxUpdateService::DoneInstalling, base::Unretained(this),
939 context->id, unpacker.error(), unpacker.extended_error()), 920 context->id, unpacker.error(), unpacker.extended_error()),
940 base::TimeDelta::FromMilliseconds(config_->StepDelay())); 921 base::TimeDelta::FromMilliseconds(config_->StepDelay()));
941 delete context; 922 delete context;
942 } 923 }
943 924
944 // Installation has been completed. Adjust the component status and 925 // Installation has been completed. Adjust the component status and
945 // schedule the next check. 926 // schedule the next check. Schedule a short delay before trying the full
927 // update when the differential update failed.
946 void CrxUpdateService::DoneInstalling(const std::string& component_id, 928 void CrxUpdateService::DoneInstalling(const std::string& component_id,
947 ComponentUnpacker::Error error, 929 ComponentUnpacker::Error error,
948 int extra_code) { 930 int extra_code) {
949 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 931 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
950 932
933 ErrorCategory error_category = kErrorNone;
934 switch (error) {
935 case ComponentUnpacker::kNone:
936 break;
937 case ComponentUnpacker::kInstallerError:
938 error_category = kInstallError;
939 break;
940 default:
941 error_category = kUnpackError;
942 break;
943 }
944
945 const bool is_success = error == ComponentUnpacker::kNone;
946
951 CrxUpdateItem* item = FindUpdateItemById(component_id); 947 CrxUpdateItem* item = FindUpdateItemById(component_id);
952 if (item->status == CrxUpdateItem::kUpdatingDiff) { 948 if (item->status == CrxUpdateItem::kUpdatingDiff && !is_success) {
953 if (error != ComponentUnpacker::kNone) { 949 item->diff_error_category = error_category;
950 item->diff_error_code = error;
951 item->diff_extra_code1 = extra_code;
954 item->diff_update_failed = true; 952 item->diff_update_failed = true;
955 size_t count = ChangeItemStatus(CrxUpdateItem::kUpdatingDiff, 953 size_t count = ChangeItemStatus(CrxUpdateItem::kUpdatingDiff,
956 CrxUpdateItem::kCanUpdate); 954 CrxUpdateItem::kCanUpdate);
957 DCHECK_EQ(count, 1ul); 955 DCHECK_EQ(count, 1ul);
958 ScheduleNextRun(true); 956 ScheduleNextRun(true);
959 return; 957 return;
960 } 958 }
959
960 if (is_success) {
961 item->status = CrxUpdateItem::kUpdated;
962 item->component.version = item->next_version;
963 item->component.fingerprint = item->next_fp;
964 } else {
965 item->status = CrxUpdateItem::kNoUpdate;
966 item->error_category = error_category;
967 item->error_code = error;
968 item->extra_code1 = extra_code;
961 } 969 }
962 970
963 item->status = (error == ComponentUnpacker::kNone) ? CrxUpdateItem::kUpdated : 971 FOR_EACH_OBSERVER(component_updater::ComponentUpdaterServiceObserver,
964 CrxUpdateItem::kNoUpdate; 972 observers_, OnUpdateComplete(item));
965 if (item->status == CrxUpdateItem::kUpdated) {
966 item->component.version = item->next_version;
967 item->component.fingerprint = item->next_fp;
968 }
969 973
970 Configurator::Events event;
971 switch (error) {
972 case ComponentUnpacker::kNone:
973 event = Configurator::kComponentUpdated;
974 break;
975 case ComponentUnpacker::kInstallerError:
976 event = Configurator::kInstallerError;
977 break;
978 default:
979 event = Configurator::kUnpackError;
980 break;
981 }
982
983 config_->OnEvent(event, CrxIdtoUMAId(component_id));
984 ScheduleNextRun(false); 974 ScheduleNextRun(false);
985 } 975 }
986 976
987 // The component update factory. Using the component updater as a singleton 977 // The component update factory. Using the component updater as a singleton
988 // is the job of the browser process. 978 // is the job of the browser process.
989 ComponentUpdateService* ComponentUpdateServiceFactory( 979 ComponentUpdateService* ComponentUpdateServiceFactory(
990 ComponentUpdateService::Configurator* config) { 980 ComponentUpdateService::Configurator* config) {
991 DCHECK(config); 981 DCHECK(config);
992 return new CrxUpdateService(config); 982 return new CrxUpdateService(config);
993 } 983 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698