comp-manager: Add new method to store ref count of applications
authorSaurav Babu <saurav.babu@samsung.com>
Thu, 5 Apr 2018 12:10:24 +0000 (17:40 +0530)
committersaerome.kim <saerome.kim@samsung.com>
Mon, 2 Jul 2018 10:38:49 +0000 (19:38 +0900)
When application deinitializes then it disables companion-manager, but
there could be a possibility that multiple application would have
initialized and when one application is deinitialized then companion
manager is killed which results in abrupt behavior for other
applications

Signed-off-by: Saurav Babu <saurav.babu@samsung.com>
src/companion-manager/include/comp_context.h
src/companion-manager/src/comp_gdbus.c
src/companion-manager/src/companion_gdbus.xml

index 81b5b11..3839026 100644 (file)
@@ -34,6 +34,7 @@ extern "C"
 typedef struct {
        GMainLoop *main_loop;
        //GDBusConnection *connection;
+       int ref_count;
 
        // resource list
        GList *resource_list[COMP_RESOURCE_TYPE_MAX];
@@ -47,6 +48,12 @@ typedef struct {
        sqlite3 *db;
 } comp_context_t;
 
+typedef struct {
+       char *conn_name;
+       int conn_id;
+       GDBusConnection *connection;
+} comp_conn_destroy_data;
+
 int comp_context_create();
 int comp_context_destroy();
 void comp_context_mutex_lock();
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);
index 34705c4..f4ebd9a 100644 (file)
@@ -6,7 +6,8 @@
 
 <node>
        <interface name="org.tizen.companion.enabler">
-               <method name="disable">
+               <method name="AddRef">
+                       <arg type="s" name="name" direction="in"/>
                        <arg type="i" name="result" direction="out"/>
                </method>
        </interface>