aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Vakulenko <avakulenko@google.com>2015-12-09 22:18:52 +0000
committerandroid-build-merger <android-build-merger@google.com>2015-12-09 22:18:52 +0000
commit0cc1f15bbaf67ce55488ec7ed8be2c2a57bc819e (patch)
tree0ba19c4b17190bae88df5134753f0e8b65cfdd55
parent37ba0b15d4f4bb71696c5b7a918987e7c25b3faf (diff)
parent3bd3ececdd8ab45b6b2e81c8fbbbe60c850c2a2c (diff)
downloadweaved-0cc1f15bbaf67ce55488ec7ed8be2c2a57bc819e.tar.gz
Add trait/component APIs to weaved
am: 3bd3ececdd * commit '3bd3ececdd8ab45b6b2e81c8fbbbe60c850c2a2c': Add trait/component APIs to weaved
-rw-r--r--buffet/dbus_bindings/com.android.Weave.Command.dbus-xml1
-rw-r--r--buffet/dbus_bindings/com.android.Weave.Manager.dbus-xml6
-rw-r--r--buffet/dbus_command_proxy.cc1
-rw-r--r--buffet/manager.cc36
-rw-r--r--buffet/manager.h4
-rw-r--r--libweaved/command.cc4
-rw-r--r--libweaved/command.h29
-rw-r--r--libweaved/device.cc79
-rw-r--r--libweaved/device.h50
-rw-r--r--libweaved/export.h2
10 files changed, 193 insertions, 19 deletions
diff --git a/buffet/dbus_bindings/com.android.Weave.Command.dbus-xml b/buffet/dbus_bindings/com.android.Weave.Command.dbus-xml
index 46913b3..3602135 100644
--- a/buffet/dbus_bindings/com.android.Weave.Command.dbus-xml
+++ b/buffet/dbus_bindings/com.android.Weave.Command.dbus-xml
@@ -33,6 +33,7 @@
</method>
<property name="Name" type="s" access="read"/>
<property name="Id" type="s" access="read"/>
+ <property name="Component" type="s" access="read"/>
<property name="State" type="s" access="read"/>
<property name="Parameters" type="a{sv}" access="read"/>
<property name="Progress" type="a{sv}" access="read"/>
diff --git a/buffet/dbus_bindings/com.android.Weave.Manager.dbus-xml b/buffet/dbus_bindings/com.android.Weave.Manager.dbus-xml
index a922491..ad26785 100644
--- a/buffet/dbus_bindings/com.android.Weave.Manager.dbus-xml
+++ b/buffet/dbus_bindings/com.android.Weave.Manager.dbus-xml
@@ -13,7 +13,13 @@
<arg name="device_id" type="s" direction="out"/>
<annotation name="org.chromium.DBus.Method.Kind" value="async"/>
</method>
+ <method name="AddComponent">
+ <arg name="name" type="s" direction="in"/>
+ <arg name="traits" type="as" direction="in"/>
+ <annotation name="org.chromium.DBus.Method.Kind" value="async"/>
+ </method>
<method name="UpdateState">
+ <arg name="component" type="s" direction="in"/>
<arg name="property_set" type="a{sv}" direction="in"/>
<annotation name="org.chromium.DBus.Method.Kind" value="async"/>
</method>
diff --git a/buffet/dbus_command_proxy.cc b/buffet/dbus_command_proxy.cc
index b7e82c1..011ba01 100644
--- a/buffet/dbus_command_proxy.cc
+++ b/buffet/dbus_command_proxy.cc
@@ -62,6 +62,7 @@ void DBusCommandProxy::RegisterAsync(
// Set the initial property values before registering the DBus object.
dbus_adaptor_.SetName(command->GetName());
dbus_adaptor_.SetId(command->GetID());
+ dbus_adaptor_.SetComponent(command->GetComponent());
dbus_adaptor_.SetState(EnumToString(command->GetState()));
dbus_adaptor_.SetProgress(
DictionaryToDBusVariantDictionary(command->GetProgress()));
diff --git a/buffet/manager.cc b/buffet/manager.cc
index 61a5d7a..85a9024 100644
--- a/buffet/manager.cc
+++ b/buffet/manager.cc
@@ -80,6 +80,23 @@ bool LoadFile(const base::FilePath& file_path,
return true;
}
+void LoadTraitDefinitions(const BuffetConfig::Options& options,
+ weave::Device* device) {
+ // Load component-specific device trait definitions.
+ base::FilePath dir{options.definitions.Append("traits")};
+ LOG(INFO) << "Looking for trait definitions in " << dir.value();
+ base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES,
+ FILE_PATH_LITERAL("*.json"));
+ std::vector<std::string> result;
+ for (base::FilePath path = enumerator.Next(); !path.empty();
+ path = enumerator.Next()) {
+ LOG(INFO) << "Loading trait definition from " << path.value();
+ std::string json;
+ CHECK(LoadFile(path, &json, nullptr));
+ device->AddTraitDefinitionsFromJson(json);
+ }
+}
+
void LoadCommandDefinitions(const BuffetConfig::Options& options,
weave::Device* device) {
auto load_packages = [device](const base::FilePath& root,
@@ -97,7 +114,8 @@ void LoadCommandDefinitions(const BuffetConfig::Options& options,
}
};
load_packages(options.definitions, FILE_PATH_LITERAL("*.json"));
- load_packages(options.test_definitions, FILE_PATH_LITERAL("*test.json"));
+ if (!options.test_definitions.empty())
+ load_packages(options.test_definitions, FILE_PATH_LITERAL("*test.json"));
}
void LoadStateDefinitions(const BuffetConfig::Options& options,
@@ -207,6 +225,7 @@ void Manager::CreateDevice() {
mdns_client_.get(), web_serv_client_.get(),
shill_client_.get(), bluetooth_client_.get());
+ LoadTraitDefinitions(options_.config_options, device_.get());
LoadCommandDefinitions(options_.config_options, device_.get());
LoadStateDefinitions(options_.config_options, device_.get());
LoadStateDefaults(options_.config_options, device_.get());
@@ -267,7 +286,20 @@ void Manager::RegisterDeviceDone(DBusMethodResponsePtr<std::string> response,
response->Return(device_->GetSettings().cloud_id);
}
+void Manager::AddComponent(DBusMethodResponsePtr<> response,
+ const std::string& name,
+ const std::vector<std::string>& traits) {
+ brillo::ErrorPtr brillo_error;
+ weave::ErrorPtr error;
+ if (!device_->AddComponent(name, traits, &error)) {
+ ConvertError(*error, &brillo_error);
+ return response->ReplyWithError(brillo_error.get());
+ }
+ response->Return();
+}
+
void Manager::UpdateState(DBusMethodResponsePtr<> response,
+ const std::string& component,
const brillo::VariantDictionary& property_set) {
brillo::ErrorPtr brillo_error;
auto properties =
@@ -276,7 +308,7 @@ void Manager::UpdateState(DBusMethodResponsePtr<> response,
return response->ReplyWithError(brillo_error.get());
weave::ErrorPtr error;
- if (!device_->SetStateProperties(*properties, &error)) {
+ if (!device_->SetStateProperties(component, *properties, &error)) {
ConvertError(*error, &brillo_error);
return response->ReplyWithError(brillo_error.get());
}
diff --git a/buffet/manager.h b/buffet/manager.h
index e8ddcc1..1dea711 100644
--- a/buffet/manager.h
+++ b/buffet/manager.h
@@ -87,7 +87,11 @@ class Manager final : public com::android::Weave::ManagerInterface {
// DBus methods:
void RegisterDevice(DBusMethodResponsePtr<std::string> response,
const std::string& ticket_id) override;
+ void AddComponent(DBusMethodResponsePtr<> response,
+ const std::string& name,
+ const std::vector<std::string>& traits) override;
void UpdateState(DBusMethodResponsePtr<> response,
+ const std::string& component,
const brillo::VariantDictionary& property_set) override;
bool GetState(brillo::ErrorPtr* error, std::string* state) override;
void AddCommand(DBusMethodResponsePtr<std::string> response,
diff --git a/libweaved/command.cc b/libweaved/command.cc
index 8b7427f..caee8b0 100644
--- a/libweaved/command.cc
+++ b/libweaved/command.cc
@@ -31,6 +31,10 @@ const std::string& Command::GetName() const {
return proxy_->name();
}
+const std::string& Command::GetComponent() const {
+ return proxy_->component();
+}
+
Command::State Command::GetState() const {
std::string state = proxy_->state();
if (state == "queued")
diff --git a/libweaved/command.h b/libweaved/command.h
index f68b150..a8332e5 100644
--- a/libweaved/command.h
+++ b/libweaved/command.h
@@ -37,6 +37,30 @@ namespace weaved {
class Device;
+namespace detail {
+
+// Helper function for Command::GetParameter<T>. Allows specialization.
+template <typename T>
+inline bool GetValue(const brillo::Any& any, T* value) {
+ return any.GetValue<T>(value);
+}
+
+// Specialization for double, allow to extract a double from an int.
+template <>
+inline bool GetValue<double>(const brillo::Any& any, double* value) {
+ if (any.GetValue<double>(value))
+ return true;
+
+ int int_val = 0;
+ if (!any.GetValue<int>(&int_val))
+ return false;
+
+ *value = static_cast<double>(int_val);
+ return true;
+}
+
+} // namespace detail
+
class LIBWEAVED_EXPORT Command final {
public:
enum class State {
@@ -58,6 +82,9 @@ class LIBWEAVED_EXPORT Command final {
// Returns the full name of the command.
const std::string& GetName() const;
+ // Returns the name of the component this command was sent to.
+ const std::string& GetComponent() const;
+
// Returns the command state.
Command::State GetState() const;
@@ -77,7 +104,7 @@ class LIBWEAVED_EXPORT Command final {
T value{};
auto p = parameters.find(name);
if (p != parameters.end())
- p->second.GetValue<T>(&value);
+ detail::GetValue<T>(p->second, &value);
return value;
}
diff --git a/libweaved/device.cc b/libweaved/device.cc
index 0da4763..5f396a7 100644
--- a/libweaved/device.cc
+++ b/libweaved/device.cc
@@ -46,13 +46,39 @@ std::unique_ptr<Device> Device::CreateInstance(
return std::unique_ptr<Device>{new Device{bus, state_required_callback}};
}
-void Device::AddCommandHandler(const std::string& command_name,
+void Device::AddComponent(const std::string& component,
+ const std::vector<std::string>& traits) {
+ ComponentEntry entry;
+ entry.component = component;
+ entry.traits = traits;
+ components_.push_back(std::move(entry));
+ if (proxy_)
+ proxy_->AddComponent(component, traits, nullptr);
+}
+
+void Device::AddCommandHandler(const std::string& component,
+ const std::string& command_name,
const CommandHandlerCallback& callback) {
- command_handler_map_.emplace(command_name, callback);
+ for (const auto& entry : command_handlers_) {
+ if (entry.command_name != command_name)
+ continue;
+ // The command names are the same, make sure we have different components.
+ // This means that both component names are not empty and are different.
+ CHECK(!component.empty() && !entry.component.empty() &&
+ component != entry.component)
+ << "Handler for " << component << ":" << command_name << " already set";
+ }
+ CommandHandlerEntry entry;
+ entry.component = component;
+ entry.command_name = command_name;
+ entry.callback = callback;
+
+ command_handlers_.push_back(std::move(entry));
// If there are any commands already received, call the handler immediately.
for (auto& pair : command_map_) {
- if (pair.first->name() == command_name) {
+ if (pair.first->name() == command_name &&
+ (component.empty() || pair.first->component() == component)) {
if (!pair.second)
pair.second.reset(new Command{pair.first});
callback.Run(pair.second);
@@ -60,30 +86,49 @@ void Device::AddCommandHandler(const std::string& command_name,
}
}
-bool Device::SetStateProperties(const brillo::VariantDictionary& dict,
+bool Device::SetStateProperties(const std::string& component,
+ const brillo::VariantDictionary& dict,
brillo::ErrorPtr* error) {
if (proxy_)
- return proxy_->UpdateState(dict, error);
+ return proxy_->UpdateState(component, dict, error);
brillo::Error::AddTo(error, FROM_HERE, "weaved", "service_unavailable",
- "Process 'weaved' is unreachable");
+ "Process 'weaved' is unreachable");
return false;
}
+bool Device::SetStateProperty(const std::string& component,
+ const std::string& name,
+ const brillo::Any& value,
+ brillo::ErrorPtr* error) {
+ return SetStateProperties(component, brillo::VariantDictionary{{name, value}},
+ error);
+}
+
+void Device::AddCommandHandler(const std::string& command_name,
+ const CommandHandlerCallback& callback) {
+ AddCommandHandler("", command_name, callback);
+}
+
+bool Device::SetStateProperties(const brillo::VariantDictionary& dict,
+ brillo::ErrorPtr* error) {
+ return SetStateProperties("", dict, error);
+}
+
bool Device::SetStateProperty(const std::string& name,
const brillo::Any& value,
brillo::ErrorPtr* error) {
- return SetStateProperties(brillo::VariantDictionary{{name, value}}, error);
+ return SetStateProperty("", name, value, error);
}
void Device::OnCommandAdded(CommandProxyInterface* proxy) {
std::shared_ptr<Command>& command = command_map_[proxy];
- auto iter = command_handler_map_.find(proxy->name());
- if (iter == command_handler_map_.end())
+ const Device::CommandHandlerCallback* callback = FindHandlerForCommand(proxy);
+ if (!callback)
return;
if (!command)
command.reset(new Command{proxy});
- iter->second.Run(command);
+ callback->Run(command);
}
void Device::OnCommandRemoved(const dbus::ObjectPath& object_path) {
@@ -95,6 +140,8 @@ void Device::OnCommandRemoved(const dbus::ObjectPath& object_path) {
void Device::OnManagerAdded(ManagerProxyInterface* proxy) {
proxy_ = proxy;
+ for (const auto& entry : components_)
+ proxy_->AddComponent(entry.component, entry.traits, nullptr);
state_required_callback_.Run();
}
@@ -102,4 +149,16 @@ void Device::OnManagerRemoved(const dbus::ObjectPath& object_path) {
proxy_ = nullptr;
}
+const Device::CommandHandlerCallback* Device::FindHandlerForCommand(
+ com::android::Weave::CommandProxyInterface* proxy) const {
+ for (const auto& entry : command_handlers_) {
+ if (proxy->name() == entry.command_name &&
+ (entry.component.empty() || proxy->component() == entry.component)) {
+ return &entry.callback;
+ }
+ }
+ return nullptr;
+}
+
+
} // namespace weave
diff --git a/libweaved/device.h b/libweaved/device.h
index c1c5dd5..376b656 100644
--- a/libweaved/device.h
+++ b/libweaved/device.h
@@ -21,6 +21,7 @@
#include <map>
#include <memory>
#include <string>
+#include <vector>
#include <base/callback.h>
#include <base/macros.h>
@@ -60,23 +61,44 @@ class LIBWEAVED_EXPORT Device final {
using CommandHandlerCallback =
base::Callback<void(const std::weak_ptr<Command>& command)>;
+ void AddComponent(const std::string& component,
+ const std::vector<std::string>& traits);
+
// Sets handler for new commands added to the queue.
// |command_name| is the full command name of the command to handle. e.g.
// "base.reboot". Each command can have no more than one handler.
- // Empty |command_name| sets default handler for all unhanded commands.
- // No new command handlers can be set after default handler was set.
- void AddCommandHandler(const std::string& command_name,
+ void AddCommandHandler(const std::string& component,
+ const std::string& command_name,
const CommandHandlerCallback& callback);
- bool SetStateProperties(const brillo::VariantDictionary& dict,
+ bool SetStateProperties(const std::string& component,
+ const brillo::VariantDictionary& dict,
brillo::ErrorPtr* error);
// Sets value of the single property.
// |name| is full property name, including package name. e.g. "base.network".
- bool SetStateProperty(const std::string& name,
+ bool SetStateProperty(const std::string& component,
+ const std::string& name,
const brillo::Any& value,
brillo::ErrorPtr* error);
+ // Sets handler for new commands added to the queue.
+ // |command_name| is the full command name of the command to handle. e.g.
+ // "base.reboot". Each command can have no more than one handler.
+ LIBWEAVED_DEPRECATED void AddCommandHandler(
+ const std::string& command_name,
+ const CommandHandlerCallback& callback);
+
+ LIBWEAVED_DEPRECATED bool SetStateProperties(
+ const brillo::VariantDictionary& dict,
+ brillo::ErrorPtr* error);
+
+ // Sets value of the single property.
+ // |name| is full property name, including package name. e.g. "base.network".
+ LIBWEAVED_DEPRECATED bool SetStateProperty(const std::string& name,
+ const brillo::Any& value,
+ brillo::ErrorPtr* error);
+
private:
Device(const scoped_refptr<dbus::Bus>& bus,
const base::Closure& state_required_callback);
@@ -87,13 +109,29 @@ class LIBWEAVED_EXPORT Device final {
void OnManagerAdded(com::android::Weave::ManagerProxyInterface* proxy);
void OnManagerRemoved(const dbus::ObjectPath& object_path);
+ const CommandHandlerCallback* FindHandlerForCommand(
+ com::android::Weave::CommandProxyInterface* proxy) const;
+
std::unique_ptr<com::android::Weave::ObjectManagerProxy> weaved_object_mgr_;
com::android::Weave::ManagerProxyInterface* proxy_{nullptr};
using CommandMap = std::map<com::android::Weave::CommandProxyInterface*,
std::shared_ptr<Command>>;
CommandMap command_map_;
- std::map<std::string, CommandHandlerCallback> command_handler_map_;
+
+ struct CommandHandlerEntry {
+ std::string component;
+ std::string command_name;
+ CommandHandlerCallback callback;
+ };
+ std::vector<CommandHandlerEntry> command_handlers_;
+
+ struct ComponentEntry {
+ std::string component;
+ std::vector<std::string> traits;
+ };
+ std::vector<ComponentEntry> components_;
+
scoped_refptr<dbus::Bus> bus_;
base::Closure state_required_callback_;
diff --git a/libweaved/export.h b/libweaved/export.h
index eb88023..4b7999f 100644
--- a/libweaved/export.h
+++ b/libweaved/export.h
@@ -18,4 +18,6 @@
#define LIBWEAVED_EXPORT __attribute__((__visibility__("default")))
#define LIBWEAVED_PRIVATE __attribute__((__visibility__("hidden")))
+#define LIBWEAVED_DEPRECATED __attribute__((deprecated))
+
#endif // LIBWEAVED_EXPORT_H_