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