Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / webui / chromeos / login / network_state_informer.cc
blob8023002f20927efbfb8ea46d0390bd3b50e6bf4b
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.
5 #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/chromeos/login/screens/network_error.h"
13 #include "chrome/browser/chromeos/net/proxy_config_handler.h"
14 #include "chromeos/network/network_state.h"
15 #include "chromeos/network/network_state_handler.h"
16 #include "components/proxy_config/proxy_config_dictionary.h"
17 #include "components/proxy_config/proxy_prefs.h"
18 #include "net/proxy/proxy_config.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h"
21 namespace chromeos {
23 namespace {
25 const char kNetworkStateOffline[] = "offline";
26 const char kNetworkStateOnline[] = "online";
27 const char kNetworkStateCaptivePortal[] = "behind captive portal";
28 const char kNetworkStateConnecting[] = "connecting";
29 const char kNetworkStateProxyAuthRequired[] = "proxy auth required";
31 bool HasDefaultNetworkProxyConfigured() {
32 const NetworkState* network =
33 NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
34 if (!network)
35 return false;
36 onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
37 scoped_ptr<ProxyConfigDictionary> proxy_dict =
38 proxy_config::GetProxyConfigForNetwork(
39 NULL, g_browser_process->local_state(), *network, &onc_source);
40 ProxyPrefs::ProxyMode mode;
41 return (proxy_dict && proxy_dict->GetMode(&mode) &&
42 mode == ProxyPrefs::MODE_FIXED_SERVERS);
45 NetworkStateInformer::State GetStateForDefaultNetwork() {
46 const NetworkState* network =
47 NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
48 if (!network)
49 return NetworkStateInformer::OFFLINE;
51 if (NetworkPortalDetector::Get()->IsEnabled()) {
52 NetworkPortalDetector::CaptivePortalState state =
53 NetworkPortalDetector::Get()->GetCaptivePortalState(network->guid());
54 NetworkPortalDetector::CaptivePortalStatus status = state.status;
55 if (status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN &&
56 NetworkState::StateIsConnecting(network->connection_state())) {
57 return NetworkStateInformer::CONNECTING;
59 // For proxy-less networks rely on shill's online state if
60 // NetworkPortalDetector's state of current network is unknown.
61 if (status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE ||
62 (status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN &&
63 !HasDefaultNetworkProxyConfigured() &&
64 network->connection_state() == shill::kStateOnline)) {
65 return NetworkStateInformer::ONLINE;
67 if (status ==
68 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED &&
69 HasDefaultNetworkProxyConfigured()) {
70 return NetworkStateInformer::PROXY_AUTH_REQUIRED;
72 if (status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL ||
73 (status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN &&
74 network->is_captive_portal()))
75 return NetworkStateInformer::CAPTIVE_PORTAL;
76 } else {
77 if (NetworkState::StateIsConnecting(network->connection_state()))
78 return NetworkStateInformer::CONNECTING;
79 if (network->connection_state() == shill::kStateOnline)
80 return NetworkStateInformer::ONLINE;
81 if (network->is_captive_portal())
82 return NetworkStateInformer::CAPTIVE_PORTAL;
84 return NetworkStateInformer::OFFLINE;
87 } // namespace
89 NetworkStateInformer::NetworkStateInformer()
90 : state_(OFFLINE),
91 weak_ptr_factory_(this) {
94 NetworkStateInformer::~NetworkStateInformer() {
95 if (NetworkHandler::IsInitialized()) {
96 NetworkHandler::Get()->network_state_handler()->RemoveObserver(
97 this, FROM_HERE);
99 NetworkPortalDetector::Get()->RemoveObserver(this);
102 void NetworkStateInformer::Init() {
103 UpdateState();
104 NetworkHandler::Get()->network_state_handler()->AddObserver(
105 this, FROM_HERE);
107 NetworkPortalDetector::Get()->AddAndFireObserver(this);
109 registrar_.Add(this,
110 chrome::NOTIFICATION_LOGIN_PROXY_CHANGED,
111 content::NotificationService::AllSources());
112 registrar_.Add(this,
113 chrome::NOTIFICATION_SESSION_STARTED,
114 content::NotificationService::AllSources());
117 void NetworkStateInformer::AddObserver(NetworkStateInformerObserver* observer) {
118 if (!observers_.HasObserver(observer))
119 observers_.AddObserver(observer);
122 void NetworkStateInformer::RemoveObserver(
123 NetworkStateInformerObserver* observer) {
124 observers_.RemoveObserver(observer);
127 void NetworkStateInformer::DefaultNetworkChanged(const NetworkState* network) {
128 UpdateStateAndNotify();
131 void NetworkStateInformer::OnPortalDetectionCompleted(
132 const NetworkState* network,
133 const NetworkPortalDetector::CaptivePortalState& state) {
134 UpdateStateAndNotify();
137 void NetworkStateInformer::Observe(
138 int type,
139 const content::NotificationSource& source,
140 const content::NotificationDetails& details) {
141 if (type == chrome::NOTIFICATION_SESSION_STARTED)
142 registrar_.RemoveAll();
143 else if (type == chrome::NOTIFICATION_LOGIN_PROXY_CHANGED)
144 SendStateToObservers(NetworkError::ERROR_REASON_PROXY_CONFIG_CHANGED);
145 else
146 NOTREACHED() << "Unknown notification: " << type;
149 void NetworkStateInformer::OnPortalDetected() {
150 UpdateStateAndNotify();
153 // static
154 const char* NetworkStateInformer::StatusString(State state) {
155 switch (state) {
156 case OFFLINE:
157 return kNetworkStateOffline;
158 case ONLINE:
159 return kNetworkStateOnline;
160 case CAPTIVE_PORTAL:
161 return kNetworkStateCaptivePortal;
162 case CONNECTING:
163 return kNetworkStateConnecting;
164 case PROXY_AUTH_REQUIRED:
165 return kNetworkStateProxyAuthRequired;
166 default:
167 NOTREACHED();
168 return NULL;
172 bool NetworkStateInformer::UpdateState() {
173 const NetworkState* default_network =
174 NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
175 State new_state = GetStateForDefaultNetwork();
176 std::string new_network_path;
177 std::string new_network_type;
178 if (default_network) {
179 new_network_path = default_network->path();
180 new_network_type = default_network->type();
183 bool updated = (new_state != state_) ||
184 (new_network_path != network_path_) ||
185 (new_network_type != network_type_);
186 state_ = new_state;
187 network_path_ = new_network_path;
188 network_type_ = new_network_type;
190 if (updated && state_ == ONLINE) {
191 FOR_EACH_OBSERVER(NetworkStateInformerObserver, observers_,
192 OnNetworkReady());
195 return updated;
198 void NetworkStateInformer::UpdateStateAndNotify() {
199 if (UpdateState())
200 SendStateToObservers(NetworkError::ERROR_REASON_NETWORK_STATE_CHANGED);
201 else
202 SendStateToObservers(NetworkError::ERROR_REASON_UPDATE);
205 void NetworkStateInformer::SendStateToObservers(
206 NetworkError::ErrorReason reason) {
207 FOR_EACH_OBSERVER(NetworkStateInformerObserver, observers_,
208 UpdateState(reason));
211 } // namespace chromeos