Convert env to a defaultdict in run_executable() to fix other callers of that function.
[chromium-blink-merge.git] / extensions / shell / browser / shell_network_controller_chromeos.cc
blob1a0d5258b16c80d054486f703921e4a14f88dc16
1 // Copyright 2014 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 "extensions/shell/browser/shell_network_controller_chromeos.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/time/time.h"
12 #include "chromeos/network/network_connection_handler.h"
13 #include "chromeos/network/network_handler.h"
14 #include "chromeos/network/network_handler_callbacks.h"
15 #include "chromeos/network/network_state.h"
16 #include "chromeos/network/network_state_handler.h"
17 #include "third_party/cros_system_api/dbus/service_constants.h"
19 namespace extensions {
21 namespace {
23 // Frequency at which networks should be scanned when not connected to a network
24 // or when connected to a non-preferred network.
25 const int kScanIntervalSec = 10;
27 void HandleEnableWifiError(const std::string& error_name,
28 scoped_ptr<base::DictionaryValue> error_data) {
29 LOG(WARNING) << "Unable to enable wifi: " << error_name;
32 // Returns a human-readable name for the network described by |network|.
33 std::string GetNetworkName(const chromeos::NetworkState& network) {
34 return !network.name().empty()
35 ? network.name()
36 : base::StringPrintf("[%s]", network.type().c_str());
39 // Returns true if shill is either connected or connecting to a network.
40 bool IsConnectedOrConnecting() {
41 chromeos::NetworkStateHandler* state_handler =
42 chromeos::NetworkHandler::Get()->network_state_handler();
43 return state_handler->ConnectedNetworkByType(
44 chromeos::NetworkTypePattern::Default()) ||
45 state_handler->ConnectingNetworkByType(
46 chromeos::NetworkTypePattern::Default());
49 } // namespace
51 ShellNetworkController::ShellNetworkController(
52 const std::string& preferred_network_name)
53 : state_(STATE_IDLE),
54 preferred_network_name_(preferred_network_name),
55 preferred_network_is_active_(false),
56 weak_ptr_factory_(this) {
57 chromeos::NetworkStateHandler* state_handler =
58 chromeos::NetworkHandler::Get()->network_state_handler();
59 state_handler->AddObserver(this, FROM_HERE);
60 state_handler->SetTechnologyEnabled(
61 chromeos::NetworkTypePattern::Primitive(shill::kTypeWifi),
62 true,
63 base::Bind(&HandleEnableWifiError));
65 // If we're unconnected, trigger a connection attempt and start scanning.
66 NetworkConnectionStateChanged(NULL);
69 ShellNetworkController::~ShellNetworkController() {
70 chromeos::NetworkHandler::Get()->network_state_handler()->RemoveObserver(
71 this, FROM_HERE);
74 void ShellNetworkController::NetworkListChanged() {
75 VLOG(1) << "Network list changed";
76 ConnectIfUnconnected();
79 void ShellNetworkController::NetworkConnectionStateChanged(
80 const chromeos::NetworkState* network) {
81 if (network) {
82 VLOG(1) << "Network connection state changed:"
83 << " name=" << GetNetworkName(*network)
84 << " type=" << network->type() << " path=" << network->path()
85 << " state=" << network->connection_state();
86 } else {
87 VLOG(1) << "Network connection state changed: [none]";
90 const chromeos::NetworkState* wifi_network = GetActiveWiFiNetwork();
91 preferred_network_is_active_ =
92 wifi_network && wifi_network->name() == preferred_network_name_;
93 VLOG(2) << "Active WiFi network is "
94 << (wifi_network ? wifi_network->name() : std::string("[none]"));
96 if (preferred_network_is_active_ ||
97 (preferred_network_name_.empty() && wifi_network)) {
98 SetScanningEnabled(false);
99 } else {
100 SetScanningEnabled(true);
101 ConnectIfUnconnected();
105 const chromeos::NetworkState* ShellNetworkController::GetActiveWiFiNetwork() {
106 chromeos::NetworkStateHandler* state_handler =
107 chromeos::NetworkHandler::Get()->network_state_handler();
108 const chromeos::NetworkState* network = state_handler->FirstNetworkByType(
109 chromeos::NetworkTypePattern::Primitive(shill::kTypeWifi));
110 return network &&
111 (network->IsConnectedState() || network->IsConnectingState())
112 ? network
113 : NULL;
116 void ShellNetworkController::SetScanningEnabled(bool enabled) {
117 const bool currently_enabled = scan_timer_.IsRunning();
118 if (enabled == currently_enabled)
119 return;
121 VLOG(1) << (enabled ? "Starting" : "Stopping") << " scanning";
122 if (enabled) {
123 RequestScan();
124 scan_timer_.Start(FROM_HERE,
125 base::TimeDelta::FromSeconds(kScanIntervalSec),
126 this,
127 &ShellNetworkController::RequestScan);
128 } else {
129 scan_timer_.Stop();
133 void ShellNetworkController::RequestScan() {
134 VLOG(1) << "Requesting scan";
135 chromeos::NetworkHandler::Get()->network_state_handler()->RequestScan();
138 void ShellNetworkController::ConnectIfUnconnected() {
139 // Don't do anything if the default network is already the preferred one or if
140 // we have a pending request to connect to it.
141 if (preferred_network_is_active_ ||
142 state_ == STATE_WAITING_FOR_PREFERRED_RESULT)
143 return;
145 const chromeos::NetworkState* best_network = NULL;
146 bool can_connect_to_preferred_network = false;
148 chromeos::NetworkHandler* handler = chromeos::NetworkHandler::Get();
149 chromeos::NetworkStateHandler::NetworkStateList network_list;
150 handler->network_state_handler()->GetVisibleNetworkListByType(
151 chromeos::NetworkTypePattern::WiFi(), &network_list);
152 for (chromeos::NetworkStateHandler::NetworkStateList::const_iterator it =
153 network_list.begin();
154 it != network_list.end();
155 ++it) {
156 const chromeos::NetworkState* network = *it;
157 if (!network->connectable())
158 continue;
160 if (!preferred_network_name_.empty() &&
161 network->name() == preferred_network_name_) {
162 best_network = network;
163 can_connect_to_preferred_network = true;
164 break;
165 } else if (!best_network) {
166 best_network = network;
170 // Don't switch networks if we're already connecting/connected and wouldn't be
171 // switching to the preferred network.
172 if ((IsConnectedOrConnecting() || state_ != STATE_IDLE) &&
173 !can_connect_to_preferred_network)
174 return;
176 if (!best_network) {
177 VLOG(1) << "Didn't find any connectable networks";
178 return;
181 VLOG(1) << "Connecting to network " << GetNetworkName(*best_network)
182 << " with path " << best_network->path() << " and strength "
183 << best_network->signal_strength();
184 state_ = can_connect_to_preferred_network
185 ? STATE_WAITING_FOR_PREFERRED_RESULT
186 : STATE_WAITING_FOR_NON_PREFERRED_RESULT;
187 handler->network_connection_handler()->ConnectToNetwork(
188 best_network->path(),
189 base::Bind(&ShellNetworkController::HandleConnectionSuccess,
190 weak_ptr_factory_.GetWeakPtr()),
191 base::Bind(&ShellNetworkController::HandleConnectionError,
192 weak_ptr_factory_.GetWeakPtr()),
193 false /* check_error_state */);
196 void ShellNetworkController::HandleConnectionSuccess() {
197 VLOG(1) << "Successfully connected to network";
198 state_ = STATE_IDLE;
201 void ShellNetworkController::HandleConnectionError(
202 const std::string& error_name,
203 scoped_ptr<base::DictionaryValue> error_data) {
204 LOG(WARNING) << "Unable to connect to network: " << error_name;
205 state_ = STATE_IDLE;
208 } // namespace extensions