summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorderat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-02 21:02:36 +0000
committerderat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-02 21:02:36 +0000
commitced067e6da6e3092a00546ed820d9657a1707d91 (patch)
treefd560d10f5b9d6bfed07e88b34b15b5ccee34273 /apps
parent9e4067f4d8c2b659d74f917dbafe7a72508dd339 (diff)
downloadchromium_src-ced067e6da6e3092a00546ed820d9657a1707d91.zip
chromium_src-ced067e6da6e3092a00546ed820d9657a1707d91.tar.gz
chromium_src-ced067e6da6e3092a00546ed820d9657a1707d91.tar.bz2
app_shell: Automatically connect to networks.
Introduce a simple ShellNetworkController class that asks shill to connect to networks when running on Chrome OS. BUG=364297 TBR=brettw@chromium.org Review URL: https://codereview.chromium.org/264953002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267912 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'apps')
-rw-r--r--apps/shell/app_shell.gyp2
-rw-r--r--apps/shell/browser/DEPS1
-rw-r--r--apps/shell/browser/shell_browser_main_parts.cc3
-rw-r--r--apps/shell/browser/shell_browser_main_parts.h7
-rw-r--r--apps/shell/browser/shell_network_controller_chromeos.cc168
-rw-r--r--apps/shell/browser/shell_network_controller_chromeos.h66
6 files changed, 247 insertions, 0 deletions
diff --git a/apps/shell/app_shell.gyp b/apps/shell/app_shell.gyp
index 8aa552a..9ce5329 100644
--- a/apps/shell/app_shell.gyp
+++ b/apps/shell/app_shell.gyp
@@ -128,6 +128,8 @@
'browser/shell_extension_web_contents_observer.h',
'browser/shell_extensions_browser_client.cc',
'browser/shell_extensions_browser_client.h',
+ 'browser/shell_network_controller_chromeos.cc',
+ 'browser/shell_network_controller_chromeos.h',
'common/shell_app_runtime.cc',
'common/shell_app_runtime.h',
'common/shell_content_client.cc',
diff --git a/apps/shell/browser/DEPS b/apps/shell/browser/DEPS
index 5b49515..9d8d30b 100644
--- a/apps/shell/browser/DEPS
+++ b/apps/shell/browser/DEPS
@@ -1,6 +1,7 @@
include_rules = [
"+chromeos",
"+components/user_prefs",
+ "+third_party/cros_system_api",
# Override apps/DEPS to be more selective about content includes.
"-content",
diff --git a/apps/shell/browser/shell_browser_main_parts.cc b/apps/shell/browser/shell_browser_main_parts.cc
index c886b74..be1c82d 100644
--- a/apps/shell/browser/shell_browser_main_parts.cc
+++ b/apps/shell/browser/shell_browser_main_parts.cc
@@ -24,6 +24,7 @@
#include "ui/base/resource/resource_bundle.h"
#if defined(OS_CHROMEOS)
+#include "apps/shell/browser/shell_network_controller_chromeos.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#endif
@@ -61,6 +62,7 @@ void ShellBrowserMainParts::PreMainMessageLoopStart() {
void ShellBrowserMainParts::PostMainMessageLoopStart() {
#if defined(OS_CHROMEOS)
chromeos::DBusThreadManager::Initialize();
+ network_controller_.reset(new ShellNetworkController);
#endif
}
@@ -144,6 +146,7 @@ void ShellBrowserMainParts::PostMainMessageLoopRun() {
void ShellBrowserMainParts::PostDestroyThreads() {
#if defined(OS_CHROMEOS)
+ network_controller_.reset();
chromeos::DBusThreadManager::Shutdown();
#endif
}
diff --git a/apps/shell/browser/shell_browser_main_parts.h b/apps/shell/browser/shell_browser_main_parts.h
index 8ae3fe4..4bc18b2 100644
--- a/apps/shell/browser/shell_browser_main_parts.h
+++ b/apps/shell/browser/shell_browser_main_parts.h
@@ -37,6 +37,10 @@ class ShellBrowserContext;
class ShellDesktopController;
class ShellExtensionsClient;
+#if defined(OS_CHROMEOS)
+class ShellNetworkController;
+#endif
+
// Handles initialization of AppShell.
class ShellBrowserMainParts : public content::BrowserMainParts,
public aura::WindowTreeHostObserver {
@@ -70,6 +74,9 @@ class ShellBrowserMainParts : public content::BrowserMainParts,
// Creates and initializes the ExtensionSystem.
void CreateExtensionSystem();
+#if defined(OS_CHROMEOS)
+ scoped_ptr<ShellNetworkController> network_controller_;
+#endif
scoped_ptr<ShellDesktopController> desktop_controller_;
scoped_ptr<ShellBrowserContext> browser_context_;
scoped_ptr<ShellExtensionsClient> extensions_client_;
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
diff --git a/apps/shell/browser/shell_network_controller_chromeos.h b/apps/shell/browser/shell_network_controller_chromeos.h
new file mode 100644
index 0000000..41317e2
--- /dev/null
+++ b/apps/shell/browser/shell_network_controller_chromeos.h
@@ -0,0 +1,66 @@
+// 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.
+
+#ifndef APPS_SHELL_BROWSER_SHELL_NETWORK_CONTROLLER_CHROMEOS_H_
+#define APPS_SHELL_BROWSER_SHELL_NETWORK_CONTROLLER_CHROMEOS_H_
+
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/timer/timer.h"
+#include "base/values.h"
+#include "chromeos/network/network_state_handler_observer.h"
+
+namespace apps {
+
+// Handles network-related tasks for app_shell on Chrome OS.
+class ShellNetworkController : public chromeos::NetworkStateHandlerObserver {
+ public:
+ // This class must be instantiated after chromeos::DBusThreadManager and
+ // destroyed before it.
+ ShellNetworkController();
+ virtual ~ShellNetworkController();
+
+ // chromeos::NetworkStateHandlerObserver overrides:
+ virtual void NetworkListChanged() OVERRIDE;
+ virtual void DefaultNetworkChanged(
+ const chromeos::NetworkState* state) OVERRIDE;
+
+ private:
+ // Controls whether scanning is performed periodically.
+ void SetScanningEnabled(bool enabled);
+
+ // Asks shill to scan for networks.
+ void RequestScan();
+
+ // If not currently connected or connecting, chooses a wireless network and
+ // asks shill to connect to it.
+ void ConnectIfUnconnected();
+
+ // Handles a successful or failed connection attempt.
+ void HandleConnectionSuccess();
+ void HandleConnectionError(
+ const std::string& error_name,
+ scoped_ptr<base::DictionaryValue> error_data);
+
+ // True when ConnectIfUnconnected() has asked shill to connect but the attempt
+ // hasn't succeeded or failed yet. This is tracked to avoid sending duplicate
+ // requests before chromeos::NetworkStateHandler has acknowledged the initial
+ // connection attempt.
+ bool waiting_for_connection_result_;
+
+ // Invokes RequestScan() periodically.
+ base::RepeatingTimer<ShellNetworkController> scan_timer_;
+
+ base::WeakPtrFactory<ShellNetworkController> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ShellNetworkController);
+};
+
+} // namespace apps
+
+#endif // APPS_SHELL_BROWSER_SHELL_NETWORK_CONTROLLER_CHROMEOS_H_