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