comp-manager: Add new method to store ref count of applications
[platform/core/api/multi-device-group.git] / src / companion-manager / src / comp_gdbus.c
index 1c05cbb..84012c2 100644 (file)
 #include <comp_gdbus.h>
 #include <sys/types.h>
 
+#define DBUS_SERVICE_DBUS              "org.freedesktop.DBus"
+#define DBUS_INTERFACE_DBUS            "org.freedesktop.DBus"
+
 static Group *group_skeleton;
+static Enabler *enabler_skeleton;
 
 Group *group_dbus_get_object()
 {
@@ -168,17 +172,90 @@ static bool __group_init(GDBusConnection *connection)
        return ret;
 }
 
-gboolean enabler_disable(Enabler *enabler, GDBusMethodInvocation *invocation,
-                                                gpointer user_data)
+static void _app_conn_destroyed_cb(GDBusConnection *conn, const gchar *Name,
+                          const gchar *path, const gchar *interface, const gchar *sig,
+                          GVariant *param, gpointer user_data)
 {
-       LOG_DEBUG("disable called using dbus successful");
-
+       gchar *name = NULL;
+       gchar *old = NULL;
+       gchar *new = NULL;
+       comp_conn_destroy_data *data = user_data;
        comp_context_t *comp_ctx = comp_context_get_context();
-       comp_check_null_ret_error("comp_ctx", comp_ctx, TRUE);
 
-       enabler_complete_disable(enabler, invocation, 0);
+       if (param == NULL)
+               return;
+
+       g_variant_get(param, "(sss)", &name, &old, &new);
+
+       if (g_strcmp0(name, data->conn_name) == 0 && *new == '\0') {
+               LOG_DEBUG("App %s Destroyed: name %s id %d", data->conn_name, name,
+                       data->conn_id);
+
+               comp_ctx->ref_count -= 1;
+
+               g_dbus_connection_signal_unsubscribe(data->connection, data->conn_id);
+       }
+
+       g_free(name);
+       g_free(old);
+       g_free(new);
+       g_free(data->conn_name);
+       g_free(data);
+
+       if (comp_ctx->ref_count == 0) {
+               LOG_DEBUG("No app remaining quit comapnion-manager");
+               g_main_loop_quit(comp_ctx->main_loop);
+       }
+
+       return;
+}
+
+static gboolean _register_comp_conn_destroy_signal(Enabler *enabler,
+                                                                  gchar *name)
+{
+       comp_conn_destroy_data *data;
+       GDBusConnection *connection = NULL;
+
+       connection = g_dbus_interface_skeleton_get_connection(
+                                         (GDBusInterfaceSkeleton *)enabler_skeleton);
+       if (NULL == connection) {
+               LOG_ERR("Failed to get GDbus connection");
+               return FALSE;
+       }
+
+       data = g_try_malloc0(sizeof(comp_conn_destroy_data));
+       if (NULL == data) {
+               LOG_ERR("Failed to Allocate memory");
+               return FALSE;
+       }
 
-       g_main_loop_quit(comp_ctx->main_loop);
+       data->conn_name = g_strdup(name);
+       data->connection = connection;
+
+       data->conn_id = g_dbus_connection_signal_subscribe(connection,
+                                                       DBUS_SERVICE_DBUS, DBUS_INTERFACE_DBUS,
+                                                       "NameOwnerChanged", NULL, name,
+                                                       G_DBUS_SIGNAL_FLAGS_NONE, _app_conn_destroyed_cb,
+                                                       data, NULL);
+
+       return TRUE;
+}
+
+gboolean enabler_add_ref(Enabler *enabler, GDBusMethodInvocation *invocation,
+       gchar *name, gpointer user_data)
+{
+       LOG_DEBUG("Add Reference for %s", name);
+
+       if (TRUE == _register_comp_conn_destroy_signal(enabler, name)) {
+               comp_context_t *comp_ctx = comp_context_get_context();
+               comp_ctx->ref_count += 1;
+
+               enabler_complete_add_ref(enabler, invocation, 0);
+       } else {
+               LOG_ERR("Failed to register connection destroy signal");
+               enabler_complete_add_ref(enabler, invocation,
+                                        COMP_ERROR_OPERATION_FAILED);
+       }
 
        return TRUE;
 }
@@ -187,7 +264,6 @@ static bool __enabler_init(GDBusConnection *connection)
 {
        gboolean ret = FALSE;
        GError *error = NULL;
-       Enabler *enabler_skeleton;
 
        GDBusObjectManagerServer *enabler;
 
@@ -196,8 +272,8 @@ static bool __enabler_init(GDBusConnection *connection)
 
        // Register for method callbacks as signal callbacks
        g_signal_connect(enabler_skeleton,
-               "handle-disable",
-               G_CALLBACK(enabler_disable),
+               "handle-add-ref",
+               G_CALLBACK(enabler_add_ref),
                NULL);
 
        enabler = g_dbus_object_manager_server_new(COMP_DBUS_ENABLER_PATH);