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