diff options
author | Alex Vakulenko <avakulenko@google.com> | 2015-12-09 22:18:52 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2015-12-09 22:18:52 +0000 |
commit | 0cc1f15bbaf67ce55488ec7ed8be2c2a57bc819e (patch) | |
tree | 0ba19c4b17190bae88df5134753f0e8b65cfdd55 | |
parent | 37ba0b15d4f4bb71696c5b7a918987e7c25b3faf (diff) | |
parent | 3bd3ececdd8ab45b6b2e81c8fbbbe60c850c2a2c (diff) | |
download | weaved-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-xml | 1 | ||||
-rw-r--r-- | buffet/dbus_bindings/com.android.Weave.Manager.dbus-xml | 6 | ||||
-rw-r--r-- | buffet/dbus_command_proxy.cc | 1 | ||||
-rw-r--r-- | buffet/manager.cc | 36 | ||||
-rw-r--r-- | buffet/manager.h | 4 | ||||
-rw-r--r-- | libweaved/command.cc | 4 | ||||
-rw-r--r-- | libweaved/command.h | 29 | ||||
-rw-r--r-- | libweaved/device.cc | 79 | ||||
-rw-r--r-- | libweaved/device.h | 50 | ||||
-rw-r--r-- | libweaved/export.h | 2 |
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_ |