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