Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / chromeos / login / network_state_informer.cc
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/ui/webui/chromeos/login/network_state_informer.h"
6
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/net/proxy_config_handler.h"
13 #include "chrome/browser/prefs/proxy_config_dictionary.h"
14 #include "chrome/browser/prefs/proxy_prefs.h"
15 #include "chromeos/network/network_state.h"
16 #include "chromeos/network/network_state_handler.h"
17 #include "net/proxy/proxy_config.h"
18 #include "third_party/cros_system_api/dbus/service_constants.h"
19
20 namespace chromeos {
21
22 namespace {
23
24 const char kNetworkStateOffline[] = "offline";
25 const char kNetworkStateOnline[] = "online";
26 const char kNetworkStateCaptivePortal[] = "behind captive portal";
27 const char kNetworkStateConnecting[] = "connecting";
28 const char kNetworkStateProxyAuthRequired[] = "proxy auth required";
29
30 bool HasDefaultNetworkProxyConfigured() {
31   const NetworkState* network =
32       NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
33   if (!network)
34     return false;
35   onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
36   scoped_ptr<ProxyConfigDictionary> proxy_dict =
37       proxy_config::GetProxyConfigForNetwork(
38           NULL, g_browser_process->local_state(), *network, &onc_source);
39   ProxyPrefs::ProxyMode mode;
40   return (proxy_dict && proxy_dict->GetMode(&mode) &&
41           mode == ProxyPrefs::MODE_FIXED_SERVERS);
42 }
43
44 NetworkStateInformer::State GetStateForDefaultNetwork() {
45   const NetworkState* network =
46       NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
47   if (!network)
48     return NetworkStateInformer::OFFLINE;
49
50   if (NetworkPortalDetector::Get()->IsEnabled()) {
51     NetworkPortalDetector::CaptivePortalState state =
52         NetworkPortalDetector::Get()->GetCaptivePortalState(network->guid());
53     NetworkPortalDetector::CaptivePortalStatus status = state.status;
54     if (status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN &&
55         NetworkState::StateIsConnecting(network->connection_state())) {
56       return NetworkStateInformer::CONNECTING;
57     }
58     // For proxy-less networks rely on shill's online state if
59     // NetworkPortalDetector's state of current network is unknown.
60     if (status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE ||
61         (status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN &&
62          !HasDefaultNetworkProxyConfigured() &&
63          network->connection_state() == shill::kStateOnline)) {
64       return NetworkStateInformer::ONLINE;
65     }
66     if (status ==
67             NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED &&
68         HasDefaultNetworkProxyConfigured()) {
69       return NetworkStateInformer::PROXY_AUTH_REQUIRED;
70     }
71     if (status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL ||
72         (status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN &&
73          network->connection_state() == shill::kStatePortal))
74       return NetworkStateInformer::CAPTIVE_PORTAL;
75   } else {
76     if (NetworkState::StateIsConnecting(network->connection_state()))
77       return NetworkStateInformer::CONNECTING;
78     if (network->connection_state() == shill::kStateOnline)
79       return NetworkStateInformer::ONLINE;
80     if (network->connection_state() == shill::kStatePortal)
81       return NetworkStateInformer::CAPTIVE_PORTAL;
82   }
83   return NetworkStateInformer::OFFLINE;
84 }
85
86 }  // namespace
87
88 NetworkStateInformer::NetworkStateInformer()
89     : state_(OFFLINE),
90       weak_ptr_factory_(this) {
91 }
92
93 NetworkStateInformer::~NetworkStateInformer() {
94   if (NetworkHandler::IsInitialized()) {
95     NetworkHandler::Get()->network_state_handler()->RemoveObserver(
96         this, FROM_HERE);
97   }
98   NetworkPortalDetector::Get()->RemoveObserver(this);
99 }
100
101 void NetworkStateInformer::Init() {
102   UpdateState();
103   NetworkHandler::Get()->network_state_handler()->AddObserver(
104       this, FROM_HERE);
105
106   NetworkPortalDetector::Get()->AddAndFireObserver(this);
107
108   registrar_.Add(this,
109                  chrome::NOTIFICATION_LOGIN_PROXY_CHANGED,
110                  content::NotificationService::AllSources());
111   registrar_.Add(this,
112                  chrome::NOTIFICATION_SESSION_STARTED,
113                  content::NotificationService::AllSources());
114 }
115
116 void NetworkStateInformer::AddObserver(NetworkStateInformerObserver* observer) {
117   if (!observers_.HasObserver(observer))
118     observers_.AddObserver(observer);
119 }
120
121 void NetworkStateInformer::RemoveObserver(
122     NetworkStateInformerObserver* observer) {
123   observers_.RemoveObserver(observer);
124 }
125
126 void NetworkStateInformer::DefaultNetworkChanged(const NetworkState* network) {
127   UpdateStateAndNotify();
128 }
129
130 void NetworkStateInformer::OnPortalDetectionCompleted(
131     const NetworkState* network,
132     const NetworkPortalDetector::CaptivePortalState& state) {
133   UpdateStateAndNotify();
134 }
135
136 void NetworkStateInformer::Observe(
137     int type,
138     const content::NotificationSource& source,
139     const content::NotificationDetails& details) {
140   if (type == chrome::NOTIFICATION_SESSION_STARTED)
141     registrar_.RemoveAll();
142   else if (type == chrome::NOTIFICATION_LOGIN_PROXY_CHANGED)
143     SendStateToObservers(ErrorScreenActor::ERROR_REASON_PROXY_CONFIG_CHANGED);
144   else
145     NOTREACHED() << "Unknown notification: " << type;
146 }
147
148 #if !defined(USE_ATHENA)
149 void NetworkStateInformer::OnPortalDetected() {
150   UpdateStateAndNotify();
151 }
152 #endif
153
154 // static
155 const char* NetworkStateInformer::StatusString(State state) {
156   switch (state) {
157     case OFFLINE:
158       return kNetworkStateOffline;
159     case ONLINE:
160       return kNetworkStateOnline;
161     case CAPTIVE_PORTAL:
162       return kNetworkStateCaptivePortal;
163     case CONNECTING:
164       return kNetworkStateConnecting;
165     case PROXY_AUTH_REQUIRED:
166       return kNetworkStateProxyAuthRequired;
167     default:
168       NOTREACHED();
169       return NULL;
170   }
171 }
172
173 bool NetworkStateInformer::UpdateState() {
174   const NetworkState* default_network =
175       NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
176   State new_state = GetStateForDefaultNetwork();
177   std::string new_network_path;
178   std::string new_network_type;
179   if (default_network) {
180     new_network_path = default_network->path();
181     new_network_type = default_network->type();
182   }
183
184   bool updated = (new_state != state_) ||
185       (new_network_path != network_path_) ||
186       (new_network_type != network_type_);
187   state_ = new_state;
188   network_path_ = new_network_path;
189   network_type_ = new_network_type;
190
191   if (updated && state_ == ONLINE) {
192     FOR_EACH_OBSERVER(NetworkStateInformerObserver, observers_,
193                       OnNetworkReady());
194   }
195
196   return updated;
197 }
198
199 void NetworkStateInformer::UpdateStateAndNotify() {
200   if (UpdateState())
201     SendStateToObservers(ErrorScreenActor::ERROR_REASON_NETWORK_STATE_CHANGED);
202   else
203     SendStateToObservers(ErrorScreenActor::ERROR_REASON_UPDATE);
204 }
205
206 void NetworkStateInformer::SendStateToObservers(
207     ErrorScreenActor::ErrorReason reason) {
208   FOR_EACH_OBSERVER(NetworkStateInformerObserver, observers_,
209       UpdateState(reason));
210 }
211
212 }  // namespace chromeos