Fix widget_service_get_widget_id API 83/91283/5
authorHwankyu Jhun <h.jhun@samsung.com>
Thu, 6 Oct 2016 12:56:50 +0000 (21:56 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Fri, 7 Oct 2016 04:08:54 +0000 (13:08 +0900)
The appid parameter of the widget_service_get_widget_id API can be
package id.

Change-Id: I8d5e41f1f161a54173b6e9e523bc02bf95f34a9c
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/widget_service.c

index b63dac5..dde849a 100644 (file)
 #define RESOLUTION_SECTION_NAME "resolution"
 #define RESOLUTION_FORMAT "%dx%d"
 
+struct widget_info_s {
+       char *appid;
+       bool is_mainapp;
+};
+
 static GList *lifecycle_cbs;
 static bool _is_resolution_loaded = false;
 
@@ -1415,9 +1420,156 @@ static char *_get_widget_id(const char *appid, uid_t uid)
        return classid;
 }
 
+static int __foreach_appinfo_cb(const pkgmgrinfo_appinfo_h handle,
+               void *user_data)
+{
+       pkgmgrinfo_app_component comp = PMINFO_ALL_APP;
+       char *appid = NULL;
+       bool is_mainapp = false;
+       struct widget_info_s *widget_info;
+       GList **widget_list = (GList **)user_data;
+       int ret;
+
+       ret = pkgmgrinfo_appinfo_get_component(handle, &comp);
+       if (ret != PMINFO_R_OK) {
+               _E("Failed to get component");
+               return 0;
+       }
+
+       if (comp != PMINFO_WIDGET_APP)
+               return 0;
+
+       ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
+       if (ret != PMINFO_R_OK) {
+               _E("Failed to get appid");
+               return 0;
+       }
+
+       ret = pkgmgrinfo_appinfo_is_mainapp(handle, &is_mainapp);
+       if (ret != PMINFO_R_OK)
+               _E("Failed to get is_mainapp");
+
+       widget_info = (struct widget_info_s *)malloc(
+                       sizeof(struct widget_info_s));
+       if (widget_info == NULL) {
+               _E("out of memory");
+               return -1;
+       }
+
+       widget_info->appid = strdup(appid);
+       if (widget_info->appid == NULL) {
+               _E("out of memory");
+               free(widget_info);
+               return -1;
+       }
+
+       widget_info->is_mainapp = is_mainapp;
+
+       *widget_list = g_list_append(*widget_list, widget_info);
+
+       return 0;
+}
+
+static char *__get_widget_main_appid_from_pkgid_or_appid(const char *id)
+{
+       pkgmgrinfo_appinfo_h appinfo = NULL;
+       pkgmgrinfo_pkginfo_h pkginfo = NULL;
+       pkgmgrinfo_appinfo_filter_h handle = NULL;
+       char *new_pkgid = NULL;
+       char *pkgid = NULL;
+       GList *widget_list = NULL;
+       GList *iter;
+       struct widget_info_s *widget_info;
+       char *widget_id = NULL;
+       int ret;
+
+       ret = pkgmgrinfo_pkginfo_get_pkginfo(id, &pkginfo);
+       if (ret != PMINFO_R_OK) {
+               ret = pkgmgrinfo_appinfo_get_appinfo(id, &appinfo);
+               if (ret != PMINFO_R_OK) {
+                       _E("Failed to get app/pkg info - %s", id);
+                       return NULL;
+               }
+
+               ret = pkgmgrinfo_appinfo_get_pkgid(appinfo, &pkgid);
+               if (ret != PMINFO_R_OK) {
+                       _E("Failed to get pkgid - %s", id);
+                       pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
+                       return NULL;
+               }
+
+               ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkginfo);
+               if (ret != PMINFO_R_OK) {
+                       _E("Failed to get pkginfo - %s", id);
+                       pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
+                       return NULL;
+               }
+
+               new_pkgid = strdup(pkgid);
+               pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
+               if (new_pkgid == NULL) {
+                       _E("out of memory");
+                       return NULL;
+               }
+               id = new_pkgid;
+       }
+
+       ret = pkgmgrinfo_appinfo_filter_create(&handle);
+       if (ret != PMINFO_R_OK) {
+               _E("Failed to create pkginfo filter");
+               goto end;
+       }
+
+       ret = pkgmgrinfo_appinfo_filter_add_string(handle,
+                       PMINFO_APPINFO_PROP_APP_PACKAGE, id);
+       if (ret != PMINFO_R_OK) {
+               _E("Failed to add filter string");
+               goto end;
+       }
+
+       ret = pkgmgrinfo_appinfo_filter_foreach_appinfo(handle,
+                       __foreach_appinfo_cb, &widget_list);
+       if (ret != PMINFO_R_OK) {
+               _E("Failed to retrieve appinfo");
+               goto end;
+       }
+
+       if (widget_list == NULL)
+               goto end;
+
+       iter = g_list_first(widget_list);
+       while (iter) {
+               widget_info = iter->data;
+               iter = g_list_next(iter);
+               if (widget_info) {
+                       widget_list = g_list_remove(widget_list, widget_info);
+                       if (widget_info->is_mainapp) {
+                               if (widget_id)
+                                       free(widget_id);
+                               widget_id = strdup(widget_info->appid);
+                       }
+
+                       if (widget_id == NULL)
+                               widget_id = strdup(widget_info->appid);
+
+                       free(widget_info->appid);
+                       free(widget_info);
+               }
+       }
+
+end:
+       pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
+       pkgmgrinfo_appinfo_filter_destroy(handle);
+       if (new_pkgid)
+               free(new_pkgid);
+
+       return widget_id;
+}
+
 EAPI char *widget_service_get_widget_id(const char *appid)
 {
        char *classid;
+       char *widget_id;
 
        if (!_is_widget_feature_enabled()) {
                _E("not supported");
@@ -1440,6 +1592,23 @@ EAPI char *widget_service_get_widget_id(const char *appid)
        if (classid == NULL && get_last_result() == WIDGET_ERROR_NOT_EXIST)
                classid = _get_widget_id(appid, GLOBALAPP_USER);
 
+       if (classid)
+               return classid;
+       else if (get_last_result() != WIDGET_ERROR_NOT_EXIST)
+               return NULL;
+
+       widget_id = __get_widget_main_appid_from_pkgid_or_appid(appid);
+       if (widget_id == NULL) {
+               _E("Failed to get widget id");
+               return NULL;
+       }
+
+       classid = _get_widget_id(widget_id, getuid());
+       if (classid == NULL && get_last_result() == WIDGET_ERROR_NOT_EXIST)
+               classid = _get_widget_id(widget_id, GLOBALAPP_USER);
+
+       free(widget_id);
+
        return classid;
 }