make FindObject() create the dbus object on the fly
authorKevron Rees <kevron.m.rees@intel.com>
Wed, 8 Jan 2014 23:37:58 +0000 (15:37 -0800)
committerKevron Rees <kevron.m.rees@intel.com>
Wed, 8 Jan 2014 23:37:58 +0000 (15:37 -0800)
plugins/dbus/abstractdbusinterface.cpp
plugins/dbus/abstractdbusinterface.h
plugins/dbus/automotivemanager.cpp
plugins/dbus/automotivemanager.h
plugins/dbus/dbusplugin.cpp

index e2ddd87..440de77 100644 (file)
@@ -318,6 +318,8 @@ void AbstractDBusInterface::unregisterObject()
 {
        if(regId)
                g_dbus_connection_unregister_object(mConnection, regId);
+
+       regId=0;
 }
 
 void AbstractDBusInterface::updateValue(AbstractProperty *property)
@@ -327,7 +329,8 @@ void AbstractDBusInterface::updateValue(AbstractProperty *property)
                return;
        }
 
-       signaller->fireSignal(mConnection, mObjectPath, "org.freedesktop.DBus.Properties", "PropertiesChanged", property);
+       if(isRegistered())
+               signaller->fireSignal(mConnection, mObjectPath, "org.freedesktop.DBus.Properties", "PropertiesChanged", property);
 }
 
 std::list<AbstractDBusInterface *> AbstractDBusInterface::getObjectsForProperty(string object)
index 5ac3bf6..4678cee 100644 (file)
@@ -95,6 +95,8 @@ public:
 
        std::unordered_map<std::string, AbstractProperty*> getProperties() { return properties; }
 
+       bool isRegistered() { return regId > 0; }
+
 protected:
 
        void startRegistration();
index 17b513f..abb2756 100644 (file)
@@ -1,5 +1,6 @@
 #include "automotivemanager.h"
 #include "abstractdbusinterface.h"
+#include "listplusplus.h"
 
 static const gchar introspection_xml[] =
   "<node>"
@@ -51,9 +52,11 @@ static void handleMethodCall(GDBusConnection       *connection,
 
        std::string method = method_name;
 
+       uint pid = getPid(sender);
+
        if(DebugOut::getDebugThreshhold() >= 6)
        {
-               DebugOut(6)<<"DBus method call from: "<<sender<< " pid: " <<getPid(sender)<< " interface: "<<interface_name<<" method: "<<method<<endl;
+               DebugOut(6)<<"DBus method call from: "<<sender<< " pid: " <<pid<< " interface: "<<interface_name<<" method: "<<method<<endl;
                DebugOut(6)<<"DBus method call path: "<<object_path<<endl;
        }
 
@@ -117,9 +120,20 @@ static void handleMethodCall(GDBusConnection       *connection,
                        AbstractDBusInterface* t = *itr;
                        if(!t->isSupported())
                                continue;
+
+                       if(!t->isRegistered())
+                               t->registerObject();
+
+                       std::list<std::string> processes = manager->subscribedProcesses[t];
+
+                       if(!contains(processes,sender))
+                       {
+                               DebugOut()<<"Referencing "<<t->objectPath()<<" with sender: "<<sender<<endl;
+                               manager->subscribedProcesses[t].push_back(sender);
+                       }
+
                        GVariant *newvar = g_variant_new("o",t->objectPath().c_str());
                        g_variant_builder_add_value(&params, newvar);
-
                }
 
                //GVariant* var =  g_variant_builder_end(&params);
@@ -311,6 +325,48 @@ static void handleMethodCall(GDBusConnection       *connection,
        }
 }
 
+static void signalCallback( GDBusConnection *connection,
+                                                                                                                                                                                                                                const gchar *sender_name,
+                                                                                                                                                                                                                                const gchar *object_path,
+                                                                                                                                                                                                                                const gchar *interface_name,
+                                                                                                                                                                                                                                const gchar *signal_name,
+                                                                                                                                                                                                                                GVariant *parameters,
+                                                                                                                                                                                                                                gpointer user_data)
+{
+       AutomotiveManager* manager = static_cast<AutomotiveManager*>(user_data);
+
+       gchar* name=nullptr;
+       gchar* newOwner=nullptr;
+       gchar* oldOwner = nullptr;
+       g_variant_get(parameters,"(sss)",&name, &oldOwner, &newOwner);
+
+       if(std::string(newOwner) == "")
+       {
+               for(auto i : manager->subscribedProcesses)
+               {
+                       AbstractDBusInterface* iface = i.first;
+                       for(auto n : i.second)
+                       {
+                               if(n == name)
+                               {
+                                       DebugOut()<<"unreferencing "<<n<<" from the subscription of "<<iface->objectPath()<<endl;
+                                       manager->subscribedProcesses[iface].remove(n);
+                               }
+                       }
+
+                       if(manager->subscribedProcesses[iface].empty())
+                       {
+                               DebugOut()<<"No more subscribers.  Unregistering."<<endl;
+                               iface->unregisterObject();
+                       }
+               }
+       }
+
+       g_free(name);
+       g_free(newOwner);
+       g_free(oldOwner);
+}
+
 static GVariant* getProperty(GDBusConnection* connection, const gchar* sender, const gchar* objectPath, const gchar* interfaceName, const gchar* propertyName, GError** error, gpointer userData)
 {
        return NULL;
@@ -347,6 +403,10 @@ AutomotiveManager::AutomotiveManager(GDBusConnection *connection)
        }
 
        g_assert(regId > 0);
+
+       g_dbus_connection_signal_subscribe(g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL,NULL), "org.freedesktop.DBus", "org.freedesktop.DBus",
+                                                                                                                                                                          "NameOwnerChanged", "/org/freedesktop/DBus", NULL, G_DBUS_SIGNAL_FLAGS_NONE,
+                                                                                                                                                                          signalCallback, this, NULL);
 }
 
 AutomotiveManager::~AutomotiveManager()
index 0db9f1b..e8d1c11 100644 (file)
@@ -2,6 +2,10 @@
 #define AUTOMOTIVEMANAGER_H_
 
 #include <gio/gio.h>
+#include <map>
+#include <list>
+
+class AbstractDBusInterface;
 
 class AutomotiveManager
 {
@@ -10,10 +14,13 @@ public:
        AutomotiveManager(GDBusConnection* connection);
        ~AutomotiveManager();
 
+       std::map<AbstractDBusInterface*, std::list<std::string>> subscribedProcesses;
+
 private:
 
        GDBusConnection* mConnection;
        guint regId;
+
 };
 
 
index 14670cc..9547072 100644 (file)
@@ -65,12 +65,6 @@ void DBusSink::supportedChanged(PropertyList supportedProperties)
                        supported = true;
                }
        }
-
-
-       if(supported)
-               registerObject();
-       else
-               unregisterObject();
 }
 
 void DBusSink::propertyChanged(AbstractPropertyType *value)