Manage user's appinfo table 16/39516/5
authorSangyoon Jang <s89.jang@samsung.com>
Mon, 18 May 2015 04:29:55 +0000 (13:29 +0900)
committerSangyoon Jang <s89.jang@samsung.com>
Tue, 19 May 2015 06:27:53 +0000 (15:27 +0900)
Change-Id: I637d84995526461eff6120b33ae1df6c81d50688
Signed-off-by: Sangyoon Jang <s89.jang@samsung.com>
am_daemon/amd_appinfo.c
am_daemon/amd_appinfo.h
am_daemon/amd_main.c

index 7c95b49..548f963 100644 (file)
@@ -2,7 +2,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <assert.h>
 #include <glib.h>
 #include <dirent.h>
 
 
 #define SERVICE_GROUP "Service"
 
-static GHashTable *appinfo_tbl; /* key is filename, value is struct appinfo */
+static GHashTable *user_tbl;
+struct user_appinfo {
+       uid_t uid;
+       GHashTable *tbl; /* key is filename, value is struct appinfo */
+};
 
 enum _appinfo_idx {
        _AI_FILE = 0, /* service filename */
@@ -73,11 +76,19 @@ static void _free_appinfo(gpointer data)
        free(c);
 }
 
+static void _free_user_appinfo(gpointer data)
+{
+       struct user_appinfo *info = (struct user_appinfo *)data;
+
+       g_hash_table_destroy(info->tbl);
+       free(info);
+}
+
 static int __app_info_insert_handler (const pkgmgrinfo_appinfo_h handle, void *data)
 {
        struct appinfo *c;
        gboolean r;
-       GHashTable *tbl = (GHashTable *)data;
+       struct user_appinfo *info = (struct user_appinfo *)data;
        char *exec;
        char *type;
        char *appid;
@@ -101,7 +112,7 @@ static int __app_info_insert_handler (const pkgmgrinfo_appinfo_h handle, void *d
                return -1;
        }
 
-       g_hash_table_remove(tbl, appid);
+       g_hash_table_remove(info->tbl, appid);
 
        c = calloc(1, sizeof(*c));
        if (!c) {
@@ -189,83 +200,46 @@ static int __app_info_insert_handler (const pkgmgrinfo_appinfo_h handle, void *d
 
        SECURE_LOGD("%s : %s : %s", c->val[_AI_FILE], c->val[_AI_COMP], c->val[_AI_TYPE]);
 
-       g_hash_table_insert(tbl, c->val[_AI_FILE], c);
+       g_hash_table_insert(info->tbl, c->val[_AI_FILE], c);
 
        return 0;
 }
 
-static int _read_pkg_info(GHashTable *tbl, uid_t uid)
+static int __pkg_list_cb(pkgmgrinfo_pkginfo_h handle, void *user_data)
 {
-       int r;
-       if(uid != GLOBAL_USER)
-               r = pkgmgrinfo_appinfo_get_usr_install_list(__app_info_insert_handler, uid, tbl);
-       else
-               r = pkgmgrinfo_appinfo_get_install_list(__app_info_insert_handler, tbl);
-       return r;
-}
-
-static void __vconf_cb(keynode_t *key, void *data)
-{
-       char *noti_string;
-       char *type_string;
-       char *appid;
-       char *uid_string;
-       uid_t uid;
-       char *saveptr;
-       pkgmgrinfo_appinfo_h handle;
-       GHashTable *tbl = (GHashTable *)data;
-       int ret;
+       bool is_global;
+       struct user_appinfo *info = (struct user_appinfo *)user_data;
 
-       noti_string = vconf_keynode_get_str(key);
-       if( noti_string == NULL ) {
-               return;
+       if (pkgmgrinfo_pkginfo_is_for_all_users(handle, &is_global)) {
+               _E("get pkginfo failed");
+               return -1;
        }
 
-       SECURE_LOGD("noti_string : %s",noti_string);
-       type_string = strtok_r(noti_string, ":", &saveptr);
-       appid = strtok_r(NULL, ":", &saveptr);
-       uid_string = strtok_r(NULL, ":", &saveptr);
-       uid = atoi(uid_string);
-
-       _D("type_string: [%s]\n", type_string);
-       _D("appid: [%s]\n", appid);
-       _D("uid: %d\n", uid);
-       if ( strncmp(type_string, "create", 6) == 0) {
-               //is_admin
-               if (uid != GLOBAL_USER)
-                 ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &handle);
-               else
-                 ret = pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
-               if(ret < 0) {
-                       _E("pkgmgrinfo_appinfo_get_appinfo fail");
+       if (info->uid == GLOBAL_USER || !is_global) {
+               if (pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
+                               __app_info_insert_handler, user_data,
+                               info->uid)) {
+                       _E("get appinfo failed");
+                       return -1;
                }
+       }
 
-               SECURE_LOGD("appid : %s /handle : %x", appid, handle);
-
-               __app_info_insert_handler(handle, data);
+       return 0;
+}
 
-               pkgmgrinfo_appinfo_destroy_appinfo(handle);
-       } else if ( strncmp(type_string, "delete", 6) == 0) {
-               g_hash_table_remove(tbl, appid);
-       } else if (strncmp(type_string, "update", 6) == 0){
-               /*REMOVE EXISTING ENTRY & CREATE AGAIN*/
-               if (g_hash_table_remove(tbl, appid)){
-                       if (pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &handle) == PMINFO_R_OK){
-                               __app_info_insert_handler(handle, data);
-                               pkgmgrinfo_appinfo_destroy_appinfo(handle);
-                       }
-               }
-       }
+static void _remove_user_appinfo(uid_t uid)
+{
+       g_hash_table_remove(user_tbl, GINT_TO_POINTER(uid));
 }
 
-int app_func(pkgmgrinfo_appinfo_h handle, void *user_data)
+static int app_func(pkgmgrinfo_appinfo_h handle, void *user_data)
 {
        char *appid = NULL;
-       GHashTable *tbl = (GHashTable *)user_data;
+       struct user_appinfo *info = (struct user_appinfo *)user_data;
        int r;
 
        pkgmgrinfo_appinfo_get_appid(handle, &appid);
-       r = g_hash_table_remove(tbl, appid);
+       r = g_hash_table_remove(info->tbl, appid);
        SECURE_LOGD("upgrading... (%s)", appid);
 
        return 0;
@@ -304,166 +278,172 @@ static int __cb(int req_id, const char *pkg_type,
        return ret;
 }
 
-int appinfo_init(void)
+static struct user_appinfo *_add_user_appinfo(uid_t uid)
 {
        int r;
-       FILE *fp = NULL;
-       char buf[4096] = {0,};
-       char *tmp = NULL;
+       struct user_appinfo *info;
+       int event_type = PMINFO_CLIENT_STATUS_UPGRADE;
 
-       fp = fopen("/proc/cmdline", "r");
-       if (fp == NULL){
-               _E("appinfo init failed: %s", strerror(errno));
-               return -1;
-       }
-       r = fgets(buf, sizeof(buf), fp);
-       tmp = strstr(buf, "gles");
-       if(tmp != NULL) {
-               sscanf(tmp,"gles=%d", &gles);
+       info = calloc(1, sizeof(struct user_appinfo));
+       if (info == NULL) {
+               _E("out of memory");
+               return NULL;
        }
-       fclose(fp);
 
-       appinfo_tbl = g_hash_table_new_full(g_str_hash, g_str_equal,
-                       NULL, _free_appinfo);
+       info->uid = uid;
+       info->tbl = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+                       _free_appinfo);
+
+       g_hash_table_insert(user_tbl, GINT_TO_POINTER(uid), info);
 
-       r = _read_pkg_info(appinfo_tbl, GLOBAL_USER);
+       r = pkgmgrinfo_pkginfo_get_usr_list(__pkg_list_cb, info, info->uid);
        if (r != PMINFO_R_OK) {
-               appinfo_fini();
-               return -1;
+               _remove_user_appinfo(uid);
+               return NULL;
        }
 
-       r = vconf_notify_key_changed(VCONFKEY_MENUSCREEN_DESKTOP, __vconf_cb, appinfo_tbl);
-       if (r < 0)
-               _E("Unable to register vconf notification callback for VCONFKEY_MENUSCREEN_DESKTOP\n");
-
-       int event_type = PMINFO_CLIENT_STATUS_UPGRADE;
        pkgmgrinfo_client *pc = NULL;
        pc = pkgmgrinfo_client_new(PMINFO_REQUEST);
        pkgmgrinfo_client_set_status_type(pc, event_type);
-       pkgmgrinfo_client_listen_status(pc, __cb , appinfo_tbl);
+       pkgmgrinfo_client_listen_status(pc, __cb , info);
 
-       return 0;
+       _D("loaded appinfo table for uid %d", uid);
+
+       return info;
 }
 
-void appinfo_fini(void)
+static struct user_appinfo *_find_user_appinfo(uid_t uid)
 {
-       g_hash_table_destroy(appinfo_tbl);
-       appinfo_tbl = NULL;
+       return g_hash_table_lookup(user_tbl, GINT_TO_POINTER(uid));
 }
 
-const struct appinfo *appinfo_find(uid_t caller_uid, const char *appid)
+static void __vconf_cb(keynode_t *key, void *data)
 {
-       struct appinfo *res;
-       gboolean r;
-       bool multiple;
-       bool preload;
-       bool onboot;
-       char *exec;
-       bool restart;
-       char *pkgid;
-       char *type;
-       pkgmgrinfo_app_hwacceleration hwacc;
+       char *noti_string;
+       char *type_string;
+       char *appid;
+       char *uid_string;
+       uid_t uid;
+       char *saveptr;
        pkgmgrinfo_appinfo_h handle;
-       pkgmgrinfo_app_component component;
-       pkgmgrinfo_permission_type permission;
+       struct user_appinfo *info;
        int ret;
 
-       ret = pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
-       if (ret != PMINFO_R_OK){
-               ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid , caller_uid , &handle);
-               if (ret != PMINFO_R_OK){
-                 _E("appid is not found in DB %s", appid);
-                 return NULL;
-               }
+       noti_string = vconf_keynode_get_str(key);
+       if( noti_string == NULL ) {
+               return;
        }
 
-       res = calloc(1, sizeof(*res));
-       if (!res) {
-               _E("create appinfo: %s", strerror(errno));
-               return NULL;
-       }
+       SECURE_LOGD("noti_string : %s",noti_string);
+       type_string = strtok_r(noti_string, ":", &saveptr);
+       appid = strtok_r(NULL, ":", &saveptr);
+       uid_string = strtok_r(NULL, ":", &saveptr);
+       uid = atoi(uid_string);
 
-       memset(res, 0, sizeof(struct appinfo));
+       _D("type_string: [%s]\n", type_string);
+       _D("appid: [%s]\n", appid);
+       _D("uid: %d\n", uid);
 
-       res->val[_AI_FILE] = strdup(appid);
-       if (!res->val[_AI_FILE]) {
-               _E("create appinfo: %s", strerror(errno));
-               _free_appinfo(res);
-                return NULL;
+       info = _find_user_appinfo(uid);
+       if (info == NULL) {
+               info = _add_user_appinfo(uid);
+               if (info == NULL)
+                       return;
        }
 
-       res->val[_AI_NAME] = strdup(appid); //TODO :
-
-       pkgmgrinfo_appinfo_get_component(handle, &component);
-       if(component == PMINFO_UI_APP) {
-               res->val[_AI_COMP] = strdup("ui"); //TODO :
-
-               r = pkgmgrinfo_appinfo_is_multiple(handle, &multiple);
-               if(multiple == true)
-                       res->val[_AI_MULTI] = strdup("true");
-               else res->val[_AI_MULTI] = strdup("false");
-
-               r = pkgmgrinfo_appinfo_is_preload(handle, &preload);
-               if (preload == false) {
-                       res->val[_AI_PRELOAD] = strdup("false");
-               } else {
-                       res->val[_AI_PRELOAD] = strdup("true");
+       if ( strncmp(type_string, "create", 6) == 0) {
+               //is_admin
+               if (uid != GLOBAL_USER)
+                 ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &handle);
+               else
+                 ret = pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
+               if(ret < 0) {
+                       _E("pkgmgrinfo_appinfo_get_appinfo fail");
                }
 
-               if(gles == 0) {
-                       res->val[_AI_HWACC] = strdup("NOT_USE");
-               } else {
+               SECURE_LOGD("appid : %s /handle : %x", appid, handle);
 
-                       r = pkgmgrinfo_appinfo_get_hwacceleration(handle, &hwacc);
-                       if (hwacc == PMINFO_HWACCELERATION_USE_GL) {
-                               res->val[_AI_HWACC] = strdup("USE");
-                       } else if (hwacc == PMINFO_HWACCELERATION_USE_SYSTEM_SETTING) {
-                               res->val[_AI_HWACC] = strdup("SYS");
-                       } else {
-                               res->val[_AI_HWACC] = strdup("NOT_USE");
+               __app_info_insert_handler(handle, info);
+
+               pkgmgrinfo_appinfo_destroy_appinfo(handle);
+       } else if ( strncmp(type_string, "delete", 6) == 0) {
+               g_hash_table_remove(info->tbl, appid);
+       } else if (strncmp(type_string, "update", 6) == 0){
+               /*REMOVE EXISTING ENTRY & CREATE AGAIN*/
+               if (g_hash_table_remove(info->tbl, appid)){
+                       if (pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &handle) == PMINFO_R_OK){
+                               __app_info_insert_handler(handle, info);
+                               pkgmgrinfo_appinfo_destroy_appinfo(handle);
                        }
                }
-       } else {
-               res->val[_AI_COMP] = strdup("svc");
+       }
+}
 
-               r = pkgmgrinfo_appinfo_is_onboot(handle, &onboot);
-               if(onboot == true)
-                       res->val[_AI_ONBOOT] = strdup("true");
-               else res->val[_AI_ONBOOT] = strdup("false");
+int appinfo_init(void)
+{
+       int r;
+       FILE *fp = NULL;
+       char buf[4096] = {0,};
+       char *tmp = NULL;
+       struct user_appinfo *global_appinfo;
 
-               r = pkgmgrinfo_appinfo_is_autorestart(handle, &restart);
-               if(restart == true)
-                       res->val[_AI_RESTART] = strdup("true");
-               else res->val[_AI_RESTART] = strdup("false");
+       fp = fopen("/proc/cmdline", "r");
+       if (fp == NULL){
+               _E("appinfo init failed: %s", strerror(errno));
+               return -1;
+       }
+       r = fgets(buf, sizeof(buf), fp);
+       tmp = strstr(buf, "gles");
+       if(tmp != NULL) {
+               sscanf(tmp,"gles=%d", &gles);
        }
+       fclose(fp);
 
-       r = pkgmgrinfo_appinfo_get_exec(handle, &exec);
-       res->val[_AI_EXEC] = strdup(exec);
+       user_tbl = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
+                       _free_user_appinfo);
 
-       r = pkgmgrinfo_appinfo_get_apptype(handle, &type);
-       if(strncmp(type, "capp", 4) == 0 ) {
-               res->val[_AI_TYPE] = strdup("rpm");
-       } else if (strncmp(type, "c++app", 6) == 0 || strncmp(type, "ospapp", 6) == 0) {
-               res->val[_AI_TYPE] = strdup("tpk");
-       } else if (strncmp(type, "webapp", 6) == 0) {
-               res->val[_AI_TYPE] = strdup("wgt");
+       global_appinfo = _add_user_appinfo(GLOBAL_USER);
+       if (global_appinfo == NULL) {
+               appinfo_fini();
+               return -1;
        }
 
-       r = pkgmgrinfo_appinfo_get_permission_type(handle, &permission);
-       if (permission == PMINFO_PERMISSION_SIGNATURE) {
-               res->val[_AI_PERM] = strdup("signature");
-       } else if (permission == PMINFO_PERMISSION_PRIVILEGE) {
-               res->val[_AI_PERM] = strdup("privilege");
-       } else {
-               res->val[_AI_PERM] = strdup("normal");
+       r = vconf_notify_key_changed(VCONFKEY_MENUSCREEN_DESKTOP, __vconf_cb, NULL);
+       if (r < 0)
+               _E("Unable to register vconf notification callback for VCONFKEY_MENUSCREEN_DESKTOP\n");
+
+       return 0;
+}
+
+void appinfo_fini(void)
+{
+       g_hash_table_destroy(user_tbl);
+}
+
+const struct appinfo *appinfo_find(uid_t caller_uid, const char *appid)
+{
+       struct user_appinfo *info;
+       struct appinfo *ai;
+
+       /* search from user table */
+       info = _find_user_appinfo(caller_uid);
+       if (info == NULL) {
+               info = _add_user_appinfo(caller_uid);
+               if (info == NULL)
+                       return NULL;
        }
 
-       r = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
-       res->val[_AI_PKGID] = strdup(pkgid);
+       ai = g_hash_table_lookup(info->tbl, appid);
+       if (ai)
+               return ai;
+
+       if (caller_uid == GLOBAL_USER)
+               return NULL;
 
-       SECURE_LOGD("%s : %s : %s", res->val[_AI_FILE], res->val[_AI_COMP], res->val[_AI_TYPE]);
+       /* search again from global table */
+       info = _find_user_appinfo(GLOBAL_USER);
 
-       return res;
+       return g_hash_table_lookup(info->tbl, appid);
 }
 
 const char *appinfo_get_value(const struct appinfo *c, enum appinfo_type type)
@@ -507,15 +487,21 @@ static void _iter_cb(gpointer key, gpointer value, gpointer user_data)
 {
        struct _cbinfo *cbi = user_data;
 
-       assert(cbi);
-
        cbi->cb(cbi->cb_data, key, value);
 }
 
-void appinfo_foreach(appinfo_iter_callback cb, void *user_data)
+void appinfo_foreach(uid_t uid, appinfo_iter_callback cb, void *user_data)
 {
+       struct user_appinfo *info;
        struct _cbinfo cbi;
 
+       info = _find_user_appinfo(uid);
+       if (info == NULL) {
+               info = _add_user_appinfo(uid);
+               if (info == NULL)
+                       return;
+       }
+
        if (!cb) {
                errno = EINVAL;
                _E("appinfo foreach: %s", strerror(errno));
@@ -525,7 +511,7 @@ void appinfo_foreach(appinfo_iter_callback cb, void *user_data)
        cbi.cb = cb;
        cbi.cb_data = user_data;
 
-       g_hash_table_foreach(appinfo_tbl, _iter_cb, &cbi);
+       g_hash_table_foreach(info->tbl, _iter_cb, &cbi);
 }
 
 int appinfo_get_boolean(const struct appinfo *c, enum appinfo_type type)
index 8feddf5..ee78e84 100644 (file)
@@ -31,6 +31,6 @@ int appinfo_get_boolean(const struct appinfo *c, enum appinfo_type type);
 
 typedef void (*appinfo_iter_callback)(void *user_data,
                const char *filename, const struct appinfo *c);
-void appinfo_foreach(appinfo_iter_callback cb, void *user_data);
+void appinfo_foreach(uid_t uid, appinfo_iter_callback cb, void *user_data);
 
 #endif /* __AUL_AMD_APPINFO_H_ */
index e0afc46..add1d4b 100644 (file)
@@ -264,7 +264,7 @@ static void __start_cb(void *user_data,
 
 static void _start_services()
 {
-       appinfo_foreach(__start_cb, NULL);
+       appinfo_foreach(GLOBAL_USER, __start_cb, NULL);
 }
 
 static int __init()