Home | History | Annotate | Download | only in chromeos
      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 #include "chrome/browser/chromeos/ui_proxy_config_service.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/values.h"
     10 #include "chrome/browser/chromeos/net/proxy_config_handler.h"
     11 #include "chrome/browser/chromeos/proxy_config_service_impl.h"
     12 #include "chromeos/network/favorite_state.h"
     13 #include "chromeos/network/network_state_handler.h"
     14 #include "grit/generated_resources.h"
     15 #include "net/proxy/proxy_config.h"
     16 
     17 namespace chromeos {
     18 
     19 namespace {
     20 
     21 const char* ModeToString(UIProxyConfig::Mode mode) {
     22   switch (mode) {
     23     case UIProxyConfig::MODE_DIRECT:
     24       return "direct";
     25     case UIProxyConfig::MODE_AUTO_DETECT:
     26       return "auto-detect";
     27     case UIProxyConfig::MODE_PAC_SCRIPT:
     28       return "pacurl";
     29     case UIProxyConfig::MODE_SINGLE_PROXY:
     30       return "single-proxy";
     31     case UIProxyConfig::MODE_PROXY_PER_SCHEME:
     32       return "proxy-per-scheme";
     33   }
     34   NOTREACHED() << "Unrecognized mode type";
     35   return "";
     36 }
     37 
     38 // Writes the proxy config of |network| to |proxy_config|.  Sets |onc_source| to
     39 // the source of this configuration. Returns false if no proxy was configured
     40 // for this network.
     41 bool GetProxyConfig(const PrefService* profile_prefs,
     42                     const PrefService* local_state_prefs,
     43                     const FavoriteState& network,
     44                     net::ProxyConfig* proxy_config,
     45                     onc::ONCSource* onc_source) {
     46   scoped_ptr<ProxyConfigDictionary> proxy_dict =
     47       proxy_config::GetProxyConfigForFavoriteNetwork(
     48           profile_prefs, local_state_prefs, network, onc_source);
     49   if (!proxy_dict)
     50     return false;
     51   return PrefProxyConfigTrackerImpl::PrefConfigToNetConfig(*proxy_dict,
     52                                                            proxy_config);
     53 }
     54 
     55 // Returns true if proxy settings from |onc_source| are editable.
     56 bool IsNetworkProxySettingsEditable(const onc::ONCSource onc_source) {
     57   return onc_source != onc::ONC_SOURCE_DEVICE_POLICY &&
     58          onc_source != onc::ONC_SOURCE_USER_POLICY;
     59 }
     60 
     61 }  // namespace
     62 
     63 UIProxyConfigService::UIProxyConfigService()
     64     : profile_prefs_(NULL), local_state_prefs_(NULL) {
     65 }
     66 
     67 UIProxyConfigService::~UIProxyConfigService() {
     68 }
     69 
     70 void UIProxyConfigService::SetPrefs(PrefService* profile_prefs,
     71                                     PrefService* local_state_prefs) {
     72   profile_prefs_ = profile_prefs;
     73   local_state_prefs_ = local_state_prefs;
     74 }
     75 
     76 void UIProxyConfigService::SetCurrentNetwork(
     77     const std::string& current_network) {
     78   current_ui_network_ = current_network;
     79 }
     80 
     81 void UIProxyConfigService::UpdateFromPrefs() {
     82   const FavoriteState* network = NULL;
     83   if (!current_ui_network_.empty()) {
     84     network = NetworkHandler::Get()->network_state_handler()->GetFavoriteState(
     85         current_ui_network_);
     86     LOG_IF(ERROR, !network) << "Couldn't find FavoriteState for network "
     87                             << current_ui_network_;
     88   }
     89   if (!network) {
     90     current_ui_network_.clear();
     91     current_ui_config_ = UIProxyConfig();
     92     return;
     93   }
     94 
     95   DetermineEffectiveConfig(*network);
     96   VLOG(1) << "Current ui network: " << network->name() << ", "
     97           << ModeToString(current_ui_config_.mode) << ", "
     98           << ProxyPrefs::ConfigStateToDebugString(current_ui_config_.state)
     99           << ", modifiable:" << current_ui_config_.user_modifiable;
    100 }
    101 
    102 void UIProxyConfigService::GetProxyConfig(UIProxyConfig* config) const {
    103   *config = current_ui_config_;
    104 }
    105 
    106 void UIProxyConfigService::SetProxyConfig(const UIProxyConfig& config) {
    107   current_ui_config_ = config;
    108   if (current_ui_network_.empty())
    109     return;
    110 
    111   const FavoriteState* network =
    112       NetworkHandler::Get()->network_state_handler()->GetFavoriteState(
    113           current_ui_network_);
    114   if (!network) {
    115     LOG(ERROR) << "Couldn't find FavoriteState for network "
    116                << current_ui_network_;
    117     return;
    118   }
    119 
    120   // Store config for this network.
    121   scoped_ptr<base::DictionaryValue> proxy_config_value(
    122       config.ToPrefProxyConfig());
    123   ProxyConfigDictionary proxy_config_dict(proxy_config_value.get());
    124 
    125   VLOG(1) << "Set proxy for " << current_ui_network_
    126           << " to " << *proxy_config_value;
    127 
    128   proxy_config::SetProxyConfigForFavoriteNetwork(proxy_config_dict, *network);
    129   current_ui_config_.state = ProxyPrefs::CONFIG_SYSTEM;
    130 }
    131 
    132 void UIProxyConfigService::DetermineEffectiveConfig(
    133     const FavoriteState& network) {
    134   DCHECK(local_state_prefs_);
    135 
    136   // The pref service to read proxy settings that apply to all networks.
    137   // Settings from the profile overrule local state.
    138   PrefService* top_pref_service =
    139       profile_prefs_ ? profile_prefs_ : local_state_prefs_;
    140 
    141   // Get prefs proxy config if available.
    142   net::ProxyConfig pref_config;
    143   ProxyPrefs::ConfigState pref_state = ProxyConfigServiceImpl::ReadPrefConfig(
    144       top_pref_service, &pref_config);
    145 
    146   // Get network proxy config if available.
    147   net::ProxyConfig network_config;
    148   net::ProxyConfigService::ConfigAvailability network_availability =
    149       net::ProxyConfigService::CONFIG_UNSET;
    150   onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
    151   if (chromeos::GetProxyConfig(profile_prefs_,
    152                                local_state_prefs_,
    153                                network,
    154                                &network_config,
    155                                &onc_source)) {
    156     // Network is private or shared with user using shared proxies.
    157     VLOG(1) << this << ": using proxy of network: " << network.path();
    158     network_availability = net::ProxyConfigService::CONFIG_VALID;
    159   }
    160 
    161   // Determine effective proxy config, either from prefs or network.
    162   ProxyPrefs::ConfigState effective_config_state;
    163   net::ProxyConfig effective_config;
    164   ProxyConfigServiceImpl::GetEffectiveProxyConfig(
    165       pref_state, pref_config,
    166       network_availability, network_config, false,
    167       &effective_config_state, &effective_config);
    168 
    169   // Store effective proxy into |current_ui_config_|.
    170   current_ui_config_.FromNetProxyConfig(effective_config);
    171   current_ui_config_.state = effective_config_state;
    172   if (ProxyConfigServiceImpl::PrefPrecedes(effective_config_state)) {
    173     current_ui_config_.user_modifiable = false;
    174   } else if (!IsNetworkProxySettingsEditable(onc_source)) {
    175     current_ui_config_.state = ProxyPrefs::CONFIG_POLICY;
    176     current_ui_config_.user_modifiable = false;
    177   } else {
    178     current_ui_config_.user_modifiable = !ProxyConfigServiceImpl::IgnoreProxy(
    179         profile_prefs_, network.profile_path(), onc_source);
    180   }
    181 }
    182 
    183 }  // namespace chromeos
    184