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

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: 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_ping_manager.h"
30 #include "chrome/browser/component_updater/component_updater_service_observer.h"
31 #include "chrome/browser/component_updater/crx_update_item.h"
28 #include "chrome/common/chrome_utility_messages.h" 32 #include "chrome/common/chrome_utility_messages.h"
29 #include "chrome/common/chrome_version_info.h" 33 #include "chrome/common/chrome_version_info.h"
30 #include "chrome/common/extensions/extension.h" 34 #include "chrome/common/extensions/extension.h"
31 #include "chrome/common/omaha_query_params/omaha_query_params.h" 35 #include "chrome/common/omaha_query_params/omaha_query_params.h"
32 #include "content/public/browser/browser_thread.h" 36 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/notification_service.h" 37 #include "content/public/browser/notification_service.h"
34 #include "content/public/browser/utility_process_host.h" 38 #include "content/public/browser/utility_process_host.h"
35 #include "content/public/browser/utility_process_host_client.h" 39 #include "content/public/browser/utility_process_host_client.h"
36 #include "net/base/escape.h" 40 #include "net/base/escape.h"
37 #include "net/base/load_flags.h" 41 #include "net/base/load_flags.h"
38 #include "net/base/net_errors.h" 42 #include "net/base/net_errors.h"
39 #include "net/url_request/url_fetcher.h" 43 #include "net/url_request/url_fetcher.h"
40 #include "net/url_request/url_fetcher_delegate.h" 44 #include "net/url_request/url_fetcher_delegate.h"
41 #include "net/url_request/url_request_status.h" 45 #include "net/url_request/url_request_status.h"
42 #include "url/gurl.h" 46 #include "url/gurl.h"
43 47
48 using component_updater::ComponentUpdaterServiceObserver;
44 using content::BrowserThread; 49 using content::BrowserThread;
45 using content::UtilityProcessHost; 50 using content::UtilityProcessHost;
46 using content::UtilityProcessHostClient; 51 using content::UtilityProcessHostClient;
47 using extensions::Extension; 52 using extensions::Extension;
48 53
49 // The component updater is designed to live until process shutdown, so 54 // The component updater is designed to live until process shutdown, so
50 // base::Bind() calls are not refcounted. 55 // base::Bind() calls are not refcounted.
51 56
52 namespace { 57 namespace {
53 58
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 &val)) { 105 &val)) {
101 id.append(1, val + 'a'); 106 id.append(1, val + 'a');
102 } else { 107 } else {
103 id.append(1, 'a'); 108 id.append(1, 'a');
104 } 109 }
105 } 110 }
106 DCHECK(Extension::IdIsValid(id)); 111 DCHECK(Extension::IdIsValid(id));
107 return id; 112 return id;
108 } 113 }
109 114
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. 115 // Helper to do version check for components.
119 bool IsVersionNewer(const Version& current, const std::string& proposed) { 116 bool IsVersionNewer(const Version& current, const std::string& proposed) {
120 Version proposed_ver(proposed); 117 Version proposed_ver(proposed);
121 if (!proposed_ver.IsValid()) 118 if (!proposed_ver.IsValid())
122 return false; 119 return false;
123 return (current.CompareTo(proposed_ver) < 0); 120 return (current.CompareTo(proposed_ver) < 0);
124 } 121 }
125 122
126 // Helper template class that allows our main class to have separate 123 // Helper template class that allows our main class to have separate
127 // OnURLFetchComplete() callbacks for different types of url requests 124 // OnURLFetchComplete() callbacks for different types of url requests
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 } 162 }
166 fetcher->Start(); 163 fetcher->Start();
167 } 164 }
168 165
169 // Returns true if the url request of |fetcher| was succesful. 166 // Returns true if the url request of |fetcher| was succesful.
170 bool FetchSuccess(const net::URLFetcher& fetcher) { 167 bool FetchSuccess(const net::URLFetcher& fetcher) {
171 return (fetcher.GetStatus().status() == net::URLRequestStatus::SUCCESS) && 168 return (fetcher.GetStatus().status() == net::URLRequestStatus::SUCCESS) &&
172 (fetcher.GetResponseCode() == 200); 169 (fetcher.GetResponseCode() == 200);
173 } 170 }
174 171
175 // This is the one and only per-item state structure. Designed to be hosted 172 // 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| 173 // 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 174 // 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 175 // fetch is pending or canceled.
179 // transition graph is: 176 int GetFetchError(const net::URLFetcher& fetcher) {
180 // 177 if (FetchSuccess(fetcher))
181 // kNew 178 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 179
225 Status status; 180 const net::URLRequestStatus::Status status(fetcher.GetStatus().status());
226 std::string id; 181 if (status == net::URLRequestStatus::FAILED)
227 CrxComponent component; 182 return fetcher.GetStatus().error();
228 183
229 base::Time last_check; 184 if (status == net::URLRequestStatus::IO_PENDING ||
185 status == net::URLRequestStatus::CANCELED)
186 return status;
230 187
231 // These members are initialized with their corresponding values from the 188 const int response_code(fetcher.GetResponseCode());
232 // update server response. 189 if (status == net::URLRequestStatus::SUCCESS && response_code != 200)
233 GURL crx_url; 190 return response_code;
234 GURL diff_crx_url;
235 int size;
236 int diff_size;
237 191
238 // The from/to version and fingerprint values. 192 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 } 193 }
253 194
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. 195 // Returns true if a differential update is available for the update item.
268 bool IsDiffUpdateAvailable(const CrxUpdateItem* update_item) { 196 bool IsDiffUpdateAvailable(const CrxUpdateItem* update_item) {
269 return update_item->diff_crx_url.is_valid(); 197 return update_item->diff_crx_url.is_valid();
270 } 198 }
271 199
272 // Returns true if a differential update is available, it has not failed yet, 200 // Returns true if a differential update is available, it has not failed yet,
273 // and the configuration allows it. 201 // and the configuration allows it.
274 bool CanTryDiffUpdate(const CrxUpdateItem* update_item, 202 bool CanTryDiffUpdate(const CrxUpdateItem* update_item,
275 const ComponentUpdateService::Configurator& config) { 203 const ComponentUpdateService::Configurator& config) {
276 return IsDiffUpdateAvailable(update_item) && 204 return IsDiffUpdateAvailable(update_item) &&
277 !update_item->diff_update_failed && 205 !update_item->diff_update_failed &&
278 config.DeltasEnabled(); 206 config.DeltasEnabled();
279 } 207 }
280 208
281 } // namespace. 209 } // namespace
210
211 CrxUpdateItem::CrxUpdateItem()
212 : status(kNew),
213 diff_update_failed(false),
214 error_category(0),
215 error_code(0),
216 extra_code1(0),
217 diff_error_category(0),
218 diff_error_code(0),
219 diff_extra_code1(0) {
220 }
221
222 CrxUpdateItem::~CrxUpdateItem() {
223 }
282 224
283 CrxComponent::CrxComponent() 225 CrxComponent::CrxComponent()
284 : installer(NULL) { 226 : installer(NULL) {
285 } 227 }
286 228
287 CrxComponent::~CrxComponent() { 229 CrxComponent::~CrxComponent() {
288 } 230 }
289 231
290 ////////////////////////////////////////////////////////////////////////////// 232 //////////////////////////////////////////////////////////////////////////////
291 // The one and only implementation of the ComponentUpdateService interface. In 233 // The one and only implementation of the ComponentUpdateService interface. In
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 CRXContext() : installer(NULL) {} 305 CRXContext() : installer(NULL) {}
364 }; 306 };
365 307
366 void OnURLFetchComplete(const net::URLFetcher* source, 308 void OnURLFetchComplete(const net::URLFetcher* source,
367 UpdateContext* context); 309 UpdateContext* context);
368 310
369 void OnURLFetchComplete(const net::URLFetcher* source, 311 void OnURLFetchComplete(const net::URLFetcher* source,
370 CRXContext* context); 312 CRXContext* context);
371 313
372 private: 314 private:
315 enum ErrorCategory {
316 kErrorNone = 0,
317 kNetworkError,
318 kUnpackError,
319 kInstallError,
320 };
321
373 // See ManifestParserBridge. 322 // See ManifestParserBridge.
374 void OnParseUpdateManifestSucceeded( 323 void OnParseUpdateManifestSucceeded(const UpdateManifest::Results& results);
375 const UpdateManifest::Results& results);
376 324
377 // See ManifestParserBridge. 325 // See ManifestParserBridge.
378 void OnParseUpdateManifestFailed(const std::string& error_message); 326 void OnParseUpdateManifestFailed(const std::string& error_message);
379 327
380 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query); 328 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query);
381 329
382 void ProcessPendingItems(); 330 void ProcessPendingItems();
383 331
384 void ScheduleNextRun(bool step_delay); 332 void ScheduleNextRun(bool step_delay);
385 333
386 void ParseManifest(const std::string& xml); 334 void ParseManifest(const std::string& xml);
387 335
388 void Install(const CRXContext* context, const base::FilePath& crx_path); 336 void Install(const CRXContext* context, const base::FilePath& crx_path);
389 337
390 void DoneInstalling(const std::string& component_id, 338 void DoneInstalling(const std::string& component_id,
391 ComponentUnpacker::Error error, 339 ComponentUnpacker::Error error,
392 int extended_error); 340 int extended_error);
393 341
394 size_t ChangeItemStatus(CrxUpdateItem::Status from, 342 size_t ChangeItemStatus(CrxUpdateItem::Status from,
395 CrxUpdateItem::Status to); 343 CrxUpdateItem::Status to);
396 344
397 CrxUpdateItem* FindUpdateItemById(const std::string& id); 345 CrxUpdateItem* FindUpdateItemById(const std::string& id);
398 346
399 scoped_ptr<ComponentUpdateService::Configurator> config_; 347 scoped_ptr<ComponentUpdateService::Configurator> config_;
400 348
401 scoped_ptr<ComponentPatcher> component_patcher_; 349 scoped_ptr<ComponentPatcher> component_patcher_;
402 350
403 scoped_ptr<net::URLFetcher> url_fetcher_; 351 scoped_ptr<net::URLFetcher> url_fetcher_;
404 352
353 ObserverList<component_updater::ComponentUpdaterServiceObserver> observers_;
354
355 scoped_ptr<component_updater::PingManager> ping_manager_;
356
405 // A collection of every work item. 357 // A collection of every work item.
406 typedef std::vector<CrxUpdateItem*> UpdateItems; 358 typedef std::vector<CrxUpdateItem*> UpdateItems;
407 UpdateItems work_items_; 359 UpdateItems work_items_;
408 360
409 // A particular set of items from work_items_, which should be checked ASAP. 361 // A particular set of items from work_items_, which should be checked ASAP.
410 std::set<CrxUpdateItem*> requested_work_items_; 362 std::set<CrxUpdateItem*> requested_work_items_;
411 363
412 base::OneShotTimer<CrxUpdateService> timer_; 364 base::OneShotTimer<CrxUpdateService> timer_;
413 365
414 const Version chrome_version_; 366 const Version chrome_version_;
415 const std::string prod_id_; 367 const std::string prod_id_;
416 368
417 bool running_; 369 bool running_;
418 370
419 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); 371 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService);
420 }; 372 };
421 373
422 ////////////////////////////////////////////////////////////////////////////// 374 //////////////////////////////////////////////////////////////////////////////
423 375
424 CrxUpdateService::CrxUpdateService(ComponentUpdateService::Configurator* config) 376 CrxUpdateService::CrxUpdateService(ComponentUpdateService::Configurator* config)
425 : config_(config), 377 : config_(config),
426 component_patcher_(config->CreateComponentPatcher()), 378 component_patcher_(config->CreateComponentPatcher()),
379 ping_manager_(new component_updater::PingManager(
380 config->PingUrl(),
381 config->RequestContext())),
427 chrome_version_(chrome::VersionInfo().Version()), 382 chrome_version_(chrome::VersionInfo().Version()),
428 prod_id_(chrome::OmahaQueryParams::GetProdIdString( 383 prod_id_(chrome::OmahaQueryParams::GetProdIdString(
429 chrome::OmahaQueryParams::CHROME)), 384 chrome::OmahaQueryParams::CHROME)),
430 running_(false) { 385 running_(false) {
386 observers_.AddObserver(ping_manager_.get());
431 } 387 }
432 388
433 CrxUpdateService::~CrxUpdateService() { 389 CrxUpdateService::~CrxUpdateService() {
434 // Because we are a singleton, at this point only the UI thread should be 390 // 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 391 // alive, this simplifies the management of the work that could be in
436 // flight in other threads. 392 // flight in other threads.
437 Stop(); 393 Stop();
438 STLDeleteElements(&work_items_); 394 STLDeleteElements(&work_items_);
395 observers_.RemoveObserver(ping_manager_.get());
439 } 396 }
440 397
441 ComponentUpdateService::Status CrxUpdateService::Start() { 398 ComponentUpdateService::Status CrxUpdateService::Start() {
442 // Note that RegisterComponent will call Start() when the first 399 // Note that RegisterComponent will call Start() when the first
443 // component is registered, so it can be called twice. This way 400 // component is registered, so it can be called twice. This way
444 // we avoid scheduling the timer if there is no work to do. 401 // we avoid scheduling the timer if there is no work to do.
445 running_ = true; 402 running_ = true;
446 if (work_items_.empty()) 403 if (work_items_.empty())
447 return kOk; 404 return kOk;
448 405
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 query)) 536 query))
580 return false; 537 return false;
581 538
582 item->status = CrxUpdateItem::kChecking; 539 item->status = CrxUpdateItem::kChecking;
583 item->last_check = base::Time::Now(); 540 item->last_check = base::Time::Now();
584 item->previous_version = item->component.version; 541 item->previous_version = item->component.version;
585 item->next_version = Version(); 542 item->next_version = Version();
586 item->previous_fp = item->component.fingerprint; 543 item->previous_fp = item->component.fingerprint;
587 item->next_fp.clear(); 544 item->next_fp.clear();
588 item->diff_update_failed = false; 545 item->diff_update_failed = false;
546 item->error_category = 0;
547 item->error_code = 0;
548 item->extra_code1 = 0;
549 item->diff_error_category = 0;
550 item->diff_error_code = 0;
551 item->diff_extra_code1 = 0;
589 return true; 552 return true;
590 } 553 }
591 554
592 // Start the process of checking for an update, for a particular component 555 // Start the process of checking for an update, for a particular component
593 // that was previously registered. 556 // that was previously registered.
594 ComponentUpdateService::Status CrxUpdateService::CheckForUpdateSoon( 557 ComponentUpdateService::Status CrxUpdateService::CheckForUpdateSoon(
595 const CrxComponent& component) { 558 const CrxComponent& component) {
596 if (component.pk_hash.empty() || 559 if (component.pk_hash.empty() ||
597 !component.version.IsValid() || 560 !component.version.IsValid() ||
598 !component.installer) 561 !component.installer)
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 size_t update_pending = 0; 757 size_t update_pending = 0;
795 std::vector<UpdateManifest::Result>::const_iterator it; 758 std::vector<UpdateManifest::Result>::const_iterator it;
796 for (it = results.list.begin(); it != results.list.end(); ++it) { 759 for (it = results.list.begin(); it != results.list.end(); ++it) {
797 CrxUpdateItem* crx = FindUpdateItemById(it->extension_id); 760 CrxUpdateItem* crx = FindUpdateItemById(it->extension_id);
798 if (!crx) 761 if (!crx)
799 continue; 762 continue;
800 763
801 if (crx->status != CrxUpdateItem::kChecking) 764 if (crx->status != CrxUpdateItem::kChecking)
802 continue; // Not updating this component now. 765 continue; // Not updating this component now.
803 766
804 config_->OnEvent(Configurator::kManifestCheck, CrxIdtoUMAId(crx->id));
805
806 if (it->version.empty()) { 767 if (it->version.empty()) {
807 // No version means no update available. 768 // No version means no update available.
808 crx->status = CrxUpdateItem::kNoUpdate; 769 crx->status = CrxUpdateItem::kNoUpdate;
809 continue; 770 continue;
810 } 771 }
811 if (!IsVersionNewer(crx->component.version, it->version)) { 772 if (!IsVersionNewer(crx->component.version, it->version)) {
812 // Our component is up to date. 773 // Our component is up to date.
813 crx->status = CrxUpdateItem::kUpToDate; 774 crx->status = CrxUpdateItem::kUpToDate;
814 continue; 775 continue;
815 } 776 }
816 if (!it->browser_min_version.empty()) { 777 if (!it->browser_min_version.empty()) {
817 if (IsVersionNewer(chrome_version_, it->browser_min_version)) { 778 if (IsVersionNewer(chrome_version_, it->browser_min_version)) {
818 // Does not apply for this chrome version. 779 // Does not apply for this chrome version.
819 crx->status = CrxUpdateItem::kNoUpdate; 780 crx->status = CrxUpdateItem::kNoUpdate;
820 continue; 781 continue;
821 } 782 }
822 } 783 }
823 // All test passed. Queue an upgrade for this component and fire the 784 // All test passed. Queue an upgrade for this component and fire the
824 // notifications. 785 // notifications.
825 crx->crx_url = it->crx_url; 786 crx->crx_url = it->crx_url;
826 crx->size = it->size;
827 crx->diff_crx_url = it->diff_crx_url; 787 crx->diff_crx_url = it->diff_crx_url;
828 crx->diff_size = it->diff_size;
829 crx->status = CrxUpdateItem::kCanUpdate; 788 crx->status = CrxUpdateItem::kCanUpdate;
830 crx->next_version = Version(it->version); 789 crx->next_version = Version(it->version);
831 crx->next_fp = it->package_fingerprint; 790 crx->next_fp = it->package_fingerprint;
832 ++update_pending; 791 ++update_pending;
833 792
834 content::NotificationService::current()->Notify( 793 content::NotificationService::current()->Notify(
835 chrome::NOTIFICATION_COMPONENT_UPDATE_FOUND, 794 chrome::NOTIFICATION_COMPONENT_UPDATE_FOUND,
836 content::Source<std::string>(&crx->id), 795 content::Source<std::string>(&crx->id),
837 content::NotificationService::NoDetails()); 796 content::NotificationService::NoDetails());
838 } 797 }
839 798
840 // All the components that are not mentioned in the manifest we 799 // All the components that are not mentioned in the manifest we
841 // consider them up to date. 800 // consider them up to date.
842 ChangeItemStatus(CrxUpdateItem::kChecking, CrxUpdateItem::kUpToDate); 801 ChangeItemStatus(CrxUpdateItem::kChecking, CrxUpdateItem::kUpToDate);
843 802
844 // If there are updates pending we do a short wait. 803 // If there are updates pending we do a short wait.
845 ScheduleNextRun(update_pending > 0); 804 ScheduleNextRun(update_pending > 0);
846 } 805 }
847 806
848 void CrxUpdateService::OnParseUpdateManifestFailed( 807 void CrxUpdateService::OnParseUpdateManifestFailed(
849 const std::string& error_message) { 808 const std::string& error_message) {
850 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 809 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
851 size_t count = ChangeItemStatus(CrxUpdateItem::kChecking, 810 size_t count = ChangeItemStatus(CrxUpdateItem::kChecking,
852 CrxUpdateItem::kNoUpdate); 811 CrxUpdateItem::kNoUpdate);
853 config_->OnEvent(Configurator::kManifestError, static_cast<int>(count));
854 DCHECK_GT(count, 0ul); 812 DCHECK_GT(count, 0ul);
855 ScheduleNextRun(false); 813 ScheduleNextRun(false);
856 } 814 }
857 815
858 // Called when the CRX package has been downloaded to a temporary location. 816 // Called when the CRX package has been downloaded to a temporary location.
859 // Here we fire the notifications and schedule the component-specific installer 817 // Here we fire the notifications and schedule the component-specific installer
860 // to be called in the file thread. 818 // to be called in the file thread.
861 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source, 819 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source,
862 CRXContext* context) { 820 CRXContext* context) {
863 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 821 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
864 int error_code = net::OK; 822 int error_code = net::OK;
865 823
866 CrxUpdateItem* crx = FindUpdateItemById(context->id); 824 CrxUpdateItem* crx = FindUpdateItemById(context->id);
867 DCHECK(crx->status == CrxUpdateItem::kDownloadingDiff || 825 DCHECK(crx->status == CrxUpdateItem::kDownloadingDiff ||
868 crx->status == CrxUpdateItem::kDownloading); 826 crx->status == CrxUpdateItem::kDownloading);
869 827
870 if (source->FileErrorOccurred(&error_code) || !FetchSuccess(*source)) { 828 if (source->FileErrorOccurred(&error_code) || !FetchSuccess(*source)) {
871 if (crx->status == CrxUpdateItem::kDownloadingDiff) { 829 if (crx->status == CrxUpdateItem::kDownloadingDiff) {
830 crx->diff_error_category = kNetworkError;
831 crx->diff_error_code = GetFetchError(*source);
872 crx->diff_update_failed = true; 832 crx->diff_update_failed = true;
873 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff, 833 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff,
874 CrxUpdateItem::kCanUpdate); 834 CrxUpdateItem::kCanUpdate);
875 DCHECK_EQ(count, 1ul); 835 DCHECK_EQ(count, 1ul);
836 url_fetcher_.reset();
837
876 ScheduleNextRun(true); 838 ScheduleNextRun(true);
877 return; 839 return;
878 } 840 }
841 crx->error_category = kNetworkError;
842 crx->error_code = GetFetchError(*source);
879 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading, 843 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading,
880 CrxUpdateItem::kNoUpdate); 844 CrxUpdateItem::kNoUpdate);
881 DCHECK_EQ(count, 1ul); 845 DCHECK_EQ(count, 1ul);
882 config_->OnEvent(Configurator::kNetworkError, CrxIdtoUMAId(context->id));
883 url_fetcher_.reset(); 846 url_fetcher_.reset();
884 847
848 // At this point, since both the differential and the full downloads failed,
849 // the update for this component has finished with an error.
850 FOR_EACH_OBSERVER(component_updater::ComponentUpdaterServiceObserver,
851 observers_, OnUpdateComplete(crx));
852
885 ScheduleNextRun(false); 853 ScheduleNextRun(false);
886 } else { 854 } else {
887 base::FilePath temp_crx_path; 855 base::FilePath temp_crx_path;
888 CHECK(source->GetResponseAsFilePath(true, &temp_crx_path)); 856 CHECK(source->GetResponseAsFilePath(true, &temp_crx_path));
889 857
890 size_t count = 0; 858 size_t count = 0;
891 if (crx->status == CrxUpdateItem::kDownloadingDiff) { 859 if (crx->status == CrxUpdateItem::kDownloadingDiff) {
892 count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff, 860 count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff,
893 CrxUpdateItem::kUpdatingDiff); 861 CrxUpdateItem::kUpdatingDiff);
894 } else { 862 } else {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 BrowserThread::PostDelayedTask( 903 BrowserThread::PostDelayedTask(
936 BrowserThread::UI, 904 BrowserThread::UI,
937 FROM_HERE, 905 FROM_HERE,
938 base::Bind(&CrxUpdateService::DoneInstalling, base::Unretained(this), 906 base::Bind(&CrxUpdateService::DoneInstalling, base::Unretained(this),
939 context->id, unpacker.error(), unpacker.extended_error()), 907 context->id, unpacker.error(), unpacker.extended_error()),
940 base::TimeDelta::FromMilliseconds(config_->StepDelay())); 908 base::TimeDelta::FromMilliseconds(config_->StepDelay()));
941 delete context; 909 delete context;
942 } 910 }
943 911
944 // Installation has been completed. Adjust the component status and 912 // Installation has been completed. Adjust the component status and
945 // schedule the next check. 913 // schedule the next check. Schedule a short delay before trying the full
914 // update when the differential update failed.
946 void CrxUpdateService::DoneInstalling(const std::string& component_id, 915 void CrxUpdateService::DoneInstalling(const std::string& component_id,
947 ComponentUnpacker::Error error, 916 ComponentUnpacker::Error error,
948 int extra_code) { 917 int extra_code) {
949 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 918 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
950 919
920 ErrorCategory error_category = kErrorNone;
921 switch (error) {
922 case ComponentUnpacker::kNone:
923 break;
924 case ComponentUnpacker::kInstallerError:
925 error_category = kInstallError;
926 break;
927 default:
928 error_category = kUnpackError;
929 break;
930 }
931
932 const bool is_success = error == ComponentUnpacker::kNone;
933
951 CrxUpdateItem* item = FindUpdateItemById(component_id); 934 CrxUpdateItem* item = FindUpdateItemById(component_id);
952 if (item->status == CrxUpdateItem::kUpdatingDiff) { 935 if (item->status == CrxUpdateItem::kUpdatingDiff && !is_success) {
953 if (error != ComponentUnpacker::kNone) { 936 item->diff_error_category = error_category;
937 item->diff_error_code = error;
938 item->diff_extra_code1 = extra_code;
954 item->diff_update_failed = true; 939 item->diff_update_failed = true;
955 size_t count = ChangeItemStatus(CrxUpdateItem::kUpdatingDiff, 940 size_t count = ChangeItemStatus(CrxUpdateItem::kUpdatingDiff,
956 CrxUpdateItem::kCanUpdate); 941 CrxUpdateItem::kCanUpdate);
957 DCHECK_EQ(count, 1ul); 942 DCHECK_EQ(count, 1ul);
958 ScheduleNextRun(true); 943 ScheduleNextRun(true);
959 return; 944 return;
960 } 945 }
946
947 if (is_success) {
948 item->status = CrxUpdateItem::kUpdated;
waffles 2013/07/12 20:48:23 Do we need to use ChangeItemStatus here? I'm not
Sorin Jianu 2013/07/12 21:01:57 I kept the code that matched what we already had a
949 item->component.version = item->next_version;
950 item->component.fingerprint = item->next_fp;
951 } else {
952 item->status = CrxUpdateItem::kNoUpdate;
953 item->error_category = error_category;
954 item->error_code = error;
955 item->extra_code1 = extra_code;
961 } 956 }
962 957
963 item->status = (error == ComponentUnpacker::kNone) ? CrxUpdateItem::kUpdated : 958 FOR_EACH_OBSERVER(component_updater::ComponentUpdaterServiceObserver,
964 CrxUpdateItem::kNoUpdate; 959 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 960
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); 961 ScheduleNextRun(false);
985 } 962 }
986 963
987 // The component update factory. Using the component updater as a singleton 964 // The component update factory. Using the component updater as a singleton
988 // is the job of the browser process. 965 // is the job of the browser process.
989 ComponentUpdateService* ComponentUpdateServiceFactory( 966 ComponentUpdateService* ComponentUpdateServiceFactory(
990 ComponentUpdateService::Configurator* config) { 967 ComponentUpdateService::Configurator* config) {
991 DCHECK(config); 968 DCHECK(config);
992 return new CrxUpdateService(config); 969 return new CrxUpdateService(config);
993 } 970 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698