[shill] Enable objects to query an opaque RPC-system ID from Adaptors
This is needed for some properties. For example Service has a property called Device, which is expected
to return a (in the current impl) a DBus path for the associated Device object.
BUG=chromium-os:16343
TEST=unit tests
Change-Id: I8bd32ab483331efabbfee05dbdeba045c7cb20da
Reviewed-on: http://gerrit.chromium.org/gerrit/3417
Reviewed-by: Chris Masone <cmasone@chromium.org>
Tested-by: Chris Masone <cmasone@chromium.org>
diff --git a/Makefile b/Makefile
index 6369018..b3f8a2d 100644
--- a/Makefile
+++ b/Makefile
@@ -94,6 +94,7 @@
ipconfig_unittest.o \
key_file_store_unittest.o \
manager_unittest.o \
+ mock_adaptors.o \
mock_control.o \
mock_device.o \
mock_service.o \
diff --git a/adaptor_interfaces.h b/adaptor_interfaces.h
index 6116e19..4c4a7e1 100644
--- a/adaptor_interfaces.h
+++ b/adaptor_interfaces.h
@@ -15,6 +15,11 @@
class ManagerAdaptorInterface {
public:
virtual ~ManagerAdaptorInterface() {}
+
+ // Getter for the opaque identifier that represents this object on the
+ // RPC interface to which the implementation is adapting.
+ virtual const std::string &GetRpcIdentifier() = 0;
+
virtual void UpdateRunning() = 0;
virtual void EmitBoolChanged(const std::string& name, bool value) = 0;
@@ -30,6 +35,11 @@
class ServiceAdaptorInterface {
public:
virtual ~ServiceAdaptorInterface() {}
+
+ // Getter for the opaque identifier that represents this object on the
+ // RPC interface to which the implementation is adapting.
+ virtual const std::string &GetRpcIdentifier() = 0;
+
virtual void UpdateConnected() = 0;
virtual void EmitBoolChanged(const std::string& name, bool value) = 0;
@@ -44,6 +54,10 @@
public:
virtual ~DeviceAdaptorInterface() {}
+ // Getter for the opaque identifier that represents this object on the
+ // RPC interface to which the implementation is adapting.
+ virtual const std::string &GetRpcIdentifier() = 0;
+
virtual void UpdateEnabled() = 0;
virtual void EmitBoolChanged(const std::string& name, bool value) = 0;
diff --git a/cellular_service.cc b/cellular_service.cc
index 70783c1..6cb4095 100644
--- a/cellular_service.cc
+++ b/cellular_service.cc
@@ -52,4 +52,8 @@
void CellularService::Disconnect() { }
+std::string CellularService::GetDeviceRpcId() {
+ return cellular_->GetRpcIdentifier();
+}
+
} // namespace shill
diff --git a/cellular_service.h b/cellular_service.h
index f748377..bcb003c 100644
--- a/cellular_service.h
+++ b/cellular_service.h
@@ -10,7 +10,6 @@
#include <base/basictypes.h>
-#include "shill/cellular.h"
#include "shill/refptr_types.h"
#include "shill/shill_event.h"
#include "shill/service.h"
@@ -43,6 +42,8 @@
std::map<std::string, std::string> last_good_apn_info_;
private:
+ std::string GetDeviceRpcId();
+
CellularRefPtr cellular_;
const std::string type_;
DISALLOW_COPY_AND_ASSIGN(CellularService);
diff --git a/device.cc b/device.cc
index 428f985..447adde 100644
--- a/device.cc
+++ b/device.cc
@@ -21,6 +21,7 @@
#include "shill/dhcp_provider.h"
#include "shill/error.h"
#include "shill/manager.h"
+#include "shill/property_accessor.h"
#include "shill/refptr_types.h"
#include "shill/rtnl_handler.h"
#include "shill/service.h"
@@ -44,6 +45,9 @@
running_(false) {
RegisterConstString(flimflam::kAddressProperty, &hardware_address_);
+ RegisterDerivedString(flimflam::kDBusObjectProperty,
+ &Device::GetRpcIdentifier,
+ NULL);
// TODO(cmasone): Chrome doesn't use this...does anyone?
// RegisterConstString(flimflam::kInterfaceProperty, &link_name_);
RegisterConstString(flimflam::kNameProperty, &link_name_);
@@ -53,7 +57,6 @@
// TODO(cmasone): Add support for R/O properties that return DBus object paths
// known_properties_.push_back(flimflam::kDBusConnectionProperty);
- // known_properties_.push_back(flimflam::kDBusObjectProperty);
// known_properties_.push_back(flimflam::kIPConfigsProperty);
// known_properties_.push_back(flimflam::kNetworksProperty);
@@ -136,6 +139,10 @@
return link_name();
}
+string Device::GetRpcIdentifier() {
+ return adaptor_->GetRpcIdentifier();
+}
+
void Device::DestroyIPConfig() {
if (ipconfig_.get()) {
RTNLHandler::GetInstance()->RemoveInterfaceAddress(interface_index_,
@@ -153,6 +160,13 @@
return ipconfig_->RequestIP();
}
+void Device::RegisterDerivedString(const string &name,
+ string(Device::*get)(void),
+ bool(Device::*set)(const string&)) {
+ string_properties_[name] =
+ StringAccessor(new CustomAccessor<Device, string>(this, get, set));
+}
+
void Device::IPConfigUpdatedCallback(const IPConfigRefPtr &ipconfig,
bool success) {
// TODO(petkov): Use DeviceInfo to configure IP, etc. -- maybe through
diff --git a/device.h b/device.h
index ef75711..641793a 100644
--- a/device.h
+++ b/device.h
@@ -80,10 +80,13 @@
// instance.
const std::string &UniqueName() const;
+ std::string GetRpcIdentifier();
+
protected:
FRIEND_TEST(DeviceTest, AcquireDHCPConfig);
FRIEND_TEST(DeviceTest, DestroyIPConfig);
FRIEND_TEST(DeviceTest, DestroyIPConfigNULL);
+ FRIEND_TEST(DeviceTest, GetProperties);
// If there's an IP configuration in |ipconfig_|, releases the IP address and
// destroys the configuration instance.
diff --git a/device_dbus_adaptor.h b/device_dbus_adaptor.h
index ee79a76..c6505fe 100644
--- a/device_dbus_adaptor.h
+++ b/device_dbus_adaptor.h
@@ -33,6 +33,7 @@
virtual ~DeviceDBusAdaptor();
// Implementation of DeviceAdaptorInterface.
+ virtual const std::string &GetRpcIdentifier() { return path(); }
void UpdateEnabled();
void EmitBoolChanged(const std::string& name, bool value);
void EmitUintChanged(const std::string& name, uint32 value);
diff --git a/device_unittest.cc b/device_unittest.cc
index 24a28eb..87eb627 100644
--- a/device_unittest.cc
+++ b/device_unittest.cc
@@ -16,6 +16,7 @@
#include "shill/dbus_adaptor.h"
#include "shill/dhcp_provider.h"
#include "shill/manager.h"
+#include "shill/mock_adaptors.h"
#include "shill/mock_control.h"
#include "shill/mock_device.h"
#include "shill/mock_glib.h"
@@ -75,6 +76,13 @@
EXPECT_EQ(props[flimflam::kNameProperty].reader().get_string(),
string(kDeviceName));
}
+ {
+ ::DBus::Error dbus_error;
+ DBusAdaptor::GetProperties(device_.get(), &props, &dbus_error);
+ ASSERT_FALSE(props.find(flimflam::kDBusObjectProperty) == props.end());
+ EXPECT_EQ(props[flimflam::kDBusObjectProperty].reader().get_string(),
+ string(DeviceMockAdaptor::kRpcId));
+ }
}
TEST_F(DeviceTest, Dispatch) {
diff --git a/ethernet_service.cc b/ethernet_service.cc
index 586dc33..88be67d 100644
--- a/ethernet_service.cc
+++ b/ethernet_service.cc
@@ -43,4 +43,8 @@
void EthernetService::Disconnect() { }
+std::string EthernetService::GetDeviceRpcId() {
+ return ethernet_->GetRpcIdentifier();
+}
+
} // namespace shill
diff --git a/ethernet_service.h b/ethernet_service.h
index df708ae..53cc021 100644
--- a/ethernet_service.h
+++ b/ethernet_service.h
@@ -7,7 +7,6 @@
#include <base/basictypes.h>
-#include "shill/ethernet.h"
#include "shill/refptr_types.h"
#include "shill/shill_event.h"
#include "shill/service.h"
@@ -28,6 +27,8 @@
virtual std::string CalculateState() { return "idle"; }
private:
+ std::string GetDeviceRpcId();
+
EthernetRefPtr ethernet_;
const std::string type_;
DISALLOW_COPY_AND_ASSIGN(EthernetService);
diff --git a/manager_dbus_adaptor.h b/manager_dbus_adaptor.h
index 6a9e0e4..62b8579 100644
--- a/manager_dbus_adaptor.h
+++ b/manager_dbus_adaptor.h
@@ -35,6 +35,7 @@
virtual ~ManagerDBusAdaptor();
// Implementation of ManagerAdaptorInterface.
+ virtual const std::string &GetRpcIdentifier() { return path(); }
void UpdateRunning();
void EmitBoolChanged(const std::string &name, bool value);
void EmitUintChanged(const std::string &name, uint32 value);
diff --git a/mock_adaptors.cc b/mock_adaptors.cc
new file mode 100644
index 0000000..ae3b97c
--- /dev/null
+++ b/mock_adaptors.cc
@@ -0,0 +1,38 @@
+// Copyright (c) 2011 The Chromium OS 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 <string>
+
+#include "shill/mock_adaptors.h"
+
+namespace shill {
+
+// static
+const char ManagerMockAdaptor::kRpcId[] = "manager-rpc";
+
+ManagerMockAdaptor::ManagerMockAdaptor() : rpc_id(kRpcId) {}
+
+ManagerMockAdaptor::~ManagerMockAdaptor() {}
+
+const std::string &ManagerMockAdaptor::GetRpcIdentifier() { return rpc_id; }
+
+// static
+const char ServiceMockAdaptor::kRpcId[] = "service-rpc";
+
+ServiceMockAdaptor::ServiceMockAdaptor() : rpc_id(kRpcId) {}
+
+ServiceMockAdaptor::~ServiceMockAdaptor() {}
+
+const std::string &ServiceMockAdaptor::GetRpcIdentifier() { return rpc_id; }
+
+// static
+const char DeviceMockAdaptor::kRpcId[] = "device-rpc";
+
+DeviceMockAdaptor::DeviceMockAdaptor() : rpc_id(kRpcId) {}
+
+DeviceMockAdaptor::~DeviceMockAdaptor() {}
+
+const std::string &DeviceMockAdaptor::GetRpcIdentifier() { return rpc_id; }
+
+} // namespace shill
diff --git a/mock_adaptors.h b/mock_adaptors.h
index 1993dbb..56a070c 100644
--- a/mock_adaptors.h
+++ b/mock_adaptors.h
@@ -16,8 +16,12 @@
// These are the functions that a Manager adaptor must support
class ManagerMockAdaptor : public ManagerAdaptorInterface {
public:
- ManagerMockAdaptor() {}
- virtual ~ManagerMockAdaptor() {}
+ static const char kRpcId[];
+
+ ManagerMockAdaptor();
+ virtual ~ManagerMockAdaptor();
+ virtual const std::string &GetRpcIdentifier();
+
MOCK_METHOD0(UpdateRunning, void(void));
MOCK_METHOD2(EmitBoolChanged, void(const std::string&, bool));
MOCK_METHOD2(EmitUintChanged, void(const std::string&, uint32));
@@ -25,30 +29,47 @@
MOCK_METHOD2(EmitStringChanged, void(const std::string&, const std::string&));
MOCK_METHOD1(EmitStateChanged, void(const std::string&));
+
+ private:
+ const std::string rpc_id;
};
// These are the functions that a Service adaptor must support
class ServiceMockAdaptor : public ServiceAdaptorInterface {
public:
- ServiceMockAdaptor() {}
- virtual ~ServiceMockAdaptor() {}
+ static const char kRpcId[];
+
+ ServiceMockAdaptor();
+ virtual ~ServiceMockAdaptor();
+ virtual const std::string &GetRpcIdentifier();
+
MOCK_METHOD0(UpdateConnected, void(void));
MOCK_METHOD2(EmitBoolChanged, void(const std::string&, bool));
MOCK_METHOD2(EmitUintChanged, void(const std::string&, uint32));
MOCK_METHOD2(EmitIntChanged, void(const std::string&, int));
MOCK_METHOD2(EmitStringChanged, void(const std::string&, const std::string&));
+
+ private:
+ const std::string rpc_id;
};
// These are the functions that a Device adaptor must support
class DeviceMockAdaptor : public DeviceAdaptorInterface {
public:
- DeviceMockAdaptor() {}
- virtual ~DeviceMockAdaptor() {}
+ static const char kRpcId[];
+
+ DeviceMockAdaptor();
+ virtual ~DeviceMockAdaptor();
+ virtual const std::string &GetRpcIdentifier();
+
MOCK_METHOD0(UpdateEnabled, void(void));
MOCK_METHOD2(EmitBoolChanged, void(const std::string&, bool));
MOCK_METHOD2(EmitUintChanged, void(const std::string&, uint32));
MOCK_METHOD2(EmitIntChanged, void(const std::string&, int));
MOCK_METHOD2(EmitStringChanged, void(const std::string&, const std::string&));
+
+ private:
+ const std::string rpc_id;
};
} // namespace shill
diff --git a/mock_control.cc b/mock_control.cc
index cd580f8..eaaf2a3 100644
--- a/mock_control.cc
+++ b/mock_control.cc
@@ -7,6 +7,10 @@
namespace shill {
+MockControl::MockControl() {}
+
+MockControl::~MockControl() {}
+
ManagerAdaptorInterface *MockControl::CreateManagerAdaptor(Manager *manager) {
return new ManagerMockAdaptor();
}
diff --git a/mock_control.h b/mock_control.h
index 1965916..72edb0a 100644
--- a/mock_control.h
+++ b/mock_control.h
@@ -5,15 +5,26 @@
#ifndef SHILL_MOCK_CONTROL_
#define SHILL_MOCK_CONTROL_
+#include <base/scoped_ptr.h>
+
#include "shill/control_interface.h"
namespace shill {
-// This is the Interface for the control channel for Shill.
+// An implementation of the Shill RPC-channel-interface-factory interface that
+// returns mocks.
class MockControl : public ControlInterface {
public:
+ MockControl();
+ virtual ~MockControl();
+
+ // Each of these can be called once. Ownership of the appropriate
+ // interface pointer is given up upon call.
ManagerAdaptorInterface *CreateManagerAdaptor(Manager *manager);
ServiceAdaptorInterface *CreateServiceAdaptor(Service *service);
DeviceAdaptorInterface *CreateDeviceAdaptor(Device *device);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockControl);
};
} // namespace shill
diff --git a/mock_service.h b/mock_service.h
index f418b81..6c5dbce 100644
--- a/mock_service.h
+++ b/mock_service.h
@@ -26,7 +26,7 @@
MOCK_METHOD0(Connect, void(void));
MOCK_METHOD0(Disconnect, void(void));
MOCK_METHOD0(CalculateState, std::string(void));
-
+ MOCK_METHOD0(GetDeviceRpcId, std::string(void));
private:
DISALLOW_COPY_AND_ASSIGN(MockService);
};
diff --git a/service.cc b/service.cc
index 247a466..9157cb7 100644
--- a/service.cc
+++ b/service.cc
@@ -44,7 +44,9 @@
RegisterBool(flimflam::kAutoConnectProperty, &auto_connect_);
RegisterString(flimflam::kCheckPortalProperty, &check_portal_);
RegisterConstBool(flimflam::kConnectableProperty, &connectable_);
- RegisterDerivedString(flimflam::kDeviceProperty, &Service::DeviceRPCID, NULL);
+ RegisterDerivedString(flimflam::kDeviceProperty,
+ &Service::GetDeviceRpcId,
+ NULL);
RegisterString(flimflam::kEapIdentityProperty, &eap_.identity);
RegisterString(flimflam::kEAPEAPProperty, &eap_.eap);
@@ -70,7 +72,7 @@
RegisterConstString(flimflam::kNameProperty, &name_);
RegisterInt32(flimflam::kPriorityProperty, &priority_);
RegisterDerivedString(flimflam::kProfileProperty,
- &Service::ProfileRPCID,
+ &Service::GetProfileRpcId,
NULL);
RegisterString(flimflam::kProxyConfigProperty, &proxy_config_);
RegisterBool(flimflam::kSaveCredentialsProperty, &save_credentials_);
diff --git a/service.h b/service.h
index 28c5c68..2ad00df 100644
--- a/service.h
+++ b/service.h
@@ -124,10 +124,9 @@
EventDispatcher *dispatcher_;
private:
- std::string DeviceRPCID() {
- return ""; // Will need to call Device to get this.
- }
- std::string ProfileRPCID() {
+ virtual std::string GetDeviceRpcId() = 0;
+
+ std::string GetProfileRpcId() {
return ""; // Will need to call Profile to get this.
}
diff --git a/service_dbus_adaptor.h b/service_dbus_adaptor.h
index a64aa9d..a9e0521 100644
--- a/service_dbus_adaptor.h
+++ b/service_dbus_adaptor.h
@@ -34,6 +34,7 @@
virtual ~ServiceDBusAdaptor();
// Implementation of ServiceAdaptorInterface.
+ virtual const std::string &GetRpcIdentifier() { return path(); }
void UpdateConnected();
void EmitBoolChanged(const std::string& name, bool value);
void EmitUintChanged(const std::string& name, uint32 value);
diff --git a/service_unittest.cc b/service_unittest.cc
index 5a8014c..1fdfbab 100644
--- a/service_unittest.cc
+++ b/service_unittest.cc
@@ -16,6 +16,7 @@
#include "shill/dbus_adaptor.h"
#include "shill/ethernet_service.h"
#include "shill/manager.h"
+#include "shill/mock_adaptors.h"
#include "shill/mock_control.h"
#include "shill/mock_service.h"
#include "shill/property_store_unittest.h"
@@ -34,19 +35,29 @@
class ServiceTest : public PropertyStoreTest {
public:
+ static const char kMockServiceName[];
+ static const char kMockDeviceRpcId[];
+
ServiceTest()
: service_(new MockService(&control_interface_,
&dispatcher_,
- "mock-service")) {
+ kMockServiceName)) {
}
virtual ~ServiceTest() {}
protected:
- ServiceRefPtr service_;
+ scoped_refptr<MockService> service_;
};
+const char ServiceTest::kMockServiceName[] = "mock-service";
+
+const char ServiceTest::kMockDeviceRpcId[] = "mock-device-rpc";
+
TEST_F(ServiceTest, GetProperties) {
+ EXPECT_CALL(*service_.get(), CalculateState()).WillRepeatedly(Return(""));
+ EXPECT_CALL(*service_.get(), GetDeviceRpcId())
+ .WillRepeatedly(Return(ServiceTest::kMockDeviceRpcId));
map<string, ::DBus::Variant> props;
Error error(Error::kInvalidProperty, "");
{
@@ -84,6 +95,13 @@
EXPECT_EQ(props[flimflam::kPriorityProperty].reader().get_int32(),
expected);
}
+ {
+ ::DBus::Error dbus_error;
+ DBusAdaptor::GetProperties(service_.get(), &props, &dbus_error);
+ ASSERT_FALSE(props.find(flimflam::kDeviceProperty) == props.end());
+ EXPECT_EQ(props[flimflam::kDeviceProperty].reader().get_string(),
+ string(ServiceTest::kMockDeviceRpcId));
+ }
}
TEST_F(ServiceTest, Dispatch) {
diff --git a/wifi_service.cc b/wifi_service.cc
index 260245f..6f4e959 100644
--- a/wifi_service.cc
+++ b/wifi_service.cc
@@ -82,4 +82,8 @@
wifi_->ConnectTo(*this);
}
+string WiFiService::GetDeviceRpcId() {
+ return wifi_->GetRpcIdentifier();
+}
+
} // namespace shill
diff --git a/wifi_service.h b/wifi_service.h
index a5a5c58..11ec253 100644
--- a/wifi_service.h
+++ b/wifi_service.h
@@ -37,6 +37,8 @@
private:
void RealConnect();
+ std::string GetDeviceRpcId();
+
// Properties
std::string passphrase_;
bool need_passphrase_;