shill: Service: Implement "SetProperties" DBus call
Configure multiple Service properties at once in a single call.
This method differs from Manager::ConfigureService in two important
ways: Firstly, since this is a service method, the service is
found via its RPC identifier as opposed to its GUID or other
properties. Secondly, only the service properties are set -- it
is not assigned a profile like ConfigureService -- in fact the
"Profile" property is silently ignored if provided to this call.
BUG=None
TEST=Unit tests
Change-Id: Ied4b75184bc4c27d88652dc14d14ef3f49b1574e
Reviewed-on: https://gerrit.chromium.org/gerrit/60775
Reviewed-by: Steven Bennetts <stevenjb@chromium.org>
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
Commit-Queue: Paul Stewart <pstew@chromium.org>
diff --git a/dbus_bindings/org.chromium.flimflam.Service.xml b/dbus_bindings/org.chromium.flimflam.Service.xml
index c178c52..01240fe 100644
--- a/dbus_bindings/org.chromium.flimflam.Service.xml
+++ b/dbus_bindings/org.chromium.flimflam.Service.xml
@@ -10,6 +10,9 @@
<arg type="s" direction="in"/>
<arg type="v" direction="in"/>
</method>
+ <method name="SetProperties">
+ <arg type="a{sv}" direction="in"/>
+ </method>
<method name="ClearProperty">
<arg type="s" direction="in"/>
</method>
diff --git a/doc/service-api.txt b/doc/service-api.txt
index 907bfa9..45d10fb 100644
--- a/doc/service-api.txt
+++ b/doc/service-api.txt
@@ -22,6 +22,22 @@
[service].Error.InvalidService
[service].Error.InvalidPassphrase
+ void SetProperties(dict properties)
+
+ Set multiple properties in a Service at once.
+ Each property from the dict is applied, excluding
+ the "Profile" property and all properties intrinsic
+ to the service including "Type" for all services,
+ as well as "Mode", "SSID" and "Security" for WiFi
+ services. In the event of multiple errors while
+ applying properties to the service, the first error
+ code is returned by this call.
+
+ Possible Errors: [service].Error.InvalidArguments
+ [service].Error.InvalidProperty
+ [service].Error.InvalidService
+ [service].Error.InvalidPassphrase
+
void ClearProperty(string name)
Clear the value of the specified property. Only
diff --git a/manager.h b/manager.h
index f1afc96..0d86f7f 100644
--- a/manager.h
+++ b/manager.h
@@ -96,9 +96,9 @@
ProfileRefPtr LookupProfileByRpcIdentifier(const std::string &profile_rpcid);
// Called via RPC call on Service (|to_set|) to set the "Profile" property.
- void SetProfileForService(const ServiceRefPtr &to_set,
- const std::string &profile,
- Error *error);
+ virtual void SetProfileForService(const ServiceRefPtr &to_set,
+ const std::string &profile,
+ Error *error);
virtual void RegisterDevice(const DeviceRefPtr &to_manage);
virtual void DeregisterDevice(const DeviceRefPtr &to_forget);
diff --git a/mock_manager.h b/mock_manager.h
index 8d3ab28..9ac6ce8 100644
--- a/mock_manager.h
+++ b/mock_manager.h
@@ -29,6 +29,9 @@
MOCK_CONST_METHOD0(run_path, const base::FilePath &());
MOCK_METHOD0(Start, void());
MOCK_METHOD0(Stop, void());
+ MOCK_METHOD3(SetProfileForService, void(const ServiceRefPtr &to_set,
+ const std::string &profile,
+ Error *error));
MOCK_METHOD1(RegisterDevice, void(const DeviceRefPtr &to_manage));
MOCK_METHOD1(DeregisterDevice, void(const DeviceRefPtr &to_forget));
MOCK_METHOD1(HasService, bool(const ServiceRefPtr &to_manage));
diff --git a/service_dbus_adaptor.cc b/service_dbus_adaptor.cc
index 1dcc351..71003d6 100644
--- a/service_dbus_adaptor.cc
+++ b/service_dbus_adaptor.cc
@@ -94,6 +94,21 @@
DBusAdaptor::SetProperty(service_->mutable_store(), name, value, &error);
}
+void ServiceDBusAdaptor::SetProperties(
+ const map<string, ::DBus::Variant> &args,
+ ::DBus::Error &error) {
+ SLOG(DBus, 2) << __func__;
+ KeyValueStore args_store;
+ Error key_value_store_error;
+ DBusAdaptor::ArgsToKeyValueStore(args, &args_store, &key_value_store_error);
+ if (key_value_store_error.ToDBusError(&error)) {
+ return;
+ }
+ Error configure_error;
+ service_->Configure(args_store, &configure_error);
+ configure_error.ToDBusError(&error);
+}
+
void ServiceDBusAdaptor::ClearProperty(const string &name,
::DBus::Error &error) {
SLOG(DBus, 2) << __func__ << ": " << name;
diff --git a/service_dbus_adaptor.h b/service_dbus_adaptor.h
index 2d3d451..521d064 100644
--- a/service_dbus_adaptor.h
+++ b/service_dbus_adaptor.h
@@ -54,6 +54,8 @@
void SetProperty(const std::string& name,
const ::DBus::Variant& value,
::DBus::Error &error);
+ void SetProperties(const std::map<std::string, ::DBus::Variant> &args,
+ ::DBus::Error &error);
void ClearProperty(const std::string&, ::DBus::Error &error);
std::vector<bool> ClearProperties(const std::vector<std::string>&,
::DBus::Error &error);
diff --git a/service_unittest.cc b/service_unittest.cc
index f0dd01a..6f657cf 100644
--- a/service_unittest.cc
+++ b/service_unittest.cc
@@ -867,6 +867,16 @@
EXPECT_FALSE(service_->auto_connect());
}
+TEST_F(ServiceTest, ConfigureProfileProperty) {
+ // Ensure that the Profile property is always ignored.
+ KeyValueStore args;
+ args.SetString(flimflam::kProfileProperty, "profile");
+ Error error;
+ EXPECT_CALL(mock_manager_, SetProfileForService(_, _, _)).Times(0);
+ service_->Configure(args, &error);
+ EXPECT_TRUE(error.IsSuccess());
+}
+
TEST_F(ServiceTest, DoPropertiesMatch) {
service_->SetAutoConnect(false);
const string kGUID0 = "guid_zero";