#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 */
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;
return -1;
}
- g_hash_table_remove(tbl, appid);
+ g_hash_table_remove(info->tbl, appid);
c = calloc(1, sizeof(*c));
if (!c) {
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;
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)
{
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));
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)