blob: a1b2919972af32c49917cd1905bb55cc8d68389d [file] [log] [blame]
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BLUETOOTH_DISPATCHER_IMPERSONATION_OBJECT_MANAGER_INTERFACE_H_
#define BLUETOOTH_DISPATCHER_IMPERSONATION_OBJECT_MANAGER_INTERFACE_H_
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include <chromeos/dbus/service_constants.h>
#include <dbus/object_manager.h>
#include "bluetooth/common/exported_object_manager_wrapper.h"
#include "bluetooth/common/property.h"
#include "bluetooth/dispatcher/client_manager.h"
#include "bluetooth/dispatcher/dispatcher_client.h"
#include "bluetooth/dispatcher/object_manager_interface_multiplexer.h"
namespace bluetooth {
// When impersonating multiple services, this rule describes whether to export
// an object depending on which impersonated service exports it.
enum class ObjectExportRule {
// Exports the object if any impersonated service exports it.
ANY_SERVICE,
// Exports the object if all impersonated services export it.
ALL_SERVICES,
};
enum class ForwardingRule {
// Forwards to default service only.
FORWARD_DEFAULT,
// Forwards to all services.
FORWARD_ALL,
};
// Clients of ImpersonationObjectManagerInterface should sub-class a
// InterfaceHandler and implement GetPropertyFactoryMap to
// specify the impersonated properties.
class InterfaceHandler {
public:
using PropertyFactoryMap =
std::map<std::string, std::unique_ptr<PropertyFactoryBase>>;
virtual ~InterfaceHandler() = default;
// Returns a map of
// (std::string property_name, PropertyFactory<T> property_factory)
// that describes what properties this interface has and what type for each
// of the properties.
virtual const PropertyFactoryMap& GetPropertyFactoryMap() const = 0;
// Returns a list of method names that this interface exposes.
virtual const std::map<std::string, ForwardingRule>& GetMethodForwardings()
const = 0;
// Returns the object export rule.
virtual ObjectExportRule GetObjectExportRule() const = 0;
};
// Impersonates other services' object manager interface to another exported
// object manager. At this moment only 1 ObjectManager source is supported so
// technically it doesn't do multiplexing yet.
// TODO(sonnysasaka): Implement support for multiple ObjectManager sources.
class ImpersonationObjectManagerInterface
: public ObjectManagerInterfaceMultiplexer {
public:
// Doesn't own |object_manager| and |exported_object_manager_wrapper|, so
// clients should make sure that those pointers outlive this object.
// |client_manager| is not owned, must outlive this object.
ImpersonationObjectManagerInterface(
const scoped_refptr<dbus::Bus>& bus,
ExportedObjectManagerWrapper* exported_object_manager_wrapper,
std::unique_ptr<InterfaceHandler> interface_handler,
const std::string& interface_name,
ClientManager* client_manager);
// CreateProperties, ObjectAdded, and ObjectRemoved are
// ObjectManagerInterfaceMultiplexer overrides.
// At this moment only 1 ObjectManager source is supported so |service_name|
// parameter is always ignored.
dbus::PropertySet* CreateProperties(
const std::string& service_name,
dbus::ObjectProxy* object_proxy,
const dbus::ObjectPath& object_path,
const std::string& interface_name) override;
void ObjectAdded(const std::string& service_name,
const dbus::ObjectPath& object_path,
const std::string& interface_name) override;
void ObjectRemoved(const std::string& service_name,
const dbus::ObjectPath& object_path,
const std::string& interface_name) override;
// Forwards any message to the impersonated service.
void HandleForwardMessage(
ForwardingRule forwarding_rule,
scoped_refptr<dbus::Bus> bus,
dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
private:
void TriggerPropertiesChanged(const std::string& service,
const dbus::ObjectPath& object_path,
const std::string& interface_name);
bool ShouldInterfaceBeExported(const std::string& object_path) const;
bool HasImpersonatedServicesForObject(const std::string& object_path) const;
int GetImpersonatedServicesCountForObject(
const std::string& object_path) const;
void AddImpersonatedServiceForObject(const std::string& object_path,
const std::string& service_name);
void RemoveImpersonatedServiceForObject(const std::string& object_path,
const std::string& service_name);
bool HasImpersonatedServiceForObject(const std::string& object_path,
const std::string& service_name);
// Returns the default service that exports the object. The default is chosen
// to be the one which is registered first via RegisterToObjectManager().
std::string GetDefaultServiceForObject(const std::string& object_path) const;
// Returns the ObjectManager of the service |service_name|. The returned
// pointer is owned by |bus_|.
dbus::ObjectManager* GetObjectManager(const std::string& service_name);
// Called when there is a value change of a property on the impersonated
// interface.
void OnPropertyChanged(const std::string& service_name,
const dbus::ObjectPath& object_path,
const std::string& interface_name,
const std::string& property_name);
// Forwards any message to the impersonated service, but uses a different
// D-Bus connection specific per client (based on the sender address of
// |method_call|).
void HandleForwardMessageWithClientConnection(
ForwardingRule forwarding_rule,
dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
// Forwards a method to service |service_index|. Once the method return is
// received, this will forward the same method to the next service, until
// there is no more service or the last response contains error.
void ForwardMessageToNextService(
scoped_refptr<dbus::Bus> bus,
dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender,
int service_index,
std::unique_ptr<dbus::Response> last_response);
void SetupPropertyHandlers(
brillo::dbus_utils::DBusInterface* prop_interface,
brillo::dbus_utils::ExportedPropertySet* property_set);
void HandleForwardSetProperty(
scoped_refptr<dbus::Bus> bus,
dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
scoped_refptr<dbus::Bus> bus_;
// Keeps which services expose any object, in the form of map of
// object_path -> set of service names.
std::map<std::string, std::set<std::string>> impersonated_services_;
// The destination object manager that impersonates the source.
ExportedObjectManagerWrapper* exported_object_manager_wrapper_;
// Defines what properties are to be impersonated.
std::unique_ptr<InterfaceHandler> interface_handler_;
// Keeps track of clients who have called the exposed methods.
ClientManager* client_manager_;
// Must come last so that weak pointers will be invalidated before other
// members are destroyed.
base::WeakPtrFactory<ImpersonationObjectManagerInterface> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ImpersonationObjectManagerInterface);
};
} // namespace bluetooth
#endif // BLUETOOTH_DISPATCHER_IMPERSONATION_OBJECT_MANAGER_INTERFACE_H_