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/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"
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";
30 bool HasDefaultNetworkProxyConfigured() {
31 const FavoriteState
* favorite
=
32 NetworkHandler::Get()->network_state_handler()->DefaultFavoriteNetwork();
35 onc::ONCSource onc_source
= onc::ONC_SOURCE_NONE
;
36 scoped_ptr
<ProxyConfigDictionary
> proxy_dict
=
37 proxy_config::GetProxyConfigForFavoriteNetwork(
38 NULL
, g_browser_process
->local_state(), *favorite
, &onc_source
);
39 ProxyPrefs::ProxyMode mode
;
40 return (proxy_dict
&& proxy_dict
->GetMode(&mode
) &&
41 mode
== ProxyPrefs::MODE_FIXED_SERVERS
);
44 NetworkStateInformer::State
GetStateForDefaultNetwork() {
45 const NetworkState
* network
=
46 NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
48 return NetworkStateInformer::OFFLINE
;
50 if (NetworkPortalDetector::Get()->IsEnabled()) {
51 NetworkPortalDetector::CaptivePortalState state
=
52 NetworkPortalDetector::Get()->GetCaptivePortalState(network
);
53 NetworkPortalDetector::CaptivePortalStatus status
= state
.status
;
54 if (status
== NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN
&&
55 NetworkState::StateIsConnecting(network
->connection_state())) {
56 return NetworkStateInformer::CONNECTING
;
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
;
67 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED
&&
68 HasDefaultNetworkProxyConfigured()) {
69 return NetworkStateInformer::PROXY_AUTH_REQUIRED
;
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
;
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
;
83 return NetworkStateInformer::OFFLINE
;
88 NetworkStateInformer::NetworkStateInformer()
90 weak_ptr_factory_(this) {
93 NetworkStateInformer::~NetworkStateInformer() {
94 if (NetworkHandler::IsInitialized()) {
95 NetworkHandler::Get()->network_state_handler()->RemoveObserver(
98 NetworkPortalDetector::Get()->RemoveObserver(this);
101 void NetworkStateInformer::Init() {
103 NetworkHandler::Get()->network_state_handler()->AddObserver(
106 NetworkPortalDetector::Get()->AddAndFireObserver(this);
109 chrome::NOTIFICATION_LOGIN_PROXY_CHANGED
,
110 content::NotificationService::AllSources());
112 chrome::NOTIFICATION_SESSION_STARTED
,
113 content::NotificationService::AllSources());
116 void NetworkStateInformer::AddObserver(NetworkStateInformerObserver
* observer
) {
117 if (!observers_
.HasObserver(observer
))
118 observers_
.AddObserver(observer
);
121 void NetworkStateInformer::RemoveObserver(
122 NetworkStateInformerObserver
* observer
) {
123 observers_
.RemoveObserver(observer
);
126 void NetworkStateInformer::DefaultNetworkChanged(const NetworkState
* network
) {
127 UpdateStateAndNotify();
130 void NetworkStateInformer::OnPortalDetectionCompleted(
131 const NetworkState
* network
,
132 const NetworkPortalDetector::CaptivePortalState
& state
) {
133 UpdateStateAndNotify();
136 void NetworkStateInformer::Observe(
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
);
145 NOTREACHED() << "Unknown notification: " << type
;
148 void NetworkStateInformer::OnPortalDetected() {
149 UpdateStateAndNotify();
153 const char* NetworkStateInformer::StatusString(State state
) {
156 return kNetworkStateOffline
;
158 return kNetworkStateOnline
;
160 return kNetworkStateCaptivePortal
;
162 return kNetworkStateConnecting
;
163 case PROXY_AUTH_REQUIRED
:
164 return kNetworkStateProxyAuthRequired
;
171 bool NetworkStateInformer::UpdateState() {
172 const NetworkState
* default_network
=
173 NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
174 State new_state
= GetStateForDefaultNetwork();
175 std::string new_network_path
;
176 std::string new_network_type
;
177 if (default_network
) {
178 new_network_path
= default_network
->path();
179 new_network_type
= default_network
->type();
182 bool updated
= (new_state
!= state_
) ||
183 (new_network_path
!= network_path_
) ||
184 (new_network_type
!= network_type_
);
186 network_path_
= new_network_path
;
187 network_type_
= new_network_type
;
189 if (updated
&& state_
== ONLINE
) {
190 FOR_EACH_OBSERVER(NetworkStateInformerObserver
, observers_
,
197 void NetworkStateInformer::UpdateStateAndNotify() {
199 SendStateToObservers(ErrorScreenActor::ERROR_REASON_NETWORK_STATE_CHANGED
);
201 SendStateToObservers(ErrorScreenActor::ERROR_REASON_UPDATE
);
204 void NetworkStateInformer::SendStateToObservers(
205 ErrorScreenActor::ErrorReason reason
) {
206 FOR_EACH_OBSERVER(NetworkStateInformerObserver
, observers_
,
207 UpdateState(reason
));
210 } // namespace chromeos