Commit e2b442be authored by semenzato's avatar semenzato Committed by Commit bot

GCM: D-Bus methods for wake-on-packet

Program the NIC to wake-on-packet for packets arriving from
the GCM server.  Chrome notifies the connection manager (shill)
by calling D-Bus methods.  The return status indicates if the
operation succeeded or not (depending on hardware support and
the type of connection).

This is a resubmission of a previous patch with the same title
and functionality containing fixes and a workaround for a problem
that is independent of this patch.  Bug 415821 remains open
for that problem.

Keywords: wowlan, wake-on-lan, wake-on-wlan

BUG=360295
TEST=verified dbus methods are called, and packets are sent on the
TEST=connection passed to the methods.  Also verified that shill
TEST=programs the NIC correctly, and packets wake up the device.

Review URL: https://codereview.chromium.org/597683005

Cr-Commit-Position: refs/heads/master@{#296516}
parent 4bcbeb30
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
#include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/device_settings_service.h" #include "chrome/browser/chromeos/settings/device_settings_service.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#endif #endif
namespace extensions { namespace extensions {
...@@ -220,6 +221,10 @@ class ExtensionGCMAppHandlerTest : public testing::Test { ...@@ -220,6 +221,10 @@ class ExtensionGCMAppHandlerTest : public testing::Test {
// This is needed to create extension service under CrOS. // This is needed to create extension service under CrOS.
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
test_user_manager_.reset(new chromeos::ScopedTestUserManager()); test_user_manager_.reset(new chromeos::ScopedTestUserManager());
// Creating a DBus thread manager setter has the side effect of
// creating a DBusThreadManager, which is needed for testing.
// We don't actually need the setter so we ignore the return value.
chromeos::DBusThreadManager::GetSetterForTesting();
#endif #endif
// Create a new profile. // Create a new profile.
......
// Copyright (c) 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/services/gcm/chromeos_gcm_connection_observer.h"
#include "base/callback.h"
#include "base/logging.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/shill_manager_client.h"
namespace gcm {
ChromeOSGCMConnectionObserver::ChromeOSGCMConnectionObserver() {
}
ChromeOSGCMConnectionObserver::~ChromeOSGCMConnectionObserver() {
}
// static
void ChromeOSGCMConnectionObserver::ErrorCallback(
const std::string& error_name,
const std::string& error) {
LOG(ERROR) << "GCM D-Bus method error " << error_name << ": " << error;
}
void ChromeOSGCMConnectionObserver::OnConnected(
const net::IPEndPoint& ip_endpoint) {
ip_endpoint_ = ip_endpoint;
chromeos::DBusThreadManager::Get()->
GetShillManagerClient()->
AddWakeOnPacketConnection(
ip_endpoint,
base::Bind(&base::DoNothing),
base::Bind(&ChromeOSGCMConnectionObserver::ErrorCallback));
}
void ChromeOSGCMConnectionObserver::OnDisconnected() {
chromeos::DBusThreadManager::Get()->
GetShillManagerClient()->
RemoveWakeOnPacketConnection(
ip_endpoint_,
base::Bind(&base::DoNothing),
base::Bind(&ChromeOSGCMConnectionObserver::ErrorCallback));
}
} // namespace gcm
// Copyright (c) 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 CHROME_BROWSER_SERVICES_GCM_CHROMEOS_GCM_CONNECTION_OBSERVER_H_
#define CHROME_BROWSER_SERVICES_GCM_CHROMEOS_GCM_CONNECTION_OBSERVER_H_
#include "base/compiler_specific.h"
#include "components/gcm_driver/gcm_connection_observer.h"
#include "net/base/ip_endpoint.h"
namespace gcm {
class ChromeOSGCMConnectionObserver : public GCMConnectionObserver {
public:
ChromeOSGCMConnectionObserver();
virtual ~ChromeOSGCMConnectionObserver();
// gcm::GCMConnectionObserver implementation:
virtual void OnConnected(const net::IPEndPoint& ip_endpoint) OVERRIDE;
virtual void OnDisconnected() OVERRIDE;
static void ErrorCallback(
const std::string& error_name,
const std::string& error);
private:
net::IPEndPoint ip_endpoint_;
DISALLOW_COPY_AND_ASSIGN(ChromeOSGCMConnectionObserver);
};
} // namespace gcm
#endif // CHROME_BROWSER_SERVICES_GCM_CHROMEOS_GCM_CONNECTION_OBSERVER_H_
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
#include "components/gcm_driver/gcm_driver_android.h" #include "components/gcm_driver/gcm_driver_android.h"
#else #else
#include "base/bind.h" #include "base/bind.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/services/gcm/chromeos_gcm_connection_observer.h"
#endif
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "chrome/browser/services/gcm/gcm_account_tracker.h" #include "chrome/browser/services/gcm/gcm_account_tracker.h"
...@@ -170,6 +173,11 @@ GCMProfileService::GCMProfileService( ...@@ -170,6 +173,11 @@ GCMProfileService::GCMProfileService(
profile_->GetPath().Append(chrome::kGCMStoreDirname), profile_->GetPath().Append(chrome::kGCMStoreDirname),
profile_->GetRequestContext()); profile_->GetRequestContext());
#if defined(OS_CHROMEOS)
chromeos_connection_observer_.reset(new gcm::ChromeOSGCMConnectionObserver);
driver_->AddConnectionObserver(chromeos_connection_observer_.get());
#endif
identity_observer_.reset(new IdentityObserver( identity_observer_.reset(new IdentityObserver(
profile, static_cast<gcm::GCMDriverDesktop*>(driver_.get()))); profile, static_cast<gcm::GCMDriverDesktop*>(driver_.get())));
} }
...@@ -205,8 +213,11 @@ void GCMProfileService::Shutdown() { ...@@ -205,8 +213,11 @@ void GCMProfileService::Shutdown() {
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
identity_observer_.reset(); identity_observer_.reset();
#endif // !defined(OS_ANDROID) #endif // !defined(OS_ANDROID)
if (driver_) { if (driver_) {
#if defined(OS_CHROMEOS)
driver_->RemoveConnectionObserver(chromeos_connection_observer_.get());
chromeos_connection_observer_.reset();
#endif
driver_->Shutdown(); driver_->Shutdown();
driver_.reset(); driver_.reset();
} }
......
...@@ -86,6 +86,9 @@ class GCMProfileService : public KeyedService { ...@@ -86,6 +86,9 @@ class GCMProfileService : public KeyedService {
class IdentityObserver; class IdentityObserver;
scoped_ptr<IdentityObserver> identity_observer_; scoped_ptr<IdentityObserver> identity_observer_;
#endif #endif
#if defined(OS_CHROMEOS)
scoped_ptr<GCMConnectionObserver> chromeos_connection_observer_;
#endif
DISALLOW_COPY_AND_ASSIGN(GCMProfileService); DISALLOW_COPY_AND_ASSIGN(GCMProfileService);
}; };
......
...@@ -15,6 +15,9 @@ ...@@ -15,6 +15,9 @@
#include "chrome/browser/services/gcm/gcm_profile_service_factory.h" #include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
#if defined(OS_CHROMEOS)
#include "chromeos/dbus/dbus_thread_manager.h"
#endif
#include "components/gcm_driver/fake_gcm_app_handler.h" #include "components/gcm_driver/fake_gcm_app_handler.h"
#include "components/gcm_driver/fake_gcm_client.h" #include "components/gcm_driver/fake_gcm_client.h"
#include "components/gcm_driver/fake_gcm_client_factory.h" #include "components/gcm_driver/fake_gcm_client_factory.h"
...@@ -116,6 +119,11 @@ FakeGCMClient* GCMProfileServiceTest::GetGCMClient() const { ...@@ -116,6 +119,11 @@ FakeGCMClient* GCMProfileServiceTest::GetGCMClient() const {
} }
void GCMProfileServiceTest::SetUp() { void GCMProfileServiceTest::SetUp() {
#if defined(OS_CHROMEOS)
// Create a DBus thread manager setter for its side effect.
// Ignore the return value.
chromeos::DBusThreadManager::GetSetterForTesting();
#endif
TestingProfile::Builder builder; TestingProfile::Builder builder;
builder.AddTestingFactory(SigninManagerFactory::GetInstance(), builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
FakeSigninManager::Build); FakeSigninManager::Build);
......
...@@ -2644,6 +2644,8 @@ ...@@ -2644,6 +2644,8 @@
# support ChromeOS with enable_plugins==0. # support ChromeOS with enable_plugins==0.
'browser/renderer_host/pepper/pepper_platform_verification_message_filter.cc', 'browser/renderer_host/pepper/pepper_platform_verification_message_filter.cc',
'browser/renderer_host/pepper/pepper_platform_verification_message_filter.h', 'browser/renderer_host/pepper/pepper_platform_verification_message_filter.h',
'browser/services/gcm/chromeos_gcm_connection_observer.cc',
'browser/services/gcm/chromeos_gcm_connection_observer.h',
], ],
# Used everywhere but ChromeOS. # Used everywhere but ChromeOS.
'chrome_browser_non_chromeos_sources': [ 'chrome_browser_non_chromeos_sources': [
......
...@@ -355,6 +355,23 @@ void FakeShillManagerClient::ConnectToBestServices( ...@@ -355,6 +355,23 @@ void FakeShillManagerClient::ConnectToBestServices(
dbus::ObjectPath(best_service_), callback, error_callback); dbus::ObjectPath(best_service_), callback, error_callback);
} }
void FakeShillManagerClient::AddWakeOnPacketConnection(
const net::IPEndPoint& ip_endpoint,
const base::Closure& callback,
const ErrorCallback& error_callback) {
}
void FakeShillManagerClient::RemoveWakeOnPacketConnection(
const net::IPEndPoint& ip_endpoint,
const base::Closure& callback,
const ErrorCallback& error_callback) {
}
void FakeShillManagerClient::RemoveAllWakeOnPacketConnections(
const base::Closure& callback,
const ErrorCallback& error_callback) {
}
ShillManagerClient::TestInterface* FakeShillManagerClient::GetTestInterface() { ShillManagerClient::TestInterface* FakeShillManagerClient::GetTestInterface() {
return this; return this;
} }
......
...@@ -12,6 +12,10 @@ ...@@ -12,6 +12,10 @@
#include "chromeos/chromeos_export.h" #include "chromeos/chromeos_export.h"
#include "chromeos/dbus/shill_manager_client.h" #include "chromeos/dbus/shill_manager_client.h"
namespace net {
class IPEndPoint;
}
namespace chromeos { namespace chromeos {
// A fake implementation of ShillManagerClient. This works in close coordination // A fake implementation of ShillManagerClient. This works in close coordination
...@@ -77,6 +81,18 @@ class CHROMEOS_EXPORT FakeShillManagerClient ...@@ -77,6 +81,18 @@ class CHROMEOS_EXPORT FakeShillManagerClient
virtual void ConnectToBestServices( virtual void ConnectToBestServices(
const base::Closure& callback, const base::Closure& callback,
const ErrorCallback& error_callback) OVERRIDE; const ErrorCallback& error_callback) OVERRIDE;
virtual void AddWakeOnPacketConnection(
const net::IPEndPoint& ip_connection,
const base::Closure& callback,
const ErrorCallback& error_callback) OVERRIDE;
virtual void RemoveWakeOnPacketConnection(
const net::IPEndPoint& ip_endpoint,
const base::Closure& callback,
const ErrorCallback& error_callback) OVERRIDE;
virtual void RemoveAllWakeOnPacketConnections(
const base::Closure& callback,
const ErrorCallback& error_callback) OVERRIDE;
virtual ShillManagerClient::TestInterface* GetTestInterface() OVERRIDE; virtual ShillManagerClient::TestInterface* GetTestInterface() OVERRIDE;
// ShillManagerClient::TestInterface overrides. // ShillManagerClient::TestInterface overrides.
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/values.h" #include "base/values.h"
#include "chromeos/dbus/shill_manager_client.h" #include "chromeos/dbus/shill_manager_client.h"
#include "chromeos/dbus/shill_property_changed_observer.h" #include "chromeos/dbus/shill_property_changed_observer.h"
#include "net/base/ip_endpoint.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
namespace chromeos { namespace chromeos {
...@@ -66,6 +67,17 @@ class MockShillManagerClient : public ShillManagerClient { ...@@ -66,6 +67,17 @@ class MockShillManagerClient : public ShillManagerClient {
MOCK_METHOD2(ConnectToBestServices, MOCK_METHOD2(ConnectToBestServices,
void(const base::Closure& callback, void(const base::Closure& callback,
const ErrorCallback& error_callback)); const ErrorCallback& error_callback));
MOCK_METHOD3(AddWakeOnPacketConnection,
void(const net::IPEndPoint& ip_connection,
const base::Closure& callback,
const ErrorCallback& error_callback));
MOCK_METHOD3(RemoveWakeOnPacketConnection,
void(const net::IPEndPoint& ip_connection,
const base::Closure& callback,
const ErrorCallback& error_callback));
MOCK_METHOD2(RemoveAllWakeOnPacketConnections,
void(const base::Closure& callback,
const ErrorCallback& error_callback));
MOCK_METHOD0(GetTestInterface, TestInterface*()); MOCK_METHOD0(GetTestInterface, TestInterface*());
}; };
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "dbus/object_path.h" #include "dbus/object_path.h"
#include "dbus/object_proxy.h" #include "dbus/object_proxy.h"
#include "dbus/values_util.h" #include "dbus/values_util.h"
#include "net/base/ip_endpoint.h"
#include "third_party/cros_system_api/dbus/service_constants.h" #include "third_party/cros_system_api/dbus/service_constants.h"
namespace chromeos { namespace chromeos {
...@@ -210,6 +211,51 @@ class ShillManagerClientImpl : public ShillManagerClient { ...@@ -210,6 +211,51 @@ class ShillManagerClientImpl : public ShillManagerClient {
error_callback); error_callback);
} }
virtual void AddWakeOnPacketConnection(
const net::IPEndPoint& ip_endpoint,
const base::Closure& callback,
const ErrorCallback& error_callback) OVERRIDE {
if (ip_endpoint.address().empty()) {
LOG(ERROR) << "AddWakeOnPacketConnection: null address";
return;
}
dbus::MethodCall method_call(shill::kFlimflamManagerInterface,
shill::kAddWakeOnPacketConnectionFunction);
dbus::MessageWriter writer(&method_call);
writer.AppendString(net::IPAddressToString(ip_endpoint.address()));
helper_->CallVoidMethodWithErrorCallback(&method_call,
callback,
error_callback);
}
virtual void RemoveWakeOnPacketConnection(
const net::IPEndPoint& ip_endpoint,
const base::Closure& callback,
const ErrorCallback& error_callback) OVERRIDE {
if (ip_endpoint.address().empty()) {
LOG(ERROR) << "RemoveWakeOnPacketConnection: null address";
return;
}
dbus::MethodCall method_call(shill::kFlimflamManagerInterface,
shill::kRemoveWakeOnPacketConnectionFunction);
dbus::MessageWriter writer(&method_call);
writer.AppendString(net::IPAddressToString(ip_endpoint.address()));
helper_->CallVoidMethodWithErrorCallback(&method_call,
callback,
error_callback);
}
virtual void RemoveAllWakeOnPacketConnections(
const base::Closure& callback,
const ErrorCallback& error_callback) OVERRIDE {
dbus::MethodCall method_call(
shill::kFlimflamManagerInterface,
shill::kRemoveAllWakeOnPacketConnectionsFunction);
helper_->CallVoidMethodWithErrorCallback(&method_call,
callback,
error_callback);
}
virtual TestInterface* GetTestInterface() OVERRIDE { virtual TestInterface* GetTestInterface() OVERRIDE {
return NULL; return NULL;
} }
......
...@@ -14,10 +14,12 @@ ...@@ -14,10 +14,12 @@
#include "chromeos/dbus/shill_client_helper.h" #include "chromeos/dbus/shill_client_helper.h"
namespace dbus { namespace dbus {
class ObjectPath; class ObjectPath;
}
} // namespace dbus namespace net {
class IPEndPoint;
}
namespace chromeos { namespace chromeos {
...@@ -193,35 +195,53 @@ class CHROMEOS_EXPORT ShillManagerClient : public DBusClient { ...@@ -193,35 +195,53 @@ class CHROMEOS_EXPORT ShillManagerClient : public DBusClient {
const ObjectPathCallback& callback, const ObjectPathCallback& callback,
const ErrorCallback& error_callback) = 0; const ErrorCallback& error_callback) = 0;
// Verify that the given data corresponds to a trusted device, and return true // Verifies that the given data corresponds to a trusted device, and returns
// to the callback if it is. // true to the callback if it is.
virtual void VerifyDestination(const VerificationProperties& properties, virtual void VerifyDestination(const VerificationProperties& properties,
const BooleanCallback& callback, const BooleanCallback& callback,
const ErrorCallback& error_callback) = 0; const ErrorCallback& error_callback) = 0;
// Verify that the given data corresponds to a trusted device, and if it is, // Verifies that the given data corresponds to a trusted device, and if it is,
// return the encrypted credentials for connecting to the network represented // returns the encrypted credentials for connecting to the network represented
// by the given |service_path|, encrypted using the |public_key| for the // by the given |service_path|, encrypted using the |public_key| for the
// trusted device. If the device is not trusted, return the empty string. // trusted device. If the device is not trusted, returns the empty string.
virtual void VerifyAndEncryptCredentials( virtual void VerifyAndEncryptCredentials(
const VerificationProperties& properties, const VerificationProperties& properties,
const std::string& service_path, const std::string& service_path,
const StringCallback& callback, const StringCallback& callback,
const ErrorCallback& error_callback) = 0; const ErrorCallback& error_callback) = 0;
// Verify that the given data corresponds to a trusted device, and return the // Verifies that the given data corresponds to a trusted device, and returns
// |data| encrypted using the |public_key| for the trusted device. If the // the |data| encrypted using the |public_key| for the trusted device. If the
// device is not trusted, return the empty string. // device is not trusted, returns the empty string.
virtual void VerifyAndEncryptData(const VerificationProperties& properties, virtual void VerifyAndEncryptData(const VerificationProperties& properties,
const std::string& data, const std::string& data,
const StringCallback& callback, const StringCallback& callback,
const ErrorCallback& error_callback) = 0; const ErrorCallback& error_callback) = 0;
// For each technology present, connect to the "best" service available. // For each technology present, connects to the "best" service available.
// Called once the user is logged in and certificates are loaded. // Called once the user is logged in and certificates are loaded.
virtual void ConnectToBestServices(const base::Closure& callback, virtual void ConnectToBestServices(const base::Closure& callback,
const ErrorCallback& error_callback) = 0; const ErrorCallback& error_callback) = 0;
// Requests that shill program the NIC so that packets incoming on
// |ip_connection| wake up the CPU.
virtual void AddWakeOnPacketConnection(
const net::IPEndPoint& ip_endpoint,
const base::Closure& callback,
const ErrorCallback& error_callback) = 0;
// Removes a request to wake up on packets coming on |ip_connection|.
virtual void RemoveWakeOnPacketConnection(
const net::IPEndPoint& ip_endpoint,
const base::Closure& callback,
const ErrorCallback& error_callback) = 0;
// Clears all requests to wake up on packets.
virtual void RemoveAllWakeOnPacketConnections(
const base::Closure& callback,
const ErrorCallback& error_callback) = 0;
// Returns an interface for testing (stub only), or returns NULL. // Returns an interface for testing (stub only), or returns NULL.
virtual TestInterface* GetTestInterface() = 0; virtual TestInterface* GetTestInterface() = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment