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"
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"
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();
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();
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
;
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
;
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
;
89 NetworkStateInformer::NetworkStateInformer()
91 weak_ptr_factory_(this) {
94 NetworkStateInformer::~NetworkStateInformer() {
95 if (NetworkHandler::IsInitialized()) {
96 NetworkHandler::Get()->network_state_handler()->RemoveObserver(
99 NetworkPortalDetector::Get()->RemoveObserver(this);
102 void NetworkStateInformer::Init() {
104 NetworkHandler::Get()->network_state_handler()->AddObserver(
107 NetworkPortalDetector::Get()->AddAndFireObserver(this);
110 chrome::NOTIFICATION_LOGIN_PROXY_CHANGED
,
111 content::NotificationService::AllSources());
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(
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
);
146 NOTREACHED() << "Unknown notification: " << type
;
149 void NetworkStateInformer::OnPortalDetected() {
150 UpdateStateAndNotify();
154 const char* NetworkStateInformer::StatusString(State state
) {
157 return kNetworkStateOffline
;
159 return kNetworkStateOnline
;
161 return kNetworkStateCaptivePortal
;
163 return kNetworkStateConnecting
;
164 case PROXY_AUTH_REQUIRED
:
165 return kNetworkStateProxyAuthRequired
;
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_
);
187 network_path_
= new_network_path
;
188 network_type_
= new_network_type
;
190 if (updated
&& state_
== ONLINE
) {
191 FOR_EACH_OBSERVER(NetworkStateInformerObserver
, observers_
,
198 void NetworkStateInformer::UpdateStateAndNotify() {
200 SendStateToObservers(NetworkError::ERROR_REASON_NETWORK_STATE_CHANGED
);
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