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

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: Added missing const decl. 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"
16 #include "base/guid.h"
15 #include "base/logging.h" 17 #include "base/logging.h"
16 #include "base/memory/scoped_ptr.h" 18 #include "base/memory/scoped_ptr.h"
17 #include "base/stl_util.h" 19 #include "base/stl_util.h"
18 #include "base/strings/string_number_conversions.h" 20 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/string_piece.h" 21 #include "base/strings/string_piece.h"
20 #include "base/strings/string_util.h" 22 #include "base/strings/string_util.h"
21 #include "base/strings/stringprintf.h" 23 #include "base/strings/stringprintf.h"
24 #include "base/sys_info.h"
22 #include "base/timer.h" 25 #include "base/timer.h"
23 #include "chrome/browser/browser_process.h" 26 #include "chrome/browser/browser_process.h"
27 #include "chrome/browser/component_updater/component_patcher.h"
24 #include "chrome/browser/component_updater/component_unpacker.h" 28 #include "chrome/browser/component_updater/component_unpacker.h"
25 #include "chrome/common/chrome_notification_types.h" 29 #include "chrome/common/chrome_notification_types.h"
26 #include "chrome/common/chrome_utility_messages.h" 30 #include "chrome/common/chrome_utility_messages.h"
27 #include "chrome/common/chrome_version_info.h" 31 #include "chrome/common/chrome_version_info.h"
28 #include "chrome/common/extensions/extension.h" 32 #include "chrome/common/extensions/extension.h"
33 #include "chrome/common/omaha_query_params/omaha_query_params.h"
29 #include "content/public/browser/browser_thread.h" 34 #include "content/public/browser/browser_thread.h"
30 #include "content/public/browser/notification_service.h" 35 #include "content/public/browser/notification_service.h"
31 #include "content/public/browser/utility_process_host.h" 36 #include "content/public/browser/utility_process_host.h"
32 #include "content/public/browser/utility_process_host_client.h" 37 #include "content/public/browser/utility_process_host_client.h"
33 #include "googleurl/src/gurl.h" 38 #include "googleurl/src/gurl.h"
34 #include "net/base/escape.h" 39 #include "net/base/escape.h"
35 #include "net/base/load_flags.h" 40 #include "net/base/load_flags.h"
36 #include "net/base/net_errors.h" 41 #include "net/base/net_errors.h"
37 #include "net/url_request/url_fetcher.h" 42 #include "net/url_request/url_fetcher.h"
38 #include "net/url_request/url_fetcher_delegate.h" 43 #include "net/url_request/url_fetcher_delegate.h"
39 #include "net/url_request/url_request_status.h" 44 #include "net/url_request/url_request_status.h"
40 45
41 using content::BrowserThread; 46 using content::BrowserThread;
42 using content::UtilityProcessHost; 47 using content::UtilityProcessHost;
43 using content::UtilityProcessHostClient; 48 using content::UtilityProcessHostClient;
44 using extensions::Extension; 49 using extensions::Extension;
45 50
46 // The component updater is designed to live until process shutdown, so 51 // The component updater is designed to live until process shutdown, so
47 // base::Bind() calls are not refcounted. 52 // base::Bind() calls are not refcounted.
48 53
49 namespace { 54 namespace {
55
56 typedef ComponentUpdateService::Configurator Config;
robertshield 2013/06/18 13:27:07 This typedef appears to be used only in a couple o
Sorin Jianu 2013/06/18 17:00:12 Done.
57
50 // Manifest sources, from most important to least important. 58 // Manifest sources, from most important to least important.
51 const CrxComponent::UrlSource kManifestSources[] = { 59 const CrxComponent::UrlSource kManifestSources[] = {
52 CrxComponent::BANDAID, 60 CrxComponent::BANDAID,
53 CrxComponent::CWS_PUBLIC, 61 CrxComponent::CWS_PUBLIC,
54 CrxComponent::CWS_SANDBOX 62 CrxComponent::CWS_SANDBOX,
55 }; 63 };
56 64
57 // Extends an omaha compatible update check url |query| string. Does 65 // Extends an omaha compatible update check url |query| string. Does
58 // not mutate the string if it would be longer than |limit| chars. 66 // not mutate the string if it would be longer than |limit| chars.
59 bool AddQueryString(const std::string& id, 67 bool AddQueryString(const std::string& id,
60 const std::string& version, 68 const std::string& version,
69 const std::string& fingerprint,
61 size_t limit, 70 size_t limit,
62 std::string* query) { 71 std::string* query) {
63 std::string additional = 72 std::string additional =
64 base::StringPrintf("id=%s&v=%s&uc", id.c_str(), version.c_str()); 73 base::StringPrintf("id=%s&v=%s&fp=%s&uc",
74 id.c_str(), version.c_str(), fingerprint.c_str());
65 additional = "x=" + net::EscapeQueryParamValue(additional, true); 75 additional = "x=" + net::EscapeQueryParamValue(additional, true);
66 if ((additional.size() + query->size() + 1) > limit) 76 if ((additional.size() + query->size() + 1) > limit)
67 return false; 77 return false;
68 if (!query->empty()) 78 if (!query->empty())
69 query->append(1, '&'); 79 query->append(1, '&');
70 query->append(additional); 80 query->append(additional);
71 return true; 81 return true;
72 } 82 }
73 83
74 // Create the final omaha compatible query. The |extra| is optional and can 84 // 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); 166 net::LOAD_DISABLE_CACHE);
157 // TODO(cpu): Define our retry and backoff policy. 167 // TODO(cpu): Define our retry and backoff policy.
158 fetcher->SetAutomaticallyRetryOn5xx(false); 168 fetcher->SetAutomaticallyRetryOn5xx(false);
159 if (save_to_file) { 169 if (save_to_file) {
160 fetcher->SaveResponseToTemporaryFile( 170 fetcher->SaveResponseToTemporaryFile(
161 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); 171 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
162 } 172 }
163 fetcher->Start(); 173 fetcher->Start();
164 } 174 }
165 175
166 // Returs true if the url request of |fetcher| was succesful. 176 // Returns true if the url request of |fetcher| was succesful.
167 bool FetchSuccess(const net::URLFetcher& fetcher) { 177 bool FetchSuccess(const net::URLFetcher& fetcher) {
168 return (fetcher.GetStatus().status() == net::URLRequestStatus::SUCCESS) && 178 return (fetcher.GetStatus().status() == net::URLRequestStatus::SUCCESS) &&
169 (fetcher.GetResponseCode() == 200); 179 (fetcher.GetResponseCode() == 200);
170 } 180 }
171 181
182 // Returns the error code which occured during the fetch. This function
183 // is intended to be called for logging purposes only, since it folds different
184 // types of errors to fit them in the returned type. The function returns 0 if
185 // the fetch was successful. If errors happen, the function could return a
186 // network error, an http response code, or the status of the fetch, if the
187 // fetch is pending or canceled.
188 int GetFetchError(const net::URLFetcher& fetcher) {
189 if (FetchSuccess(fetcher))
190 return 0;
191
192 const net::URLRequestStatus::Status status(fetcher.GetStatus().status());
193 if (status == net::URLRequestStatus::FAILED)
194 return fetcher.GetStatus().error();
195
196 if (status == net::URLRequestStatus::IO_PENDING ||
197 status == net::URLRequestStatus::CANCELED)
198 return status;
199
200 const int response_code(fetcher.GetResponseCode());
201 if (status == net::URLRequestStatus::SUCCESS && response_code != 200)
202 return response_code;
203
204 return -1;
205 }
206
207
172 // This is the one and only per-item state structure. Designed to be hosted 208 // 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| 209 // 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 210 // 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 211 // is modified as the item is processed by the update pipeline. The expected
176 // transition graph is: 212 // transition graph is:
177 // error error error 213 //
178 // +--kNoUpdate<------<-------+------<------+------<------+ 214 // kNew
179 // | | | | 215 // |
180 // V yes | | | 216 // V
181 // kNew --->kChecking-->[update?]----->kCanUpdate-->kDownloading-->kUpdating 217 // +----------------------> kChecking -<---------+-----<-------+
182 // ^ | | 218 // | | | |
183 // | |no | 219 // | V no | |
184 // |--kUpToDate<---+ | 220 // kNoUpdate [update?] ->---- kUpToDate kUpdated
185 // | success | 221 // ^ | ^
186 // +--kUpdated<-------------------------------------------+ 222 // | yes | |
223 // | diff=false V |
224 // | +-----------> kCanUpdate |
225 // | | | |
226 // | | V no |
227 // | | [differential update?]->----+ |
228 // | | | | |
229 // | | yes | | |
230 // | | error V | |
231 // | +---------<- kDownloadingDiff | |
232 // | | | | |
233 // | | | | |
234 // | | error V | |
235 // | +---------<- kUpdatingDiff ->--------|-----------+ success
236 // | | |
237 // | error V |
238 // +----------------------------------------- kDownloading |
239 // | | |
240 // | error V |
241 // +------------------------------------------ kUpdating ->----+ success
187 // 242 //
188 struct CrxUpdateItem { 243 struct CrxUpdateItem {
189 enum Status { 244 enum Status {
190 kNew, 245 kNew,
191 kChecking, 246 kChecking,
192 kCanUpdate, 247 kCanUpdate,
248 kDownloadingDiff,
193 kDownloading, 249 kDownloading,
250 kUpdatingDiff,
194 kUpdating, 251 kUpdating,
195 kUpdated, 252 kUpdated,
196 kUpToDate, 253 kUpToDate,
197 kNoUpdate, 254 kNoUpdate,
198 kLastStatus 255 kLastStatus
199 }; 256 };
200 257
201 Status status; 258 Status status;
259 std::string id;
260 CrxComponent component;
261
262 base::Time last_check;
263
264 // True if the update response includes an update for this component.
265 bool is_update_available;
266
267 // True is a completion ping has been queued for this component. If an update
cpu_(ooo_6.6-7.5) 2013/06/18 17:02:06 "True is"?
Sorin Jianu 2013/06/18 20:46:39 Done.
268 // is available for this component, one completion ping must be sent
269 // after the component has reached either the kNoUpdate or kUpdated states.
270 bool ping_queued;
cpu_(ooo_6.6-7.5) 2013/06/18 17:02:06 maybe I got it wrong but you don't need this. If i
Sorin Jianu 2013/06/18 20:46:39 We removed the queuing of pings
271
272 // These members are initialized with their corresponding values from the
273 // update server response.
202 GURL crx_url; 274 GURL crx_url;
203 std::string id; 275 GURL diff_crx_url;
204 base::Time last_check; 276 std::string package_hash;
205 CrxComponent component; 277 std::string diff_package_hash;
cpu_(ooo_6.6-7.5) 2013/06/18 17:02:06 In here we differ in philosophy. As you can see I
Sorin Jianu 2013/06/18 20:46:39 I am sorry if we are breaking the existing design.
278 int size;
279 int diff_size;
cpu_(ooo_6.6-7.5) 2013/06/18 17:02:06 why do we need these sizes here? I failed to find
Sorin Jianu 2013/06/18 20:46:39 These are values that we parsed from the update re
280
281 // The from/to version and fingerprint values.
282 Version previous_version;
206 Version next_version; 283 Version next_version;
284 std::string previous_fp;
285 std::string next_fp;
207 286
208 CrxUpdateItem() : status(kNew) {} 287 // True if the differential update failed for any reason.
288 bool diff_update_failed;
289
290 // The error information for full and differential updates.
291 int error_code;
292 int extra_code1;
293 int diff_error_code;
294 int diff_extra_code1;
cpu_(ooo_6.6-7.5) 2013/06/18 17:02:06 sigh
Sorin Jianu 2013/06/18 20:46:39 I understand. The challenge we have here is that t
295
296 CrxUpdateItem()
297 : status(kNew),
298 is_update_available(false),
299 ping_queued(false),
300 size(0),
301 diff_size(0),
302 diff_update_failed(false),
303 error_code(0),
304 extra_code1(0),
305 diff_error_code(0),
306 diff_extra_code1(0) {
307 }
209 308
210 // Function object used to find a specific component. 309 // Function object used to find a specific component.
211 class FindById { 310 class FindById {
212 public: 311 public:
213 explicit FindById(const std::string& id) : id_(id) {} 312 explicit FindById(const std::string& id) : id_(id) {}
214 313
215 bool operator() (CrxUpdateItem* item) const { 314 bool operator() (CrxUpdateItem* item) const {
216 return (item->id == id_); 315 return (item->id == id_);
217 } 316 }
218 private: 317 private:
219 const std::string& id_; 318 const std::string& id_;
220 }; 319 };
221 }; 320 };
222 321
322 // Returns true if a differential update is available for the update item.
323 bool IsDiffUpdateAvailable(const CrxUpdateItem* update_item) {
324 return update_item->diff_crx_url.is_valid();
325 }
326
327 // Returns true if a differential update is available, it has not failed yet,
328 // and the configuration allows it.
329 bool CanTryDiffUpdate(const CrxUpdateItem* update_item, const Config& config) {
330 return IsDiffUpdateAvailable(update_item) &&
331 !update_item->diff_update_failed &&
332 config.DeltasEnabled();
333 }
334
223 } // namespace. 335 } // namespace.
224 336
225 typedef ComponentUpdateService::Configurator Config;
226
227 CrxComponent::CrxComponent() 337 CrxComponent::CrxComponent()
228 : installer(NULL), 338 : installer(NULL),
229 source(BANDAID) { 339 source(BANDAID) {
230 } 340 }
231 341
232 CrxComponent::~CrxComponent() { 342 CrxComponent::~CrxComponent() {
233 } 343 }
234 344
235 ////////////////////////////////////////////////////////////////////////////// 345 //////////////////////////////////////////////////////////////////////////////
236 // The one and only implementation of the ComponentUpdateService interface. In 346 // The one and only implementation of the ComponentUpdateService interface. In
237 // charge of running the show. The main method is ProcessPendingItems() which 347 // charge of running the show. The main method is ProcessPendingItems() which
238 // is called periodically to do the upgrades/installs or the update checks. 348 // 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 349 // 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 350 // 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 351 // 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_| 352 // the tasks. Also when we do network requests there is only one |url_fetcher_|
243 // in flight at at a time. 353 // in flight at a time.
244 // There are no locks in this code, the main structure |work_items_| is mutated 354 // 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 355 // 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 356 // thread and the network requests are done in the IO thread and in the file
247 // thread. 357 // thread.
248 class CrxUpdateService : public ComponentUpdateService { 358 class CrxUpdateService : public ComponentUpdateService {
249 public: 359 public:
250 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); 360 explicit CrxUpdateService(ComponentUpdateService::Configurator* config);
251 361
252 virtual ~CrxUpdateService(); 362 virtual ~CrxUpdateService();
253 363
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 CrxUpdateService* service_; 402 CrxUpdateService* service_;
293 DISALLOW_COPY_AND_ASSIGN(ManifestParserBridge); 403 DISALLOW_COPY_AND_ASSIGN(ManifestParserBridge);
294 }; 404 };
295 405
296 // Context for a update check url request. See DelegateWithContext above. 406 // Context for a update check url request. See DelegateWithContext above.
297 struct UpdateContext { 407 struct UpdateContext {
298 base::Time start; 408 base::Time start;
299 UpdateContext() : start(base::Time::Now()) {} 409 UpdateContext() : start(base::Time::Now()) {}
300 }; 410 };
301 411
412 // Context for a completion ping. See DelegateWithContext above. The type
413 // is needed for template type deduction and it could be used in the
414 // future to pass arguments to the callback.
415 struct PingContext {
416 };
417
302 // Context for a crx download url request. See DelegateWithContext above. 418 // Context for a crx download url request. See DelegateWithContext above.
303 struct CRXContext { 419 struct CRXContext {
304 ComponentInstaller* installer; 420 ComponentInstaller* installer;
305 std::vector<uint8> pk_hash; 421 std::vector<uint8> pk_hash;
306 std::string id; 422 std::string id;
423 std::string fingerprint;
307 CRXContext() : installer(NULL) {} 424 CRXContext() : installer(NULL) {}
308 }; 425 };
309 426
310 void OnURLFetchComplete(const net::URLFetcher* source, 427 void OnURLFetchComplete(const net::URLFetcher* source,
311 UpdateContext* context); 428 UpdateContext* context);
312 429
313 void OnURLFetchComplete(const net::URLFetcher* source, 430 void OnURLFetchComplete(const net::URLFetcher* source,
314 CRXContext* context); 431 CRXContext* context);
315 432
433 void OnURLFetchComplete(const net::URLFetcher* source,
434 PingContext* context);
435
316 private: 436 private:
317 // See ManifestParserBridge. 437 // See ManifestParserBridge.
318 void OnParseUpdateManifestSucceeded( 438 void OnParseUpdateManifestSucceeded(
319 const UpdateManifest::Results& results); 439 const UpdateManifest::Results& results);
320 440
321 // See ManifestParserBridge. 441 // See ManifestParserBridge.
322 void OnParseUpdateManifestFailed( 442 void OnParseUpdateManifestFailed(const std::string& error_message);
323 const std::string& error_message);
324 443
325 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query); 444 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query);
326 445
327 void ProcessPendingItems(); 446 void ProcessPendingItems();
328 447
329 void ScheduleNextRun(bool step_delay); 448 void ScheduleNextRun(bool step_delay);
330 449
331 void ParseManifest(const std::string& xml); 450 void ParseManifest(const std::string& xml);
332 451
333 void Install(const CRXContext* context, const base::FilePath& crx_path); 452 void Install(const CRXContext* context, const base::FilePath& crx_path);
334 453
335 void DoneInstalling(const std::string& component_id, 454 void DoneInstalling(const std::string& component_id,
336 ComponentUnpacker::Error error); 455 ComponentUnpacker::Error error,
456 int extended_error);
337 457
338 size_t ChangeItemStatus(CrxUpdateItem::Status from, 458 size_t ChangeItemStatus(CrxUpdateItem::Status from,
339 CrxUpdateItem::Status to); 459 CrxUpdateItem::Status to);
340 460
341 CrxUpdateItem* FindUpdateItemById(const std::string& id); 461 CrxUpdateItem* FindUpdateItemById(const std::string& id);
342 462
463 // Returns true if completion pings are enabled.
464 bool CanPing() const;
465
466 void SendPing(const std::string& ping);
467
468 // These functions build a ping request. Building the ping changes the state
469 // of the update item to indicate that a completion ping has been collected
470 // and queued for this item.
471 std::string BuildPing() const;
472 std::string BuildPingApps() const;
473 static std::string BuildPingEvent(CrxUpdateItem* item);
474
343 scoped_ptr<Config> config_; 475 scoped_ptr<Config> config_;
344 476
477 scoped_ptr<ComponentPatcher> component_patcher_;
478
345 scoped_ptr<net::URLFetcher> url_fetcher_; 479 scoped_ptr<net::URLFetcher> url_fetcher_;
346 480
481 scoped_ptr<net::URLFetcher> ping_sender_;
482
483 // A collection of every work item.
347 typedef std::vector<CrxUpdateItem*> UpdateItems; 484 typedef std::vector<CrxUpdateItem*> UpdateItems;
348 // A collection of every work item.
349 UpdateItems work_items_; 485 UpdateItems work_items_;
350 486
351 // A particular set of items from work_items_, which should be checked ASAP. 487 // A particular set of items from work_items_, which should be checked ASAP.
352 std::set<CrxUpdateItem*> requested_work_items_; 488 std::set<CrxUpdateItem*> requested_work_items_;
353 489
354 base::OneShotTimer<CrxUpdateService> timer_; 490 base::OneShotTimer<CrxUpdateService> timer_;
355 491
356 Version chrome_version_; 492 const Version chrome_version_;
493 const std::string prod_id_;
494 const std::string os_type_;
495 const std::string os_version_;
357 496
358 bool running_; 497 bool running_;
359 498
360 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); 499 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService);
361 }; 500 };
362 501
363 ////////////////////////////////////////////////////////////////////////////// 502 //////////////////////////////////////////////////////////////////////////////
364 503
365 CrxUpdateService::CrxUpdateService( 504 CrxUpdateService::CrxUpdateService(ComponentUpdateService::Configurator* config)
366 ComponentUpdateService::Configurator* config)
367 : config_(config), 505 : config_(config),
506 component_patcher_(config->CreateComponentPatcher()),
368 chrome_version_(chrome::VersionInfo().Version()), 507 chrome_version_(chrome::VersionInfo().Version()),
508 prod_id_(chrome::OmahaQueryParams::GetProdIdString(
509 chrome::OmahaQueryParams::CHROME)),
510 os_type_(chrome::VersionInfo().OSType()),
cpu_(ooo_6.6-7.5) 2013/06/18 17:02:06 is this expensive to query, enough that we want to
Sorin Jianu 2013/06/18 20:46:39 I agree that the state has to go somewhere or it h
511 os_version_(base::SysInfo().OperatingSystemVersion()),
369 running_(false) { 512 running_(false) {
370 } 513 }
371 514
372 CrxUpdateService::~CrxUpdateService() { 515 CrxUpdateService::~CrxUpdateService() {
373 // Because we are a singleton, at this point only the UI thread should be 516 // 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 517 // alive, this simplifies the management of the work that could be in
375 // flight in other threads. 518 // flight in other threads.
376 Stop(); 519 Stop();
377 STLDeleteElements(&work_items_); 520 STLDeleteElements(&work_items_);
378 } 521 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 void CrxUpdateService::ScheduleNextRun(bool step_delay) { 554 void CrxUpdateService::ScheduleNextRun(bool step_delay) {
412 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 555 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
413 DCHECK(url_fetcher_.get() == NULL); 556 DCHECK(url_fetcher_.get() == NULL);
414 CHECK(!timer_.IsRunning()); 557 CHECK(!timer_.IsRunning());
415 // It could be the case that Stop() had been called while a url request 558 // It could be the case that Stop() had been called while a url request
416 // or unpacking was in flight, if so we arrive here but |running_| is 559 // or unpacking was in flight, if so we arrive here but |running_| is
417 // false. In that case do not loop again. 560 // false. In that case do not loop again.
418 if (!running_) 561 if (!running_)
419 return; 562 return;
420 563
564 if (!step_delay && CanPing()) {
565 const std::string ping(BuildPing());
566 if (!ping.empty())
567 SendPing(ping);
568 }
569
421 // Keep the delay short if in the middle of an update (step_delay), 570 // Keep the delay short if in the middle of an update (step_delay),
422 // or there are new requested_work_items_ that have not been processed yet. 571 // or there are new requested_work_items_ that have not been processed yet.
423 int64 delay = (step_delay || requested_work_items_.size() > 0) 572 int64 delay = (step_delay || requested_work_items_.size() > 0)
424 ? config_->StepDelay() : config_->NextCheckDelay(); 573 ? config_->StepDelay() : config_->NextCheckDelay();
425 574
426 if (!step_delay) { 575 if (!step_delay) {
427 content::NotificationService::current()->Notify( 576 content::NotificationService::current()->Notify(
428 chrome::NOTIFICATION_COMPONENT_UPDATER_SLEEPING, 577 chrome::NOTIFICATION_COMPONENT_UPDATER_SLEEPING,
429 content::Source<ComponentUpdateService>(this), 578 content::Source<ComponentUpdateService>(this),
430 content::NotificationService::NoDetails()); 579 content::NotificationService::NoDetails());
(...skipping 12 matching lines...) Expand all
443 CrxUpdateItem::FindById finder(id); 592 CrxUpdateItem::FindById finder(id);
444 UpdateItems::iterator it = std::find_if(work_items_.begin(), 593 UpdateItems::iterator it = std::find_if(work_items_.begin(),
445 work_items_.end(), 594 work_items_.end(),
446 finder); 595 finder);
447 if (it == work_items_.end()) 596 if (it == work_items_.end())
448 return NULL; 597 return NULL;
449 return (*it); 598 return (*it);
450 } 599 }
451 600
452 // Changes all the components in |work_items_| that have |from| status to 601 // Changes all the components in |work_items_| that have |from| status to
453 // |to| statatus and returns how many have been changed. 602 // |to| statatus and returns how many have been changed.
cpu_(ooo_6.6-7.5) 2013/06/18 17:02:06 typo here :)
Sorin Jianu 2013/06/18 20:46:39 What is the typo? I am sorry, we might have fixed
waffles 2013/06/18 20:50:41 Sorry for the confusion, I fixed that one. :)
Sorin Jianu 2013/06/19 00:29:10 Done.
454 size_t CrxUpdateService::ChangeItemStatus(CrxUpdateItem::Status from, 603 size_t CrxUpdateService::ChangeItemStatus(CrxUpdateItem::Status from,
455 CrxUpdateItem::Status to) { 604 CrxUpdateItem::Status to) {
456 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 605 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
457 size_t count = 0; 606 size_t count = 0;
458 for (UpdateItems::iterator it = work_items_.begin(); 607 for (UpdateItems::iterator it = work_items_.begin();
459 it != work_items_.end(); ++it) { 608 it != work_items_.end(); ++it) {
460 CrxUpdateItem* item = *it; 609 CrxUpdateItem* item = *it;
461 if (item->status != from) 610 if (item->status != from)
462 continue; 611 continue;
463 item->status = to; 612 item->status = to;
(...skipping 20 matching lines...) Expand all
484 CrxUpdateItem* uit; 633 CrxUpdateItem* uit;
485 uit = FindUpdateItemById(id); 634 uit = FindUpdateItemById(id);
486 if (uit) { 635 if (uit) {
487 uit->component = component; 636 uit->component = component;
488 return kReplaced; 637 return kReplaced;
489 } 638 }
490 639
491 uit = new CrxUpdateItem; 640 uit = new CrxUpdateItem;
492 uit->id.swap(id); 641 uit->id.swap(id);
493 uit->component = component; 642 uit->component = component;
643
494 work_items_.push_back(uit); 644 work_items_.push_back(uit);
495 // If this is the first component registered we call Start to 645 // If this is the first component registered we call Start to
496 // schedule the first timer. 646 // schedule the first timer.
497 if (running_ && (work_items_.size() == 1)) 647 if (running_ && (work_items_.size() == 1))
498 Start(); 648 Start();
499 649
500 return kOk; 650 return kOk;
501 } 651 }
502 652
503 // Sets a component to be checked for updates. 653 // Sets a component to be checked for updates.
504 // The componet to add is |crxit| and the |query| string is modified with the 654 // 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 655 // required omaha compatible query. Returns false when the query strings
506 // is longer than specified by UrlSizeLimit(). 656 // is longer than specified by UrlSizeLimit().
507 bool CrxUpdateService::AddItemToUpdateCheck(CrxUpdateItem* item, 657 bool CrxUpdateService::AddItemToUpdateCheck(CrxUpdateItem* item,
508 std::string* query) { 658 std::string* query) {
509 if (!AddQueryString(item->id, 659 if (!AddQueryString(item->id,
510 item->component.version.GetString(), 660 item->component.version.GetString(),
661 item->component.fingerprint,
511 config_->UrlSizeLimit(), query)) 662 config_->UrlSizeLimit(), query))
512 return false; 663 return false;
664
513 item->status = CrxUpdateItem::kChecking; 665 item->status = CrxUpdateItem::kChecking;
514 item->last_check = base::Time::Now(); 666 item->last_check = base::Time::Now();
667 item->is_update_available = false;
668 item->ping_queued = false;
669 item->previous_version = item->component.version;
670 item->next_version = Version();
671 item->previous_fp = item->component.fingerprint;
672 item->next_fp = "";
673 item->diff_update_failed = false;
674 item->error_code = 0;
675 item->extra_code1 = 0;
676 item->diff_error_code = 0;
677 item->diff_extra_code1 = 0;
515 return true; 678 return true;
516 } 679 }
517 680
518 // Start the process of checking for an update, for a particular component 681 // Start the process of checking for an update, for a particular component
519 // that was previously registered. 682 // that was previously registered.
520 ComponentUpdateService::Status CrxUpdateService::CheckForUpdateSoon( 683 ComponentUpdateService::Status CrxUpdateService::CheckForUpdateSoon(
521 const CrxComponent& component) { 684 const CrxComponent& component) {
522 if (component.pk_hash.empty() || 685 if (component.pk_hash.empty() ||
523 !component.version.IsValid() || 686 !component.version.IsValid() ||
524 !component.installer) 687 !component.installer)
525 return kError; 688 return kError;
526 689
527 std::string id = 690 std::string id =
528 HexStringToID(StringToLowerASCII(base::HexEncode(&component.pk_hash[0], 691 HexStringToID(StringToLowerASCII(base::HexEncode(&component.pk_hash[0],
529 component.pk_hash.size()/2))); 692 component.pk_hash.size()/2)));
530 693
531 CrxUpdateItem* uit; 694 CrxUpdateItem* uit;
532 uit = FindUpdateItemById(id); 695 uit = FindUpdateItemById(id);
533 if (!uit) 696 if (!uit)
534 return kError; 697 return kError;
535 698
536 // Check if the request is too soon. 699 // Check if the request is too soon.
537 base::TimeDelta delta = base::Time::Now() - uit->last_check; 700 base::TimeDelta delta = base::Time::Now() - uit->last_check;
538 if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay())) { 701 if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay()))
539 return kError; 702 return kError;
540 }
541 703
542 switch (uit->status) { 704 switch (uit->status) {
543 // If the item is already in the process of being updated, there is 705 // If the item is already in the process of being updated, there is
544 // no point in this call, so return kInProgress. 706 // no point in this call, so return kInProgress.
545 case CrxUpdateItem::kChecking: 707 case CrxUpdateItem::kChecking:
546 case CrxUpdateItem::kCanUpdate: 708 case CrxUpdateItem::kCanUpdate:
709 case CrxUpdateItem::kDownloadingDiff:
547 case CrxUpdateItem::kDownloading: 710 case CrxUpdateItem::kDownloading:
711 case CrxUpdateItem::kUpdatingDiff:
548 case CrxUpdateItem::kUpdating: 712 case CrxUpdateItem::kUpdating:
549 return kInProgress; 713 return kInProgress;
550 // Otherwise the item was already checked a while back (or it is new), 714 // 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. 715 // set its status to kNew to give it a slightly higher priority.
552 case CrxUpdateItem::kNew: 716 case CrxUpdateItem::kNew:
553 case CrxUpdateItem::kUpdated: 717 case CrxUpdateItem::kUpdated:
554 case CrxUpdateItem::kUpToDate: 718 case CrxUpdateItem::kUpToDate:
555 case CrxUpdateItem::kNoUpdate: 719 case CrxUpdateItem::kNoUpdate:
556 uit->status = CrxUpdateItem::kNew; 720 uit->status = CrxUpdateItem::kNew;
557 requested_work_items_.insert(uit); 721 requested_work_items_.insert(uit);
(...skipping 18 matching lines...) Expand all
576 void CrxUpdateService::ProcessPendingItems() { 740 void CrxUpdateService::ProcessPendingItems() {
577 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 741 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
578 // First check for ready upgrades and do one. The first 742 // First check for ready upgrades and do one. The first
579 // step is to fetch the crx package. 743 // step is to fetch the crx package.
580 for (UpdateItems::const_iterator it = work_items_.begin(); 744 for (UpdateItems::const_iterator it = work_items_.begin();
581 it != work_items_.end(); ++it) { 745 it != work_items_.end(); ++it) {
582 CrxUpdateItem* item = *it; 746 CrxUpdateItem* item = *it;
583 if (item->status != CrxUpdateItem::kCanUpdate) 747 if (item->status != CrxUpdateItem::kCanUpdate)
584 continue; 748 continue;
585 // Found component to update, start the process. 749 // Found component to update, start the process.
586 item->status = CrxUpdateItem::kDownloading;
587 CRXContext* context = new CRXContext; 750 CRXContext* context = new CRXContext;
588 context->pk_hash = item->component.pk_hash; 751 context->pk_hash = item->component.pk_hash;
589 context->id = item->id; 752 context->id = item->id;
590 context->installer = item->component.installer; 753 context->installer = item->component.installer;
754 context->fingerprint = item->next_fp;
755 GURL package_url;
756 if (CanTryDiffUpdate(item, *config_)) {
757 package_url = item->diff_crx_url;
758 item->status = CrxUpdateItem::kDownloadingDiff;
759 } else {
760 package_url = item->crx_url;
761 item->status = CrxUpdateItem::kDownloading;
762 }
591 url_fetcher_.reset(net::URLFetcher::Create( 763 url_fetcher_.reset(net::URLFetcher::Create(
592 0, item->crx_url, net::URLFetcher::GET, 764 0, package_url, net::URLFetcher::GET,
593 MakeContextDelegate(this, context))); 765 MakeContextDelegate(this, context)));
594 StartFetch(url_fetcher_.get(), config_->RequestContext(), true); 766 StartFetch(url_fetcher_.get(), config_->RequestContext(), true);
595 return; 767 return;
596 } 768 }
597 769
598 for (size_t ix = 0; ix != arraysize(kManifestSources); ++ix) { 770 for (size_t ix = 0; ix != arraysize(kManifestSources); ++ix) {
599 const CrxComponent::UrlSource manifest_source = kManifestSources[ix]; 771 const CrxComponent::UrlSource manifest_source = kManifestSources[ix];
600 772
601 std::string query; 773 std::string query;
602 // If no pending upgrades, we check if there are new components we have not 774 // 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; 865 delete context;
694 } 866 }
695 867
696 // Parsing the manifest is either done right now for tests or in a sandboxed 868 // 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 869 // process for the production environment. This mitigates the case where an
698 // attacker was able to feed us a malicious xml string. 870 // attacker was able to feed us a malicious xml string.
699 void CrxUpdateService::ParseManifest(const std::string& xml) { 871 void CrxUpdateService::ParseManifest(const std::string& xml) {
700 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 872 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
701 if (config_->InProcess()) { 873 if (config_->InProcess()) {
702 UpdateManifest manifest; 874 UpdateManifest manifest;
703 if (!manifest.Parse(xml)) { 875 if (!manifest.Parse(xml))
704 CrxUpdateService::OnParseUpdateManifestFailed(manifest.errors()); 876 CrxUpdateService::OnParseUpdateManifestFailed(manifest.errors());
705 } else { 877 else
706 CrxUpdateService::OnParseUpdateManifestSucceeded(manifest.results()); 878 CrxUpdateService::OnParseUpdateManifestSucceeded(manifest.results());
707 }
708 } else { 879 } else {
709 UtilityProcessHost* host = 880 UtilityProcessHost* host =
710 UtilityProcessHost::Create(new ManifestParserBridge(this), 881 UtilityProcessHost::Create(new ManifestParserBridge(this),
711 base::MessageLoopProxy::current().get()); 882 base::MessageLoopProxy::current().get());
712 host->EnableZygote(); 883 host->EnableZygote();
713 host->Send(new ChromeUtilityMsg_ParseUpdateManifest(xml)); 884 host->Send(new ChromeUtilityMsg_ParseUpdateManifest(xml));
714 } 885 }
715 } 886 }
716 887
717 // A valid Omaha update check has arrived, from only the list of components that 888 // A valid Omaha update check has arrived, from only the list of components that
(...skipping 27 matching lines...) Expand all
745 } 916 }
746 if (!it->browser_min_version.empty()) { 917 if (!it->browser_min_version.empty()) {
747 if (IsVersionNewer(chrome_version_, it->browser_min_version)) { 918 if (IsVersionNewer(chrome_version_, it->browser_min_version)) {
748 // Does not apply for this chrome version. 919 // Does not apply for this chrome version.
749 crx->status = CrxUpdateItem::kNoUpdate; 920 crx->status = CrxUpdateItem::kNoUpdate;
750 continue; 921 continue;
751 } 922 }
752 } 923 }
753 // All test passed. Queue an upgrade for this component and fire the 924 // All test passed. Queue an upgrade for this component and fire the
754 // notifications. 925 // notifications.
926 crx->is_update_available = true;
755 crx->crx_url = it->crx_url; 927 crx->crx_url = it->crx_url;
928 crx->package_hash = it->package_hash;
929 crx->size = it->size;
930 crx->diff_crx_url = it->diff_crx_url;
931 crx->diff_package_hash = it->diff_package_hash;
932 crx->diff_size = it->diff_size;
756 crx->status = CrxUpdateItem::kCanUpdate; 933 crx->status = CrxUpdateItem::kCanUpdate;
757 crx->next_version = Version(it->version); 934 crx->next_version = Version(it->version);
935 crx->next_fp = it->package_fingerprint;
758 ++update_pending; 936 ++update_pending;
759 937
760 content::NotificationService::current()->Notify( 938 content::NotificationService::current()->Notify(
761 chrome::NOTIFICATION_COMPONENT_UPDATE_FOUND, 939 chrome::NOTIFICATION_COMPONENT_UPDATE_FOUND,
762 content::Source<std::string>(&crx->id), 940 content::Source<std::string>(&crx->id),
763 content::NotificationService::NoDetails()); 941 content::NotificationService::NoDetails());
764 } 942 }
765 943
766 // All the components that are not mentioned in the manifest we 944 // All the components that are not mentioned in the manifest we
767 // consider them up to date. 945 // consider them up to date.
(...skipping 14 matching lines...) Expand all
782 } 960 }
783 961
784 // Called when the CRX package has been downloaded to a temporary location. 962 // Called when the CRX package has been downloaded to a temporary location.
785 // Here we fire the notifications and schedule the component-specific installer 963 // Here we fire the notifications and schedule the component-specific installer
786 // to be called in the file thread. 964 // to be called in the file thread.
787 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source, 965 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source,
788 CRXContext* context) { 966 CRXContext* context) {
789 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 967 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
790 int error_code = net::OK; 968 int error_code = net::OK;
791 969
970 CrxUpdateItem* crx = FindUpdateItemById(context->id);
971
792 if (source->FileErrorOccurred(&error_code) || !FetchSuccess(*source)) { 972 if (source->FileErrorOccurred(&error_code) || !FetchSuccess(*source)) {
793 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading, 973 if (crx->status == CrxUpdateItem::kDownloadingDiff) {
794 CrxUpdateItem::kNoUpdate); 974 crx->diff_error_code = GetFetchError(*source);
795 DCHECK_EQ(count, 1ul); 975 crx->diff_update_failed = true;
976 crx->status = CrxUpdateItem::kCanUpdate;
977 BrowserThread::PostTask(
978 BrowserThread::UI,
979 FROM_HERE,
980 base::Bind(&CrxUpdateService::ProcessPendingItems,
981 base::Unretained(this)));
982 return;
983 }
984 crx->error_code = GetFetchError(*source);
985 crx->status = CrxUpdateItem::kNoUpdate;
cpu_(ooo_6.6-7.5) 2013/06/18 17:02:06 Use ChangeItemStatus
Sorin Jianu 2013/06/18 20:46:39 ChangeItemStatus changes the state of all items (f
cpu_(ooo_6.6-7.5) 2013/06/18 22:02:36 Correct. The way it is used like in line 802 is be
Sorin Jianu 2013/06/19 00:29:10 Done by using ChangeItemStatus throughout this fun
796 config_->OnEvent(Configurator::kNetworkError, CrxIdtoUMAId(context->id)); 986 config_->OnEvent(Configurator::kNetworkError, CrxIdtoUMAId(context->id));
cpu_(ooo_6.6-7.5) 2013/06/18 17:02:06 and here we get to the fun part, as you can see th
Sorin Jianu 2013/06/18 20:46:39 Let's discuss this and see what is reasonable to d
cpu_(ooo_6.6-7.5) 2013/06/18 22:18:25 Neat to have agreement here. I like 2a or 2b. If
Sorin Jianu 2013/06/19 00:29:10 I am mailing the comments and uploading the fixes
797 url_fetcher_.reset(); 987 url_fetcher_.reset();
798 ScheduleNextRun(false); 988 ScheduleNextRun(false);
799 } else { 989 } else {
800 base::FilePath temp_crx_path; 990 base::FilePath temp_crx_path;
801 CHECK(source->GetResponseAsFilePath(true, &temp_crx_path)); 991 CHECK(source->GetResponseAsFilePath(true, &temp_crx_path));
802 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading, 992 crx->status = (crx->status == CrxUpdateItem::kDownloadingDiff) ?
803 CrxUpdateItem::kUpdating); 993 CrxUpdateItem::kUpdatingDiff : CrxUpdateItem::kUpdating;
804 DCHECK_EQ(count, 1ul); 994
805 url_fetcher_.reset(); 995 url_fetcher_.reset();
806 996
807 content::NotificationService::current()->Notify( 997 content::NotificationService::current()->Notify(
808 chrome::NOTIFICATION_COMPONENT_UPDATE_READY, 998 chrome::NOTIFICATION_COMPONENT_UPDATE_READY,
809 content::Source<std::string>(&context->id), 999 content::Source<std::string>(&context->id),
810 content::NotificationService::NoDetails()); 1000 content::NotificationService::NoDetails());
811 1001
812 // Why unretained? See comment at top of file. 1002 // Why unretained? See comment at top of file.
813 BrowserThread::PostDelayedTask( 1003 BrowserThread::PostDelayedTask(
814 BrowserThread::FILE, 1004 BrowserThread::FILE,
815 FROM_HERE, 1005 FROM_HERE,
816 base::Bind(&CrxUpdateService::Install, 1006 base::Bind(&CrxUpdateService::Install,
817 base::Unretained(this), 1007 base::Unretained(this),
818 context, 1008 context,
819 temp_crx_path), 1009 temp_crx_path),
820 base::TimeDelta::FromMilliseconds(config_->StepDelay())); 1010 base::TimeDelta::FromMilliseconds(config_->StepDelay()));
821 } 1011 }
822 } 1012 }
823 1013
824 // Install consists of digital signature verification, unpacking and then 1014 // Install consists of digital signature verification, unpacking and then
825 // calling the component specific installer. All that is handled by the 1015 // 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 1016 // |unpacker|. If there is an error this function is in charge of deleting
827 // the files created. 1017 // the files created.
828 void CrxUpdateService::Install(const CRXContext* context, 1018 void CrxUpdateService::Install(const CRXContext* context,
829 const base::FilePath& crx_path) { 1019 const base::FilePath& crx_path) {
830 // This function owns the |crx_path| and the |context| object. 1020 // This function owns the |crx_path| and the |context| object.
831 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 1021 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
832 ComponentUnpacker 1022 ComponentUnpacker unpacker(context->pk_hash,
833 unpacker(context->pk_hash, crx_path, context->installer); 1023 crx_path,
834 if (!file_util::Delete(crx_path, false)) { 1024 context->fingerprint,
1025 component_patcher_.get(),
1026 context->installer);
1027 if (!file_util::Delete(crx_path, false))
835 NOTREACHED() << crx_path.value(); 1028 NOTREACHED() << crx_path.value();
836 }
837 // Why unretained? See comment at top of file. 1029 // Why unretained? See comment at top of file.
838 BrowserThread::PostDelayedTask( 1030 BrowserThread::PostDelayedTask(
839 BrowserThread::UI, 1031 BrowserThread::UI,
840 FROM_HERE, 1032 FROM_HERE,
841 base::Bind(&CrxUpdateService::DoneInstalling, base::Unretained(this), 1033 base::Bind(&CrxUpdateService::DoneInstalling, base::Unretained(this),
842 context->id, unpacker.error()), 1034 context->id, unpacker.error(), unpacker.extended_error()),
843 base::TimeDelta::FromMilliseconds(config_->StepDelay())); 1035 base::TimeDelta::FromMilliseconds(config_->StepDelay()));
844 delete context; 1036 delete context;
845 } 1037 }
846 1038
847 // Installation has been completed. Adjust the component status and 1039 // Installation has been completed. Adjust the component status and
848 // schedule the next check. 1040 // schedule the next check.
849 void CrxUpdateService::DoneInstalling(const std::string& component_id, 1041 void CrxUpdateService::DoneInstalling(const std::string& component_id,
850 ComponentUnpacker::Error error) { 1042 ComponentUnpacker::Error error,
1043 int extra_code) {
851 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1044 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
852 1045
853 CrxUpdateItem* item = FindUpdateItemById(component_id); 1046 CrxUpdateItem* item = FindUpdateItemById(component_id);
1047 if (item->status == CrxUpdateItem::kUpdatingDiff) {
1048 if (error != ComponentUnpacker::kNone) {
1049 item->diff_error_code = error;
1050 item->diff_extra_code1 = extra_code;
1051 item->diff_update_failed = true;
1052 item->status = CrxUpdateItem::kCanUpdate;
1053 BrowserThread::PostTask(
1054 BrowserThread::UI,
1055 FROM_HERE,
1056 base::Bind(&CrxUpdateService::ProcessPendingItems,
1057 base::Unretained(this)));
1058 return;
1059 }
1060 }
1061
1062 if (error != ComponentUnpacker::kNone) {
1063 item->error_code = error;
1064 item->extra_code1 = extra_code;
1065 }
1066
854 item->status = (error == ComponentUnpacker::kNone) ? CrxUpdateItem::kUpdated : 1067 item->status = (error == ComponentUnpacker::kNone) ? CrxUpdateItem::kUpdated :
855 CrxUpdateItem::kNoUpdate; 1068 CrxUpdateItem::kNoUpdate;
856 if (item->status == CrxUpdateItem::kUpdated) 1069 if (item->status == CrxUpdateItem::kUpdated) {
857 item->component.version = item->next_version; 1070 item->component.version = item->next_version;
1071 item->component.fingerprint = item->next_fp;
1072 }
858 1073
859 Configurator::Events event; 1074 Configurator::Events event;
860 switch (error) { 1075 switch (error) {
861 case ComponentUnpacker::kNone: 1076 case ComponentUnpacker::kNone:
862 event = Configurator::kComponentUpdated; 1077 event = Configurator::kComponentUpdated;
863 break; 1078 break;
864 case ComponentUnpacker::kInstallerError: 1079 case ComponentUnpacker::kInstallerError:
865 event = Configurator::kInstallerError; 1080 event = Configurator::kInstallerError;
866 break; 1081 break;
867 default: 1082 default:
868 event = Configurator::kUnpackError; 1083 event = Configurator::kUnpackError;
869 break; 1084 break;
870 } 1085 }
871 1086
872 config_->OnEvent(event, CrxIdtoUMAId(component_id)); 1087 config_->OnEvent(event, CrxIdtoUMAId(component_id));
873 ScheduleNextRun(false); 1088 ScheduleNextRun(false);
874 } 1089 }
875 1090
1091 bool CrxUpdateService::CanPing() const {
1092 return config_->PingUrl().is_valid();
1093 }
1094
1095 void CrxUpdateService::SendPing(const std::string& ping) {
1096 VLOG(3) << "Sending ping. " << ping;
cpu_(ooo_6.6-7.5) 2013/06/18 17:02:06 please remove all the VLOGing, instrument your loc
Sorin Jianu 2013/06/18 20:46:39 Done.
1097 const std::string ping_url(config_->PingUrl().spec());
1098 ping_sender_.reset(net::URLFetcher::Create(
1099 0, GURL(ping_url), net::URLFetcher::POST,
1100 MakeContextDelegate(this, new PingContext())));
1101 ping_sender_->SetUploadData(std::string("application/xml"), ping);
1102 StartFetch(ping_sender_.get(), config_->RequestContext(), false);
1103 }
1104
1105 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source,
1106 PingContext* context) {
1107 VLOG(3) << "Sending component update ping returned "
1108 << FetchSuccess(*source);
1109 ping_sender_.reset();
1110 }
1111
1112 // Builds a ping message for the update items that have completed. Returns
1113 // an empty string if there are no completed items.
1114 std::string CrxUpdateService::BuildPing() const {
1115 const std::string apps(BuildPingApps());
1116 if (apps.empty())
1117 return std::string();
1118
1119 const char response_format[] =
1120 "<o:gupdate xmlns:o=\"http://www.google.com/update2/request\" "
1121 "protocol=\"2.0\" version=\"%s-%s\" requestid=\"{%s}\"> "
1122 "<o:os platform=\"%s\" version=\"%s\"/> "
1123 "%s"
1124 "</o:gupdate>";
1125 const std::string response_envelope(
1126 base::StringPrintf(response_format,
1127 prod_id_.c_str(),
1128 chrome_version_.GetString().c_str(),
1129 base::GenerateGUID().c_str(),
1130 os_type_.c_str(),
1131 os_version_.c_str(),
1132 apps.c_str()));
1133 return response_envelope;
1134 }
1135
1136 // Returns a string containing the sequence of app elements inside the
1137 // ping message.
1138 std::string CrxUpdateService::BuildPingApps() const {
1139 const char app_format[] = "<o:app appid=\"%s\" version=\"%s\">%s</o:app>";
1140
1141 std::string ping_apps;
1142 for (UpdateItems::const_iterator it = work_items_.begin();
1143 it != work_items_.end(); ++it) {
1144 CrxUpdateItem* item = *it;
1145 // Only ping once if an update was available and the item is completed.
1146 if (item->is_update_available && !item->ping_queued &&
1147 (item->status == CrxUpdateItem::kNoUpdate ||
1148 item->status == CrxUpdateItem::kUpdated)) {
1149 const std::string version = item->component.version.GetString().c_str();
1150 ping_apps += base::StringPrintf(app_format,
1151 item->id.c_str(),
1152 version.c_str(),
1153 BuildPingEvent(item).c_str());
1154 }
1155 }
1156 return ping_apps;
1157 }
1158
1159 // Returns a string representing one ping event for an update item.
1160 std::string CrxUpdateService::BuildPingEvent(CrxUpdateItem* item) {
1161 DCHECK(item->status == CrxUpdateItem::kNoUpdate ||
1162 item->status == CrxUpdateItem::kUpdated);
1163 DCHECK(item->is_update_available);
1164
1165 using base::StringAppendF;
1166
1167 std::string ping_event("<o:event eventtype=\"3\"");
1168 const int event_result = item->status == CrxUpdateItem::kUpdated;
1169 StringAppendF(&ping_event, " eventresult=\"%d\"", event_result);
1170 StringAppendF(&ping_event, " previousversion=\"%s\"",
1171 item->previous_version.GetString().c_str());
1172 StringAppendF(&ping_event, " nextversion=\"%s\"",
1173 item->next_version.GetString().c_str());
1174 if (item->error_code)
1175 StringAppendF(&ping_event, " errorcode=\"%d\"", item->error_code);
1176 if (item->extra_code1)
1177 StringAppendF(&ping_event, " extracode1=\"%d\"", item->extra_code1);
1178 if (IsDiffUpdateAvailable(item))
1179 StringAppendF(&ping_event, " diffresult=\"%d\"", !item->diff_update_failed);
1180 if (item->diff_error_code)
1181 StringAppendF(&ping_event, " differrorcode=\"%d\"", item->diff_error_code);
1182 if (item->diff_extra_code1) {
1183 StringAppendF(&ping_event,
1184 " diffextracode1=\"%d\"",
1185 item->diff_extra_code1);
1186 }
1187 if (!item->previous_fp.empty())
1188 StringAppendF(&ping_event, " previousfp=\"%s\"", item->previous_fp.c_str());
1189 if (!item->next_fp.empty())
1190 StringAppendF(&ping_event, " nextfp=\"%s\"", item->next_fp.c_str());
1191 StringAppendF(&ping_event, "/>");
1192 item->ping_queued = true;
1193 return ping_event;
1194 }
1195
1196
876 // The component update factory. Using the component updater as a singleton 1197 // The component update factory. Using the component updater as a singleton
877 // is the job of the browser process. 1198 // is the job of the browser process.
878 ComponentUpdateService* ComponentUpdateServiceFactory( 1199 ComponentUpdateService* ComponentUpdateServiceFactory(
879 ComponentUpdateService::Configurator* config) { 1200 ComponentUpdateService::Configurator* config) {
880 DCHECK(config); 1201 DCHECK(config);
881 return new CrxUpdateService(config); 1202 return new CrxUpdateService(config);
882 } 1203 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698