blob: 426a4cce4146acac616f5f496ddcb4a4cf91e42e [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
16#include "src/commands/command_dictionary.h"
17#include "src/commands/command_queue.h"
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080018
19namespace weave {
20
21class CommandInstance;
22
Alex Vakulenko7b588fc2015-12-04 16:03:59 -080023// A simple notification record event to track component state changes.
24// The |timestamp| records the time of the state change.
25// |changed_properties| contains a property set with the new property values
26// which were updated at the time the event was recorded.
27struct ComponentStateChange {
28 ComponentStateChange(base::Time time,
29 const std::string& path,
30 std::unique_ptr<base::DictionaryValue> properties)
31 : timestamp{time}, component{path},
32 changed_properties{std::move(properties)} {}
33 base::Time timestamp;
34 std::string component;
35 std::unique_ptr<base::DictionaryValue> changed_properties;
36};
37
Alex Vakulenkoba981152015-12-05 13:58:22 -080038class ComponentManager {
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080039 public:
Alex Vakulenko7b588fc2015-12-04 16:03:59 -080040 using UpdateID = uint64_t;
41 using Token =
42 std::unique_ptr<base::CallbackList<void(UpdateID)>::Subscription>;
43 struct StateSnapshot {
44 UpdateID update_id;
45 std::vector<ComponentStateChange> state_changes;
46 };
47
Alex Vakulenkoba981152015-12-05 13:58:22 -080048 ComponentManager() {}
49 virtual ~ComponentManager() {}
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080050
51 // Loads trait definition schema.
Alex Vakulenkoba981152015-12-05 13:58:22 -080052 virtual bool LoadTraits(const base::DictionaryValue& dict,
53 ErrorPtr* error) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080054
55 // Same as the overload above, but takes a json string to read the trait
56 // definitions from.
Alex Vakulenkoba981152015-12-05 13:58:22 -080057 virtual bool LoadTraits(const std::string& json, ErrorPtr* error) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080058
59 // Sets callback which is called when new trait definitions are added.
Alex Vakulenkoba981152015-12-05 13:58:22 -080060 virtual void AddTraitDefChangedCallback(const base::Closure& callback) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080061
62 // Adds a new component instance to device.
63 // |path| is a path to the parent component (or empty string if a root-level
64 // component is being added).
65 // |name| is a component name being added.
66 // |traits| is a list of trait names this component supports.
Alex Vakulenkoba981152015-12-05 13:58:22 -080067 virtual bool AddComponent(const std::string& path,
68 const std::string& name,
69 const std::vector<std::string>& traits,
70 ErrorPtr* error) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080071
72 // Adds a new component instance to device, as a part of component array.
73 // |path| is a path to the parent component.
74 // |name| is an array root element inside the child components.
75 // |traits| is a list of trait names this component supports.
Alex Vakulenkoba981152015-12-05 13:58:22 -080076 virtual bool AddComponentArrayItem(const std::string& path,
77 const std::string& name,
78 const std::vector<std::string>& traits,
79 ErrorPtr* error) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080080
Alex Vakulenko7b588fc2015-12-04 16:03:59 -080081 // Sets callback which is called when new components are added.
Alex Vakulenkoba981152015-12-05 13:58:22 -080082 virtual void AddComponentTreeChangedCallback(
83 const base::Closure& callback) = 0;
Alex Vakulenko7b588fc2015-12-04 16:03:59 -080084
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080085 // Adds a new command instance to the command queue. The command specified in
86 // |command_instance| must be fully initialized and have its name, component,
87 // id populated.
Alex Vakulenkoba981152015-12-05 13:58:22 -080088 virtual void AddCommand(
89 std::unique_ptr<CommandInstance> command_instance) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080090
91 // Parses the command definition from a json dictionary and adds it to the
92 // command queue. The new command ID is returned through optional |id| param.
Alex Vakulenkoba981152015-12-05 13:58:22 -080093 virtual bool AddCommand(const base::DictionaryValue& command,
94 UserRole role,
95 std::string* id,
96 ErrorPtr* error) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -080097
98 // Find a command instance with the given ID in the command queue.
Alex Vakulenkoba981152015-12-05 13:58:22 -080099 virtual CommandInstance* FindCommand(const std::string& id) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800100
101 // Command queue monitoring callbacks (called when a new command is added to
102 // or removed from the queue).
Alex Vakulenkoba981152015-12-05 13:58:22 -0800103 virtual void AddCommandAddedCallback(
104 const CommandQueue::CommandCallback& callback) = 0;
105 virtual void AddCommandRemovedCallback(
106 const CommandQueue::CommandCallback& callback) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800107
108 // Adds a command handler for specific component's command.
109 // |component_path| is a path to target component (e.g. "stove.burners[2]").
110 // |command_name| is a full path of the command, including trait name and
111 // command name (e.g. "burner.setPower").
Alex Vakulenkoba981152015-12-05 13:58:22 -0800112 virtual void AddCommandHandler(
113 const std::string& component_path,
114 const std::string& command_name,
115 const Device::CommandHandlerCallback& callback) = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800116
117 // Finds a component instance by its full path.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800118 virtual const base::DictionaryValue* FindComponent(
119 const std::string& path,
120 ErrorPtr* error) const = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800121 // Finds a definition of trait with the given |name|.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800122 virtual const base::DictionaryValue* FindTraitDefinition(
123 const std::string& name) const = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800124
125 // Finds a command definition, where |command_name| is in the form of
126 // "trait.command".
Alex Vakulenkoba981152015-12-05 13:58:22 -0800127 virtual const base::DictionaryValue* FindCommandDefinition(
128 const std::string& command_name) const = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800129
130 // Checks the minimum required user role for a given command.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800131 virtual bool GetMinimalRole(const std::string& command_name,
132 UserRole* minimal_role,
133 ErrorPtr* error) const = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800134
135 // Returns the full JSON dictionary containing trait definitions.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800136 virtual const base::DictionaryValue& GetTraits() const = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800137
138 // Returns the full JSON dictionary containing component instances.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800139 virtual const base::DictionaryValue& GetComponents() const = 0;
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800140
Alex Vakulenko7b588fc2015-12-04 16:03:59 -0800141 // Component state manipulation methods.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800142 virtual bool SetStateProperties(const std::string& component_path,
143 const base::DictionaryValue& dict,
144 ErrorPtr* error) = 0;
145 virtual bool SetStatePropertiesFromJson(const std::string& component_path,
146 const std::string& json,
147 ErrorPtr* error) = 0;
148 virtual const base::Value* GetStateProperty(const std::string& component_path,
149 const std::string& name,
150 ErrorPtr* error) const = 0;
151 virtual bool SetStateProperty(const std::string& component_path,
152 const std::string& name,
153 const base::Value& value,
154 ErrorPtr* error) = 0;
Alex Vakulenko7b588fc2015-12-04 16:03:59 -0800155
Alex Vakulenkoba981152015-12-05 13:58:22 -0800156 virtual void AddStateChangedCallback(const base::Closure& callback) = 0;
Alex Vakulenko7b588fc2015-12-04 16:03:59 -0800157
158 // Returns the recorded state changes since last time this method was called.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800159 virtual StateSnapshot GetAndClearRecordedStateChanges() = 0;
Alex Vakulenko7b588fc2015-12-04 16:03:59 -0800160
161 // Called to notify that the state patch with |id| has been successfully sent
162 // to the server and processed.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800163 virtual void NotifyStateUpdatedOnServer(UpdateID id) = 0;
Alex Vakulenko7b588fc2015-12-04 16:03:59 -0800164
165 // Returns an ID of last state change update. Each SetStatePropertyNNN()
166 // invocation increments this value by 1.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800167 virtual UpdateID GetLastStateChangeId() const = 0;
Alex Vakulenko7b588fc2015-12-04 16:03:59 -0800168
169 // Subscribes for device state update notifications from cloud server.
170 // The |callback| will be called every time a state patch with given ID is
171 // successfully received and processed by Weave server.
172 // Returns a subscription token. As soon as this token is destroyed, the
173 // respective callback is removed from the callback list.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800174 virtual Token AddServerStateUpdatedCallback(
175 const base::Callback<void(UpdateID)>& callback) = 0;
Alex Vakulenko7b588fc2015-12-04 16:03:59 -0800176
Alex Vakulenkoa3c5e6d2015-12-04 17:54:38 -0800177 // Helper method for legacy API to obtain first component that implements
178 // the given trait. This is useful for routing commands that have no component
179 // path specified.
180 // Returns empty string if no components are found.
181 // This method only searches for component on the top level of components
182 // tree. No sub-components are searched.
Alex Vakulenkoba981152015-12-05 13:58:22 -0800183 virtual std::string FindComponentWithTrait(
184 const std::string& trait) const = 0;
Alex Vakulenko7b588fc2015-12-04 16:03:59 -0800185
Alex Vakulenko44c1dbe2015-12-03 15:35:09 -0800186 DISALLOW_COPY_AND_ASSIGN(ComponentManager);
187};
188
189} // namespace weave
190
191#endif // LIBWEAVE_SRC_COMPONENT_MANAGER_H_