[Non-ACR] add handling for app-terminate event 56/244456/6 accepted/tizen/5.5/unified/20200923.234046 submit/tizen_5.5/20200922.123956
authorAbhishek Vijay <abhishek.v@samsung.com>
Fri, 18 Sep 2020 11:52:38 +0000 (17:22 +0530)
committerAbhishek Vijay <abhishek.v@samsung.com>
Tue, 22 Sep 2020 12:12:14 +0000 (17:42 +0530)
Change-Id: I5a7ce05f77f332f12eb2c699067307a2a25b6018
Signed-off-by: Abhishek Vijay <abhishek.v@samsung.com>
src/battery_dump/bm_listeners.c

index 2eb9458..93277e5 100644 (file)
 #include <glib.h>
 #include <device/battery-internal.h>
 
+typedef struct ApplicationInfo {
+       int hsp_info;
+       int app_state;
+} appInfo;
+
 wifi_manager_h wifi = NULL;
 static bool display_on;
 static int brightness_val = 0;
@@ -72,6 +77,7 @@ static int fill_ptr = 0;
 static int use_ptr = 0;
 static TapiHandle *handle = NULL;
 GHashTable *app_list = NULL;
+static GHashTable *pid_map = NULL;
 
 #define DBUS_DEVICED "org.tizen.system.deviced"
 #define DBUS_DEVICED_PATH "/Org/Tizen/System/DeviceD/Display"
@@ -83,6 +89,73 @@ GHashTable *app_list = NULL;
 
 static GDBusConnection *dbus_connection;
 
