Add new elements for component-based application
[platform/core/appfw/pkgmgr-info.git] / src / pkgmgrinfo_appinfo.c
index 232d75e..bc42092 100644 (file)
@@ -155,7 +155,7 @@ static int _appinfo_get_category(sqlite3 *db, const char *appid,
 }
 
 static void __parse_appcontrol(GList **appcontrol, char *appcontrol_str,
-               char *visibility)
+               char *visibility, char *id)
 {
        char *dup;
        char *token;
@@ -187,6 +187,7 @@ static void __parse_appcontrol(GList **appcontrol, char *appcontrol_str,
                if (token && strcmp(token, "NULL"))
                        ac->mime = strdup(token);
                ac->visibility = strdup(visibility);
+               ac->id = strdup(id);
                *appcontrol = g_list_append(*appcontrol, ac);
        } while ((token = strtok_r(NULL, ";", &ptr)));
 
@@ -197,13 +198,15 @@ static int _appinfo_get_app_control(sqlite3 *db, const char *appid,
                GList **appcontrol)
 {
        static const char query_raw[] =
-               "SELECT app_control, visibility FROM package_app_app_control "
-               "WHERE app_id=%Q";
+               "SELECT app_control, visibility, app_control_id "
+               "FROM package_app_app_control WHERE app_id=%Q";
        int ret;
+       int idx;
        char *query;
        sqlite3_stmt *stmt;
        char *str;
        char *visibility;
+       char *id;
 
        query = sqlite3_mprintf(query_raw, appid);
        if (query == NULL) {
@@ -221,12 +224,16 @@ static int _appinfo_get_app_control(sqlite3 *db, const char *appid,
        while (sqlite3_step(stmt) == SQLITE_ROW) {
                str = NULL;
                visibility = NULL;
-               _save_column_str(stmt, 0, &str);
-               _save_column_str(stmt, 0, &visibility);
+               id = NULL;
+               idx = 0;
+               _save_column_str(stmt, idx++, &str);
+               _save_column_str(stmt, idx++, &visibility);
+               _save_column_str(stmt, idx++, &id);
                /* TODO: revise */
-               __parse_appcontrol(appcontrol, str, visibility);
+               __parse_appcontrol(appcontrol, str, visibility, id);
                free(str);
                free(visibility);
+               free(id);
        }
 
        sqlite3_finalize(stmt);
@@ -325,6 +332,52 @@ static int _appinfo_get_splashscreens(sqlite3 *db, const char *appid,
        return PMINFO_R_OK;
 }
 
+static int _appinfo_get_component_info(sqlite3 *db, const char *appid,
+               GList **components)
+{
+       static const char query_raw[] =
+               "SELECT component_id, type, launch_mode "
+               "FROM package_app_component_info "
+               "WHERE app_id=%Q";
+       int ret;
+       char *query;
+       sqlite3_stmt *stmt;
+       int idx;
+       component_x *info;
+
+       query = sqlite3_mprintf(query_raw, appid);
+       if (query == NULL) {
+               LOGE("out of memory");
+               return PMINFO_R_ERROR;
+       }
+
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       sqlite3_free(query);
+       if (ret != SQLITE_OK) {
+               LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return PMINFO_R_ERROR;
+       }
+
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               info = calloc(1, sizeof(component_x));
+               if (info == NULL) {
+                       LOGE("out of memory");
+                       sqlite3_finalize(stmt);
+                       return PMINFO_R_ERROR;
+               }
+
+               idx = 0;
+               _save_column_str(stmt, idx++, &info->id);
+               _save_column_str(stmt, idx++, &info->type);
+               _save_column_str(stmt, idx++, &info->launch_mode);
+               *components = g_list_append(*components, info);
+       }
+
+       sqlite3_finalize(stmt);
+
+       return PMINFO_R_OK;
+}
+
 static GList *__get_background_category(const char *value)
 {
        GList *category_list = NULL;
@@ -696,6 +749,15 @@ static int _appinfo_get_applications(uid_t db_uid, uid_t uid,
                        }
                }
 
+               if (info->component &&
+                               !strcmp(info->component, "componentbasedapp")) {
+                       if (_appinfo_get_component_info(db, info->appid,
+                                               &info->components)) {
+                               ret = PMINFO_R_ERROR;
+                               goto catch;
+                       }
+               }
+
                if (is_check_storage &&
                                __appinfo_check_installed_storage(info) != PMINFO_R_OK) {
                        ret = PMINFO_R_ERROR;
@@ -1073,6 +1135,28 @@ static gpointer __copy_splashscreens(gconstpointer src, gpointer data)
        return splashscreen;
 }
 
+static gpointer __copy_components(gconstpointer src, gpointer data)
+{
+       component_x *tmp = (component_x *)src;
+       component_x *component;
+
+       component = (component_x *)calloc(1, sizeof(component_x));
+       if (component == NULL) {
+               LOGE("memory alloc failed");
+               *(int *)data = -1;
+               return NULL;
+       }
+
+       if (tmp->id)
+               component->id = strdup(tmp->id);
+       if (tmp->type)
+               component->type = strdup(tmp->type);
+       if (tmp->launch_mode)
+               component->launch_mode = strdup(tmp->launch_mode);
+
+       return component;
+}
+
 static int _appinfo_copy_appinfo(application_x **application, application_x *data)
 {
        application_x *app_info;
@@ -1216,6 +1300,15 @@ static int _appinfo_copy_appinfo(application_x **application, application_x *dat
                return PMINFO_R_ERROR;
        }
 
+       ret = 0;
+       app_info->components = g_list_copy_deep(data->components,
+                       __copy_components, &ret);
+       if (ret < 0) {
+               LOGE("memory alloc failed");
+               pkgmgrinfo_basic_free_application(app_info);
+               return PMINFO_R_ERROR;
+       }
+
        *application = app_info;
 
        return PMINFO_R_OK;
@@ -1718,6 +1811,8 @@ static pkgmgrinfo_app_component __appcomponent_convert(const char *comp)
                return PMINFO_WIDGET_APP;
        else if (strcasecmp(comp, "watchapp") == 0)
                return PMINFO_WATCH_APP;
+       else if (strcasecmp(comp, "componentbasedapp") == 0)
+               return PMINFO_COMPONENT_BASED_APP;
        else
                return -1;
 }
@@ -1733,6 +1828,8 @@ static const char *__appcomponent_str(pkgmgrinfo_app_component comp)
                return "widgetapp";
        case PMINFO_WATCH_APP:
                return "watchapp";
+       case PMINFO_COMPONENT_BASED_APP:
+               return "componentbasedapp";
        default:
                return NULL;
        }
@@ -3623,3 +3720,82 @@ API int pkgmgrinfo_appinfo_is_guestmode_visibility(pkgmgrinfo_appinfo_h handle,
        *status = _get_bool_value(val);
        return PMINFO_R_OK;
 }
+
+API int pkgmgrinfo_appinfo_foreach_appcontrol_v2(pkgmgrinfo_appinfo_h handle,
+               pkgmgrinfo_app_control_list_cb_v2 appcontrol_func,
+               void *user_data)
+{
+       retvm_if(handle == NULL, PMINFO_R_EINVAL, "appinfo handle is NULL");
+       retvm_if(appcontrol_func == NULL, PMINFO_R_EINVAL, "Callback function is NULL");
+       int ret;
+       pkgmgr_appinfo_x *info = (pkgmgr_appinfo_x *)handle;
+       appcontrol_x *appcontrol;
+       GList *tmp;
+
+       if (info->app_info == NULL)
+               return PMINFO_R_ERROR;
+
+       for (tmp = info->app_info->appcontrol; tmp; tmp = tmp->next) {
+               appcontrol = (appcontrol_x *)tmp->data;
+               if (appcontrol == NULL ||
+                               !strcasecmp(appcontrol->visibility, "remote-only"))
+                       continue;
+               ret = appcontrol_func(appcontrol->operation, appcontrol->uri,
+                               appcontrol->mime, appcontrol->id, user_data);
+               if (ret < 0)
+                       break;
+       }
+
+       return PMINFO_R_OK;
+}
+
+API int pkgmgrinfo_appinfo_foreach_remote_appcontrol_v2(
+               pkgmgrinfo_appinfo_h handle,
+               pkgmgrinfo_app_control_list_cb_v2 appcontrol_func,
+               void *user_data)
+{
+       retvm_if(handle == NULL, PMINFO_R_EINVAL, "appinfo handle is NULL");
+       retvm_if(appcontrol_func == NULL, PMINFO_R_EINVAL, "Callback function is NULL");
+       int ret;
+       pkgmgr_appinfo_x *info = (pkgmgr_appinfo_x *)handle;
+       appcontrol_x *appcontrol;
+       GList *tmp;
+
+       if (info->app_info == NULL)
+               return PMINFO_R_ERROR;
+
+       for (tmp = info->app_info->appcontrol; tmp; tmp = tmp->next) {
+               appcontrol = (appcontrol_x *)tmp->data;
+               if (appcontrol == NULL ||
+                               !strcasecmp(appcontrol->visibility, "local-only"))
+                       continue;
+               ret = appcontrol_func(appcontrol->operation, appcontrol->uri,
+                               appcontrol->mime, appcontrol->id, user_data);
+               if (ret < 0)
+                       break;
+       }
+
+       return PMINFO_R_OK;
+}
+
+API int pkgmgrinfo_appinfo_foreach_component_info(pkgmgrinfo_appinfo_h handle,
+               pkgmgrinfo_component_info_list_cb callback, void *user_data)
+{
+       retvm_if(handle == NULL, PMINFO_R_EINVAL, "appinfo handle is NULL");
+       retvm_if(callback == NULL, PMINFO_R_EINVAL, "callback is NULL");
+       pkgmgr_appinfo_x *info = (pkgmgr_appinfo_x *)handle;
+       pkgmgr_compinfo_x compinfo;
+       GList *tmp;
+
+       if (info->app_info == NULL)
+               return PMINFO_R_ERROR;
+
+       compinfo.appid = info->app_info->appid;
+       for (tmp = info->app_info->components; tmp; tmp = tmp->next) {
+               compinfo.comp_info = (component_x *)tmp->data;
+               if (callback(&compinfo, user_data) < 0)
+                       break;
+       }
+
+       return PMINFO_R_OK;
+}