blob: 5f16ac43a9155ba618e8981cd1c35ac6abc784f0 [file] [log] [blame]
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -08001// Copyright 2015 The Weave Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef LIBWEAVE_SRC_COMPONENT_MANAGER_H_
6#define LIBWEAVE_SRC_COMPONENT_MANAGER_H_
7
Alex Vakulenko7b588fc2015-12-04 16:03:59 -08008#include <map>
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -08009#include <memory>
10
Alex Vakulenko7b588fc2015-12-04 16:03:59 -080011#include <base/callback_list.h>
12#include <base/time/clock.h>
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080013#include <base/values.h>
14#include <weave/error.h>
15
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080016#include "src/commands/command_queue.h"
17
18namespace weave {
19
20class CommandInstance;
21
Alex Vakulenkod91d6252015-12-05 17:14:39 -080022enum class UserRole {
23 kViewer,
24 kUser,
25 kManager,
26 kOwner,
27};
28
Alex Vakulenko7b588fc2015-12-04 16:03:59 -080029// A simple notification record event to track component state changes.
30// The |timestamp| records the time of the state change.
31// |changed_properties| contains a property set with the new property values
32// which were updated at the time the event was recorded.
33struct ComponentStateChange {
34 ComponentStateChange(base::Time time,
35 const std::string& path,
36 std::unique_ptr<base::DictionaryValue> properties)
37 : timestamp{time}, component{path},
38 changed_properties{std::move(properties)} {}
39 base::Time timestamp;
40 std::string component;
41 std::unique_ptr<base::DictionaryValue> changed_properties;
42};
43
Alex Vakulenkoba981152015-12-05 13:58:22 -080044class ComponentManager {
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080045 public:
Alex Vakulenko7b588fc2015-12-04 16:03:59 -080046 using UpdateID = uint64_t;
47 using Token =
48 std::unique_ptr<base::CallbackList<void(UpdateID)>::Subscription>;
49 struct StateSnapshot {
50 UpdateID update_id;
51 std::vector<ComponentStateChange> state_changes;
52 };
53
Alex Vakulenkoba981152015-12-05 13:58:22 -080054 ComponentManager() {}
55 virtual ~ComponentManager() {}
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080056
57 // Loads trait definition schema.
Alex Vakulenkoba981152015-12-05 13:58:22 -080058 virtual bool LoadTraits(const base::DictionaryValue& dict,
59 ErrorPtr* error) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080060
61 // Same as the overload above, but takes a json string to read the trait
62 // definitions from.
Alex Vakulenkoba981152015-12-05 13:58:22 -080063 virtual bool LoadTraits(const std::string& json, ErrorPtr* error) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080064
65 // Sets callback which is called when new trait definitions are added.
Alex Vakulenkoba981152015-12-05 13:58:22 -080066 virtual void AddTraitDefChangedCallback(const base::Closure& callback) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080067
68 // Adds a new component instance to device.
69 // |path| is a path to the parent component (or empty string if a root-level
70 // component is being added).
71 // |name| is a component name being added.
72 // |traits| is a list of trait names this component supports.
Alex Vakulenkoba981152015-12-05 13:58:22 -080073 virtual bool AddComponent(const std::string& path,
74 const std::string& name,
75 const std::vector<std::string>& traits,
76 ErrorPtr* error) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080077
78 // Adds a new component instance to device, as a part of component array.
79 // |path| is a path to the parent component.
80 // |name| is an array root element inside the child components.
81 // |traits| is a list of trait names this component supports.
Alex Vakulenkoba981152015-12-05 13:58:22 -080082 virtual bool AddComponentArrayItem(const std::string& path,
83 const std::string& name,
84 const std::vector<std::string>& traits,
85 ErrorPtr* error) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080086
Alex Vakulenko7b588fc2015-12-04 16:03:59 -080087 // Sets callback which is called when new components are added.
Alex Vakulenkoba981152015-12-05 13:58:22 -080088 virtual void AddComponentTreeChangedCallback(
89 const base::Closure& callback) = 0;
Alex Vakulenko7b588fc2015-12-04 16:03:59 -080090
Alex Vakulenkod91d6252015-12-05 17:14:39 -080091 // Adds a new command instance to the command queue. The command specified in
92 // |command_instance| must be fully initialized and have its name, component,
93 // id populated.
94 virtual void AddCommand(
95 std::unique_ptr<CommandInstance> command_instance) = 0;
96
97 // Parses the command definition from a json dictionary. The resulting command
98 // instance is populated with all the required fields and partially validated
99 // against syntax/schema.
100 // The new command ID is returned through optional |id| param.
101 virtual std::unique_ptr<CommandInstance> ParseCommandInstance(
102 const base::DictionaryValue& command,
103 Command::Origin command_origin,
104 UserRole role,
105 std::string* id,
106 ErrorPtr* error) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800107
108 // Find a command instance with the given ID in the command queue.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800109 virtual CommandInstance* FindCommand(const std::string& id) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800110
111 // Command queue monitoring callbacks (called when a new command is added to
112 // or removed from the queue).
Alex Vakulenkoba981152015-12-05 13:58:22 -0800113 virtual void AddCommandAddedCallback(
114 const CommandQueue::CommandCallback& callback) = 0;
115 virtual void AddCommandRemovedCallback(
116 const CommandQueue::CommandCallback& callback) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800117
118 // Adds a command handler for specific component's command.
119 // |component_path| is a path to target component (e.g. "stove.burners[2]").
120 // |command_name| is a full path of the command, including trait name and
121 // command name (e.g. "burner.setPower").
Alex Vakulenkoba981152015-12-05 13:58:22 -0800122 virtual void AddCommandHandler(
123 const std::string& component_path,
124 const std::string& command_name,
125 const Device::CommandHandlerCallback& callback) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800126
127 // Finds a component instance by its full path.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800128 virtual const base::DictionaryValue* FindComponent(
129 const std::string& path,
130 ErrorPtr* error) const = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800131 // Finds a definition of trait with the given |name|.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800132 virtual const base::DictionaryValue* FindTraitDefinition(
133 const std::string& name) const = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800134
135 // Finds a command definition, where |command_name| is in the form of
136 // "trait.command".
Alex Vakulenkoba981152015-12-05 13:58:22 -0800137 virtual const base::DictionaryValue* FindCommandDefinition(
138 const std::string& command_name) const = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800139
140 // Checks the minimum required user role for a given command.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800141 virtual bool GetMinimalRole(const std::string& command_name,
142 UserRole* minimal_role,
143 ErrorPtr* error) const = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800144
145 // Returns the full JSON dictionary containing trait definitions.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800146 virtual const base::DictionaryValue& GetTraits() const = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800147
148 // Returns the full JSON dictionary containing component instances.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800149 virtual const base::DictionaryValue& GetComponents() const = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800150
Alex Vakulenko7b588fc2015-12-04 16:03:59 -0800151 // Component state manipulation methods.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800152 virtual bool SetStateProperties(const std::string& component_path,
153 const base::DictionaryValue& dict,
154 ErrorPtr* error) = 0;
155 virtual bool SetStatePropertiesFromJson(const std::string& component_path,
156 const std::string& json,
157 ErrorPtr* error) = 0;
158 virtual const base::Value* GetStateProperty(const std::string& component_path,
159 const std::string& name,
160 ErrorPtr* error) const = 0;
161 virtual bool SetStateProperty(const std::string& component_path,
162 const std::string& name,
163 const base::Value& value,
164 ErrorPtr* error) = 0;
Alex Vakulenko7b588fc2015-12-04 16:03:59 -0800165
Alex Vakulenkoba981152015-12-05 13:58:22 -0800166 virtual void AddStateChangedCallback(const base::Closure& callback) = 0;
Alex Vakulenko7b588fc2015-12-04 16:03:59 -0800167
168 // Returns the recorded state changes since last time this method was called.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800169 virtual StateSnapshot GetAndClearRecordedStateChanges() = 0;
Alex Vakulenko7b588fc2015-12-04 16:03:59 -0800170
171 // Called to notify that the state patch with |id| has been successfully sent
172 // to the server and processed.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800173 virtual void NotifyStateUpdatedOnServer(UpdateID id) = 0;
Alex Vakulenko7b588fc2015-12-04 16:03:59 -0800174
175 // Returns an ID of last state change update. Each SetStatePropertyNNN()
176 // invocation increments this value by 1.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800177 virtual UpdateID GetLastStateChangeId() const = 0;
Alex Vakulenko7b588fc2015-12-04 16:03:59 -0800178
179 // Subscribes for device state update notifications from cloud server.
180 // The |callback| will be called every time a state patch with given ID is
181 // successfully received and processed by Weave server.
182 // Returns a subscription token. As soon as this token is destroyed, the
183 // respective callback is removed from the callback list.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800184 virtual Token AddServerStateUpdatedCallback(
185 const base::Callback<void(UpdateID)>& callback) = 0;
Alex Vakulenko7b588fc2015-12-04 16:03:59 -0800186
Alex Vakulenkoa3c5e6d2015-12-04 17:54:38 -0800187 // Helper method for legacy API to obtain first component that implements
188 // the given trait. This is useful for routing commands that have no component
189 // path specified.
190 // Returns empty string if no components are found.
191 // This method only searches for component on the top level of components
192 // tree. No sub-components are searched.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800193 virtual std::string FindComponentWithTrait(
194 const std::string& trait) const = 0;
Alex Vakulenko7b588fc2015-12-04 16:03:59 -0800195
Alex Vakulenko6b394d12015-12-05 15:52:54 -0800196 // Support for legacy APIs. Setting command and state definitions.
197 // This translates into modifying a trait definition.
198 virtual bool AddLegacyCommandDefinitions(const base::DictionaryValue& dict,
199 ErrorPtr* error) = 0;
200 virtual bool AddLegacyStateDefinitions(const base::DictionaryValue& dict,
201 ErrorPtr* error) = 0;
202 // Returns device state for legacy APIs.
203 virtual const base::DictionaryValue& GetLegacyState() const = 0;
204 // Returns command definitions for legacy APIs.
205 virtual const base::DictionaryValue& GetLegacyCommandDefinitions() const = 0;
206
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800207 DISALLOW_COPY_AND_ASSIGN(ComponentManager);
208};
209
210} // namespace weave
211
212#endif // LIBWEAVE_SRC_COMPONENT_MANAGER_H_