Home | History | Annotate | Download | only in updater
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_UPDATER_H_
      6 #define CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_UPDATER_H_
      7 
      8 #include <list>
      9 #include <map>
     10 #include <set>
     11 #include <stack>
     12 #include <string>
     13 
     14 #include "base/callback_forward.h"
     15 #include "base/compiler_specific.h"
     16 #include "base/files/file_path.h"
     17 #include "base/gtest_prod_util.h"
     18 #include "base/memory/scoped_ptr.h"
     19 #include "base/memory/weak_ptr.h"
     20 #include "base/time/time.h"
     21 #include "base/timer/timer.h"
     22 #include "chrome/browser/extensions/updater/extension_downloader_delegate.h"
     23 #include "chrome/browser/extensions/updater/manifest_fetch_data.h"
     24 #include "content/public/browser/notification_observer.h"
     25 #include "content/public/browser/notification_registrar.h"
     26 #include "url/gurl.h"
     27 
     28 class ExtensionServiceInterface;
     29 class ExtensionSet;
     30 class PrefService;
     31 class Profile;
     32 
     33 namespace extensions {
     34 
     35 class ExtensionDownloader;
     36 class ExtensionPrefs;
     37 class ExtensionUpdaterTest;
     38 
     39 // A class for doing auto-updates of installed Extensions. Used like this:
     40 //
     41 // ExtensionUpdater* updater = new ExtensionUpdater(my_extensions_service,
     42 //                                                  extension_prefs,
     43 //                                                  pref_service,
     44 //                                                  profile,
     45 //                                                  update_frequency_secs);
     46 // updater->Start();
     47 // ....
     48 // updater->Stop();
     49 class ExtensionUpdater : public ExtensionDownloaderDelegate,
     50                          public content::NotificationObserver {
     51  public:
     52   typedef base::Closure FinishedCallback;
     53 
     54   struct CheckParams {
     55     // Creates a default CheckParams instance that checks for all extensions.
     56     CheckParams();
     57     ~CheckParams();
     58 
     59     // The set of extensions that should be checked for updates. If empty
     60     // all extensions will be included in the update check.
     61     std::list<std::string> ids;
     62 
     63     // Normally extension updates get installed only when the extension is idle.
     64     // Setting this to true causes any updates that are found to be installed
     65     // right away.
     66     bool install_immediately;
     67 
     68     // Callback to call when the update check is complete. Can be null, if
     69     // you're not interested in when this happens.
     70     FinishedCallback callback;
     71   };
     72 
     73   // Holds a pointer to the passed |service|, using it for querying installed
     74   // extensions and installing updated ones. The |frequency_seconds| parameter
     75   // controls how often update checks are scheduled.
     76   ExtensionUpdater(ExtensionServiceInterface* service,
     77                    ExtensionPrefs* extension_prefs,
     78                    PrefService* prefs,
     79                    Profile* profile,
     80                    int frequency_seconds);
     81 
     82   virtual ~ExtensionUpdater();
     83 
     84   // Starts the updater running.  Should be called at most once.
     85   void Start();
     86 
     87   // Stops the updater running, cancelling any outstanding update manifest and
     88   // crx downloads. Does not cancel any in-progress installs.
     89   void Stop();
     90 
     91   // Posts a task to do an update check.  Does nothing if there is
     92   // already a pending task that has not yet run.
     93   void CheckSoon();
     94 
     95   // Starts an update check for the specified extension soon. If a check
     96   // is already running, or finished too recently without an update being
     97   // installed, this method returns false and the check won't be scheduled.
     98   bool CheckExtensionSoon(const std::string& extension_id,
     99                           const FinishedCallback& callback);
    100 
    101   // Starts an update check right now, instead of waiting for the next
    102   // regularly scheduled check or a pending check from CheckSoon().
    103   void CheckNow(const CheckParams& params);
    104 
    105   // Returns true iff CheckSoon() has been called but the update check
    106   // hasn't been performed yet.  This is used mostly by tests; calling
    107   // code should just call CheckSoon().
    108   bool WillCheckSoon() const;
    109 
    110   // Changes the params that are used for the automatic periodic update checks,
    111   // as well as for explicit calls to CheckSoon.
    112   void set_default_check_params(const CheckParams& params) {
    113     default_params_ = params;
    114   }
    115 
    116  private:
    117   friend class ExtensionUpdaterTest;
    118   friend class ExtensionUpdaterFileHandler;
    119 
    120   // FetchedCRXFile holds information about a CRX file we fetched to disk,
    121   // but have not yet installed.
    122   struct FetchedCRXFile {
    123     FetchedCRXFile();
    124     FetchedCRXFile(const std::string& id,
    125                    const base::FilePath& path,
    126                    const GURL& download_url,
    127                    const std::set<int>& request_ids);
    128     ~FetchedCRXFile();
    129 
    130     std::string extension_id;
    131     base::FilePath path;
    132     GURL download_url;
    133     std::set<int> request_ids;
    134   };
    135 
    136   struct InProgressCheck {
    137     InProgressCheck();
    138     ~InProgressCheck();
    139 
    140     bool install_immediately;
    141     FinishedCallback callback;
    142     // The ids of extensions that have in-progress update checks.
    143     std::list<std::string> in_progress_ids_;
    144   };
    145 
    146   struct ThrottleInfo;
    147 
    148   // Computes when to schedule the first update check.
    149   base::TimeDelta DetermineFirstCheckDelay();
    150 
    151   // Sets the timer to call TimerFired after roughly |target_delay| from now.
    152   // To help spread load evenly on servers, this method adds some random
    153   // jitter. It also saves the scheduled time so it can be reloaded on
    154   // browser restart.
    155   void ScheduleNextCheck(const base::TimeDelta& target_delay);
    156 
    157   // Add fetch records for extensions that are installed to the downloader,
    158   // ignoring |pending_ids| so the extension isn't fetched again.
    159   void AddToDownloader(const ExtensionSet* extensions,
    160                        const std::list<std::string>& pending_ids,
    161                        int request_id);
    162 
    163   // BaseTimer::ReceiverMethod callback.
    164   void TimerFired();
    165 
    166   // Posted by CheckSoon().
    167   void DoCheckSoon();
    168 
    169   // Implenentation of ExtensionDownloaderDelegate.
    170   virtual void OnExtensionDownloadFailed(
    171       const std::string& id,
    172       Error error,
    173       const PingResult& ping,
    174       const std::set<int>& request_ids) OVERRIDE;
    175 
    176   virtual void OnExtensionDownloadFinished(
    177       const std::string& id,
    178       const base::FilePath& path,
    179       const GURL& download_url,
    180       const std::string& version,
    181       const PingResult& ping,
    182       const std::set<int>& request_id) OVERRIDE;
    183 
    184   virtual bool GetPingDataForExtension(
    185       const std::string& id,
    186       ManifestFetchData::PingData* ping_data) OVERRIDE;
    187 
    188   virtual std::string GetUpdateUrlData(const std::string& id) OVERRIDE;
    189 
    190   virtual bool IsExtensionPending(const std::string& id) OVERRIDE;
    191 
    192   virtual bool GetExtensionExistingVersion(const std::string& id,
    193                                            std::string* version) OVERRIDE;
    194 
    195   void UpdatePingData(const std::string& id, const PingResult& ping_result);
    196 
    197   // Starts installing a crx file that has been fetched but not installed yet.
    198   void MaybeInstallCRXFile();
    199 
    200   // content::NotificationObserver implementation.
    201   virtual void Observe(int type,
    202                        const content::NotificationSource& source,
    203                        const content::NotificationDetails& details) OVERRIDE;
    204 
    205   // Send a notification that update checks are starting.
    206   void NotifyStarted();
    207 
    208   // Send a notification if we're finished updating.
    209   void NotifyIfFinished(int request_id);
    210 
    211   void ExtensionCheckFinished(const std::string& extension_id,
    212                               const FinishedCallback& callback);
    213 
    214   // Whether Start() has been called but not Stop().
    215   bool alive_;
    216 
    217   base::WeakPtrFactory<ExtensionUpdater> weak_ptr_factory_;
    218 
    219   // Pointer back to the service that owns this ExtensionUpdater.
    220   ExtensionServiceInterface* service_;
    221 
    222   // Fetches the crx files for the extensions that have an available update.
    223   scoped_ptr<ExtensionDownloader> downloader_;
    224 
    225   base::OneShotTimer<ExtensionUpdater> timer_;
    226   int frequency_seconds_;
    227   bool will_check_soon_;
    228 
    229   ExtensionPrefs* extension_prefs_;
    230   PrefService* prefs_;
    231   Profile* profile_;
    232 
    233   std::map<int, InProgressCheck> requests_in_progress_;
    234   int next_request_id_;
    235 
    236   // Observes CRX installs we initiate.
    237   content::NotificationRegistrar registrar_;
    238 
    239   // True when a CrxInstaller is doing an install.  Used in MaybeUpdateCrxFile()
    240   // to keep more than one install from running at once.
    241   bool crx_install_is_running_;
    242 
    243   // Fetched CRX files waiting to be installed.
    244   std::stack<FetchedCRXFile> fetched_crx_files_;
    245   FetchedCRXFile current_crx_file_;
    246 
    247   CheckParams default_params_;
    248 
    249   // Keeps track of when an extension tried to update itself, so we can throttle
    250   // checks to prevent too many requests from being made.
    251   std::map<std::string, ThrottleInfo> throttle_info_;
    252 
    253   DISALLOW_COPY_AND_ASSIGN(ExtensionUpdater);
    254 };
    255 
    256 }  // namespace extensions
    257 
    258 #endif  // CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_UPDATER_H_
    259