Home | History | Annotate | Download | only in component_updater
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_COMPONENT_UPDATER_CRX_DOWNLOADER_H_
      6 #define CHROME_BROWSER_COMPONENT_UPDATER_CRX_DOWNLOADER_H_
      7 
      8 #include <vector>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/callback.h"
     12 #include "base/files/file_path.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/sequenced_task_runner.h"
     16 #include "url/gurl.h"
     17 
     18 namespace net {
     19 class URLRequestContextGetter;
     20 }
     21 
     22 namespace component_updater {
     23 
     24 // Defines a download interface for downloading components, with retrying on
     25 // fallback urls in case of errors. This class implements a chain of
     26 // responsibility design pattern. It can give successors in the chain a chance
     27 // to handle a download request, until one of them succeeds, or there are no
     28 // more urls or successors to try. A callback is always called at the end of
     29 // the download, one time only.
     30 // When multiple urls and downloaders exists, first all the urls are tried, in
     31 // the order they are provided in the StartDownload function argument. After
     32 // that, the download request is routed to the next downloader in the chain.
     33 // The members of this class expect to be called from the UI thread only.
     34 class CrxDownloader {
     35  public:
     36   struct DownloadMetrics {
     37     enum Downloader { kNone = 0, kUrlFetcher, kBits };
     38 
     39     DownloadMetrics();
     40 
     41     GURL url;
     42 
     43     Downloader downloader;
     44 
     45     int error;
     46 
     47     int64 downloaded_bytes;  // -1 means that the byte count is unknown.
     48     int64 total_bytes;
     49 
     50     uint64 download_time_ms;
     51   };
     52 
     53   // Contains the progress or the outcome of the download.
     54   struct Result {
     55     Result();
     56 
     57     // Download error: 0 indicates success.
     58     int error;
     59 
     60     // Path of the downloaded file if the download was successful.
     61     base::FilePath response;
     62 
     63     // Number of bytes actually downloaded, not including the bytes downloaded
     64     // as a result of falling back on urls.
     65     int64 downloaded_bytes;
     66 
     67     // Number of bytes expected to be downloaded.
     68     int64 total_bytes;
     69   };
     70 
     71   // The callback fires only once, regardless of how many urls are tried, and
     72   // how many successors in the chain of downloaders have handled the
     73   // download. The callback interface can be extended if needed to provide
     74   // more visibility into how the download has been handled, including
     75   // specific error codes and download metrics.
     76   typedef base::Callback<void(const Result& result)> DownloadCallback;
     77 
     78   // The callback may fire 0 or many times during a download. Since this
     79   // class implements a chain of responsibility, the callback can fire for
     80   // different urls and different downloaders. The number of actual downloaded
     81   // bytes is not guaranteed to monotonically increment over time.
     82   typedef base::Callback<void(const Result& result)> ProgressCallback;
     83 
     84   // Factory method to create an instance of this class and build the
     85   // chain of responsibility. |is_background_download| specifies that a
     86   // background downloader be used, if the platform supports it.
     87   static CrxDownloader* Create(
     88       bool is_background_download,
     89       net::URLRequestContextGetter* context_getter,
     90       scoped_refptr<base::SequencedTaskRunner> task_runner);
     91   virtual ~CrxDownloader();
     92 
     93   void set_progress_callback(const ProgressCallback& progress_callback);
     94 
     95   // Starts the download. One instance of the class handles one download only.
     96   // One instance of CrxDownloader can only be started once, otherwise the
     97   // behavior is undefined. The callback gets invoked if the download can't
     98   // be started.
     99   void StartDownloadFromUrl(const GURL& url,
    100                             const DownloadCallback& download_callback);
    101   void StartDownload(const std::vector<GURL>& urls,
    102                      const DownloadCallback& download_callback);
    103 
    104   const std::vector<DownloadMetrics> download_metrics() const;
    105 
    106  protected:
    107   explicit CrxDownloader(scoped_ptr<CrxDownloader> successor);
    108 
    109   // Handles the fallback in the case of multiple urls and routing of the
    110   // download to the following successor in the chain. Derived classes must call
    111   // this function after each attempt at downloading the urls provided
    112   // in the StartDownload function.
    113   // In case of errors, |is_handled| indicates that a server side error has
    114   // occured for the current url and the url should not be retried down
    115   // the chain to avoid DDOS of the server. This url will be removed from the
    116   // list of url and never tried again.
    117   void OnDownloadComplete(bool is_handled,
    118                           const Result& result,
    119                           const DownloadMetrics& download_metrics);
    120 
    121   // Calls the callback when progress is made.
    122   void OnDownloadProgress(const Result& result);
    123 
    124   // Returns the url which is currently being downloaded from.
    125   GURL url() const;
    126 
    127  private:
    128   virtual void DoStartDownload(const GURL& url) = 0;
    129 
    130   std::vector<GURL> urls_;
    131   scoped_ptr<CrxDownloader> successor_;
    132   DownloadCallback download_callback_;
    133   ProgressCallback progress_callback_;
    134 
    135   std::vector<GURL>::iterator current_url_;
    136 
    137   std::vector<DownloadMetrics> download_metrics_;
    138 
    139   DISALLOW_COPY_AND_ASSIGN(CrxDownloader);
    140 };
    141 
    142 }  // namespace component_updater
    143 
    144 #endif  // CHROME_BROWSER_COMPONENT_UPDATER_CRX_DOWNLOADER_H_
    145