OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/component_updater/background_downloader_win.h" | 5 #include "components/update_client/background_downloader_win.h" |
6 | 6 |
7 #include <atlbase.h> | 7 #include <atlbase.h> |
8 #include <atlcom.h> | 8 #include <atlcom.h> |
9 | 9 |
10 #include <stdint.h> | 10 #include <stdint.h> |
11 #include <functional> | 11 #include <functional> |
12 #include <iomanip> | 12 #include <iomanip> |
13 #include <limits> | 13 #include <limits> |
14 #include <vector> | 14 #include <vector> |
15 | 15 |
16 #include "base/bind.h" | 16 #include "base/bind.h" |
17 #include "base/bind_helpers.h" | 17 #include "base/bind_helpers.h" |
18 #include "base/files/file_util.h" | 18 #include "base/files/file_util.h" |
19 #include "base/message_loop/message_loop_proxy.h" | 19 #include "base/message_loop/message_loop_proxy.h" |
20 #include "base/single_thread_task_runner.h" | 20 #include "base/single_thread_task_runner.h" |
21 #include "base/strings/sys_string_conversions.h" | 21 #include "base/strings/sys_string_conversions.h" |
22 #include "base/win/scoped_co_mem.h" | 22 #include "base/win/scoped_co_mem.h" |
23 #include "components/component_updater/component_updater_utils.h" | 23 #include "components/update_client/utils.h" |
24 #include "ui/base/win/atl_module.h" | 24 #include "ui/base/win/atl_module.h" |
25 #include "url/gurl.h" | 25 #include "url/gurl.h" |
26 | 26 |
27 using base::win::ScopedCoMem; | 27 using base::win::ScopedCoMem; |
28 using base::win::ScopedComPtr; | 28 using base::win::ScopedComPtr; |
29 | 29 |
30 // The class BackgroundDownloader in this module is an adapter between | 30 // The class BackgroundDownloader in this module is an adapter between |
31 // the CrxDownloader interface and the BITS service interfaces. | 31 // the CrxDownloader interface and the BITS service interfaces. |
32 // The interface exposed on the CrxDownloader code runs on the main thread, | 32 // The interface exposed on the CrxDownloader code runs on the main thread, |
33 // while the BITS specific code runs on a separate thread passed in by the | 33 // while the BITS specific code runs on a separate thread passed in by the |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
86 // | 86 // |
87 // In addition to how BITS is managing the life time of the job, there are a | 87 // In addition to how BITS is managing the life time of the job, there are a |
88 // couple of special cases defined by the BackgroundDownloader. | 88 // couple of special cases defined by the BackgroundDownloader. |
89 // First, if the job encounters any of the 5xx HTTP responses, the job is | 89 // First, if the job encounters any of the 5xx HTTP responses, the job is |
90 // not retried, in order to avoid DDOS-ing the servers. | 90 // not retried, in order to avoid DDOS-ing the servers. |
91 // Second, there is a simple mechanism to detect stuck jobs, and allow the rest | 91 // Second, there is a simple mechanism to detect stuck jobs, and allow the rest |
92 // of the code to move on to trying other urls or trying other components. | 92 // of the code to move on to trying other urls or trying other components. |
93 // Last, after completing a job, irrespective of the outcome, the jobs older | 93 // Last, after completing a job, irrespective of the outcome, the jobs older |
94 // than a week are proactively cleaned up. | 94 // than a week are proactively cleaned up. |
95 | 95 |
96 namespace component_updater { | 96 namespace update_client { |
97 | 97 |
98 namespace { | 98 namespace { |
99 | 99 |
100 // All jobs created by this module have a specific description so they can | 100 // All jobs created by this module have a specific description so they can |
101 // be found at run-time or by using system administration tools. | 101 // be found at run-time or by using system administration tools. |
102 const base::char16 kJobDescription[] = L"Chrome Component Updater"; | 102 const base::char16 kJobDescription[] = L"Chrome Component Updater"; |
103 | 103 |
104 // How often the code looks for changes in the BITS job state. | 104 // How often the code looks for changes in the BITS job state. |
105 const int kJobPollingIntervalSec = 4; | 105 const int kJobPollingIntervalSec = 4; |
106 | 106 |
(...skipping 27 matching lines...) Expand all Loading... | |
134 const int kHttpStatusFirst = 100; // Continue. | 134 const int kHttpStatusFirst = 100; // Continue. |
135 const int kHttpStatusLast = 505; // Version not supported. | 135 const int kHttpStatusLast = 505; // Version not supported. |
136 bool is_valid = HIWORD(error) == 0x8019 && | 136 bool is_valid = HIWORD(error) == 0x8019 && |
137 LOWORD(error) >= kHttpStatusFirst && | 137 LOWORD(error) >= kHttpStatusFirst && |
138 LOWORD(error) <= kHttpStatusLast; | 138 LOWORD(error) <= kHttpStatusLast; |
139 return is_valid ? LOWORD(error) : 0; | 139 return is_valid ? LOWORD(error) : 0; |
140 } | 140 } |
141 | 141 |
142 // Returns the files in a BITS job. | 142 // Returns the files in a BITS job. |
143 HRESULT GetFilesInJob(IBackgroundCopyJob* job, | 143 HRESULT GetFilesInJob(IBackgroundCopyJob* job, |
144 std::vector<ScopedComPtr<IBackgroundCopyFile> >* files) { | 144 std::vector<ScopedComPtr<IBackgroundCopyFile>>* files) { |
145 ScopedComPtr<IEnumBackgroundCopyFiles> enum_files; | 145 ScopedComPtr<IEnumBackgroundCopyFiles> enum_files; |
146 HRESULT hr = job->EnumFiles(enum_files.Receive()); | 146 HRESULT hr = job->EnumFiles(enum_files.Receive()); |
147 if (FAILED(hr)) | 147 if (FAILED(hr)) |
148 return hr; | 148 return hr; |
149 | 149 |
150 ULONG num_files = 0; | 150 ULONG num_files = 0; |
151 hr = enum_files->GetCount(&num_files); | 151 hr = enum_files->GetCount(&num_files); |
152 if (FAILED(hr)) | 152 if (FAILED(hr)) |
153 return hr; | 153 return hr; |
154 | 154 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
252 *error_code_out = FAILED(error_code) ? error_code : E_FAIL; | 252 *error_code_out = FAILED(error_code) ? error_code : E_FAIL; |
253 return S_OK; | 253 return S_OK; |
254 } | 254 } |
255 | 255 |
256 // Finds the component updater jobs matching the given predicate. | 256 // Finds the component updater jobs matching the given predicate. |
257 // Returns S_OK if the function has found at least one job, returns S_FALSE if | 257 // Returns S_OK if the function has found at least one job, returns S_FALSE if |
258 // no job was found, and it returns an error otherwise. | 258 // no job was found, and it returns an error otherwise. |
259 template <class Predicate> | 259 template <class Predicate> |
260 HRESULT FindBitsJobIf(Predicate pred, | 260 HRESULT FindBitsJobIf(Predicate pred, |
261 IBackgroundCopyManager* bits_manager, | 261 IBackgroundCopyManager* bits_manager, |
262 std::vector<ScopedComPtr<IBackgroundCopyJob> >* jobs) { | 262 std::vector<ScopedComPtr<IBackgroundCopyJob>>* jobs) { |
263 ScopedComPtr<IEnumBackgroundCopyJobs> enum_jobs; | 263 ScopedComPtr<IEnumBackgroundCopyJobs> enum_jobs; |
264 HRESULT hr = bits_manager->EnumJobs(0, enum_jobs.Receive()); | 264 HRESULT hr = bits_manager->EnumJobs(0, enum_jobs.Receive()); |
265 if (FAILED(hr)) | 265 if (FAILED(hr)) |
266 return hr; | 266 return hr; |
267 | 267 |
268 ULONG job_count = 0; | 268 ULONG job_count = 0; |
269 hr = enum_jobs->GetCount(&job_count); | 269 hr = enum_jobs->GetCount(&job_count); |
270 if (FAILED(hr)) | 270 if (FAILED(hr)) |
271 return hr; | 271 return hr; |
272 | 272 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
310 // of any file in a job matches the argument. | 310 // of any file in a job matches the argument. |
311 struct JobFileUrlEqual : public std::binary_function<IBackgroundCopyJob*, | 311 struct JobFileUrlEqual : public std::binary_function<IBackgroundCopyJob*, |
312 const base::string16&, | 312 const base::string16&, |
313 bool> { | 313 bool> { |
314 bool operator()(IBackgroundCopyJob* job, | 314 bool operator()(IBackgroundCopyJob* job, |
315 const base::string16& remote_name) const; | 315 const base::string16& remote_name) const; |
316 }; | 316 }; |
317 | 317 |
318 bool JobFileUrlEqual::operator()(IBackgroundCopyJob* job, | 318 bool JobFileUrlEqual::operator()(IBackgroundCopyJob* job, |
319 const base::string16& remote_name) const { | 319 const base::string16& remote_name) const { |
320 std::vector<ScopedComPtr<IBackgroundCopyFile> > files; | 320 std::vector<ScopedComPtr<IBackgroundCopyFile>> files; |
321 HRESULT hr = GetFilesInJob(job, &files); | 321 HRESULT hr = GetFilesInJob(job, &files); |
322 if (FAILED(hr)) | 322 if (FAILED(hr)) |
323 return false; | 323 return false; |
324 | 324 |
325 for (size_t i = 0; i != files.size(); ++i) { | 325 for (size_t i = 0; i != files.size(); ++i) { |
326 ScopedCoMem<base::char16> name; | 326 ScopedCoMem<base::char16> name; |
327 if (SUCCEEDED(files[i]->GetRemoteName(&name)) && | 327 if (SUCCEEDED(files[i]->GetRemoteName(&name)) && |
328 remote_name.compare(name) == 0) | 328 remote_name.compare(name) == 0) |
329 return true; | 329 return true; |
330 } | 330 } |
331 | 331 |
332 return false; | 332 return false; |
333 } | 333 } |
334 | 334 |
335 // Creates an instance of the BITS manager. | 335 // Creates an instance of the BITS manager. |
336 HRESULT GetBitsManager(IBackgroundCopyManager** bits_manager) { | 336 HRESULT GetBitsManager(IBackgroundCopyManager** bits_manager) { |
337 ScopedComPtr<IBackgroundCopyManager> object; | 337 ScopedComPtr<IBackgroundCopyManager> object; |
338 HRESULT hr = object.CreateInstance(__uuidof(BackgroundCopyManager)); | 338 HRESULT hr = object.CreateInstance(__uuidof(BackgroundCopyManager)); |
339 if (FAILED(hr)) { | 339 if (FAILED(hr)) { |
340 return hr; | 340 return hr; |
341 } | 341 } |
342 *bits_manager = object.Detach(); | 342 *bits_manager = object.Detach(); |
343 return S_OK; | 343 return S_OK; |
344 } | 344 } |
345 | 345 |
346 void CleanupJobFiles(IBackgroundCopyJob* job) { | 346 void CleanupJobFiles(IBackgroundCopyJob* job) { |
347 std::vector<ScopedComPtr<IBackgroundCopyFile> > files; | 347 std::vector<ScopedComPtr<IBackgroundCopyFile>> files; |
348 if (FAILED(GetFilesInJob(job, &files))) | 348 if (FAILED(GetFilesInJob(job, &files))) |
349 return; | 349 return; |
350 for (size_t i = 0; i != files.size(); ++i) { | 350 for (size_t i = 0; i != files.size(); ++i) { |
351 base::string16 local_name; | 351 base::string16 local_name; |
352 HRESULT hr(GetJobFileProperties(files[i].get(), &local_name, NULL, NULL)); | 352 HRESULT hr(GetJobFileProperties(files[i].get(), &local_name, NULL, NULL)); |
353 if (SUCCEEDED(hr)) | 353 if (SUCCEEDED(hr)) |
354 DeleteFileAndEmptyParentDirectory(base::FilePath(local_name)); | 354 DeleteFileAndEmptyParentDirectory(base::FilePath(local_name)); |
355 } | 355 } |
356 } | 356 } |
357 | 357 |
358 // Cleans up incompleted jobs that are too old. | 358 // Cleans up incompleted jobs that are too old. |
359 HRESULT CleanupStaleJobs( | 359 HRESULT CleanupStaleJobs( |
360 base::win::ScopedComPtr<IBackgroundCopyManager> bits_manager) { | 360 base::win::ScopedComPtr<IBackgroundCopyManager> bits_manager) { |
361 if (!bits_manager.get()) | 361 if (!bits_manager.get()) |
362 return E_FAIL; | 362 return E_FAIL; |
363 | 363 |
364 static base::Time last_sweep; | 364 static base::Time last_sweep; |
365 | 365 |
366 const base::TimeDelta time_delta( | 366 const base::TimeDelta time_delta( |
367 base::TimeDelta::FromDays(kPurgeStaleJobsIntervalBetweenChecksDays)); | 367 base::TimeDelta::FromDays(kPurgeStaleJobsIntervalBetweenChecksDays)); |
368 const base::Time current_time(base::Time::Now()); | 368 const base::Time current_time(base::Time::Now()); |
369 if (last_sweep + time_delta > current_time) | 369 if (last_sweep + time_delta > current_time) |
370 return S_OK; | 370 return S_OK; |
371 | 371 |
372 last_sweep = current_time; | 372 last_sweep = current_time; |
373 | 373 |
374 std::vector<ScopedComPtr<IBackgroundCopyJob> > jobs; | 374 std::vector<ScopedComPtr<IBackgroundCopyJob>> jobs; |
375 HRESULT hr = FindBitsJobIf( | 375 HRESULT hr = FindBitsJobIf( |
376 std::bind2nd(JobCreationOlderThanDays(), kPurgeStaleJobsAfterDays), | 376 std::bind2nd(JobCreationOlderThanDays(), kPurgeStaleJobsAfterDays), |
377 bits_manager.get(), &jobs); | 377 bits_manager.get(), &jobs); |
378 if (FAILED(hr)) | 378 if (FAILED(hr)) |
379 return hr; | 379 return hr; |
380 | 380 |
381 for (size_t i = 0; i != jobs.size(); ++i) { | 381 for (size_t i = 0; i != jobs.size(); ++i) { |
382 jobs[i]->Cancel(); | 382 jobs[i]->Cancel(); |
383 CleanupJobFiles(jobs[i].get()); | 383 CleanupJobFiles(jobs[i].get()); |
384 } | 384 } |
(...skipping 26 matching lines...) Expand all Loading... | |
411 // the interface pointers are valid. Releasing the ownership means leaking | 411 // the interface pointers are valid. Releasing the ownership means leaking |
412 // these objects and their associated resources. | 412 // these objects and their associated resources. |
413 timer_.release(); | 413 timer_.release(); |
414 bits_manager_.Detach(); | 414 bits_manager_.Detach(); |
415 job_.Detach(); | 415 job_.Detach(); |
416 } | 416 } |
417 | 417 |
418 void BackgroundDownloader::DoStartDownload(const GURL& url) { | 418 void BackgroundDownloader::DoStartDownload(const GURL& url) { |
419 DCHECK(thread_checker_.CalledOnValidThread()); | 419 DCHECK(thread_checker_.CalledOnValidThread()); |
420 | 420 |
421 task_runner_->PostTask( | 421 task_runner_->PostTask(FROM_HERE, |
422 FROM_HERE, | 422 base::Bind(&BackgroundDownloader::BeginDownload, |
423 base::Bind( | 423 base::Unretained(this), url)); |
424 &BackgroundDownloader::BeginDownload, base::Unretained(this), url)); | |
425 } | 424 } |
426 | 425 |
427 // Called once when this class is asked to do a download. Creates or opens | 426 // Called once when this class is asked to do a download. Creates or opens |
428 // an existing bits job, hooks up the notifications, and starts the timer. | 427 // an existing bits job, hooks up the notifications, and starts the timer. |
429 void BackgroundDownloader::BeginDownload(const GURL& url) { | 428 void BackgroundDownloader::BeginDownload(const GURL& url) { |
430 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 429 DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
431 | 430 |
432 DCHECK(!timer_); | 431 DCHECK(!timer_); |
433 | 432 |
434 is_completed_ = false; | 433 is_completed_ = false; |
435 download_start_time_ = base::Time::Now(); | 434 download_start_time_ = base::Time::Now(); |
436 job_stuck_begin_time_ = download_start_time_; | 435 job_stuck_begin_time_ = download_start_time_; |
437 | 436 |
438 HRESULT hr = QueueBitsJob(url); | 437 HRESULT hr = QueueBitsJob(url); |
439 if (FAILED(hr)) { | 438 if (FAILED(hr)) { |
440 EndDownload(hr); | 439 EndDownload(hr); |
441 return; | 440 return; |
442 } | 441 } |
443 | 442 |
444 // A repeating timer retains the user task. This timer can be stopped and | 443 // A repeating timer retains the user task. This timer can be stopped and |
445 // reset multiple times. | 444 // reset multiple times. |
446 timer_.reset(new base::RepeatingTimer<BackgroundDownloader>); | 445 timer_.reset(new base::RepeatingTimer<BackgroundDownloader>); |
447 timer_->Start(FROM_HERE, | 446 timer_->Start(FROM_HERE, base::TimeDelta::FromSeconds(kJobPollingIntervalSec), |
448 base::TimeDelta::FromSeconds(kJobPollingIntervalSec), | 447 this, &BackgroundDownloader::OnDownloading); |
waffles
2015/01/20 21:49:07
Did git cl format do this? I liked the old format
| |
449 this, | |
450 &BackgroundDownloader::OnDownloading); | |
451 } | 448 } |
452 | 449 |
453 // Called any time the timer fires. | 450 // Called any time the timer fires. |
454 void BackgroundDownloader::OnDownloading() { | 451 void BackgroundDownloader::OnDownloading() { |
455 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 452 DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
456 | 453 |
457 DCHECK(job_.get()); | 454 DCHECK(job_.get()); |
458 | 455 |
459 DCHECK(!is_completed_); | 456 DCHECK(!is_completed_); |
460 if (is_completed_) | 457 if (is_completed_) |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
551 download_metrics.download_time_ms = download_time.InMilliseconds(); | 548 download_metrics.download_time_ms = download_time.InMilliseconds(); |
552 | 549 |
553 Result result; | 550 Result result; |
554 result.error = error_to_report; | 551 result.error = error_to_report; |
555 result.response = response_; | 552 result.response = response_; |
556 result.downloaded_bytes = downloaded_bytes; | 553 result.downloaded_bytes = downloaded_bytes; |
557 result.total_bytes = total_bytes; | 554 result.total_bytes = total_bytes; |
558 main_task_runner_->PostTask( | 555 main_task_runner_->PostTask( |
559 FROM_HERE, | 556 FROM_HERE, |
560 base::Bind(&BackgroundDownloader::OnDownloadComplete, | 557 base::Bind(&BackgroundDownloader::OnDownloadComplete, |
561 base::Unretained(this), | 558 base::Unretained(this), is_handled, result, download_metrics)); |
562 is_handled, | |
563 result, | |
564 download_metrics)); | |
565 | 559 |
566 // Once the task is posted to the the main thread, this object may be deleted | 560 // Once the task is posted to the the main thread, this object may be deleted |
567 // by its owner. It is not safe to access members of this object on the | 561 // by its owner. It is not safe to access members of this object on the |
568 // task runner from this point on. The timer is stopped and all BITS | 562 // task runner from this point on. The timer is stopped and all BITS |
569 // interface pointers have been released. | 563 // interface pointers have been released. |
570 } | 564 } |
571 | 565 |
572 // Called when the BITS job has been transferred successfully. Completes the | 566 // Called when the BITS job has been transferred successfully. Completes the |
573 // BITS job by removing it from the BITS queue and making the download | 567 // BITS job by removing it from the BITS queue and making the download |
574 // available to the caller. | 568 // available to the caller. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
622 int64_t total_bytes = -1; | 616 int64_t total_bytes = -1; |
623 HRESULT hr = GetJobByteCount(job_.get(), &downloaded_bytes, &total_bytes); | 617 HRESULT hr = GetJobByteCount(job_.get(), &downloaded_bytes, &total_bytes); |
624 if (FAILED(hr)) | 618 if (FAILED(hr)) |
625 return; | 619 return; |
626 | 620 |
627 Result result; | 621 Result result; |
628 result.downloaded_bytes = downloaded_bytes; | 622 result.downloaded_bytes = downloaded_bytes; |
629 result.total_bytes = total_bytes; | 623 result.total_bytes = total_bytes; |
630 | 624 |
631 main_task_runner_->PostTask( | 625 main_task_runner_->PostTask( |
632 FROM_HERE, | 626 FROM_HERE, base::Bind(&BackgroundDownloader::OnDownloadProgress, |
633 base::Bind(&BackgroundDownloader::OnDownloadProgress, | 627 base::Unretained(this), result)); |
634 base::Unretained(this), | |
635 result)); | |
636 } | 628 } |
637 | 629 |
638 // Called when the download was cancelled. Since the observer should have | 630 // Called when the download was cancelled. Since the observer should have |
639 // been disconnected by now, this notification must not be seen. | 631 // been disconnected by now, this notification must not be seen. |
640 void BackgroundDownloader::OnStateCancelled() { | 632 void BackgroundDownloader::OnStateCancelled() { |
641 EndDownload(E_UNEXPECTED); | 633 EndDownload(E_UNEXPECTED); |
642 } | 634 } |
643 | 635 |
644 // Called when the download was completed. Same as above. | 636 // Called when the download was completed. Same as above. |
645 void BackgroundDownloader::OnStateAcknowledged() { | 637 void BackgroundDownloader::OnStateAcknowledged() { |
(...skipping 19 matching lines...) Expand all Loading... | |
665 if (hr == S_OK) { | 657 if (hr == S_OK) { |
666 hr = InitializeNewJob(url); | 658 hr = InitializeNewJob(url); |
667 if (FAILED(hr)) | 659 if (FAILED(hr)) |
668 return hr; | 660 return hr; |
669 } | 661 } |
670 | 662 |
671 return job_->Resume(); | 663 return job_->Resume(); |
672 } | 664 } |
673 | 665 |
674 HRESULT BackgroundDownloader::CreateOrOpenJob(const GURL& url) { | 666 HRESULT BackgroundDownloader::CreateOrOpenJob(const GURL& url) { |
675 std::vector<ScopedComPtr<IBackgroundCopyJob> > jobs; | 667 std::vector<ScopedComPtr<IBackgroundCopyJob>> jobs; |
676 HRESULT hr = FindBitsJobIf( | 668 HRESULT hr = FindBitsJobIf( |
677 std::bind2nd(JobFileUrlEqual(), base::SysUTF8ToWide(url.spec())), | 669 std::bind2nd(JobFileUrlEqual(), base::SysUTF8ToWide(url.spec())), |
678 bits_manager_.get(), &jobs); | 670 bits_manager_.get(), &jobs); |
679 if (SUCCEEDED(hr) && !jobs.empty()) { | 671 if (SUCCEEDED(hr) && !jobs.empty()) { |
680 job_ = jobs.front(); | 672 job_ = jobs.front(); |
681 return S_FALSE; | 673 return S_FALSE; |
682 } | 674 } |
683 | 675 |
684 // Use kJobDescription as a temporary job display name until the proper | 676 // Use kJobDescription as a temporary job display name until the proper |
685 // display name is initialized later on. | 677 // display name is initialized later on. |
686 GUID guid = {0}; | 678 GUID guid = {0}; |
687 ScopedComPtr<IBackgroundCopyJob> job; | 679 ScopedComPtr<IBackgroundCopyJob> job; |
688 hr = bits_manager_->CreateJob( | 680 hr = bits_manager_->CreateJob(kJobDescription, BG_JOB_TYPE_DOWNLOAD, &guid, |
689 kJobDescription, BG_JOB_TYPE_DOWNLOAD, &guid, job.Receive()); | 681 job.Receive()); |
690 if (FAILED(hr)) | 682 if (FAILED(hr)) |
691 return hr; | 683 return hr; |
692 | 684 |
693 job_ = job; | 685 job_ = job; |
694 return S_OK; | 686 return S_OK; |
695 } | 687 } |
696 | 688 |
697 HRESULT BackgroundDownloader::InitializeNewJob(const GURL& url) { | 689 HRESULT BackgroundDownloader::InitializeNewJob(const GURL& url) { |
698 const base::string16 filename(base::SysUTF8ToWide(url.ExtractFileName())); | 690 const base::string16 filename(base::SysUTF8ToWide(url.ExtractFileName())); |
699 | 691 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
735 const base::TimeDelta job_stuck_timeout( | 727 const base::TimeDelta job_stuck_timeout( |
736 base::TimeDelta::FromMinutes(kJobStuckTimeoutMin)); | 728 base::TimeDelta::FromMinutes(kJobStuckTimeoutMin)); |
737 return job_stuck_begin_time_ + job_stuck_timeout < base::Time::Now(); | 729 return job_stuck_begin_time_ + job_stuck_timeout < base::Time::Now(); |
738 } | 730 } |
739 | 731 |
740 HRESULT BackgroundDownloader::CompleteJob() { | 732 HRESULT BackgroundDownloader::CompleteJob() { |
741 HRESULT hr = job_->Complete(); | 733 HRESULT hr = job_->Complete(); |
742 if (FAILED(hr) && hr != BG_S_UNABLE_TO_DELETE_FILES) | 734 if (FAILED(hr) && hr != BG_S_UNABLE_TO_DELETE_FILES) |
743 return hr; | 735 return hr; |
744 | 736 |
745 std::vector<ScopedComPtr<IBackgroundCopyFile> > files; | 737 std::vector<ScopedComPtr<IBackgroundCopyFile>> files; |
746 hr = GetFilesInJob(job_.get(), &files); | 738 hr = GetFilesInJob(job_.get(), &files); |
747 if (FAILED(hr)) | 739 if (FAILED(hr)) |
748 return hr; | 740 return hr; |
749 | 741 |
750 if (files.empty()) | 742 if (files.empty()) |
751 return E_UNEXPECTED; | 743 return E_UNEXPECTED; |
752 | 744 |
753 base::string16 local_name; | 745 base::string16 local_name; |
754 BG_FILE_PROGRESS progress = {0}; | 746 BG_FILE_PROGRESS progress = {0}; |
755 hr = GetJobFileProperties(files.front().get(), &local_name, NULL, &progress); | 747 hr = GetJobFileProperties(files.front().get(), &local_name, NULL, &progress); |
756 if (FAILED(hr)) | 748 if (FAILED(hr)) |
757 return hr; | 749 return hr; |
758 | 750 |
759 // Sanity check the post-conditions of a successful download, including | 751 // Sanity check the post-conditions of a successful download, including |
760 // the file and job invariants. The byte counts for a job and its file | 752 // the file and job invariants. The byte counts for a job and its file |
761 // must match as a job only contains one file. | 753 // must match as a job only contains one file. |
762 DCHECK(progress.Completed); | 754 DCHECK(progress.Completed); |
763 DCHECK_EQ(progress.BytesTotal, progress.BytesTransferred); | 755 DCHECK_EQ(progress.BytesTotal, progress.BytesTransferred); |
764 | 756 |
765 response_ = base::FilePath(local_name); | 757 response_ = base::FilePath(local_name); |
766 | 758 |
767 return S_OK; | 759 return S_OK; |
768 } | 760 } |
769 | 761 |
770 } // namespace component_updater | 762 } // namespace update_client |
OLD | NEW |