Home | History | Annotate | Download | only in libweaved
      1 // Copyright 2016 The Android Open Source Project
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #ifndef LIBWEAVED_SERVICE_H_
     16 #define LIBWEAVED_SERVICE_H_
     17 
     18 #include <memory>
     19 #include <string>
     20 #include <vector>
     21 
     22 #include <base/callback.h>
     23 #include <base/compiler_specific.h>
     24 #include <base/macros.h>
     25 #include <brillo/errors/error.h>
     26 #include <libweaved/command.h>
     27 #include <libweaved/export.h>
     28 
     29 namespace brillo {
     30 class MessageLoop;
     31 }  // namespace brillo
     32 
     33 namespace weaved {
     34 
     35 // A weaved service is an abstract interface representing an instance of weave
     36 // services for a particular client daemon. Apart from providing an API to
     37 // weaved process, it manages resources specific for an instance of the client.
     38 // For example, when a client exits, it removes any resources (e.g. components)
     39 // that were added by this client from the weaved's component tree.
     40 class LIBWEAVED_EXPORT Service {
     41  public:
     42   // Callback type for AddCommandHandler.
     43   using CommandHandlerCallback =
     44       base::Callback<void(std::unique_ptr<Command> command)>;
     45 
     46   // Callback type for AddPairingInfoListener.
     47   struct PairingInfo {
     48     std::string session_id;
     49     std::string pairing_mode;
     50     std::string pairing_code;
     51   };
     52   using PairingInfoCallback =
     53       base::Callback<void(const PairingInfo* pairing_info)>;
     54 
     55   Service() = default;
     56   virtual ~Service() = default;
     57 
     58   // Adds a new component instance to device.
     59   // |component| is a component name being added.
     60   // |traits| is a list of trait names this component supports.
     61   virtual bool AddComponent(const std::string& component,
     62                             const std::vector<std::string>& traits,
     63                             brillo::ErrorPtr* error) = 0;
     64 
     65   // Sets handler for new commands added to the queue for a given |component|.
     66   // |command_name| is the name of the command to handle (e.g. "reboot").
     67   // |trait_name| is the name of a trait the command belongs to (e.g. "base").
     68   // Each command can have no more than one handler.
     69   virtual void AddCommandHandler(const std::string& component,
     70                                  const std::string& trait_name,
     71                                  const std::string& command_name,
     72                                  const CommandHandlerCallback& callback) = 0;
     73 
     74   // Sets a number of state properties for a given |component|.
     75   // |dict| is a dictionary containing property-name/property-value pairs.
     76   virtual bool SetStateProperties(const std::string& component,
     77                                   const base::DictionaryValue& dict,
     78                                   brillo::ErrorPtr* error) = 0;
     79 
     80   // Sets value of the single property.
     81   // |component| is a path to the component to set the property value to.
     82   // |trait_name| is the name of the trait this property is part of.
     83   // |property_name| is the property name.
     84   virtual bool SetStateProperty(const std::string& component,
     85                                 const std::string& trait_name,
     86                                 const std::string& property_name,
     87                                 const base::Value& value,
     88                                 brillo::ErrorPtr* error) = 0;
     89 
     90   // Specifies a callback to be invoked when the device enters/exist pairing
     91   // mode. The |pairing_info| parameter is set to a pointer to pairing
     92   // information on starting the pairing session and is nullptr when the pairing
     93   // session ends.
     94   virtual void SetPairingInfoListener(const PairingInfoCallback& callback) = 0;
     95 
     96   // Service creation functionality.
     97   // Subscription is a base class for an object responsible for life-time
     98   // management for the service. The service instance is kept alive for as long
     99   // as the service connection is alive. See comments for Service::Connect for
    100   // more details.
    101   class Subscription {
    102    public:
    103     virtual ~Subscription() = default;
    104 
    105    protected:
    106     Subscription() = default;
    107 
    108    private:
    109     DISALLOW_COPY_AND_ASSIGN(Subscription);
    110   };
    111 
    112   using ConnectionCallback =
    113       base::Callback<void(const std::weak_ptr<Service>& service)>;
    114 
    115   // Creates an instance of weaved service asynchronously. This not only creates
    116   // the service class instance but also establishes an RPC connection to
    117   // weaved daemon. Upon connection having been established, a |callback| is
    118   // invoked and an instance of Service is passed to it as an argument.
    119   // The service instance provided to the callback is a weak pointer to the
    120   // actual service which may be destroyed at any time if RPC connection to
    121   // weaved is lost. If this happens, a connection is re-established and the
    122   // |callback| is called again with a new instance of the service.
    123   // Therefore, if locking the |service| produces nullptr, this means that the
    124   // service got disconnected, so no further action can be taken. Since the
    125   // |callback| will be invoked with the new service instance when connection
    126   // is re-established, it's a good idea to update the device state on each
    127   // invocation of the callback (along with registering command handlers, etc).
    128   // IMPORTANT: Keep the returned subscription object around for as long as the
    129   // service is needed. As soon as the subscription is destroyed, the connection
    130   // to weaved is terminated and the service instance is discarded.
    131   static std::unique_ptr<Subscription> Connect(
    132       brillo::MessageLoop* message_loop,
    133       const ConnectionCallback& callback) WARN_UNUSED_RESULT;
    134 
    135  private:
    136   DISALLOW_COPY_AND_ASSIGN(Service);
    137 };
    138 
    139 }  // namespace weaved
    140 
    141 #endif  // LIBWEAVED_SERVICE_H_
    142