Home | History | Annotate | Download | only in src
      1 // 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 
      8 #include <map>
      9 #include <memory>
     10 
     11 #include <base/callback_list.h>
     12 #include <base/time/clock.h>
     13 #include <base/values.h>
     14 #include <weave/error.h>
     15 
     16 #include "src/commands/command_queue.h"
     17 
     18 namespace weave {
     19 
     20 class CommandInstance;
     21 
     22 enum class UserRole {
     23   kViewer,
     24   kUser,
     25   kManager,
     26   kOwner,
     27 };
     28 
     29 // 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.
     33 struct ComponentStateChange {
     34   ComponentStateChange(base::Time time,
     35                        const std::string& path,
     36                        std::unique_ptr<base::DictionaryValue> properties)
     37       : timestamp{time},
     38         component{path},
     39         changed_properties{std::move(properties)} {}
     40   base::Time timestamp;
     41   std::string component;
     42   std::unique_ptr<base::DictionaryValue> changed_properties;
     43 };
     44 
     45 class ComponentManager {
     46  public:
     47   using UpdateID = uint64_t;
     48   using Token =
     49       std::unique_ptr<base::CallbackList<void(UpdateID)>::Subscription>;
     50   struct StateSnapshot {
     51     UpdateID update_id;
     52     std::vector<ComponentStateChange> state_changes;
     53   };
     54 
     55   ComponentManager() {}
     56   virtual ~ComponentManager() {}
     57 
     58   // Loads trait definition schema.
     59   virtual bool LoadTraits(const base::DictionaryValue& dict,
     60                           ErrorPtr* error) = 0;
     61 
     62   // Same as the overload above, but takes a json string to read the trait
     63   // definitions from.
     64   virtual bool LoadTraits(const std::string& json, ErrorPtr* error) = 0;
     65 
     66   // Sets callback which is called when new trait definitions are added.
     67   virtual void AddTraitDefChangedCallback(const base::Closure& callback) = 0;
     68 
     69   // Adds a new component instance to device.
     70   // |path| is a path to the parent component (or empty string if a root-level
     71   // component is being added).
     72   // |name| is a component name being added.
     73   // |traits| is a list of trait names this component supports.
     74   virtual bool AddComponent(const std::string& path,
     75                             const std::string& name,
     76                             const std::vector<std::string>& traits,
     77                             ErrorPtr* error) = 0;
     78 
     79   // Adds a new component instance to device, as a part of component array.
     80   // |path| is a path to the parent component.
     81   // |name| is an array root element inside the child components.
     82   // |traits| is a list of trait names this component supports.
     83   virtual bool AddComponentArrayItem(const std::string& path,
     84                                      const std::string& name,
     85                                      const std::vector<std::string>& traits,
     86                                      ErrorPtr* error) = 0;
     87 
     88   // Removes an existing component instance from device.
     89   // |path| is a path to the parent component (or empty string if a root-level
     90   // component is being removed).
     91   // |name| is a name of the component to be removed.
     92   virtual bool RemoveComponent(const std::string& path,
     93                                const std::string& name,
     94                                ErrorPtr* error) = 0;
     95 
     96   // Removes an element from component array.
     97   // |path| is a path to the parent component.
     98   // |index| is a zero-based element index in the component array.
     99   virtual bool RemoveComponentArrayItem(const std::string& path,
    100                                         const std::string& name,
    101                                         size_t index,
    102                                         ErrorPtr* error) = 0;
    103 
    104   // Sets callback which is called when new components are added.
    105   virtual void AddComponentTreeChangedCallback(
    106       const base::Closure& callback) = 0;
    107 
    108   // Adds a new command instance to the command queue. The command specified in
    109   // |command_instance| must be fully initialized and have its name, component,
    110   // id populated.
    111   virtual void
    112   AddCommand(std::unique_ptr<CommandInstance> command_instance) = 0;
    113 
    114   // Parses the command definition from a json dictionary. The resulting command
    115   // instance is populated with all the required fields and partially validated
    116   // against syntax/schema.
    117   // The new command ID is returned through optional |id| param.
    118   virtual std::unique_ptr<CommandInstance> ParseCommandInstance(
    119       const base::DictionaryValue& command,
    120       Command::Origin command_origin,
    121       UserRole role,
    122       std::string* id,
    123       ErrorPtr* error) = 0;
    124 
    125   // Find a command instance with the given ID in the command queue.
    126   virtual CommandInstance* FindCommand(const std::string& id) = 0;
    127 
    128   // Command queue monitoring callbacks (called when a new command is added to
    129   // or removed from the queue).
    130   virtual void AddCommandAddedCallback(
    131       const CommandQueue::CommandCallback& callback) = 0;
    132   virtual void AddCommandRemovedCallback(
    133       const CommandQueue::CommandCallback& callback) = 0;
    134 
    135   // Adds a command handler for specific component's command.
    136   // |component_path| is a path to target component (e.g. "stove.burners[2]").
    137   // |command_name| is a full path of the command, including trait name and
    138   // command name (e.g. "burner.setPower").
    139   virtual void AddCommandHandler(
    140       const std::string& component_path,
    141       const std::string& command_name,
    142       const Device::CommandHandlerCallback& callback) = 0;
    143 
    144   // Finds a component instance by its full path.
    145   virtual const base::DictionaryValue* FindComponent(const std::string& path,
    146                                                      ErrorPtr* error) const = 0;
    147   // Finds a definition of trait with the given |name|.
    148   virtual const base::DictionaryValue* FindTraitDefinition(
    149       const std::string& name) const = 0;
    150 
    151   // Finds a command definition, where |command_name| is in the form of
    152   // "trait.command".
    153   virtual const base::DictionaryValue* FindCommandDefinition(
    154       const std::string& command_name) const = 0;
    155 
    156   // Checks the minimum required user role for a given command.
    157   virtual bool GetMinimalRole(const std::string& command_name,
    158                               UserRole* minimal_role,
    159                               ErrorPtr* error) const = 0;
    160 
    161   // Returns the full JSON dictionary containing trait definitions.
    162   virtual const base::DictionaryValue& GetTraits() const = 0;
    163 
    164   // Returns the full JSON dictionary containing component instances.
    165   virtual const base::DictionaryValue& GetComponents() const = 0;
    166 
    167   // Component state manipulation methods.
    168   virtual bool SetStateProperties(const std::string& component_path,
    169                                   const base::DictionaryValue& dict,
    170                                   ErrorPtr* error) = 0;
    171   virtual bool SetStatePropertiesFromJson(const std::string& component_path,
    172                                           const std::string& json,
    173                                           ErrorPtr* error) = 0;
    174   virtual const base::Value* GetStateProperty(const std::string& component_path,
    175                                               const std::string& name,
    176                                               ErrorPtr* error) const = 0;
    177   virtual bool SetStateProperty(const std::string& component_path,
    178                                 const std::string& name,
    179                                 const base::Value& value,
    180                                 ErrorPtr* error) = 0;
    181 
    182   virtual void AddStateChangedCallback(const base::Closure& callback) = 0;
    183 
    184   // Returns the recorded state changes since last time this method was called.
    185   virtual StateSnapshot GetAndClearRecordedStateChanges() = 0;
    186 
    187   // Called to notify that the state patch with |id| has been successfully sent
    188   // to the server and processed.
    189   virtual void NotifyStateUpdatedOnServer(UpdateID id) = 0;
    190 
    191   // Returns an ID of last state change update. Each SetStatePropertyNNN()
    192   // invocation increments this value by 1.
    193   virtual UpdateID GetLastStateChangeId() const = 0;
    194 
    195   // Subscribes for device state update notifications from cloud server.
    196   // The |callback| will be called every time a state patch with given ID is
    197   // successfully received and processed by Weave server.
    198   // Returns a subscription token. As soon as this token is destroyed, the
    199   // respective callback is removed from the callback list.
    200   virtual Token AddServerStateUpdatedCallback(
    201       const base::Callback<void(UpdateID)>& callback) = 0;
    202 
    203   // Helper method for legacy API to obtain first component that implements
    204   // the given trait. This is useful for routing commands that have no component
    205   // path specified.
    206   // Returns empty string if no components are found.
    207   // This method only searches for component on the top level of components
    208   // tree. No sub-components are searched.
    209   virtual std::string FindComponentWithTrait(
    210       const std::string& trait) const = 0;
    211 
    212   // Support for legacy APIs. Setting command and state definitions.
    213   // This translates into modifying a trait definition.
    214   virtual bool AddLegacyCommandDefinitions(const base::DictionaryValue& dict,
    215                                            ErrorPtr* error) = 0;
    216   virtual bool AddLegacyStateDefinitions(const base::DictionaryValue& dict,
    217                                          ErrorPtr* error) = 0;
    218   // Returns device state for legacy APIs.
    219   virtual const base::DictionaryValue& GetLegacyState() const = 0;
    220   // Returns command definitions for legacy APIs.
    221   virtual const base::DictionaryValue& GetLegacyCommandDefinitions() const = 0;
    222 
    223   DISALLOW_COPY_AND_ASSIGN(ComponentManager);
    224 };
    225 
    226 }  // namespace weave
    227 
    228 #endif  // LIBWEAVE_SRC_COMPONENT_MANAGER_H_
    229