| Index: chrome/browser/chromeos/net/wake_on_wifi_manager.cc
|
| diff --git a/chrome/browser/chromeos/net/wake_on_wifi_manager.cc b/chrome/browser/chromeos/net/wake_on_wifi_manager.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d163378aee122cb6ae06ed0dbc691713dbaddac3
|
| --- /dev/null
|
| +++ b/chrome/browser/chromeos/net/wake_on_wifi_manager.cc
|
| @@ -0,0 +1,213 @@
|
| +// 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 "chrome/browser/chromeos/net/wake_on_wifi_manager.h"
|
| +
|
| +#include <string>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/command_line.h"
|
| +#include "base/containers/scoped_ptr_hash_map.h"
|
| +#include "base/logging.h"
|
| +#include "base/macros.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/sys_info.h"
|
| +#include "chrome/browser/chrome_notification_types.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/browser/services/gcm/gcm_profile_service.h"
|
| +#include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
|
| +#include "chromeos/login/login_state.h"
|
| +#include "chromeos/network/device_state.h"
|
| +#include "chromeos/network/network_device_handler.h"
|
| +#include "chromeos/network/network_handler.h"
|
| +#include "chromeos/network/network_state_handler.h"
|
| +#include "chromeos/network/network_type_pattern.h"
|
| +#include "components/gcm_driver/gcm_connection_observer.h"
|
| +#include "components/gcm_driver/gcm_driver.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/notification_service.h"
|
| +#include "content/public/browser/notification_source.h"
|
| +#include "net/base/ip_endpoint.h"
|
| +#include "third_party/cros_system_api/dbus/service_constants.h"
|
| +
|
| +namespace chromeos {
|
| +
|
| +namespace {
|
| +
|
| +const char kWakeOnNone[] = "none";
|
| +const char kWakeOnPacket[] = "packet";
|
| +const char kWakeOnSsid[] = "ssid";
|
| +const char kWakeOnPacketAndSsid[] = "packet_and_ssid";
|
| +
|
| +std::string WakeOnWifiFeatureToString(
|
| + WakeOnWifiManager::WakeOnWifiFeature feature) {
|
| + switch (feature) {
|
| + case WakeOnWifiManager::WAKE_ON_NONE:
|
| + return kWakeOnNone;
|
| + case WakeOnWifiManager::WAKE_ON_PACKET:
|
| + return kWakeOnPacket;
|
| + case WakeOnWifiManager::WAKE_ON_SSID:
|
| + return kWakeOnSsid;
|
| + case WakeOnWifiManager::WAKE_ON_PACKET_AND_SSID:
|
| + return kWakeOnPacketAndSsid;
|
| + }
|
| +
|
| + NOTREACHED() << "Unknown wake on wifi feature: " << feature;
|
| + return std::string();
|
| +}
|
| +
|
| +// Weak pointer. This class is owned by ChromeBrowserMainPartsChromeos.
|
| +WakeOnWifiManager* g_wake_on_wifi_manager = NULL;
|
| +
|
| +} // namespace
|
| +
|
| +// Simple class that listens for a connection to the GCM server and passes the
|
| +// connection information down to shill. Each profile gets its own instance of
|
| +// this class.
|
| +class WakeOnWifiManager::WakeOnPacketConnectionObserver
|
| + : public gcm::GCMConnectionObserver {
|
| + public:
|
| + explicit WakeOnPacketConnectionObserver(Profile* profile)
|
| + : profile_(profile),
|
| + ip_endpoint_(net::IPEndPoint()) {
|
| + gcm::GCMProfileServiceFactory::GetForProfile(profile_)
|
| + ->driver()
|
| + ->AddConnectionObserver(this);
|
| + }
|
| +
|
| + ~WakeOnPacketConnectionObserver() override {
|
| + if (!(ip_endpoint_ == net::IPEndPoint()))
|
| + OnDisconnected();
|
| +
|
| + gcm::GCMProfileServiceFactory::GetForProfile(profile_)
|
| + ->driver()
|
| + ->RemoveConnectionObserver(this);
|
| + }
|
| +
|
| + // gcm::GCMConnectionObserver overrides.
|
| +
|
| + void OnConnected(const net::IPEndPoint& ip_endpoint) override {
|
| + ip_endpoint_ = ip_endpoint;
|
| +
|
| + NetworkHandler::Get()
|
| + ->network_device_handler()
|
| + ->AddWifiWakeOnPacketConnection(
|
| + ip_endpoint_,
|
| + base::Bind(&base::DoNothing),
|
| + network_handler::ErrorCallback());
|
| + }
|
| +
|
| + void OnDisconnected() override {
|
| + if (ip_endpoint_ == net::IPEndPoint()) {
|
| + LOG(WARNING) << "Received GCMConnectionObserver::OnDisconnected without "
|
| + << "a valid IPEndPoint.";
|
| + return;
|
| + }
|
| +
|
| + NetworkHandler::Get()
|
| + ->network_device_handler()
|
| + ->RemoveWifiWakeOnPacketConnection(
|
| + ip_endpoint_,
|
| + base::Bind(&base::DoNothing),
|
| + network_handler::ErrorCallback());
|
| +
|
| + ip_endpoint_ = net::IPEndPoint();
|
| + }
|
| +
|
| + private:
|
| + Profile* profile_;
|
| + net::IPEndPoint ip_endpoint_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(WakeOnPacketConnectionObserver);
|
| +};
|
| +
|
| +// static
|
| +WakeOnWifiManager* WakeOnWifiManager::Get() {
|
| + DCHECK(g_wake_on_wifi_manager);
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + return g_wake_on_wifi_manager;
|
| +}
|
| +
|
| +WakeOnWifiManager::WakeOnWifiManager() {
|
| + // This class must be constructed before any users are logged in, i.e., before
|
| + // any profiles are created or added to the ProfileManager. Additionally,
|
| + // IsUserLoggedIn always returns true when we are not running on a Chrome OS
|
| + // device so this check should only run on real devices.
|
| + CHECK(!base::SysInfo::IsRunningOnChromeOS() ||
|
| + !LoginState::Get()->IsUserLoggedIn());
|
| + DCHECK(!g_wake_on_wifi_manager);
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| +
|
| + g_wake_on_wifi_manager = this;
|
| +
|
| + registrar_.Add(this,
|
| + chrome::NOTIFICATION_PROFILE_ADDED,
|
| + content::NotificationService::AllBrowserContextsAndSources());
|
| + registrar_.Add(this,
|
| + chrome::NOTIFICATION_PROFILE_DESTROYED,
|
| + content::NotificationService::AllBrowserContextsAndSources());
|
| +
|
| + NetworkHandler::Get()
|
| + ->network_device_handler()
|
| + ->RemoveAllWifiWakeOnPacketConnections(
|
| + base::Bind(&base::DoNothing),
|
| + network_handler::ErrorCallback());
|
| +}
|
| +
|
| +WakeOnWifiManager::~WakeOnWifiManager() {
|
| + DCHECK(g_wake_on_wifi_manager);
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + g_wake_on_wifi_manager = NULL;
|
| +}
|
| +
|
| +void WakeOnWifiManager::OnPreferenceChanged(
|
| + WakeOnWifiManager::WakeOnWifiFeature feature) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + const DeviceState* device =
|
| + NetworkHandler::Get()->network_state_handler()->GetDeviceStateByType(
|
| + NetworkTypePattern::WiFi());
|
| + if (!device)
|
| + return;
|
| +
|
| + std::string feature_string(WakeOnWifiFeatureToString(feature));
|
| + DCHECK(!feature_string.empty());
|
| +
|
| + NetworkHandler::Get()->network_device_handler()->SetDeviceProperty(
|
| + device->path(),
|
| + shill::kWakeOnWiFiFeaturesEnabledProperty,
|
| + base::StringValue(feature_string),
|
| + base::Bind(&base::DoNothing),
|
| + network_handler::ErrorCallback());
|
| +}
|
| +
|
| +void WakeOnWifiManager::Observe(int type,
|
| + const content::NotificationSource& source,
|
| + const content::NotificationDetails& details) {
|
| + switch (type) {
|
| + case chrome::NOTIFICATION_PROFILE_ADDED: {
|
| + OnProfileAdded(content::Source<Profile>(source).ptr());
|
| + break;
|
| + }
|
| + case chrome::NOTIFICATION_PROFILE_DESTROYED: {
|
| + OnProfileDestroyed(content::Source<Profile>(source).ptr());
|
| + break;
|
| + }
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| +}
|
| +
|
| +void WakeOnWifiManager::OnProfileAdded(Profile* profile) {
|
| + // add will do nothing if |profile| already exists in |connection_observers_|.
|
| + connection_observers_.add(
|
| + profile,
|
| + make_scoped_ptr(
|
| + new WakeOnWifiManager::WakeOnPacketConnectionObserver(profile)));
|
| +}
|
| +
|
| +void WakeOnWifiManager::OnProfileDestroyed(Profile* profile) {
|
| + connection_observers_.erase(profile);
|
| +}
|
| +
|
| +} // namespace chromeos
|
|
|