diff options
Diffstat (limited to 'apps/shell/browser/shell_network_controller_chromeos.cc')
-rw-r--r-- | apps/shell/browser/shell_network_controller_chromeos.cc | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/apps/shell/browser/shell_network_controller_chromeos.cc b/apps/shell/browser/shell_network_controller_chromeos.cc new file mode 100644 index 0000000..fd7fd42 --- /dev/null +++ b/apps/shell/browser/shell_network_controller_chromeos.cc @@ -0,0 +1,168 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "apps/shell/browser/shell_network_controller_chromeos.h" + +#include "base/bind.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/strings/stringprintf.h" +#include "base/time/time.h" +#include "chromeos/network/network_connection_handler.h" +#include "chromeos/network/network_handler.h" +#include "chromeos/network/network_handler_callbacks.h" +#include "chromeos/network/network_state.h" +#include "chromeos/network/network_state_handler.h" +#include "chromeos/network/shill_property_util.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace apps { + +namespace { + +// Frequency at which networks should be scanned when not connected. +const int kScanIntervalSec = 10; + +void HandleEnableWifiError( + const std::string& error_name, + scoped_ptr<base::DictionaryValue> error_data) { + LOG(WARNING) << "Unable to enable wifi: " << error_name; +} + +// Returns a human-readable name for the network described by |state|. +std::string GetNetworkName(const chromeos::NetworkState& state) { + return !state.name().empty() ? state.name() : + base::StringPrintf("[%s]", state.type().c_str()); +} + +// Returns true if shill is either connected or connecting to a network. +bool IsConnectedOrConnecting() { + chromeos::NetworkStateHandler* state_handler = + chromeos::NetworkHandler::Get()->network_state_handler(); + return state_handler->ConnectedNetworkByType( + chromeos::NetworkTypePattern::Default()) || + state_handler->ConnectingNetworkByType( + chromeos::NetworkTypePattern::Default()); +} + +} // namespace + +ShellNetworkController::ShellNetworkController() + : waiting_for_connection_result_(false), + weak_ptr_factory_(this) { + chromeos::NetworkHandler::Initialize(); + chromeos::NetworkStateHandler* state_handler = + chromeos::NetworkHandler::Get()->network_state_handler(); + DCHECK(state_handler); + state_handler->AddObserver(this, FROM_HERE); + state_handler->SetTechnologyEnabled( + chromeos::NetworkTypePattern::Primitive(shill::kTypeWifi), + true, base::Bind(&HandleEnableWifiError)); + + if (!IsConnectedOrConnecting()) { + RequestScan(); + SetScanningEnabled(true); + ConnectIfUnconnected(); + } +} + +ShellNetworkController::~ShellNetworkController() { + chromeos::NetworkHandler::Get()->network_state_handler()->RemoveObserver( + this, FROM_HERE); + chromeos::NetworkHandler::Shutdown(); +} + +void ShellNetworkController::NetworkListChanged() { + VLOG(1) << "Network list changed"; + ConnectIfUnconnected(); +} + +void ShellNetworkController::DefaultNetworkChanged( + const chromeos::NetworkState* state) { + if (state) { + VLOG(1) << "Default network state changed:" + << " name=" << GetNetworkName(*state) + << " path=" << state->path() + << " state=" << state->connection_state(); + } else { + VLOG(1) << "Default network state changed: [no network]"; + } + + if (IsConnectedOrConnecting()) { + SetScanningEnabled(false); + } else { + SetScanningEnabled(true); + ConnectIfUnconnected(); + } +} + +void ShellNetworkController::SetScanningEnabled(bool enabled) { + const bool currently_enabled = scan_timer_.IsRunning(); + if (enabled == currently_enabled) + return; + + VLOG(1) << (enabled ? "Starting" : "Stopping") << " scanning"; + if (enabled) { + scan_timer_.Start(FROM_HERE, + base::TimeDelta::FromSeconds(kScanIntervalSec), + this, &ShellNetworkController::RequestScan); + } else { + scan_timer_.Stop(); + } +} + +void ShellNetworkController::RequestScan() { + VLOG(1) << "Requesting scan"; + chromeos::NetworkHandler::Get()->network_state_handler()->RequestScan(); +} + +// Attempts to connect to an available network if not already connecting or +// connected. +void ShellNetworkController::ConnectIfUnconnected() { + chromeos::NetworkHandler* handler = chromeos::NetworkHandler::Get(); + DCHECK(handler); + if (waiting_for_connection_result_ || IsConnectedOrConnecting()) + return; + + chromeos::NetworkStateHandler::NetworkStateList state_list; + handler->network_state_handler()->GetNetworkListByType( + chromeos::NetworkTypePattern::WiFi(), &state_list); + for (chromeos::NetworkStateHandler::NetworkStateList::const_iterator it = + state_list.begin(); it != state_list.end(); ++it) { + const chromeos::NetworkState* state = *it; + DCHECK(state); + if (!state->connectable()) + continue; + + VLOG(1) << "Connecting to network " << GetNetworkName(*state) + << " with path " << state->path() << " and strength " + << state->signal_strength(); + waiting_for_connection_result_ = true; + handler->network_connection_handler()->ConnectToNetwork( + state->path(), + base::Bind(&ShellNetworkController::HandleConnectionSuccess, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&ShellNetworkController::HandleConnectionError, + weak_ptr_factory_.GetWeakPtr()), + false /* check_error_state */); + + return; + } + + VLOG(1) << "Didn't find any connectable networks"; +} + +void ShellNetworkController::HandleConnectionSuccess() { + VLOG(1) << "Successfully connected to network"; + waiting_for_connection_result_ = false; +} + +void ShellNetworkController::HandleConnectionError( + const std::string& error_name, + scoped_ptr<base::DictionaryValue> error_data) { + LOG(WARNING) << "Unable to connect to network: " << error_name; + waiting_for_connection_result_ = false; +} + +} // namespace apps |