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

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

Powered by Google App Engine
This is Rietveld 408576698