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

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

Issue 17551004: Revert 207805 "Differential updates for components. We are addin..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/component_updater/component_updater_service.h" 5 #include "chrome/browser/component_updater/component_updater_service.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/at_exit.h" 11 #include "base/at_exit.h"
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/compiler_specific.h"
14 #include "base/file_util.h" 13 #include "base/file_util.h"
15 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
16 #include "base/logging.h" 15 #include "base/logging.h"
17 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/scoped_ptr.h"
18 #include "base/stl_util.h" 17 #include "base/stl_util.h"
19 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/string_piece.h" 19 #include "base/strings/string_piece.h"
21 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h" 21 #include "base/strings/stringprintf.h"
23 #include "base/timer.h" 22 #include "base/timer.h"
24 #include "chrome/browser/browser_process.h" 23 #include "chrome/browser/browser_process.h"
25 #include "chrome/browser/component_updater/component_patcher.h"
26 #include "chrome/browser/component_updater/component_unpacker.h" 24 #include "chrome/browser/component_updater/component_unpacker.h"
27 #include "chrome/common/chrome_notification_types.h" 25 #include "chrome/common/chrome_notification_types.h"
28 #include "chrome/common/chrome_utility_messages.h" 26 #include "chrome/common/chrome_utility_messages.h"
29 #include "chrome/common/chrome_version_info.h" 27 #include "chrome/common/chrome_version_info.h"
30 #include "chrome/common/extensions/extension.h" 28 #include "chrome/common/extensions/extension.h"
31 #include "chrome/common/omaha_query_params/omaha_query_params.h"
32 #include "content/public/browser/browser_thread.h" 29 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/notification_service.h" 30 #include "content/public/browser/notification_service.h"
34 #include "content/public/browser/utility_process_host.h" 31 #include "content/public/browser/utility_process_host.h"
35 #include "content/public/browser/utility_process_host_client.h" 32 #include "content/public/browser/utility_process_host_client.h"
36 #include "googleurl/src/gurl.h" 33 #include "googleurl/src/gurl.h"
37 #include "net/base/escape.h" 34 #include "net/base/escape.h"
38 #include "net/base/load_flags.h" 35 #include "net/base/load_flags.h"
39 #include "net/base/net_errors.h" 36 #include "net/base/net_errors.h"
40 #include "net/url_request/url_fetcher.h" 37 #include "net/url_request/url_fetcher.h"
41 #include "net/url_request/url_fetcher_delegate.h" 38 #include "net/url_request/url_fetcher_delegate.h"
42 #include "net/url_request/url_request_status.h" 39 #include "net/url_request/url_request_status.h"
43 40
44 using content::BrowserThread; 41 using content::BrowserThread;
45 using content::UtilityProcessHost; 42 using content::UtilityProcessHost;
46 using content::UtilityProcessHostClient; 43 using content::UtilityProcessHostClient;
47 using extensions::Extension; 44 using extensions::Extension;
48 45
49 // The component updater is designed to live until process shutdown, so 46 // The component updater is designed to live until process shutdown, so
50 // base::Bind() calls are not refcounted. 47 // base::Bind() calls are not refcounted.
51 48
52 namespace { 49 namespace {
53
54 // Manifest sources, from most important to least important. 50 // Manifest sources, from most important to least important.
55 const CrxComponent::UrlSource kManifestSources[] = { 51 const CrxComponent::UrlSource kManifestSources[] = {
56 CrxComponent::BANDAID, 52 CrxComponent::BANDAID,
57 CrxComponent::CWS_PUBLIC, 53 CrxComponent::CWS_PUBLIC,
58 CrxComponent::CWS_SANDBOX, 54 CrxComponent::CWS_SANDBOX
59 }; 55 };
60 56
61 // Extends an omaha compatible update check url |query| string. Does 57 // Extends an omaha compatible update check url |query| string. Does
62 // not mutate the string if it would be longer than |limit| chars. 58 // not mutate the string if it would be longer than |limit| chars.
63 bool AddQueryString(const std::string& id, 59 bool AddQueryString(const std::string& id,
64 const std::string& version, 60 const std::string& version,
65 const std::string& fingerprint,
66 size_t limit, 61 size_t limit,
67 std::string* query) { 62 std::string* query) {
68 std::string additional = 63 std::string additional =
69 base::StringPrintf("id=%s&v=%s&fp=%s&uc", 64 base::StringPrintf("id=%s&v=%s&uc", id.c_str(), version.c_str());
70 id.c_str(), version.c_str(), fingerprint.c_str());
71 additional = "x=" + net::EscapeQueryParamValue(additional, true); 65 additional = "x=" + net::EscapeQueryParamValue(additional, true);
72 if ((additional.size() + query->size() + 1) > limit) 66 if ((additional.size() + query->size() + 1) > limit)
73 return false; 67 return false;
74 if (!query->empty()) 68 if (!query->empty())
75 query->append(1, '&'); 69 query->append(1, '&');
76 query->append(additional); 70 query->append(additional);
77 return true; 71 return true;
78 } 72 }
79 73
80 // Create the final omaha compatible query. The |extra| is optional and can 74 // Create the final omaha compatible query. The |extra| is optional and can
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 net::LOAD_DISABLE_CACHE); 156 net::LOAD_DISABLE_CACHE);
163 // TODO(cpu): Define our retry and backoff policy. 157 // TODO(cpu): Define our retry and backoff policy.
164 fetcher->SetAutomaticallyRetryOn5xx(false); 158 fetcher->SetAutomaticallyRetryOn5xx(false);
165 if (save_to_file) { 159 if (save_to_file) {
166 fetcher->SaveResponseToTemporaryFile( 160 fetcher->SaveResponseToTemporaryFile(
167 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); 161 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
168 } 162 }
169 fetcher->Start(); 163 fetcher->Start();
170 } 164 }
171 165
172 // Returns true if the url request of |fetcher| was succesful. 166 // Returs true if the url request of |fetcher| was succesful.
173 bool FetchSuccess(const net::URLFetcher& fetcher) { 167 bool FetchSuccess(const net::URLFetcher& fetcher) {
174 return (fetcher.GetStatus().status() == net::URLRequestStatus::SUCCESS) && 168 return (fetcher.GetStatus().status() == net::URLRequestStatus::SUCCESS) &&
175 (fetcher.GetResponseCode() == 200); 169 (fetcher.GetResponseCode() == 200);
176 } 170 }
177 171
178 // This is the one and only per-item state structure. Designed to be hosted 172 // This is the one and only per-item state structure. Designed to be hosted
179 // in a std::vector or a std::list. The two main members are |component| 173 // in a std::vector or a std::list. The two main members are |component|
180 // which is supplied by the the component updater client and |status| which 174 // which is supplied by the the component updater client and |status| which
181 // is modified as the item is processed by the update pipeline. The expected 175 // is modified as the item is processed by the update pipeline. The expected
182 // transition graph is: 176 // transition graph is:
183 // 177 // error error error
184 // kNew 178 // +--kNoUpdate<------<-------+------<------+------<------+
185 // | 179 // | | | |
186 // V 180 // V yes | | |
187 // +----------------------> kChecking -<---------+-----<-------+ 181 // kNew --->kChecking-->[update?]----->kCanUpdate-->kDownloading-->kUpdating
188 // | | | | 182 // ^ | |
189 // | error V no | | 183 // | |no |
190 // kNoUpdate <---------------- [update?] ->---- kUpToDate kUpdated 184 // |--kUpToDate<---+ |
191 // ^ | ^ 185 // | success |
192 // | yes | | 186 // +--kUpdated<-------------------------------------------+
193 // | diff=false V |
194 // | +-----------> kCanUpdate |
195 // | | | |
196 // | | V no |
197 // | | [differential update?]->----+ |
198 // | | | | |
199 // | | yes | | |
200 // | | error V | |
201 // | +---------<- kDownloadingDiff | |
202 // | | | | |
203 // | | | | |
204 // | | error V | |
205 // | +---------<- kUpdatingDiff ->--------|-----------+ success
206 // | | |
207 // | error V |
208 // +----------------------------------------- kDownloading |
209 // | | |
210 // | error V |
211 // +------------------------------------------ kUpdating ->----+ success
212 // 187 //
213 struct CrxUpdateItem { 188 struct CrxUpdateItem {
214 enum Status { 189 enum Status {
215 kNew, 190 kNew,
216 kChecking, 191 kChecking,
217 kCanUpdate, 192 kCanUpdate,
218 kDownloadingDiff,
219 kDownloading, 193 kDownloading,
220 kUpdatingDiff,
221 kUpdating, 194 kUpdating,
222 kUpdated, 195 kUpdated,
223 kUpToDate, 196 kUpToDate,
224 kNoUpdate, 197 kNoUpdate,
225 kLastStatus 198 kLastStatus
226 }; 199 };
227 200
228 Status status; 201 Status status;
202 GURL crx_url;
229 std::string id; 203 std::string id;
204 base::Time last_check;
230 CrxComponent component; 205 CrxComponent component;
206 Version next_version;
231 207
232 base::Time last_check; 208 CrxUpdateItem() : status(kNew) {}
233
234 // These members are initialized with their corresponding values from the
235 // update server response.
236 GURL crx_url;
237 GURL diff_crx_url;
238 int size;
239 int diff_size;
240
241 // The from/to version and fingerprint values.
242 Version previous_version;
243 Version next_version;
244 std::string previous_fp;
245 std::string next_fp;
246
247 // True if the differential update failed for any reason.
248 bool diff_update_failed;
249
250 CrxUpdateItem()
251 : status(kNew),
252 size(0),
253 diff_size(0),
254 diff_update_failed(false) {
255 }
256 209
257 // Function object used to find a specific component. 210 // Function object used to find a specific component.
258 class FindById { 211 class FindById {
259 public: 212 public:
260 explicit FindById(const std::string& id) : id_(id) {} 213 explicit FindById(const std::string& id) : id_(id) {}
261 214
262 bool operator() (CrxUpdateItem* item) const { 215 bool operator() (CrxUpdateItem* item) const {
263 return (item->id == id_); 216 return (item->id == id_);
264 } 217 }
265 private: 218 private:
266 const std::string& id_; 219 const std::string& id_;
267 }; 220 };
268 }; 221 };
269 222
270 // Returns true if a differential update is available for the update item. 223 } // namespace.
271 bool IsDiffUpdateAvailable(const CrxUpdateItem* update_item) {
272 return update_item->diff_crx_url.is_valid();
273 }
274 224
275 // Returns true if a differential update is available, it has not failed yet, 225 typedef ComponentUpdateService::Configurator Config;
276 // and the configuration allows it.
277 bool CanTryDiffUpdate(const CrxUpdateItem* update_item,
278 const ComponentUpdateService::Configurator& config) {
279 return IsDiffUpdateAvailable(update_item) &&
280 !update_item->diff_update_failed &&
281 config.DeltasEnabled();
282 }
283
284 } // namespace.
285 226
286 CrxComponent::CrxComponent() 227 CrxComponent::CrxComponent()
287 : installer(NULL), 228 : installer(NULL),
288 source(BANDAID) { 229 source(BANDAID) {
289 } 230 }
290 231
291 CrxComponent::~CrxComponent() { 232 CrxComponent::~CrxComponent() {
292 } 233 }
293 234
294 ////////////////////////////////////////////////////////////////////////////// 235 //////////////////////////////////////////////////////////////////////////////
295 // The one and only implementation of the ComponentUpdateService interface. In 236 // The one and only implementation of the ComponentUpdateService interface. In
296 // charge of running the show. The main method is ProcessPendingItems() which 237 // charge of running the show. The main method is ProcessPendingItems() which
297 // is called periodically to do the upgrades/installs or the update checks. 238 // is called periodically to do the upgrades/installs or the update checks.
298 // An important consideration here is to be as "low impact" as we can to the 239 // An important consideration here is to be as "low impact" as we can to the
299 // rest of the browser, so even if we have many components registered and 240 // rest of the browser, so even if we have many components registered and
300 // eligible for update, we only do one thing at a time with pauses in between 241 // eligible for update, we only do one thing at a time with pauses in between
301 // the tasks. Also when we do network requests there is only one |url_fetcher_| 242 // the tasks. Also when we do network requests there is only one |url_fetcher_|
302 // in flight at a time. 243 // in flight at at a time.
303 // There are no locks in this code, the main structure |work_items_| is mutated 244 // There are no locks in this code, the main structure |work_items_| is mutated
304 // only from the UI thread. The unpack and installation is done in the file 245 // only from the UI thread. The unpack and installation is done in the file
305 // thread and the network requests are done in the IO thread and in the file 246 // thread and the network requests are done in the IO thread and in the file
306 // thread. 247 // thread.
307 class CrxUpdateService : public ComponentUpdateService { 248 class CrxUpdateService : public ComponentUpdateService {
308 public: 249 public:
309 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); 250 explicit CrxUpdateService(ComponentUpdateService::Configurator* config);
310 251
311 virtual ~CrxUpdateService(); 252 virtual ~CrxUpdateService();
312 253
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 struct UpdateContext { 297 struct UpdateContext {
357 base::Time start; 298 base::Time start;
358 UpdateContext() : start(base::Time::Now()) {} 299 UpdateContext() : start(base::Time::Now()) {}
359 }; 300 };
360 301
361 // Context for a crx download url request. See DelegateWithContext above. 302 // Context for a crx download url request. See DelegateWithContext above.
362 struct CRXContext { 303 struct CRXContext {
363 ComponentInstaller* installer; 304 ComponentInstaller* installer;
364 std::vector<uint8> pk_hash; 305 std::vector<uint8> pk_hash;
365 std::string id; 306 std::string id;
366 std::string fingerprint;
367 CRXContext() : installer(NULL) {} 307 CRXContext() : installer(NULL) {}
368 }; 308 };
369 309
370 void OnURLFetchComplete(const net::URLFetcher* source, 310 void OnURLFetchComplete(const net::URLFetcher* source,
371 UpdateContext* context); 311 UpdateContext* context);
372 312
373 void OnURLFetchComplete(const net::URLFetcher* source, 313 void OnURLFetchComplete(const net::URLFetcher* source,
374 CRXContext* context); 314 CRXContext* context);
375 315
376 private: 316 private:
377 // See ManifestParserBridge. 317 // See ManifestParserBridge.
378 void OnParseUpdateManifestSucceeded( 318 void OnParseUpdateManifestSucceeded(
379 const UpdateManifest::Results& results); 319 const UpdateManifest::Results& results);
380 320
381 // See ManifestParserBridge. 321 // See ManifestParserBridge.
382 void OnParseUpdateManifestFailed(const std::string& error_message); 322 void OnParseUpdateManifestFailed(
323 const std::string& error_message);
383 324
384 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query); 325 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query);
385 326
386 void ProcessPendingItems(); 327 void ProcessPendingItems();
387 328
388 void ScheduleNextRun(bool step_delay); 329 void ScheduleNextRun(bool step_delay);
389 330
390 void ParseManifest(const std::string& xml); 331 void ParseManifest(const std::string& xml);
391 332
392 void Install(const CRXContext* context, const base::FilePath& crx_path); 333 void Install(const CRXContext* context, const base::FilePath& crx_path);
393 334
394 void DoneInstalling(const std::string& component_id, 335 void DoneInstalling(const std::string& component_id,
395 ComponentUnpacker::Error error, 336 ComponentUnpacker::Error error);
396 int extended_error);
397 337
398 size_t ChangeItemStatus(CrxUpdateItem::Status from, 338 size_t ChangeItemStatus(CrxUpdateItem::Status from,
399 CrxUpdateItem::Status to); 339 CrxUpdateItem::Status to);
400 340
401 CrxUpdateItem* FindUpdateItemById(const std::string& id); 341 CrxUpdateItem* FindUpdateItemById(const std::string& id);
402 342
403 scoped_ptr<ComponentUpdateService::Configurator> config_; 343 scoped_ptr<Config> config_;
404
405 scoped_ptr<ComponentPatcher> component_patcher_;
406 344
407 scoped_ptr<net::URLFetcher> url_fetcher_; 345 scoped_ptr<net::URLFetcher> url_fetcher_;
408 346
347 typedef std::vector<CrxUpdateItem*> UpdateItems;
409 // A collection of every work item. 348 // A collection of every work item.
410 typedef std::vector<CrxUpdateItem*> UpdateItems;
411 UpdateItems work_items_; 349 UpdateItems work_items_;
412 350
413 // A particular set of items from work_items_, which should be checked ASAP. 351 // A particular set of items from work_items_, which should be checked ASAP.
414 std::set<CrxUpdateItem*> requested_work_items_; 352 std::set<CrxUpdateItem*> requested_work_items_;
415 353
416 base::OneShotTimer<CrxUpdateService> timer_; 354 base::OneShotTimer<CrxUpdateService> timer_;
417 355
418 const Version chrome_version_; 356 Version chrome_version_;
419 const std::string prod_id_;
420 357
421 bool running_; 358 bool running_;
422 359
423 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); 360 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService);
424 }; 361 };
425 362
426 ////////////////////////////////////////////////////////////////////////////// 363 //////////////////////////////////////////////////////////////////////////////
427 364
428 CrxUpdateService::CrxUpdateService(ComponentUpdateService::Configurator* config) 365 CrxUpdateService::CrxUpdateService(
366 ComponentUpdateService::Configurator* config)
429 : config_(config), 367 : config_(config),
430 component_patcher_(config->CreateComponentPatcher()),
431 chrome_version_(chrome::VersionInfo().Version()), 368 chrome_version_(chrome::VersionInfo().Version()),
432 prod_id_(chrome::OmahaQueryParams::GetProdIdString(
433 chrome::OmahaQueryParams::CHROME)),
434 running_(false) { 369 running_(false) {
435 } 370 }
436 371
437 CrxUpdateService::~CrxUpdateService() { 372 CrxUpdateService::~CrxUpdateService() {
438 // Because we are a singleton, at this point only the UI thread should be 373 // Because we are a singleton, at this point only the UI thread should be
439 // alive, this simplifies the management of the work that could be in 374 // alive, this simplifies the management of the work that could be in
440 // flight in other threads. 375 // flight in other threads.
441 Stop(); 376 Stop();
442 STLDeleteElements(&work_items_); 377 STLDeleteElements(&work_items_);
443 } 378 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 CrxUpdateItem::FindById finder(id); 443 CrxUpdateItem::FindById finder(id);
509 UpdateItems::iterator it = std::find_if(work_items_.begin(), 444 UpdateItems::iterator it = std::find_if(work_items_.begin(),
510 work_items_.end(), 445 work_items_.end(),
511 finder); 446 finder);
512 if (it == work_items_.end()) 447 if (it == work_items_.end())
513 return NULL; 448 return NULL;
514 return (*it); 449 return (*it);
515 } 450 }
516 451
517 // Changes all the components in |work_items_| that have |from| status to 452 // Changes all the components in |work_items_| that have |from| status to
518 // |to| status and returns how many have been changed. 453 // |to| statatus and returns how many have been changed.
519 size_t CrxUpdateService::ChangeItemStatus(CrxUpdateItem::Status from, 454 size_t CrxUpdateService::ChangeItemStatus(CrxUpdateItem::Status from,
520 CrxUpdateItem::Status to) { 455 CrxUpdateItem::Status to) {
521 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 456 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
522 size_t count = 0; 457 size_t count = 0;
523 for (UpdateItems::iterator it = work_items_.begin(); 458 for (UpdateItems::iterator it = work_items_.begin();
524 it != work_items_.end(); ++it) { 459 it != work_items_.end(); ++it) {
525 CrxUpdateItem* item = *it; 460 CrxUpdateItem* item = *it;
526 if (item->status != from) 461 if (item->status != from)
527 continue; 462 continue;
528 item->status = to; 463 item->status = to;
(...skipping 20 matching lines...) Expand all
549 CrxUpdateItem* uit; 484 CrxUpdateItem* uit;
550 uit = FindUpdateItemById(id); 485 uit = FindUpdateItemById(id);
551 if (uit) { 486 if (uit) {
552 uit->component = component; 487 uit->component = component;
553 return kReplaced; 488 return kReplaced;
554 } 489 }
555 490
556 uit = new CrxUpdateItem; 491 uit = new CrxUpdateItem;
557 uit->id.swap(id); 492 uit->id.swap(id);
558 uit->component = component; 493 uit->component = component;
559
560 work_items_.push_back(uit); 494 work_items_.push_back(uit);
561 // If this is the first component registered we call Start to 495 // If this is the first component registered we call Start to
562 // schedule the first timer. 496 // schedule the first timer.
563 if (running_ && (work_items_.size() == 1)) 497 if (running_ && (work_items_.size() == 1))
564 Start(); 498 Start();
565 499
566 return kOk; 500 return kOk;
567 } 501 }
568 502
569 // Sets a component to be checked for updates. 503 // Sets a component to be checked for updates.
570 // The component to add is |crxit| and the |query| string is modified with the 504 // The componet to add is |crxit| and the |query| string is modified with the
571 // required omaha compatible query. Returns false when the query strings 505 // required omaha compatible query. Returns false when the query strings
572 // is longer than specified by UrlSizeLimit(). 506 // is longer than specified by UrlSizeLimit().
573 bool CrxUpdateService::AddItemToUpdateCheck(CrxUpdateItem* item, 507 bool CrxUpdateService::AddItemToUpdateCheck(CrxUpdateItem* item,
574 std::string* query) { 508 std::string* query) {
575 if (!AddQueryString(item->id, 509 if (!AddQueryString(item->id,
576 item->component.version.GetString(), 510 item->component.version.GetString(),
577 item->component.fingerprint,
578 config_->UrlSizeLimit(), query)) 511 config_->UrlSizeLimit(), query))
579 return false; 512 return false;
580
581 item->status = CrxUpdateItem::kChecking; 513 item->status = CrxUpdateItem::kChecking;
582 item->last_check = base::Time::Now(); 514 item->last_check = base::Time::Now();
583 item->previous_version = item->component.version;
584 item->next_version = Version();
585 item->previous_fp = item->component.fingerprint;
586 item->next_fp.clear();
587 item->diff_update_failed = false;
588 return true; 515 return true;
589 } 516 }
590 517
591 // Start the process of checking for an update, for a particular component 518 // Start the process of checking for an update, for a particular component
592 // that was previously registered. 519 // that was previously registered.
593 ComponentUpdateService::Status CrxUpdateService::CheckForUpdateSoon( 520 ComponentUpdateService::Status CrxUpdateService::CheckForUpdateSoon(
594 const CrxComponent& component) { 521 const CrxComponent& component) {
595 if (component.pk_hash.empty() || 522 if (component.pk_hash.empty() ||
596 !component.version.IsValid() || 523 !component.version.IsValid() ||
597 !component.installer) 524 !component.installer)
598 return kError; 525 return kError;
599 526
600 std::string id = 527 std::string id =
601 HexStringToID(StringToLowerASCII(base::HexEncode(&component.pk_hash[0], 528 HexStringToID(StringToLowerASCII(base::HexEncode(&component.pk_hash[0],
602 component.pk_hash.size()/2))); 529 component.pk_hash.size()/2)));
603 530
604 CrxUpdateItem* uit; 531 CrxUpdateItem* uit;
605 uit = FindUpdateItemById(id); 532 uit = FindUpdateItemById(id);
606 if (!uit) 533 if (!uit)
607 return kError; 534 return kError;
608 535
609 // Check if the request is too soon. 536 // Check if the request is too soon.
610 base::TimeDelta delta = base::Time::Now() - uit->last_check; 537 base::TimeDelta delta = base::Time::Now() - uit->last_check;
611 if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay())) 538 if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay())) {
612 return kError; 539 return kError;
540 }
613 541
614 switch (uit->status) { 542 switch (uit->status) {
615 // If the item is already in the process of being updated, there is 543 // If the item is already in the process of being updated, there is
616 // no point in this call, so return kInProgress. 544 // no point in this call, so return kInProgress.
617 case CrxUpdateItem::kChecking: 545 case CrxUpdateItem::kChecking:
618 case CrxUpdateItem::kCanUpdate: 546 case CrxUpdateItem::kCanUpdate:
619 case CrxUpdateItem::kDownloadingDiff:
620 case CrxUpdateItem::kDownloading: 547 case CrxUpdateItem::kDownloading:
621 case CrxUpdateItem::kUpdatingDiff:
622 case CrxUpdateItem::kUpdating: 548 case CrxUpdateItem::kUpdating:
623 return kInProgress; 549 return kInProgress;
624 // Otherwise the item was already checked a while back (or it is new), 550 // Otherwise the item was already checked a while back (or it is new),
625 // set its status to kNew to give it a slightly higher priority. 551 // set its status to kNew to give it a slightly higher priority.
626 case CrxUpdateItem::kNew: 552 case CrxUpdateItem::kNew:
627 case CrxUpdateItem::kUpdated: 553 case CrxUpdateItem::kUpdated:
628 case CrxUpdateItem::kUpToDate: 554 case CrxUpdateItem::kUpToDate:
629 case CrxUpdateItem::kNoUpdate: 555 case CrxUpdateItem::kNoUpdate:
630 uit->status = CrxUpdateItem::kNew; 556 uit->status = CrxUpdateItem::kNew;
631 requested_work_items_.insert(uit); 557 requested_work_items_.insert(uit);
(...skipping 18 matching lines...) Expand all
650 void CrxUpdateService::ProcessPendingItems() { 576 void CrxUpdateService::ProcessPendingItems() {
651 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 577 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
652 // First check for ready upgrades and do one. The first 578 // First check for ready upgrades and do one. The first
653 // step is to fetch the crx package. 579 // step is to fetch the crx package.
654 for (UpdateItems::const_iterator it = work_items_.begin(); 580 for (UpdateItems::const_iterator it = work_items_.begin();
655 it != work_items_.end(); ++it) { 581 it != work_items_.end(); ++it) {
656 CrxUpdateItem* item = *it; 582 CrxUpdateItem* item = *it;
657 if (item->status != CrxUpdateItem::kCanUpdate) 583 if (item->status != CrxUpdateItem::kCanUpdate)
658 continue; 584 continue;
659 // Found component to update, start the process. 585 // Found component to update, start the process.
586 item->status = CrxUpdateItem::kDownloading;
660 CRXContext* context = new CRXContext; 587 CRXContext* context = new CRXContext;
661 context->pk_hash = item->component.pk_hash; 588 context->pk_hash = item->component.pk_hash;
662 context->id = item->id; 589 context->id = item->id;
663 context->installer = item->component.installer; 590 context->installer = item->component.installer;
664 context->fingerprint = item->next_fp;
665 GURL package_url;
666 if (CanTryDiffUpdate(item, *config_)) {
667 package_url = item->diff_crx_url;
668 item->status = CrxUpdateItem::kDownloadingDiff;
669 } else {
670 package_url = item->crx_url;
671 item->status = CrxUpdateItem::kDownloading;
672 }
673 url_fetcher_.reset(net::URLFetcher::Create( 591 url_fetcher_.reset(net::URLFetcher::Create(
674 0, package_url, net::URLFetcher::GET, 592 0, item->crx_url, net::URLFetcher::GET,
675 MakeContextDelegate(this, context))); 593 MakeContextDelegate(this, context)));
676 StartFetch(url_fetcher_.get(), config_->RequestContext(), true); 594 StartFetch(url_fetcher_.get(), config_->RequestContext(), true);
677 return; 595 return;
678 } 596 }
679 597
680 for (size_t ix = 0; ix != arraysize(kManifestSources); ++ix) { 598 for (size_t ix = 0; ix != arraysize(kManifestSources); ++ix) {
681 const CrxComponent::UrlSource manifest_source = kManifestSources[ix]; 599 const CrxComponent::UrlSource manifest_source = kManifestSources[ix];
682 600
683 std::string query; 601 std::string query;
684 // If no pending upgrades, we check if there are new components we have not 602 // If no pending upgrades, we check if there are new components we have not
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 delete context; 693 delete context;
776 } 694 }
777 695
778 // Parsing the manifest is either done right now for tests or in a sandboxed 696 // Parsing the manifest is either done right now for tests or in a sandboxed
779 // process for the production environment. This mitigates the case where an 697 // process for the production environment. This mitigates the case where an
780 // attacker was able to feed us a malicious xml string. 698 // attacker was able to feed us a malicious xml string.
781 void CrxUpdateService::ParseManifest(const std::string& xml) { 699 void CrxUpdateService::ParseManifest(const std::string& xml) {
782 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 700 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
783 if (config_->InProcess()) { 701 if (config_->InProcess()) {
784 UpdateManifest manifest; 702 UpdateManifest manifest;
785 if (!manifest.Parse(xml)) 703 if (!manifest.Parse(xml)) {
786 CrxUpdateService::OnParseUpdateManifestFailed(manifest.errors()); 704 CrxUpdateService::OnParseUpdateManifestFailed(manifest.errors());
787 else 705 } else {
788 CrxUpdateService::OnParseUpdateManifestSucceeded(manifest.results()); 706 CrxUpdateService::OnParseUpdateManifestSucceeded(manifest.results());
707 }
789 } else { 708 } else {
790 UtilityProcessHost* host = 709 UtilityProcessHost* host =
791 UtilityProcessHost::Create(new ManifestParserBridge(this), 710 UtilityProcessHost::Create(new ManifestParserBridge(this),
792 base::MessageLoopProxy::current().get()); 711 base::MessageLoopProxy::current().get());
793 host->EnableZygote(); 712 host->EnableZygote();
794 host->Send(new ChromeUtilityMsg_ParseUpdateManifest(xml)); 713 host->Send(new ChromeUtilityMsg_ParseUpdateManifest(xml));
795 } 714 }
796 } 715 }
797 716
798 // A valid Omaha update check has arrived, from only the list of components that 717 // A valid Omaha update check has arrived, from only the list of components that
(...skipping 28 matching lines...) Expand all
827 if (!it->browser_min_version.empty()) { 746 if (!it->browser_min_version.empty()) {
828 if (IsVersionNewer(chrome_version_, it->browser_min_version)) { 747 if (IsVersionNewer(chrome_version_, it->browser_min_version)) {
829 // Does not apply for this chrome version. 748 // Does not apply for this chrome version.
830 crx->status = CrxUpdateItem::kNoUpdate; 749 crx->status = CrxUpdateItem::kNoUpdate;
831 continue; 750 continue;
832 } 751 }
833 } 752 }
834 // All test passed. Queue an upgrade for this component and fire the 753 // All test passed. Queue an upgrade for this component and fire the
835 // notifications. 754 // notifications.
836 crx->crx_url = it->crx_url; 755 crx->crx_url = it->crx_url;
837 crx->size = it->size;
838 crx->diff_crx_url = it->diff_crx_url;
839 crx->diff_size = it->diff_size;
840 crx->status = CrxUpdateItem::kCanUpdate; 756 crx->status = CrxUpdateItem::kCanUpdate;
841 crx->next_version = Version(it->version); 757 crx->next_version = Version(it->version);
842 crx->next_fp = it->package_fingerprint;
843 ++update_pending; 758 ++update_pending;
844 759
845 content::NotificationService::current()->Notify( 760 content::NotificationService::current()->Notify(
846 chrome::NOTIFICATION_COMPONENT_UPDATE_FOUND, 761 chrome::NOTIFICATION_COMPONENT_UPDATE_FOUND,
847 content::Source<std::string>(&crx->id), 762 content::Source<std::string>(&crx->id),
848 content::NotificationService::NoDetails()); 763 content::NotificationService::NoDetails());
849 } 764 }
850 765
851 // All the components that are not mentioned in the manifest we 766 // All the components that are not mentioned in the manifest we
852 // consider them up to date. 767 // consider them up to date.
(...skipping 14 matching lines...) Expand all
867 } 782 }
868 783
869 // Called when the CRX package has been downloaded to a temporary location. 784 // Called when the CRX package has been downloaded to a temporary location.
870 // Here we fire the notifications and schedule the component-specific installer 785 // Here we fire the notifications and schedule the component-specific installer
871 // to be called in the file thread. 786 // to be called in the file thread.
872 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source, 787 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source,
873 CRXContext* context) { 788 CRXContext* context) {
874 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 789 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
875 int error_code = net::OK; 790 int error_code = net::OK;
876 791
877 CrxUpdateItem* crx = FindUpdateItemById(context->id);
878 DCHECK(crx->status == CrxUpdateItem::kDownloadingDiff ||
879 crx->status == CrxUpdateItem::kDownloading);
880
881 if (source->FileErrorOccurred(&error_code) || !FetchSuccess(*source)) { 792 if (source->FileErrorOccurred(&error_code) || !FetchSuccess(*source)) {
882 if (crx->status == CrxUpdateItem::kDownloadingDiff) {
883 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff,
884 CrxUpdateItem::kCanUpdate);
885 DCHECK_EQ(count, 1ul);
886 ScheduleNextRun(true);
887 return;
888 }
889 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading, 793 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading,
890 CrxUpdateItem::kNoUpdate); 794 CrxUpdateItem::kNoUpdate);
891 DCHECK_EQ(count, 1ul); 795 DCHECK_EQ(count, 1ul);
892 config_->OnEvent(Configurator::kNetworkError, CrxIdtoUMAId(context->id)); 796 config_->OnEvent(Configurator::kNetworkError, CrxIdtoUMAId(context->id));
893 url_fetcher_.reset(); 797 url_fetcher_.reset();
894
895 ScheduleNextRun(false); 798 ScheduleNextRun(false);
896 } else { 799 } else {
897 base::FilePath temp_crx_path; 800 base::FilePath temp_crx_path;
898 CHECK(source->GetResponseAsFilePath(true, &temp_crx_path)); 801 CHECK(source->GetResponseAsFilePath(true, &temp_crx_path));
899 802 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading,
900 size_t count = 0; 803 CrxUpdateItem::kUpdating);
901 if (crx->status == CrxUpdateItem::kDownloadingDiff) {
902 count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff,
903 CrxUpdateItem::kUpdatingDiff);
904 } else {
905 count = ChangeItemStatus(CrxUpdateItem::kDownloading,
906 CrxUpdateItem::kUpdating);
907 }
908 DCHECK_EQ(count, 1ul); 804 DCHECK_EQ(count, 1ul);
909
910 url_fetcher_.reset(); 805 url_fetcher_.reset();
911 806
912 content::NotificationService::current()->Notify( 807 content::NotificationService::current()->Notify(
913 chrome::NOTIFICATION_COMPONENT_UPDATE_READY, 808 chrome::NOTIFICATION_COMPONENT_UPDATE_READY,
914 content::Source<std::string>(&context->id), 809 content::Source<std::string>(&context->id),
915 content::NotificationService::NoDetails()); 810 content::NotificationService::NoDetails());
916 811
917 // Why unretained? See comment at top of file. 812 // Why unretained? See comment at top of file.
918 BrowserThread::PostDelayedTask( 813 BrowserThread::PostDelayedTask(
919 BrowserThread::FILE, 814 BrowserThread::FILE,
920 FROM_HERE, 815 FROM_HERE,
921 base::Bind(&CrxUpdateService::Install, 816 base::Bind(&CrxUpdateService::Install,
922 base::Unretained(this), 817 base::Unretained(this),
923 context, 818 context,
924 temp_crx_path), 819 temp_crx_path),
925 base::TimeDelta::FromMilliseconds(config_->StepDelay())); 820 base::TimeDelta::FromMilliseconds(config_->StepDelay()));
926 } 821 }
927 } 822 }
928 823
929 // Install consists of digital signature verification, unpacking and then 824 // Install consists of digital signature verification, unpacking and then
930 // calling the component specific installer. All that is handled by the 825 // calling the component specific installer. All that is handled by the
931 // |unpacker|. If there is an error this function is in charge of deleting 826 // |unpacker|. If there is an error this function is in charge of deleting
932 // the files created. 827 // the files created.
933 void CrxUpdateService::Install(const CRXContext* context, 828 void CrxUpdateService::Install(const CRXContext* context,
934 const base::FilePath& crx_path) { 829 const base::FilePath& crx_path) {
935 // This function owns the |crx_path| and the |context| object. 830 // This function owns the |crx_path| and the |context| object.
936 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 831 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
937 ComponentUnpacker unpacker(context->pk_hash, 832 ComponentUnpacker
938 crx_path, 833 unpacker(context->pk_hash, crx_path, context->installer);
939 context->fingerprint, 834 if (!file_util::Delete(crx_path, false)) {
940 component_patcher_.get(),
941 context->installer);
942 if (!file_util::Delete(crx_path, false))
943 NOTREACHED() << crx_path.value(); 835 NOTREACHED() << crx_path.value();
836 }
944 // Why unretained? See comment at top of file. 837 // Why unretained? See comment at top of file.
945 BrowserThread::PostDelayedTask( 838 BrowserThread::PostDelayedTask(
946 BrowserThread::UI, 839 BrowserThread::UI,
947 FROM_HERE, 840 FROM_HERE,
948 base::Bind(&CrxUpdateService::DoneInstalling, base::Unretained(this), 841 base::Bind(&CrxUpdateService::DoneInstalling, base::Unretained(this),
949 context->id, unpacker.error(), unpacker.extended_error()), 842 context->id, unpacker.error()),
950 base::TimeDelta::FromMilliseconds(config_->StepDelay())); 843 base::TimeDelta::FromMilliseconds(config_->StepDelay()));
951 delete context; 844 delete context;
952 } 845 }
953 846
954 // Installation has been completed. Adjust the component status and 847 // Installation has been completed. Adjust the component status and
955 // schedule the next check. 848 // schedule the next check.
956 void CrxUpdateService::DoneInstalling(const std::string& component_id, 849 void CrxUpdateService::DoneInstalling(const std::string& component_id,
957 ComponentUnpacker::Error error, 850 ComponentUnpacker::Error error) {
958 int extra_code) {
959 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 851 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
960 852
961 CrxUpdateItem* item = FindUpdateItemById(component_id); 853 CrxUpdateItem* item = FindUpdateItemById(component_id);
962 if (item->status == CrxUpdateItem::kUpdatingDiff) {
963 if (error != ComponentUnpacker::kNone) {
964 item->diff_update_failed = true;
965 size_t count = ChangeItemStatus(CrxUpdateItem::kUpdatingDiff,
966 CrxUpdateItem::kCanUpdate);
967 DCHECK_EQ(count, 1ul);
968 ScheduleNextRun(true);
969 return;
970 }
971 }
972
973 item->status = (error == ComponentUnpacker::kNone) ? CrxUpdateItem::kUpdated : 854 item->status = (error == ComponentUnpacker::kNone) ? CrxUpdateItem::kUpdated :
974 CrxUpdateItem::kNoUpdate; 855 CrxUpdateItem::kNoUpdate;
975 if (item->status == CrxUpdateItem::kUpdated) { 856 if (item->status == CrxUpdateItem::kUpdated)
976 item->component.version = item->next_version; 857 item->component.version = item->next_version;
977 item->component.fingerprint = item->next_fp;
978 }
979 858
980 Configurator::Events event; 859 Configurator::Events event;
981 switch (error) { 860 switch (error) {
982 case ComponentUnpacker::kNone: 861 case ComponentUnpacker::kNone:
983 event = Configurator::kComponentUpdated; 862 event = Configurator::kComponentUpdated;
984 break; 863 break;
985 case ComponentUnpacker::kInstallerError: 864 case ComponentUnpacker::kInstallerError:
986 event = Configurator::kInstallerError; 865 event = Configurator::kInstallerError;
987 break; 866 break;
988 default: 867 default:
989 event = Configurator::kUnpackError; 868 event = Configurator::kUnpackError;
990 break; 869 break;
991 } 870 }
992 871
993 config_->OnEvent(event, CrxIdtoUMAId(component_id)); 872 config_->OnEvent(event, CrxIdtoUMAId(component_id));
994 ScheduleNextRun(false); 873 ScheduleNextRun(false);
995 } 874 }
996 875
997 // The component update factory. Using the component updater as a singleton 876 // The component update factory. Using the component updater as a singleton
998 // is the job of the browser process. 877 // is the job of the browser process.
999 ComponentUpdateService* ComponentUpdateServiceFactory( 878 ComponentUpdateService* ComponentUpdateServiceFactory(
1000 ComponentUpdateService::Configurator* config) { 879 ComponentUpdateService::Configurator* config) {
1001 DCHECK(config); 880 DCHECK(config);
1002 return new CrxUpdateService(config); 881 return new CrxUpdateService(config);
1003 } 882 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698