1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
/* Copyright (C) 2013 BMW Group
* Author: Manfred Bathelt (manfred.bathelt@bmw.de)
* Author: Juergen Gehring (juergen.gehring@bmw.de)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef COMMONAPI_DBUS_DBUS_FREEDESKTOP_OBJECT_MANAGER_STUB_H_
#define COMMONAPI_DBUS_DBUS_FREEDESKTOP_OBJECT_MANAGER_STUB_H_
#include "DBusInterfaceHandler.h"
#include <memory>
#include <mutex>
#include <string>
namespace CommonAPI {
namespace DBus {
class DBusStubAdapter;
/**
* Stub for standard <a href="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager">org.freedesktop.dbus.ObjectManager</a> interface.
*
* Instantiated within a manager stub and it must hold reference to all registered objects.
* Whenever the manager gets destroyed all references to registered objects are lost too.
* This duplicates the semantic of the CommonAPI::ServicePublisher class.
*
* Only one DBusStubAdapter instance could be registered per DBusObjectManagerStub instance.
*
* The owner of the DBusObjectManagerStub instance must take care of registering and unregistering it.
*
* Example stub life cycle:
* - create CommonAPI::ServicePublisher
* - create stub A
* - register stub A to CommonAPI::ServicePublisher
* - create stub B
* - register stub B with stub A as object manager
* - drop all references to stub B, stub A keeps a reference to stub B
* - drop all references to stub A, CommonAPI::ServicePublisher keeps a reference to stub A
* - reference overview: Application > CommonAPI::ServicePublisher > Stub A > Stub B
* - drop all references to CommonAPI::ServicePublisher causes all object references to be dropped
*/
class DBusObjectManagerStub: public DBusInterfaceHandler {
public:
// serialization trick: use bool instead of variant since we never serialize it
typedef std::unordered_map<std::string, bool> DBusPropertiesChangedDict;
typedef std::unordered_map<std::string, DBusPropertiesChangedDict> DBusInterfacesAndPropertiesDict;
typedef std::unordered_map<std::string, DBusInterfacesAndPropertiesDict> DBusObjectPathAndInterfacesDict;
public:
DBusObjectManagerStub(const std::string& dbusObjectPath, const std::shared_ptr<DBusProxyConnection>&);
/**
* Unregisters all currently registered DBusStubAdapter instances from the DBusServicePublisher
*/
virtual ~DBusObjectManagerStub();
/**
* Export DBusStubAdapter instance with the current DBusObjectManagerStub instance.
*
* The DBusStubAdapter must be registered with the DBusServicePublisher!
*
* On registering a
* <a href="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager">InsterfaceAdded</a>
* signal will be emitted with the DBusObjectManagerStub instance's current D-Bus object path.
*
* @param dbusStubAdapter a refernce to DBusStubAdapter instance
*
* @return false if the @a dbusStubAdapter instance was already registered
* @return false if sending the InterfaceAdded signal fails
*
* @see ~DBusObjectManagerStub()
* @see CommonAPI::ServicePublisher
* @see DBusObjectManager
*/
bool exportManagedDBusStubAdapter(std::shared_ptr<DBusStubAdapter> dbusStubAdapter);
/**
* Unexport DBusStubAdapter instance from this DBusObjectManagerStub instance.
*
* On unregistering a
* <a href="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager">InsterfaceRemoved</a>
* signal will be emitted with the DBusObjectManagerStub instance's current D-Bus object path.
*
* @param dbusStubAdapter
*
* @return false if @a dbusStubAdapter wasn't registered
* @return true even if sending the InterfaceRemoved signal fails
*
* @see exportDBusStubAdapter()
*/
bool unexportManagedDBusStubAdapter(std::shared_ptr<DBusStubAdapter> dbusStubAdapter);
bool isDBusStubAdapterExported(std::shared_ptr<DBusStubAdapter> dbusStubAdapter);
const std::string& getDBusObjectPath() const;
static const char* getInterfaceName();
virtual const char* getMethodsDBusIntrospectionXmlData() const;
virtual bool onInterfaceDBusMessage(const DBusMessage& dbusMessage);
virtual const bool hasFreedesktopProperties();
private:
bool registerDBusStubAdapter(std::shared_ptr<DBusStubAdapter> dbusStubAdapter);
bool unregisterDBusStubAdapter(std::shared_ptr<DBusStubAdapter> dbusStubAdapter);
bool emitInterfacesAddedSignal(std::shared_ptr<DBusStubAdapter> dbusStubAdapter,
const std::shared_ptr<DBusProxyConnection>& dbusConnection) const;
bool emitInterfacesRemovedSignal(std::shared_ptr<DBusStubAdapter> dbusStubAdapter,
const std::shared_ptr<DBusProxyConnection>& dbusConnection) const;
std::string dbusObjectPath_;
std::weak_ptr<DBusProxyConnection> dbusConnection_;
typedef std::unordered_map<std::string, std::shared_ptr<DBusStubAdapter>> DBusInterfacesMap;
typedef std::unordered_map<std::string, DBusInterfacesMap> DBusObjectPathsMap;
DBusObjectPathsMap registeredDBusObjectPathsMap_;
std::mutex dbusObjectManagerStubLock_;
};
} // namespace DBus
} // namespace CommonAPI
#endif // COMMONAPI_DBUS_DBUS_FREEDESKTOP_OBJECT_MANAGER_STUB_H_
|