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

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

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

Powered by Google App Engine
This is Rietveld 408576698