| OLD | NEW | 
|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/crx_downloader.h" | 5 #include "chrome/browser/component_updater/crx_downloader.h" | 
| 6 #include "chrome/browser/component_updater/url_fetcher_downloader.h" | 6 #include "chrome/browser/component_updater/url_fetcher_downloader.h" | 
| 7 #include "content/public/browser/browser_thread.h" | 7 #include "content/public/browser/browser_thread.h" | 
| 8 | 8 | 
|  | 9 #if defined(OS_WIN) | 
|  | 10 #include "chrome/browser/component_updater/background_downloader_win.h" | 
|  | 11 #endif | 
|  | 12 | 
| 9 using content::BrowserThread; | 13 using content::BrowserThread; | 
| 10 | 14 | 
| 11 namespace component_updater { | 15 namespace component_updater { | 
| 12 | 16 | 
| 13 // This factory method builds the chain of downloaders. Currently, there is only | 17 // On Windows, the first downloader in the chain is a background downloader, | 
| 14 // a url fetcher downloader but more downloaders can be chained up to handle | 18 // which uses the BITS service. | 
| 15 // the request. |  | 
| 16 CrxDownloader* CrxDownloader::Create( | 19 CrxDownloader* CrxDownloader::Create( | 
|  | 20     bool is_background_download, | 
| 17     net::URLRequestContextGetter* context_getter, | 21     net::URLRequestContextGetter* context_getter, | 
| 18     scoped_refptr<base::SequencedTaskRunner> task_runner, | 22     scoped_refptr<base::SequencedTaskRunner> task_runner, | 
| 19     const DownloadCallback& download_callback) { | 23     const DownloadCallback& download_callback) { | 
| 20   CrxDownloader* crx_downloader = | 24   scoped_ptr<CrxDownloader> url_fetcher_downloader( | 
| 21       new UrlFetcherDownloader(context_getter, task_runner); | 25       new UrlFetcherDownloader(scoped_ptr<CrxDownloader>().Pass(), | 
|  | 26                                context_getter, | 
|  | 27                                task_runner, | 
|  | 28                                download_callback)); | 
|  | 29 #if defined (OS_WIN) | 
|  | 30   if (is_background_download) { | 
|  | 31     return new BackgroundDownloader(url_fetcher_downloader.Pass(), | 
|  | 32                                     context_getter, | 
|  | 33                                     task_runner, | 
|  | 34                                     download_callback); | 
|  | 35   } | 
|  | 36 #endif | 
| 22 | 37 | 
| 23   crx_downloader->download_callback_ = download_callback; | 38   return url_fetcher_downloader.release(); | 
| 24 |  | 
| 25   return crx_downloader; |  | 
| 26 } | 39 } | 
| 27 | 40 | 
| 28 CrxDownloader::CrxDownloader() : current_url_(0) { | 41 CrxDownloader::CrxDownloader( | 
| 29   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 42     scoped_ptr<CrxDownloader> successor, | 
|  | 43     const DownloadCallback& download_callback) | 
|  | 44     : successor_(successor.Pass()), | 
|  | 45       download_callback_(download_callback), | 
|  | 46       is_active_(false) { | 
|  | 47       DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
| 30 } | 48 } | 
| 31 | 49 | 
| 32 CrxDownloader::~CrxDownloader() { | 50 CrxDownloader::~CrxDownloader() { | 
| 33 } | 51 } | 
| 34 | 52 | 
| 35 void CrxDownloader::StartDownloadFromUrl(const GURL& url) { | 53 bool CrxDownloader::StartDownloadFromUrl(const GURL& url) { | 
| 36   std::vector<GURL> urls; | 54   std::vector<GURL> urls; | 
| 37   urls.push_back(url); | 55   urls.push_back(url); | 
| 38   StartDownload(urls); | 56   return StartDownload(urls); | 
| 39 } | 57 } | 
| 40 | 58 | 
| 41 void CrxDownloader::StartDownload(const std::vector<GURL>& urls) { | 59 bool CrxDownloader::StartDownload(const std::vector<GURL>& urls) { | 
| 42   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 60   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
| 43 | 61 | 
| 44   if (urls.empty()) | 62   if (urls.empty() || is_active_) | 
| 45     return; | 63     return false; | 
|  | 64 | 
|  | 65   // |is_active_| defensively protects against mutating the container of urls | 
|  | 66   // once the download has started. | 
|  | 67   is_active_ =  true; | 
| 46 | 68 | 
| 47   urls_ = urls; | 69   urls_ = urls; | 
|  | 70   current_url_ = urls_.begin(); | 
| 48 | 71 | 
| 49   current_url_ = 0; | 72   DoStartDownload(*current_url_); | 
| 50   DoStartDownload(urls[current_url_]); | 73   return true; | 
| 51 } | 74 } | 
| 52 | 75 | 
| 53 // Handles the fallback in the case of multiple urls and routing of the | 76 void CrxDownloader::OnDownloadComplete(bool is_handled, const Result& result) { | 
| 54 // download to the following successor in the chain. |  | 
| 55 void CrxDownloader::OnDownloadComplete(bool is_handled, |  | 
| 56                                        int error, |  | 
| 57                                        const base::FilePath& response) { |  | 
| 58   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 77   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
| 59 | 78 | 
| 60   // If an error has occured, try the next url if possible, then move on | 79   // If an error has occured, try the next url if there is any, then move on | 
| 61   // to the successor in the chain, if the request has not been handled | 80   // to the successor in the chain if the request has not been handled. | 
| 62   if (error) { | 81   // In the case of an error, and if the downloader has received a 5xx error, as | 
| 63     ++current_url_; | 82   // indicated by the |is_handled| flag, remove that url from the list of | 
| 64     if (current_url_ != urls_.size()) { | 83   // urls so the url is not handed over to the successor. | 
| 65       DoStartDownload(urls_[current_url_]); | 84   if (result.error) { | 
|  | 85     if (!is_handled) | 
|  | 86       ++current_url_; | 
|  | 87     else | 
|  | 88       current_url_ = urls_.erase(current_url_); | 
|  | 89 | 
|  | 90     if (current_url_ != urls_.end()) { | 
|  | 91       DoStartDownload(*current_url_); | 
| 66       return; | 92       return; | 
| 67     } | 93     } | 
| 68 | 94 | 
| 69     if (!is_handled && successor_) { | 95     if (!is_handled && successor_) { | 
| 70       successor_->StartDownload(urls_); | 96       successor_->StartDownload(urls_); | 
| 71       return; | 97       return; | 
| 72     } | 98     } | 
| 73   } | 99   } | 
| 74 | 100 | 
| 75   DCHECK(is_handled || !error || !successor_); | 101   DCHECK(is_handled || !result.error || !successor_); | 
| 76 | 102 | 
| 77   download_callback_.Run(error, response); | 103   download_callback_.Run(result); | 
| 78 } | 104 } | 
| 79 | 105 | 
| 80 }  // namespace component_updater | 106 }  // namespace component_updater | 
| 81 | 107 | 
| OLD | NEW | 
|---|