summaryrefslogtreecommitdiffstats
path: root/components/update_client/crx_downloader.cc
diff options
context:
space:
mode:
authorsorin <sorin@chromium.org>2015-01-23 17:15:00 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-24 01:16:25 +0000
commit52ac088530b109fa506c4491aea8cf12bcadc63d (patch)
tree64a47ef9e8d4e4662e7366aaea856b9da32ff168 /components/update_client/crx_downloader.cc
parent9d3bb0c75ddbeafd53f5ad32813b0fe70b7e0779 (diff)
downloadchromium_src-52ac088530b109fa506c4491aea8cf12bcadc63d.zip
chromium_src-52ac088530b109fa506c4491aea8cf12bcadc63d.tar.gz
chromium_src-52ac088530b109fa506c4491aea8cf12bcadc63d.tar.bz2
This is a mechanical change. It is large but straightforward in its intention.
jam: please review the changes under //src/chrome/browser blundell: please review the changes under //src/components waffles: please review the component updater and the update client changes. The intention here is to move most of the component updater dependencies to update_client, with the goal of creating an update_client Chrome component that encapsulates the details of talking with the update servers, downloading, and invoking installers of CRXs for both extensions and components. The dependencies should be: component_updater->update_client. This change just lays down some of the code that will be further used by update_client. No functionality is provided in this change. Also consider the overall goal as WIP; therefore, some of the naming and dependencies are not final. We want to have most of the code in place for future work, but want to minimize the changes to the existing production code and keep the refactoring mechanical for this change. BUG=450337 Review URL: https://codereview.chromium.org/808773005 Cr-Commit-Position: refs/heads/master@{#312986}
Diffstat (limited to 'components/update_client/crx_downloader.cc')
-rw-r--r--components/update_client/crx_downloader.cc157
1 files changed, 157 insertions, 0 deletions
diff --git a/components/update_client/crx_downloader.cc b/components/update_client/crx_downloader.cc
new file mode 100644
index 0000000..ecbf301
--- /dev/null
+++ b/components/update_client/crx_downloader.cc
@@ -0,0 +1,157 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/update_client/crx_downloader.h"
+
+#include "base/logging.h"
+#include "base/sequenced_task_runner.h"
+#include "base/single_thread_task_runner.h"
+#include "components/update_client/url_fetcher_downloader.h"
+
+#if defined(OS_WIN)
+#include "components/update_client/background_downloader_win.h"
+#endif
+
+namespace update_client {
+
+CrxDownloader::Result::Result()
+ : error(0), downloaded_bytes(-1), total_bytes(-1) {
+}
+
+CrxDownloader::DownloadMetrics::DownloadMetrics()
+ : downloader(kNone),
+ error(0),
+ downloaded_bytes(-1),
+ total_bytes(-1),
+ download_time_ms(0) {
+}
+
+// On Windows, the first downloader in the chain is a background downloader,
+// which uses the BITS service.
+CrxDownloader* CrxDownloader::Create(
+ bool is_background_download,
+ net::URLRequestContextGetter* context_getter,
+ scoped_refptr<base::SequencedTaskRunner> url_fetcher_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> background_task_runner) {
+ scoped_ptr<CrxDownloader> url_fetcher_downloader(
+ new UrlFetcherDownloader(scoped_ptr<CrxDownloader>().Pass(),
+ context_getter, url_fetcher_task_runner));
+#if defined(OS_WIN)
+ if (is_background_download) {
+ return new BackgroundDownloader(url_fetcher_downloader.Pass(),
+ context_getter, background_task_runner);
+ }
+#endif
+
+ return url_fetcher_downloader.release();
+}
+
+CrxDownloader::CrxDownloader(scoped_ptr<CrxDownloader> successor)
+ : successor_(successor.Pass()) {
+}
+
+CrxDownloader::~CrxDownloader() {
+}
+
+void CrxDownloader::set_progress_callback(
+ const ProgressCallback& progress_callback) {
+ progress_callback_ = progress_callback;
+}
+
+GURL CrxDownloader::url() const {
+ return current_url_ != urls_.end() ? *current_url_ : GURL();
+}
+
+const std::vector<CrxDownloader::DownloadMetrics>
+CrxDownloader::download_metrics() const {
+ if (!successor_)
+ return download_metrics_;
+
+ std::vector<DownloadMetrics> retval(successor_->download_metrics());
+ retval.insert(retval.begin(), download_metrics_.begin(),
+ download_metrics_.end());
+ return retval;
+}
+
+void CrxDownloader::StartDownloadFromUrl(
+ const GURL& url,
+ const DownloadCallback& download_callback) {
+ std::vector<GURL> urls;
+ urls.push_back(url);
+ StartDownload(urls, download_callback);
+}
+
+void CrxDownloader::StartDownload(const std::vector<GURL>& urls,
+ const DownloadCallback& download_callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (urls.empty()) {
+ // Make a result and complete the download with a generic error for now.
+ Result result;
+ result.error = -1;
+ download_callback.Run(result);
+ return;
+ }
+
+ // If the urls are mutated while this downloader is active, then the
+ // behavior is undefined in the sense that the outcome of the download could
+ // be inconsistent for the list of urls. At any rate, the |current_url_| is
+ // reset at this point, and the iterator will be valid in all conditions.
+ urls_ = urls;
+ current_url_ = urls_.begin();
+ download_callback_ = download_callback;
+
+ DoStartDownload(*current_url_);
+}
+
+void CrxDownloader::OnDownloadComplete(
+ bool is_handled,
+ const Result& result,
+ const DownloadMetrics& download_metrics) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ download_metrics_.push_back(download_metrics);
+
+ if (result.error) {
+ // If an error has occured, in general try the next url if there is any,
+ // then move on to the successor in the chain if there is any successor.
+ // If this downloader has received a 5xx error for the current url,
+ // as indicated by the |is_handled| flag, remove that url from the list of
+ // urls so the url is never retried. In both cases, move on to the
+ // next url.
+ if (!is_handled) {
+ ++current_url_;
+ } else {
+ current_url_ = urls_.erase(current_url_);
+ }
+
+ // Try downloading from another url from the list.
+ if (current_url_ != urls_.end()) {
+ DoStartDownload(*current_url_);
+ return;
+ }
+
+ // If there is another downloader that can accept this request, then hand
+ // the request over to it so that the successor can try the pruned list
+ // of urls. Otherwise, the request ends here since the current downloader
+ // has tried all urls and it can't fall back on any other downloader.
+ if (successor_ && !urls_.empty()) {
+ successor_->StartDownload(urls_, download_callback_);
+ return;
+ }
+ }
+
+ download_callback_.Run(result);
+}
+
+void CrxDownloader::OnDownloadProgress(const Result& result) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (progress_callback_.is_null())
+ return;
+
+ progress_callback_.Run(result);
+}
+
+} // namespace update_client