summaryrefslogtreecommitdiff
path: root/src/CommonAPI/DBus/DBusObjectManagerStub.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/CommonAPI/DBus/DBusObjectManagerStub.h')
-rw-r--r--src/CommonAPI/DBus/DBusObjectManagerStub.h149
1 files changed, 149 insertions, 0 deletions
diff --git a/src/CommonAPI/DBus/DBusObjectManagerStub.h b/src/CommonAPI/DBus/DBusObjectManagerStub.h
new file mode 100644
index 0000000..42db8e3
--- /dev/null
+++ b/src/CommonAPI/DBus/DBusObjectManagerStub.h
@@ -0,0 +1,149 @@
+/* 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_
+
+// TODO rename DBusObjectManager to DBusStubManager
+
+// TODO proxy/client logic simply instantiates DBusObjectManagerProxy
+// with the object path of the currently instantiated proxy. That
+// way asking about available instances is a matter of calling
+// getManagedObjects(). Maybe we'll also have to cache within the
+// proxy like the service registry is doing.
+
+// TODO Service Discovery
+// - first detect all objects of a service via the Introspectible interface (like d-feet does).
+// - Introspectible is less efficient than a global ObjectManager but a global ObjectManager
+// conflicts with local ones, so we can't intentionally have one. The tradeoff is efficiency for correctness
+// - Register for all InterfaceAdded and InterfaceRemoved signals on the bus.
+// - Handle double InterfaceAdded and InterfaceRemoved signals properly (ignore them!).
+
+#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:
+ // XXX 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 exportDBusStubAdapter(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 unexportDBusStubAdapter(DBusStubAdapter* dbusStubAdapter);
+
+ bool isDBusStubAdapterExported(DBusStubAdapter* dbusStubAdapter);
+
+ inline const std::string& getDBusObjectPath() const;
+ inline static const char* getInterfaceName();
+
+ virtual const char* getMethodsDBusIntrospectionXmlData() const;
+ virtual bool onInterfaceDBusMessage(const DBusMessage& dbusMessage);
+
+ private:
+ bool registerDBusStubAdapter(DBusStubAdapter* dbusStubAdapter);
+ bool unregisterDBusStubAdapter(DBusStubAdapter* dbusStubAdapter);
+
+ bool emitInterfacesAddedSignal(DBusStubAdapter* dbusStubAdapter,
+ const std::shared_ptr<DBusProxyConnection>& dbusConnection) const;
+
+ bool emitInterfacesRemovedSignal(DBusStubAdapter* dbusStubAdapter,
+ const std::shared_ptr<DBusProxyConnection>& dbusConnection) const;
+
+ std::string dbusObjectPath_;
+ std::weak_ptr<DBusProxyConnection> dbusConnectionWeakPtr_;
+
+ typedef std::unordered_map<std::string, DBusStubAdapter*> DBusInterfacesMap;
+ typedef std::unordered_map<std::string, DBusInterfacesMap> DBusObjectPathsMap;
+ DBusObjectPathsMap registeredDBusObjectPathsMap_;
+
+ std::mutex dbusObjectManagerStubLock_;
+};
+
+
+inline const std::string& DBusObjectManagerStub::getDBusObjectPath() const {
+ return dbusObjectPath_;
+}
+
+const char* DBusObjectManagerStub::getInterfaceName() {
+ return "org.freedesktop.DBus.ObjectManager";
+}
+
+} // namespace DBus
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DBUS_DBUS_FREEDESKTOP_OBJECT_MANAGER_STUB_H_