[Non-ACR] add handling appLaunch & appTerminate events 01/244801/2
authorAbhishek Vijay <abhishek.v@samsung.com>
Thu, 24 Sep 2020 08:45:09 +0000 (14:15 +0530)
committerAbhishek Vijay <abhishek.v@samsung.com>
Thu, 24 Sep 2020 09:01:14 +0000 (14:31 +0530)
Change-Id: I1d3ea0fec7b350db624fad73248ef1050d20e5af

include/bm_common.h
src/battery_dump/bm_listeners.c

index 69c1edc709faa2869fc07786e26d3f2b8495d2d5..33140ebccc98060522be704ad6a814bd14dc1026 100644 (file)
@@ -119,6 +119,13 @@ typedef enum {
 #define DBUS_DEVICED_SLEEP_MEMBER              "sleep"
 #define DBUS_DEVICED_WAKEUP_MEMBER             "wakeup"
 
+/* app status events */
+#define DBUS_AUL_APP                           "org.tizen.aul.AppStatus"
+#define DBUS_AUL_APP_PATH                      "/Org/Tizen/Aul/AppStatus"
+#define DBUS_AUL_APP_STATUS_CHANGE_MEMBER      "AppStatusChange"
+#define DBUS_AUL_APP_LAUNCH_MEMBER             "AppLaunch"
+#define DBUS_AUL_APP_TERMINATE_MEMBER          "AppTerminate"
+
 /* Pre-defined App ID */
 #define BM_APPID_SYSTEM        "Tizen"
 
index ed2df5f45948688b46d7e9ab13268bd33bc89055..723d886fc60c385f1630ca6d5504e6d81af200a3 100644 (file)
 #include "bm_util.h"
 #include "bd_history_item.h"
 
+typedef struct ApplicationInfo {
+       int hsp_info;
+       int app_state;
+} appInfo;
+
 wifi_manager_h wifi = NULL;
 struct timeval prev_event_time;
 
@@ -48,6 +53,74 @@ static event_pool events_buf[10];
 static int buff_count = 0;
 
 GHashTable *app_list = NULL;
+static GHashTable *pid_map = NULL;
+
+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 bd_listener_set_appId_info(char *app_id)
 {
@@ -722,32 +795,41 @@ static int bd_listener_set_app_status_change_data(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;
        static int app_hsp = 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 (bd_listener_set_appId_info(app_id)) {
                                                error_code = 1;
                                                goto out;
@@ -755,20 +837,26 @@ static int bd_listener_set_app_status_change_data(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 (bd_listener_set_appId_info(app_id)) {
                                                error_code = 1;
                                                goto out;
                                        }
+
                                        error_code = 0;
                                        return error_code;
                                }
@@ -777,30 +865,47 @@ static int bd_listener_set_app_status_change_data(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 (bd_listener_set_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 (bd_listener_set_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;
                        }
@@ -1643,6 +1748,7 @@ static void _bd_listener_create_lock_event(char *lock_type, pid_t pid)
        event_pool *event = bd_listener_get_event_obj(LISTEN_POWERLOCKUNLOCK_STATE, val, pname);
        if (event == NULL) {
                _ERR("Failed to get event pool object");
+               BM_FREE(pname);
                return;
        }
 
@@ -1768,6 +1874,84 @@ static void _bd_listener_app_status_signal_cb(GDBusConnection *conn, const gchar
        return;
 }
 
+static void _bd_listener_app_launch_signal_cb(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;
+       }
+
+       gint pid = -1;
+       char *app_id = NULL, *pkg_id = NULL, *type = NULL;
+
+       /* (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");
+               return;
+       }
+
+       /* insert into table for later retrieval */
+       bd_insert_app_id_into_table(pid, app_id);
+
+       EXIT;
+       return;
+}
+
+static void _bd_listener_app_terminate_signal_cb(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;
+       }
+
+       int val = -1; gint pid = -1;
+       char *app_id = NULL;
+
+       /* (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");
+               return;
+       }
+
+       /* 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);
+               return;
+       }
+
+       /* remove app_id from table as terminate signal is received */
+       bd_remove_app_id_from_table(pid);
+
+       /* get event object */
+       event_pool *event = bd_listener_get_event_obj(LISTEN_APP_STATUS, val, app_id);
+       if (event == NULL) {
+               _ERR("Failed to get event pool object");
+               return;
+       }
+
+       /* create thread */
+       bd_create_producer_thread(event, "app_status");
+
+       EXIT;
+       return;
+}
+
 static int  bd_subscribe_charging_status_listeners()
 {
        ENTER;
@@ -2012,12 +2196,32 @@ static int bd_subscribe_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,
+       ret = g_dbus_connection_signal_subscribe(dbus_connection, NULL, DBUS_AUL_APP,
+                               DBUS_AUL_APP_STATUS_CHANGE_MEMBER, DBUS_AUL_APP_PATH, NULL,
                                G_DBUS_SIGNAL_FLAGS_NONE, _bd_listener_app_status_signal_cb, NULL, NULL);
 
        if (ret == 0) {
-               _ERR("Failed to subscrive bus signal"); //LCOV_EXCL_LINE System Error
+               _ERR("Failed to subscribe signal - appStatusChange"); //LCOV_EXCL_LINE System Error
+               return 1;
+       }
+
+       ret = g_dbus_connection_signal_subscribe(dbus_connection, NULL, DBUS_AUL_APP,
+                               DBUS_AUL_APP_TERMINATE_MEMBER, DBUS_AUL_APP_PATH, NULL,
+                               G_DBUS_SIGNAL_FLAGS_NONE, _bd_listener_app_terminate_signal_cb,
+                               NULL, NULL);
+
+       if (ret == 0) {
+               _ERR("Failed to subscribe signal - appTerminate"); //LCOV_EXCL_LINE System Error
+               return 1;
+       }
+
+       ret = g_dbus_connection_signal_subscribe(dbus_connection, NULL, DBUS_AUL_APP,
+                               DBUS_AUL_APP_LAUNCH_MEMBER, DBUS_AUL_APP_PATH, NULL,
+                               G_DBUS_SIGNAL_FLAGS_NONE, _bd_listener_app_launch_signal_cb,
+                               NULL, NULL);
+
+       if (ret == 0) {
+               _ERR("Failed to subscribe signal - appLaunch"); //LCOV_EXCL_LINE System Error
                return 1;
        }
 
@@ -2035,8 +2239,19 @@ static int bd_initialize_data_items()
                return BATTERY_MONITOR_ERROR_NOT_SUPPORTED;
        }
 
-       // Hash table initialize for application list
+       /* app-list hash table */
        app_list = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+       if (app_list == NULL) {
+               _ERR("failed to create app-list table");
+               return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY;
+       }
+
+       /* pid-app_id map */
+       pid_map = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free);
+       if (pid_map == NULL) {
+               _ERR("failed to create pid-map table");
+               return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY;
+       }
 
        if (data_obj == NULL) {
                data_obj = (history_item_s *)calloc(1, sizeof(history_item_s));
@@ -2192,7 +2407,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);
 
        /* TODO - check about internal struct members */
        BM_FREE(data_obj);