+static void bd_get_app_id_from_table(gint pid, char **app_id)
+{
+       if (pid_map == NULL) {
+               _ERR("invalid pid_map");
+               return;
+       }
+
+       _DBG("app_id for pid[%d], table size[%d]", pid, g_hash_table_size(pid_map));
+
+       void *orig_pid = NULL;
+       void *orig_app_id = NULL;
+
+       if (g_hash_table_lookup_extended(pid_map, &pid, &orig_pid, &orig_app_id) == true) {
+               *app_id = strdup((char *)orig_app_id);
+       } else {
+               _ERR("pid not available in map");
+               goto END;
+       }
+
+       _DBG("retrieved app_id[%s] for pid[%d]", *app_id, pid);
+END:
+       return;
+}
+
+static void bd_insert_app_id_into_table(gint pid, char *appid)
+{
+       if (appid == NULL) {
+               _ERR("invalid appid");
+               goto END;
+       }
+
+       /* redundant keys are not required */
+       if (g_hash_table_contains(pid_map, &pid) == true) {
+               _DBG("key[%d] already present, no insertion required", pid);
+               goto END;
+       }
+
+       gint* lpid = g_new0(gint, 1);
+       if (lpid == NULL) {
+               _ERR("failed to allocate memory");
+               goto END;
+       }
+
+       *lpid = pid;
+
+       _DBG("creating map - pid[%d], appid[%s]", *lpid, appid);
+
+       if (g_hash_table_insert(pid_map, lpid, strdup(appid)) == false)
+               _WARN("key already available, replacing old value");
+END:
+       return;
+}
+
+static void bd_remove_app_id_from_table(gint pid)
+{
+       if (g_hash_table_contains(pid_map, &pid) != true) {
+               _DBG("key[%d] not present in list", pid);
+               goto END;
+       }
+
+       g_hash_table_remove(pid_map, &pid);
+
+       _DBG("removed key[%d] from table", pid);
+END:
+       return;
+}
+
 static int bm_listener_dbus_init(void)
 {
        ENTER;
@@ -764,30 +837,40 @@ static int fill_app_status_change(int val, char *app_id)
 {
        ENTER;
 
-       if (app_id == NULL)
+       if (app_id == NULL) {
+               _ERR("app_id is NULL");
                return 1;
+       }
 
-       void *prv_data = NULL;
-       void *prv_app_id = NULL;
+       void *prv_data = NULL, *prv_app_id = NULL;
        int error_code = 0;
 
-       _WARN(" App status changed for = %s ", app_id);
+       _DBG(" App status change - app[%s], val[%d]", app_id, val);
+
        if (data_obj) {
-               if (val) {
+               if (val == 1) { /* foreground */
                        data_obj->event_code = ET_NONE;
                        data_obj->event_code |= ET_FOREGROUND;
                        data_obj->event_code |= ET_FLAG_START;
                        data_obj->event_tag = NULL;
+
                        data_obj->event_tag = (history_tag_s *)calloc(1, sizeof(history_tag_s));
                        if (data_obj->event_tag) {
-                               listener_hsp++;
-                               app_hsp = listener_hsp;
+                               app_hsp = ++listener_hsp;
+
                                _INFO("event Tag creation succeeded \n");
+
                                data_obj->event_tag->sp_idx = app_hsp;
+
+                               /* check if exists in hash-table */
                                if (g_hash_table_lookup_extended(app_list, app_id, &prv_app_id, &prv_data) == true) {
-                                       int *temp = (int *)prv_data;
-                                       *temp = app_hsp;
-                                       _INFO(" sp index for this app id is = %d and apphsp= %d", *temp, app_hsp);
+                                       appInfo *prevInfo = (appInfo *)prv_data;
+                                       prevInfo->hsp_info = app_hsp;
+                                       prevInfo->app_state = val;
+
+                                       _DBG(" sp index for this app id is = %d and apphsp= %d",
+                                                               prevInfo->hsp_info, app_hsp);
+
                                        if (fill_AppId_info(app_id)) {
                                                error_code = 1;
                                                goto out;
@@ -795,20 +878,26 @@ static int fill_app_status_change(int val, char *app_id)
                                        error_code = 0;
                                        goto out;
                                } else {
-                                       int *temp = (int *)calloc(1, sizeof(int));
-                                       if (temp == NULL) {
+                                       /* first time for app_id , insert into hash-table */
+                                       appInfo *info = (appInfo *)calloc(1, sizeof(appInfo));
+                                       if (info == NULL) {
                                                _ERR("memory allocation failed");
                                                BM_FREE(data_obj->event_tag);
                                                error_code = 1;
                                                goto out;
                                        }
-                                       *temp = app_hsp;
-                                       _INFO("This App is not present in the list, inserting it");
-                                       g_hash_table_insert(app_list, app_id, temp);
+                                       info->hsp_info = app_hsp;
+                                       info->app_state = val;
+
+                                       _INFO("inserting in table - [%s]", app_id);
+
+                                       g_hash_table_insert(app_list, app_id, info);
+
                                        if (fill_AppId_info(app_id)) {
                                                error_code = 1;
                                                goto out;
                                        }
+
                                        error_code = 0;
                                        return error_code;
                                }
@@ -817,30 +906,47 @@ static int fill_app_status_change(int val, char *app_id)
                                error_code = 1;
                                goto out;
                        }
-               } else {
-                       data_obj->event_code = ET_NONE;
-                       data_obj->event_code |= ET_FOREGROUND;
-                       data_obj->event_code |= ET_FLAG_FINISH;
-                       data_obj->event_tag = NULL;
-                       data_obj->event_tag = (history_tag_s *)calloc(1, sizeof(history_tag_s));
-                       if (data_obj->event_tag) {
-                               _INFO("looking for key = %s \n", app_id);
-                               if (g_hash_table_lookup_extended(app_list, app_id, &prv_app_id, &prv_data) == true) {
-                                       int *tmp = (int *)prv_data;
-                                       app_hsp = *tmp;
-                                       error_code = 0;
-                                       data_obj->event_tag->sp_idx = app_hsp;
-                                       if (fill_AppId_info(app_id))
+               } else { /* background & terminate */
+
+                       if (g_hash_table_lookup_extended(app_list, app_id, &prv_app_id, &prv_data) == true) {
+
+                               appInfo *prevInfo = (appInfo *)prv_data;
+
+                               _DBG("app available in list - app_id[%s], prev_app_id[%s], app_state[%d]",
+                                                               app_id, (char *)prv_app_id, prevInfo->app_state);
+
+                               /* event tag is created only when app transits from foreground to either
+                                * background or terminate state. No event tag is created when transition
+                                * is from background state to terminate state */
+                               if (prevInfo->app_state == 1 && (val == 0 || val == -1))
+                               {
+                                       prevInfo->app_state = val; /* update new value for app_id */
+
+                                       data_obj->event_code = ET_NONE;
+                                       data_obj->event_code |= ET_FOREGROUND;
+                                       data_obj->event_code |= ET_FLAG_FINISH;
+                                       data_obj->event_tag = NULL;
+
+                                       data_obj->event_tag = (history_tag_s *)calloc(1, sizeof(history_tag_s));
+                                       if (data_obj->event_tag) {
+                                               app_hsp = prevInfo->hsp_info;
+                                               error_code = 0;
+                                               data_obj->event_tag->sp_idx = app_hsp;
+                                               if (fill_AppId_info(app_id))
+                                                       error_code = 1;
+                                       } else {
+                                               _ERR(" data_obj->event_tag object creation fails ");
                                                error_code = 1;
-                                       goto out;
+                                               goto out;
+                                       }
                                } else {
-                                       _INFO(" This App is not present in the list and in background");
-                                       BM_FREE(data_obj->event_tag);
+                                       _DBG("event-tag not created - prev_appid[%s], prev_state[%d], val[%d]",
+                                                       (char *)prv_app_id, prevInfo->app_state, val);
                                        error_code = 1;
                                        goto out;
                                }
                        } else {
-                               _ERR(" data_obj->event_tag object creation fails ");
+                               _INFO("application not available in list ");
                                error_code = 1;
                                goto out;
                        }
@@ -1729,7 +1835,8 @@ static void __app_status_signal_callback(GDBusConnection *conn,
                gpointer user_data)
 {
        ENTER;
-       int pid, val;
+       gint pid;
+       int val;
        char *appid;
        char *status;
 
@@ -1754,10 +1861,11 @@ static void __app_status_signal_callback(GDBusConnection *conn,
 
        _DBG("pid:%d, appid:%s, status:%s", pid, appid, status);
 
-       if (g_strcmp0(status, "fg") == 0)
+       if (g_strcmp0(status, "fg") == 0) {
                val = 1;
-       else
+       } else {
                val = 0;
+       }
 
        app_event->type = LISTEN_APP_STATUS;
        app_event->val = val;
@@ -1774,6 +1882,91 @@ static void __app_status_signal_callback(GDBusConnection *conn,
        return;
 }
 
+static void __app_state_subscribe_signal_callback(GDBusConnection *conn, const gchar *sender, const gchar *path,
+                               const gchar *iface, const gchar *signal, GVariant *params, gpointer user_data)
+{
+       ENTER;
+
+       if (params == NULL) {
+               _ERR("invalid params");
+               return;
+       }
+
+       _DBG("signal received - [%s]", signal);
+
+       int val = -1;
+       gint pid = -1;
+       char *app_id = NULL, *pkg_id = NULL, *type = NULL;
+
+       if (g_strcmp0(signal, "AppLaunch") == 0) {
+
+               /* (isss) : pid, appid, pkgid, type */
+               g_variant_get(params, "(i&s&s&s)", &pid, &app_id, &pkg_id, &type);
+
+               _DBG("signal[%s], pid[%d], app_id[%s], pkg_id[%s], type[%s]",
+                               signal, pid, app_id, pkg_id, type);
+
+               if (pid == -1 || app_id == NULL) {
+                       _ERR("invalid pid/app_id");
+                       goto END;
+               }
+
+               /* insert into table for later retrieval */
+               bd_insert_app_id_into_table(pid, app_id);
+
+               goto END;
+
+       } else if (g_strcmp0(signal, "AppTerminate") == 0) {
+
+               /* (isss) : pid, appid, pkgid, type */
+               g_variant_get(params, "(i&s&s&s)", &pid, NULL, NULL, NULL);
+
+               _DBG("signal[%s], pid[%d]", signal, pid);
+
+               if (pid == -1) {
+                       _ERR("invalid pid");
+                       goto END;
+               }
+
+               /* get app_id from table */
+               bd_get_app_id_from_table(pid, &app_id);
+               if (app_id == NULL) {
+                       _ERR("app_id not available for pid[%d], no event created", pid);
+                       goto END;
+               }
+
+               /* remove pid from table as terminate signal is
+                * received for this pid */
+               bd_remove_app_id_from_table(pid);
+
+       } else {
+               _ERR("invalid signal received - [%s]", signal);
+       }
+
+       /* create event */
+       event_pool *app_event = (event_pool *)calloc(1, sizeof(event_pool));
+       if (!app_event) {
+               _ERR("Failed to allocate memory ");
+               BM_FREE(app_id);
+               goto END;
+       }
+
+       app_event->type = LISTEN_APP_STATUS;
+       app_event->val = val;
+       app_event->app = app_id;
+
+       /* create thread */
+       pthread_t producer;
+       if (pthread_create(&producer, &attr, event_producer, app_event)) {
+               _ERR("Failed to pthread_create.");
+               BM_FREE(app_event->app);
+               BM_FREE(app_event);
+       }
+END:
+       EXIT;
+       return;
+}
+
 static int  bm_charging_status_listeners()
 {
        ENTER;
@@ -2052,19 +2245,32 @@ static int bm_app_status_listener(void)
                return 1;
        }
 
-       ret = g_dbus_connection_signal_subscribe(dbus_connection,
-                               NULL,
-                               "org.tizen.aul.AppStatus",
-                               "AppStatusChange",
-                               "/Org/Tizen/Aul/AppStatus",
-                               NULL,
-                               G_DBUS_SIGNAL_FLAGS_NONE,
-                               __app_status_signal_callback,
-                               NULL,
-                               NULL);
+       ret = g_dbus_connection_signal_subscribe(dbus_connection, NULL, "org.tizen.aul.AppStatus",
+                               "AppStatusChange", "/Org/Tizen/Aul/AppStatus", NULL,
+                               G_DBUS_SIGNAL_FLAGS_NONE, __app_status_signal_callback, NULL, NULL);
 
        if (ret == 0) {
-               _ERR("Failed to subscrive bus signal"); //LCOV_EXCL_LINE System Error
+               _ERR("Failed to subscribe bus signal"); //LCOV_EXCL_LINE System Error
+               return 1;
+       }
+
+       ret = g_dbus_connection_signal_subscribe(dbus_connection, NULL, "org.tizen.aul.AppStatus",
+                               "AppTerminate", "/Org/Tizen/Aul/AppStatus", NULL,
+                               G_DBUS_SIGNAL_FLAGS_NONE, __app_state_subscribe_signal_callback,
+                               NULL, NULL);
+
+       if (ret == 0) {
+               _ERR("Failed to subscribe bus signal"); //LCOV_EXCL_LINE System Error
+               return 1;
+       }
+
+       ret = g_dbus_connection_signal_subscribe(dbus_connection, NULL, "org.tizen.aul.AppStatus",
+                               "AppLaunch", "/Org/Tizen/Aul/AppStatus", NULL,
+                               G_DBUS_SIGNAL_FLAGS_NONE, __app_state_subscribe_signal_callback,
+                               NULL, NULL);
+
+       if (ret == 0) {
+               _ERR("Failed to subscribe bus signal"); //LCOV_EXCL_LINE System Error
                return 1;
        }
 
@@ -2108,6 +2314,9 @@ static int bm_initialize_history_data_obj()
        // Hash table initialize for application list
        app_list = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
 
+       /* pid-app_id map */
+       pid_map = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free);
+
        if (data_obj != NULL) {
                _WARN(" History data object already exits");
                return BATTERY_MONITOR_ERROR_NONE;
@@ -2308,7 +2517,11 @@ int bd_deinitialize_listeners()
        if (pthread_attr_destroy(&attr) != 0)
                _ERR("pthread_attr_destroy failed");
 
-       g_hash_table_destroy(app_list);
+       if (app_list)
+               g_hash_table_destroy(app_list);
+
+       if (pid_map)
+               g_hash_table_destroy(pid_map);
 
        if (data_obj)
                BM_FREE(data_obj);