Home | History | Annotate | Download | only in component_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 #include "chrome/browser/component_updater/component_updater_configurator.h"
      6 
      7 #include <algorithm>
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/command_line.h"
     12 #include "base/compiler_specific.h"
     13 #include "base/strings/string_util.h"
     14 #include "base/win/windows_version.h"
     15 #include "build/build_config.h"
     16 #include "chrome/browser/component_updater/component_patcher.h"
     17 #include "chrome/common/chrome_switches.h"
     18 #include "net/url_request/url_request_context_getter.h"
     19 
     20 #if defined(OS_WIN)
     21 #include "chrome/browser/component_updater/component_patcher_win.h"
     22 #endif
     23 
     24 namespace {
     25 
     26 // Default time constants.
     27 const int kDelayOneMinute = 60;
     28 const int kDelayOneHour = kDelayOneMinute * 60;
     29 
     30 // Debug values you can pass to --component-updater=value1,value2.
     31 // Speed up component checking.
     32 const char kSwitchFastUpdate[] = "fast-update";
     33 
     34 // Add "testrequest=1" attribute to the update check request.
     35 const char kSwitchRequestParam[] = "test-request";
     36 
     37 // Disables pings. Pings are the requests sent to the update server that report
     38 // the success or the failure of component install or update attempts.
     39 extern const char kSwitchDisablePings[] = "disable-pings";
     40 
     41 // Sets the URL for updates.
     42 const char kSwitchUrlSource[] = "url-source";
     43 
     44 #define COMPONENT_UPDATER_SERVICE_ENDPOINT \
     45     "//clients2.google.com/service/update2"
     46 
     47 // The default url for the v3 protocol service endpoint. Can be
     48 // overridden with --component-updater=url-source=someurl.
     49 const char kDefaultUrlSource[] = "https:" COMPONENT_UPDATER_SERVICE_ENDPOINT;
     50 
     51 // The url to send the pings to.
     52 const char kPingUrl[] = "http:" COMPONENT_UPDATER_SERVICE_ENDPOINT;
     53 
     54 #if defined(OS_WIN)
     55 // Disables differential updates.
     56 const char kSwitchDisableDeltaUpdates[] = "disable-delta-updates";
     57 // Disables background downloads.
     58 const char kSwitchDisableBackgroundDownloads[] = "disable-background-downloads";
     59 #endif  // defined(OS_WIN)
     60 
     61 // Returns true if and only if |test| is contained in |vec|.
     62 bool HasSwitchValue(const std::vector<std::string>& vec, const char* test) {
     63   if (vec.empty())
     64     return 0;
     65   return (std::find(vec.begin(), vec.end(), test) != vec.end());
     66 }
     67 
     68 // If there is an element of |vec| of the form |test|=.*, returns the right-
     69 // hand side of that assignment. Otherwise, returns an empty string.
     70 // The right-hand side may contain additional '=' characters, allowing for
     71 // further nesting of switch arguments.
     72 std::string GetSwitchArgument(const std::vector<std::string>& vec,
     73                               const char* test) {
     74   if (vec.empty())
     75     return std::string();
     76   for (std::vector<std::string>::const_iterator it = vec.begin();
     77       it != vec.end();
     78       ++it) {
     79     const std::size_t found = it->find("=");
     80     if (found != std::string::npos) {
     81       if (it->substr(0, found) == test) {
     82         return it->substr(found + 1);
     83       }
     84     }
     85   }
     86   return std::string();
     87 }
     88 
     89 }  // namespace
     90 
     91 class ChromeConfigurator : public ComponentUpdateService::Configurator {
     92  public:
     93   ChromeConfigurator(const CommandLine* cmdline,
     94                      net::URLRequestContextGetter* url_request_getter);
     95 
     96   virtual ~ChromeConfigurator() {}
     97 
     98   virtual int InitialDelay() OVERRIDE;
     99   virtual int NextCheckDelay() OVERRIDE;
    100   virtual int StepDelay() OVERRIDE;
    101   virtual int StepDelayMedium() OVERRIDE;
    102   virtual int MinimumReCheckWait() OVERRIDE;
    103   virtual int OnDemandDelay() OVERRIDE;
    104   virtual GURL UpdateUrl() OVERRIDE;
    105   virtual GURL PingUrl() OVERRIDE;
    106   virtual std::string ExtraRequestParams() OVERRIDE;
    107   virtual size_t UrlSizeLimit() OVERRIDE;
    108   virtual net::URLRequestContextGetter* RequestContext() OVERRIDE;
    109   virtual bool InProcess() OVERRIDE;
    110   virtual ComponentPatcher* CreateComponentPatcher() OVERRIDE;
    111   virtual bool DeltasEnabled() const OVERRIDE;
    112   virtual bool UseBackgroundDownloader() const OVERRIDE;
    113 
    114  private:
    115   net::URLRequestContextGetter* url_request_getter_;
    116   std::string extra_info_;
    117   std::string url_source_;
    118   bool fast_update_;
    119   bool pings_enabled_;
    120   bool deltas_enabled_;
    121   bool background_downloads_enabled_;
    122 };
    123 
    124 ChromeConfigurator::ChromeConfigurator(const CommandLine* cmdline,
    125     net::URLRequestContextGetter* url_request_getter)
    126       : url_request_getter_(url_request_getter),
    127         fast_update_(false),
    128         pings_enabled_(false),
    129         deltas_enabled_(false),
    130         background_downloads_enabled_(false) {
    131   // Parse comma-delimited debug flags.
    132   std::vector<std::string> switch_values;
    133   Tokenize(cmdline->GetSwitchValueASCII(switches::kComponentUpdater),
    134       ",", &switch_values);
    135   fast_update_ = HasSwitchValue(switch_values, kSwitchFastUpdate);
    136   pings_enabled_ = !HasSwitchValue(switch_values, kSwitchDisablePings);
    137 #if defined(OS_WIN)
    138   deltas_enabled_ = !HasSwitchValue(switch_values, kSwitchDisableDeltaUpdates);
    139   background_downloads_enabled_ =
    140       !HasSwitchValue(switch_values, kSwitchDisableBackgroundDownloads);
    141 #else
    142   deltas_enabled_ = false;
    143   background_downloads_enabled_ = false;
    144 #endif
    145 
    146   url_source_ = GetSwitchArgument(switch_values, kSwitchUrlSource);
    147   if (url_source_.empty()) {
    148     url_source_ = kDefaultUrlSource;
    149   }
    150 
    151   if (HasSwitchValue(switch_values, kSwitchRequestParam))
    152     extra_info_ += "testrequest=\"1\"";
    153 }
    154 
    155 int ChromeConfigurator::InitialDelay() {
    156   return fast_update_ ? 1 : (6 * kDelayOneMinute);
    157 }
    158 
    159 int ChromeConfigurator::NextCheckDelay() {
    160   return fast_update_ ? 3 : (6 * kDelayOneHour);
    161 }
    162 
    163 int ChromeConfigurator::StepDelayMedium() {
    164   return fast_update_ ? 3 : (15 * kDelayOneMinute);
    165 }
    166 
    167 int ChromeConfigurator::StepDelay() {
    168   return fast_update_ ? 1 : 1;
    169 }
    170 
    171 int ChromeConfigurator::MinimumReCheckWait() {
    172   return fast_update_ ? 30 : (6 * kDelayOneHour);
    173 }
    174 
    175 int ChromeConfigurator::OnDemandDelay() {
    176   return fast_update_ ? 2 : (30 * kDelayOneMinute);
    177 }
    178 
    179 GURL ChromeConfigurator::UpdateUrl() {
    180   return GURL(url_source_);
    181 }
    182 
    183 GURL ChromeConfigurator::PingUrl() {
    184   return pings_enabled_ ? GURL(kPingUrl) : GURL();
    185 }
    186 
    187 std::string ChromeConfigurator::ExtraRequestParams() {
    188   return extra_info_;
    189 }
    190 
    191 size_t ChromeConfigurator::UrlSizeLimit() {
    192   return 1024ul;
    193 }
    194 
    195 net::URLRequestContextGetter* ChromeConfigurator::RequestContext() {
    196   return url_request_getter_;
    197 }
    198 
    199 bool ChromeConfigurator::InProcess() {
    200   return false;
    201 }
    202 
    203 ComponentPatcher* ChromeConfigurator::CreateComponentPatcher() {
    204 #if defined(OS_WIN)
    205   return new ComponentPatcherWin();
    206 #else
    207   return new ComponentPatcherCrossPlatform();
    208 #endif
    209 }
    210 
    211 bool ChromeConfigurator::DeltasEnabled() const {
    212   return deltas_enabled_;
    213 }
    214 
    215 bool ChromeConfigurator::UseBackgroundDownloader() const {
    216   return background_downloads_enabled_;
    217 }
    218 
    219 ComponentUpdateService::Configurator* MakeChromeComponentUpdaterConfigurator(
    220     const CommandLine* cmdline, net::URLRequestContextGetter* context_getter) {
    221   return new ChromeConfigurator(cmdline, context_getter);
    222 }
    223