+ sqlite3_finalize(stmt);
+
+ if (*appid == NULL) {
+ LOGE("out of memory");
+ return PMINFO_R_ERROR;
+ }
+
+ return PMINFO_R_OK;
+}
+
+static int _pkgmgrinfo_appinfo_get_datacontrol_appid(uid_t uid,
+ const char *providerid, char **appid)
+{
+ int ret;
+ char *dbpath;
+ sqlite3 *db;
+
+ dbpath = getUserPkgParserDBPathUID(GLOBAL_USER);
+ if (dbpath == NULL)
+ return PMINFO_R_ERROR;
+
+ ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
+ free(dbpath);
+ if (ret != SQLITE_OK) {
+ LOGE("open db failed: %s", sqlite3_errmsg(db));
+ return PMINFO_R_ERROR;
+ }
+
+ ret = _appinfo_get_datacontrol_appid(db, providerid, appid);
+ sqlite3_close_v2(db);
+
+ return ret;
+}
+
+API int pkgmgrinfo_appinfo_usr_get_datacontrol_appid(const char *providerid,
+ uid_t uid, char **appid)
+{
+ int ret;
+
+ if (providerid == NULL || appid == NULL) {
+ LOGE("invalid parameter");
+ return PMINFO_R_EINVAL;
+ }
+
+ ret = _pkgmgrinfo_appinfo_get_datacontrol_appid(GLOBAL_USER, providerid,
+ appid);
+ if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER)
+ ret = _pkgmgrinfo_appinfo_get_datacontrol_appid(uid, providerid,
+ appid);
+
+ /* FIXME: It should return PMINFO_R_ENOENT but to keep previous
+ * implementation, return PMINFO_R_ERROR. This should be
+ * modified later...
+ */
+ if (ret == PMINFO_R_ENOENT) {
+ LOGE("no datacontrol appid of %s", providerid);
+ ret = PMINFO_R_ERROR;
+ }
+
+ return ret;
+}
+
+API int pkgmgrinfo_appinfo_get_datacontrol_appid(const char *providerid, char **appid)
+{
+ return pkgmgrinfo_appinfo_usr_get_datacontrol_appid(providerid, _getuid(), appid);
+}
+
+static int _appinfo_get_datacontrol_trusted_info(sqlite3 *db,
+ const char *providerid, const char *type, char **appid,
+ bool *is_trusted)
+{
+ static const char query[] =
+ "SELECT app_id, trusted FROM package_app_data_control "
+ "WHERE providerid=? AND type=?";
+ int ret;
+ sqlite3_stmt *stmt;
+
+ ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("prepare failed: %s", sqlite3_errmsg(db));
+ return PMINFO_R_ERROR;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, providerid, -1, SQLITE_STATIC);
+ if (ret != SQLITE_OK) {
+ LOGE("bind failed: %s", sqlite3_errmsg(db));
+ sqlite3_finalize(stmt);
+ return PMINFO_R_ERROR;
+ }
+
+ ret = sqlite3_bind_text(stmt, 2, type, -1, SQLITE_STATIC);
+ if (ret != SQLITE_OK) {
+ LOGE("bind failed: %s", sqlite3_errmsg(db));
+ sqlite3_finalize(stmt);
+ return PMINFO_R_ERROR;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_ROW) {
+ sqlite3_finalize(stmt);
+ if (ret == SQLITE_DONE) {
+ return PMINFO_R_ENOENT;
+ } else {
+ LOGE("step error: %s", sqlite3_errmsg(db));
+ return PMINFO_R_ERROR;
+ }
+ }
+
+ *appid = strdup((char *)sqlite3_column_text(stmt, 0));
+ *is_trusted = _get_bool_value((char *)sqlite3_column_text(stmt, 1));
+
+ sqlite3_finalize(stmt);
+
+ if (*appid == NULL) {
+ LOGE("out of memory");
+ return PMINFO_R_ERROR;
+ }
+
+ return PMINFO_R_OK;
+}
+
+static int _pkgmgrinfo_appinfo_get_datacontrol_trusted_info(uid_t uid,
+ const char *providerid, const char *type, char **appid,
+ bool *is_trusted)
+{
+ int ret;
+ char *dbpath;
+ sqlite3 *db;
+
+ dbpath = getUserPkgParserDBPathUID(GLOBAL_USER);
+ if (dbpath == NULL)
+ return PMINFO_R_ERROR;
+
+ ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
+ free(dbpath);
+ if (ret != SQLITE_OK) {
+ LOGE("open db failed: %s", sqlite3_errmsg(db));
+ return PMINFO_R_ERROR;
+ }
+
+ ret = _appinfo_get_datacontrol_trusted_info(db, providerid, type, appid,
+ is_trusted);
+ sqlite3_close_v2(db);
+
+ return ret;
+}
+
+API int pkgmgrinfo_appinfo_usr_get_datacontrol_trusted_info(
+ const char *providerid, const char *type, uid_t uid,
+ char **appid, bool *is_trusted)
+{
+ int ret;
+
+ if (providerid == NULL || type == NULL || appid == NULL ||
+ is_trusted == NULL) {
+ LOGE("invalid parameter");
+ return PMINFO_R_EINVAL;
+ }
+
+ ret = _pkgmgrinfo_appinfo_get_datacontrol_trusted_info(GLOBAL_USER,
+ providerid, type, appid, is_trusted);
+ if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER)
+ ret = _pkgmgrinfo_appinfo_get_datacontrol_trusted_info(uid,
+ providerid, type, appid, is_trusted);
+
+ /* FIXME: It should return PMINFO_R_ENOENT but to keep previous
+ * implementation, return PMINFO_R_ERROR. This should be
+ * modified later...
+ */
+ if (ret == PMINFO_R_ENOENT) {
+ LOGE("no datacontrol trusted info of %s", providerid);
+ ret = PMINFO_R_ERROR;
+ }
+
+ return ret;
+}
+
+API int pkgmgrinfo_appinfo_get_datacontrol_trsuted_info(const char *providerid,
+ const char *type, char **appid, bool *is_trusted)
+{
+ return pkgmgrinfo_appinfo_usr_get_datacontrol_trusted_info(providerid,
+ type, _getuid(), appid, is_trusted);
+}
+
+static int _appinfo_foreach_datacontrol_privileges(sqlite3 *db,
+ const char *providerid, const char *type,
+ pkgmgrinfo_pkg_privilege_list_cb callback, void *user_data)
+{
+ static const char query[] =
+ "SELECT privilege FROM package_app_data_control_privilege "
+ "WHERE providerid=? AND type=?";
+ int ret;
+ sqlite3_stmt *stmt;
+ int count = 0;
+
+ ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("prepare failed: %s", sqlite3_errmsg(db));
+ return PMINFO_R_ERROR;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, providerid, -1, SQLITE_STATIC);
+ if (ret != SQLITE_OK) {
+ LOGE("bind failed: %s", sqlite3_errmsg(db));
+ sqlite3_finalize(stmt);
+ return PMINFO_R_ERROR;
+ }
+
+ ret = sqlite3_bind_text(stmt, 2, type, -1, SQLITE_STATIC);
+ if (ret != SQLITE_OK) {
+ LOGE("bind failed: %s", sqlite3_errmsg(db));
+ sqlite3_finalize(stmt);
+ return PMINFO_R_ERROR;
+ }
+
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ count++;
+ ret = callback((const char *)sqlite3_column_text(stmt, 0),
+ user_data);
+ if (ret < 0)
+ break;
+ }
+
+ sqlite3_finalize(stmt);
+
+ return count ? PMINFO_R_OK : PMINFO_R_ENOENT;
+}
+
+static int _pkgmgrinfo_appinfo_foreach_datacontrol_privileges(uid_t uid,
+ const char *providerid, const char *type,
+ pkgmgrinfo_pkg_privilege_list_cb callback, void *user_data)
+{
+ int ret;
+ char *dbpath;
+ sqlite3 *db;
+
+ dbpath = getUserPkgParserDBPathUID(GLOBAL_USER);
+ if (dbpath == NULL)
+ return PMINFO_R_ERROR;
+
+ ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
+ free(dbpath);
+ if (ret != SQLITE_OK) {
+ LOGE("open db failed: %s", sqlite3_errmsg(db));
+ return PMINFO_R_ERROR;
+ }
+
+ ret = _appinfo_foreach_datacontrol_privileges(db, providerid, type,
+ callback, user_data);
+ sqlite3_close_v2(db);
+
+ return ret;
+}
+
+API int pkgmgrinfo_appinfo_usr_foreach_datacontrol_privileges(
+ const char *providerid, const char *type,
+ pkgmgrinfo_pkg_privilege_list_cb privilege_func,
+ void *user_data, uid_t uid)
+{
+ int ret;
+
+ if (providerid == NULL || type == NULL || privilege_func == NULL) {
+ LOGE("invalid parameter");
+ return PMINFO_R_EINVAL;
+ }
+
+ ret = _pkgmgrinfo_appinfo_foreach_datacontrol_privileges(GLOBAL_USER,
+ providerid, type, privilege_func, user_data);
+ if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER)
+ ret = _pkgmgrinfo_appinfo_foreach_datacontrol_privileges(uid,
+ providerid, type, privilege_func, user_data);
+
+ if (ret == PMINFO_R_ENOENT)
+ ret = PMINFO_R_OK;
+
+ return ret;
+}
+
+API int pkgmgrinfo_appinfo_foreach_datacontrol_privileges(
+ const char *providerid, const char *type,
+ pkgmgrinfo_pkg_privilege_list_cb privilege_func,
+ void *user_data)
+{
+ return pkgmgrinfo_appinfo_usr_foreach_datacontrol_privileges(
+ providerid, type, privilege_func, user_data, _getuid());
+}
+
+API int pkgmgrinfo_appinfo_get_support_mode(pkgmgrinfo_appinfo_h handle, int *support_mode)
+{
+ retvm_if(handle == NULL, PMINFO_R_EINVAL, "appinfo handle is NULL");
+ retvm_if(support_mode == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
+
+ pkgmgr_appinfo_x *info = (pkgmgr_appinfo_x *)handle;
+ if (info->app_info->support_mode)
+ *support_mode = atoi(info->app_info->support_mode);
+ else
+ *support_mode = 0;
+
+ return PMINFO_R_OK;
+}
+
+API int pkgmgrinfo_appinfo_foreach_category(pkgmgrinfo_appinfo_h handle,
+ pkgmgrinfo_app_category_list_cb category_func, void *user_data)
+{
+ retvm_if(handle == NULL, PMINFO_R_EINVAL, "appinfo handle is NULL");
+ retvm_if(category_func == NULL, PMINFO_R_EINVAL, "Callback function is NULL");
+ int ret = -1;
+ const char *category;
+ GList *tmp;
+ pkgmgr_appinfo_x *info = (pkgmgr_appinfo_x *)handle;
+
+ if (info->app_info == NULL)
+ return PMINFO_R_ERROR;
+
+ for (tmp = info->app_info->category; tmp; tmp = tmp->next) {
+ category = (const char *)tmp->data;
+ if (category) {
+ ret = category_func(category, user_data);
+ if (ret < 0)
+ break;
+ }
+ }
+ return PMINFO_R_OK;
+}
+
+API int pkgmgrinfo_appinfo_foreach_metadata(pkgmgrinfo_appinfo_h handle,
+ pkgmgrinfo_app_metadata_list_cb metadata_func, void *user_data)
+{
+ retvm_if(handle == NULL, PMINFO_R_EINVAL, "appinfo handle is NULL");
+ retvm_if(metadata_func == NULL, PMINFO_R_EINVAL, "Callback function is NULL");
+ int ret = -1;
+ metadata_x *ptr;
+ GList *tmp;
+ pkgmgr_appinfo_x *info = (pkgmgr_appinfo_x *)handle;
+
+ if (info->app_info == NULL)
+ return PMINFO_R_ERROR;
+
+ for (tmp = info->app_info->metadata; tmp; tmp = tmp->next) {
+ ptr = (metadata_x *)tmp->data;
+ if (ptr == NULL)
+ continue;
+ if (ptr->key) {
+ ret = metadata_func(ptr->key, ptr->value ? ptr->value : "", user_data);
+ if (ret < 0)
+ break;
+ }
+ }
+ return PMINFO_R_OK;
+}
+
+static int _appinfo_foreach_appcontrol_privileges(sqlite3 *db,
+ const char *appid, const char *operation,
+ pkgmgrinfo_pkg_privilege_list_cb callback, void *user_data)
+{
+ static const char query[] =
+ "SELECT app_control, privilege FROM package_app_app_control_privilege "
+ "WHERE app_id=?";
+ int ret;
+ sqlite3_stmt *stmt;
+ const char *app_control;
+ char *dup_app_control;
+ char *token;
+ char *saveptr = NULL;
+ const char *privilege;
+ int count = 0;
+
+ ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("prepare failed: %s", sqlite3_errmsg(db));
+ return PMINFO_R_ERROR;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_STATIC);
+ if (ret != SQLITE_OK) {
+ LOGE("bind failed: %s", sqlite3_errmsg(db));
+ sqlite3_finalize(stmt);
+ return PMINFO_R_ERROR;
+ }
+
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ app_control = (const char *)sqlite3_column_text(stmt, 0);
+ if (!app_control)
+ continue;
+
+ dup_app_control = strdup(app_control);
+ if (!dup_app_control)
+ continue;
+
+ token = strtok_r(dup_app_control, "|", &saveptr);
+ if (token && !strcmp(token, operation)) {
+ count++;
+ privilege = (const char *)sqlite3_column_text(stmt, 1);
+ ret = callback(privilege, user_data);
+ if (ret < 0) {
+ free(dup_app_control);
+ break;
+ }
+ }
+ free(dup_app_control);
+ }