#include "launch.h"
#define MAX_CHECKSUM_BUF 2048
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#define FREE_AND_NULL(x) do { \
+ if (x) { \
+ free(x); \
+ x = NULL; \
+ } \
+} while (0)
/* callback handling */
typedef struct _aul_svc_cb_info_t {
return __set_bundle(b, AUL_SVC_K_LAUNCH_MODE, mode);
}
-static int __run_service(bundle *b, int request_code,
- aul_svc_res_fn cbfunc, aul_svc_err_cb err_cb,
- void *data, uid_t uid, bool sync)
-{
- aul_svc_resolve_info_t info;
- char *pkgname;
- char *operation;
- int pkg_count = 0;
- int ret = -1;
+typedef struct resolution_info_s {
char *appid;
- int l;
- GSList *pkg_list = NULL;
- char *query = NULL;
+ const char *uri_r_info;
+ GSList *list;
+ bundle *b;
+ uid_t uid;
+ aul_svc_resolve_info_t ri;
gchar *checksum;
+ char *cache;
+} resolution_info_t;
- if (b == NULL) {
- _E("bundle is NULL");
- return AUL_SVC_RET_EINVAL;
- }
-
- pkgname = (char *)aul_svc_get_pkgname(b);
- operation = (char *)aul_svc_get_operation(b);
-
- /* explict*/
- if (pkgname) {
- if (operation == NULL)
- aul_svc_set_operation(b, AUL_SVC_OPERATION_DEFAULT);
- ret = __run_svc_with_pkgname(pkgname, b, request_code, cbfunc,
- err_cb, data, uid, sync);
- return ret;
- }
+typedef int (*resolution_handler)(resolution_info_t *info);
- /* share panel */
- if (TIZEN_FEATURE_SHARE_PANEL
- && (operation && (strcmp(operation, AUL_SVC_OPERATION_SHARE) == 0
- || strcmp(operation, AUL_SVC_OPERATION_MULTI_SHARE) == 0
- || strcmp(operation, AUL_SVC_OPERATION_SHARE_TEXT) == 0))) {
- ret = __run_svc_with_pkgname(SHARE_PANEL, b, request_code,
- cbfunc, err_cb, data, uid, sync);
- return ret;
- }
+static int __resolution_pre(resolution_info_t *info)
+{
+ aul_svc_resolve_info_t *ri = &info->ri;
+ int ret;
+ size_t n;
- memset(&info, 0, sizeof(aul_svc_resolve_info_t));
- ret = __get_resolve_info(b, &info);
- if (ret < 0) {
- __free_resolve_info_data(&info);
- return ret;
- }
+ ret = __get_resolve_info(info->b, ri);
+ if (ret < 0)
+ goto err;
SECURE_LOGD("op - %s / mime - %s / scheme - %s",
- info.op, info.origin_mime, info.scheme);
-
- checksum = __make_checksum(info.op, info.uri, info.origin_mime);
- appid = __get_cache(checksum, uid);
-
- if (appid) {
- _D("Hit! %s / %s", checksum, appid);
- l = strlen("@APP_SELECTOR ");
- if (!strncmp("@APP_SELECTOR ", appid, l)) {
- bundle_add(b, AUL_SVC_K_URI_R_INFO, &appid[l]);
- ret = __run_svc_with_pkgname(APP_SELECTOR, b,
- request_code, cbfunc, err_cb,
- data, uid, sync);
- } else if (!strcmp(appid, "^")) {
+ ri->op, ri->origin_mime, ri->scheme);
+
+ info->checksum = __make_checksum(ri->op, ri->uri, ri->origin_mime);
+ info->cache = __get_cache(info->checksum, info->uid);
+ if (info->cache) {
+ _D("Hit! %s / %s", info->checksum, info->cache);
+ if (!strcmp(info->cache, "^")) {
ret = AUL_SVC_RET_ENOMATCH;
+ goto err;
+ }
+
+ n = strlen("@APP_SELECTOR ");
+ if (!strncmp("@APP_SELECTOR ", info->cache, n)) {
+ bundle_add(info->b, AUL_SVC_K_URI_R_INFO,
+ &info->cache[n]);
+ info->appid = strdup(APP_SELECTOR);
+ if (info->appid == NULL) {
+ _E("Out of memory");
+ ret = AUL_SVC_RET_ERROR;
+ goto err;
+ }
} else {
- ret = __run_svc_with_pkgname(appid, b, request_code,
- cbfunc, err_cb, data, uid, sync);
+ info->appid = info->cache;
}
- free(appid);
- g_free(checksum);
- __free_resolve_info_data(&info);
- return ret;
+
+ return AUL_SVC_RET_OK;
}
- ret = _svc_db_check_perm(uid, true);
+ ret = _svc_db_check_perm(info->uid, true);
if (ret < 0) {
- _E("permission error : %d", ret);
+ _E("Permission denied. error(%d)", ret);
ret = AUL_SVC_RET_EILLACC;
- goto end;
+ goto err;
}
- /*uri*/
- pkgname = _svc_db_get_app(info.op, info.origin_mime, info.uri, uid);
- if (pkgname != NULL) {
- __put_cache(checksum, pkgname, uid);
- ret = __run_svc_with_pkgname(pkgname, b, request_code,
- cbfunc, err_cb, data, uid, sync);
- free(pkgname);
- goto end;
- }
+ return AUL_SVC_RET_OK;
- query = __make_query_with_collation(info.op, info.uri,
- info.mime, info.m_type, info.s_type);
+err:
+ if (info->cache) {
+ free(info->cache);
+ info->cache = NULL;
+ }
- query = _svc_db_query_builder_build(query);
- _svc_db_exec_query(query, &pkg_list, uid);
- if (query) {
- free(query);
- query = NULL;
+ if (info->checksum) {
+ g_free(info->checksum);
+ info->checksum = NULL;
}
- pkg_count = g_slist_length(pkg_list);
- if (pkg_count > 0) {
- __free_pkg_list(pkg_list);
- pkg_list = NULL;
- if (info.uri_r_info) {
- query = __make_query(query, info.op, info.uri_r_info,
- info.mime, info.m_type, info.s_type);
- }
+ __free_resolve_info_data(ri);
- query = __make_query(query, info.op, info.scheme,
- info.mime, info.m_type, info.s_type);
+ return ret;
+}
- query = __make_query(query, info.op, "*",
- info.mime, info.m_type, info.s_type);
+static int __resolution_uri(resolution_info_t *info)
+{
+ aul_svc_resolve_info_t *ri = &info->ri;
+ char *id;
+ char *query;
- if (info.scheme && (strcmp(info.scheme, "file") == 0)
- && info.mime && (strcmp(info.mime, "NULL") != 0)) {
- query = __make_query(query, info.op, "NULL",
- info.mime, info.m_type, info.s_type);
- }
+ if (info->appid || info->list)
+ return AUL_SVC_RET_OK;
- query = _svc_db_query_builder_build(query);
- _svc_db_exec_query(query, &pkg_list, uid);
- if (query) {
- free(query);
- query = NULL;
- }
+ id = _svc_db_get_app(ri->op, ri->origin_mime, ri->uri, info->uid);
+ if (id) {
+ info->appid = id;
+ return AUL_SVC_RET_OK;
+ }
- if (info.category)
- __get_list_with_category(info.category, &pkg_list, uid);
+ query = __make_query_with_collation(ri->op, ri->uri, ri->mime,
+ ri->m_type, ri->s_type);
+ query = _svc_db_query_builder_build(query);
+ _svc_db_exec_query(query, &info->list, info->uid);
+ FREE_AND_NULL(query);
- __get_list_with_submode(info.op, info.win_id, &pkg_list, uid);
+ if (!info->list)
+ return AUL_SVC_RET_OK;
- pkg_count = g_slist_length(pkg_list);
- _D("pkg_count : %d", pkg_count);
+ __free_pkg_list(info->list);
+ info->list = NULL;
- if (pkg_count == 1) {
- pkgname = (char *)pkg_list->data;
- if (pkgname != NULL) {
- __put_cache(checksum, pkgname, uid);
- ret = __run_svc_with_pkgname(pkgname, b, request_code,
- cbfunc, err_cb, data, uid, sync);
- goto end;
- }
- } else if (pkg_count > 1) {
- bundle_add(b, AUL_SVC_K_URI_R_INFO, info.uri);
- __put_cache_with_info(checksum, info.uri, uid);
- ret = __run_svc_with_pkgname(APP_SELECTOR, b, request_code,
- cbfunc, err_cb, data, uid, sync);
- goto end;
- }
- __free_pkg_list(pkg_list);
- pkg_list = NULL;
+ if (ri->uri_r_info) {
+ query = __make_query(query, ri->op, ri->uri_r_info,
+ ri->mime, ri->m_type, ri->s_type);
}
- /*scheme & host*/
- if (info.uri_r_info) {
- pkgname = _svc_db_get_app(info.op, info.origin_mime, info.uri_r_info, uid);
+ query = __make_query(query, ri->op, ri->scheme, ri->mime,
+ ri->m_type, ri->s_type);
+ query = __make_query(query, ri->op, "*", ri->mime,
+ ri->m_type, ri->s_type);
+ if ((ri->scheme && !strcmp(ri->scheme, "file")) &&
+ (ri->mime && !strcmp(ri->mime, "NULL"))) {
+ query = __make_query(query, ri->op, "NULL", ri->mime,
+ ri->m_type, ri->s_type);
+ }
+ query = _svc_db_query_builder_build(query);
+ _svc_db_exec_query(query, &info->list, info->uid);
+ FREE_AND_NULL(query);
- if (pkgname != NULL) {
- __put_cache(checksum, pkgname, uid);
- ret = __run_svc_with_pkgname(pkgname, b, request_code,
- cbfunc, err_cb, data, uid, sync);
- free(pkgname);
- goto end;
- }
+ if (ri->category)
+ __get_list_with_category(ri->category, &info->list, info->uid);
+ __get_list_with_submode(ri->op, ri->win_id, &info->list, info->uid);
- query = __make_query(query, info.op, info.uri_r_info,
- info.mime, info.m_type, info.s_type);
- query = _svc_db_query_builder_build(query);
- _svc_db_exec_query(query, &pkg_list, uid);
- if (query) {
- free(query);
- query = NULL;
- }
+ if (info->list)
+ info->uri_r_info = ri->uri;
- pkg_count = g_slist_length(pkg_list);
- if (pkg_count > 0) {
- __free_pkg_list(pkg_list);
- pkg_list = NULL;
- query = __make_query(query, info.op, "*",
- info.mime, info.m_type, info.s_type);
+ return AUL_SVC_RET_OK;
+}
- if (info.scheme && (strcmp(info.scheme, "file") == 0)
- && info.mime && (strcmp(info.mime, "NULL") != 0)) {
- query = __make_query(query, info.op, "NULL",
- info.mime, info.m_type, info.s_type);
- }
+static int __resolution_scheme_and_host(resolution_info_t *info)
+{
+ aul_svc_resolve_info_t *ri = &info->ri;
+ char *id;
+ char *query = NULL;
- query = _svc_db_query_builder_build(query);
- _svc_db_exec_query(query, &pkg_list, uid);
- if (query) {
- free(query);
- query = NULL;
- }
+ if (info->appid || info->list)
+ return AUL_SVC_RET_OK;
+
+ if (!ri->uri_r_info)
+ return AUL_SVC_RET_OK;
- if (info.category)
- __get_list_with_category(info.category, &pkg_list, uid);
+ id = _svc_db_get_app(ri->op, ri->origin_mime, ri->uri_r_info,
+ info->uid);
+ if (id) {
+ info->appid = id;
+ return AUL_SVC_RET_OK;
+ }
- __get_list_with_submode(info.op, info.win_id, &pkg_list, uid);
+ query = __make_query(query, ri->op, ri->uri_r_info, ri->mime,
+ ri->m_type, ri->s_type);
+ query = _svc_db_query_builder_build(query);
+ _svc_db_exec_query(query, &info->list, info->uid);
+ FREE_AND_NULL(query);
- pkg_count = g_slist_length(pkg_list);
- _D("pkg_count : %d", pkg_count);
+ if (!info->list)
+ return AUL_SVC_RET_OK;
- if (pkg_count == 1) {
- pkgname = (char *)pkg_list->data;
- if (pkgname != NULL) {
- __put_cache(checksum, pkgname, uid);
- ret = __run_svc_with_pkgname(pkgname, b, request_code,
- cbfunc, err_cb, data, uid, sync);
- goto end;
- }
- } else if (pkg_count > 1) {
- bundle_add(b, AUL_SVC_K_URI_R_INFO, info.uri_r_info);
- __put_cache_with_info(checksum, info.uri_r_info, uid);
- ret = __run_svc_with_pkgname(APP_SELECTOR, b, request_code,
- cbfunc, err_cb, data, uid, sync);
- goto end;
- }
+ __free_pkg_list(info->list);
+ info->list = NULL;
- __free_pkg_list(pkg_list);
- pkg_list = NULL;
- }
+ query = __make_query(query, ri->op, "*", ri->mime, ri->m_type,
+ ri->s_type);
+ if ((ri->scheme && !strcmp(ri->scheme, "file")) &&
+ (ri->mime && !strcmp(ri->mime, "NULL"))) {
+ query = __make_query(query, ri->op, "NULL", ri->mime,
+ ri->m_type, ri->s_type);
}
+ query = _svc_db_query_builder_build(query);
+ _svc_db_exec_query(query, &info->list, info->uid);
+ FREE_AND_NULL(query);
- /*scheme*/
- pkgname = _svc_db_get_app(info.op, info.origin_mime, info.scheme, uid);
+ if (ri->category)
+ __get_list_with_category(ri->category, &info->list, info->uid);
+ __get_list_with_submode(ri->op, ri->win_id, &info->list, info->uid);
- if (pkgname != NULL) {
- __put_cache(checksum, pkgname, uid);
- ret = __run_svc_with_pkgname(pkgname, b, request_code,
- cbfunc, err_cb, data, uid, sync);
- free(pkgname);
- goto end;
- }
+ if (info->list)
+ info->uri_r_info = ri->uri_r_info;
- query = __make_query(query, info.op, info.scheme,
- info.mime, info.m_type, info.s_type);
+ return AUL_SVC_RET_OK;
+}
- query = __make_query(query, info.op, "*",
- info.mime, info.m_type, info.s_type);
+static int __resolution_scheme(resolution_info_t *info)
+{
+ aul_svc_resolve_info_t *ri = &info->ri;
+ char *id;
+ char *query = NULL;
- if (info.scheme && (strcmp(info.scheme, "file") == 0)
- && info.mime && (strcmp(info.mime, "NULL") != 0)) {
- query = __make_query(query, info.op, "NULL",
- info.mime, info.m_type, info.s_type);
+ if (info->appid || info->list)
+ return AUL_SVC_RET_OK;
+
+ id = _svc_db_get_app(ri->op, ri->origin_mime, ri->scheme, info->uid);
+ if (id) {
+ info->appid = id;
+ return AUL_SVC_RET_OK;
}
+ query = __make_query(query, ri->op, ri->scheme, ri->mime,
+ ri->m_type, ri->s_type);
+ query = __make_query(query, ri->op, "*", ri->mime,
+ ri->m_type, ri->s_type);
+ if ((ri->scheme && !strcmp(ri->scheme, "file")) &&
+ (ri->mime && !strcmp(ri->mime, "NULL"))) {
+ query = __make_query(query, ri->op, "NULL", ri->mime,
+ ri->m_type, ri->s_type);
+ }
query = _svc_db_query_builder_build(query);
- _svc_db_exec_query(query, &pkg_list, uid);
+ _svc_db_exec_query(query, &info->list, info->uid);
+ FREE_AND_NULL(query);
- if (query) {
- free(query);
- query = NULL;
- }
+ if (ri->category)
+ __get_list_with_category(ri->category, &info->list, info->uid);
+ __get_list_with_submode(ri->op, ri->win_id, &info->list, info->uid);
- if (info.category)
- __get_list_with_category(info.category, &pkg_list, uid);
+ if (info->list)
+ info->uri_r_info = ri->scheme;
- __get_list_with_submode(info.op, info.win_id, &pkg_list, uid);
+ return AUL_SVC_RET_OK;
+}
- pkg_count = g_slist_length(pkg_list);
- _D("pkg_count : %d", pkg_count);
-
- if (pkg_count == 1) {
- pkgname = (char *)pkg_list->data;
- if (pkgname != NULL) {
- __put_cache(checksum, pkgname, uid);
- ret = __run_svc_with_pkgname(pkgname, b, request_code,
- cbfunc, err_cb, data, uid, sync);
+static int __resolution_post(resolution_info_t *info)
+{
+ int ret = AUL_SVC_RET_OK;
+ int count;
+
+ if (info->appid) {
+ __put_cache(info->checksum, info->appid, info->uid);
+ goto end;
+ }
+
+ count = g_slist_length(info->list);
+ _D("count: %d", count);
+ if (count == 1) {
+ info->appid = strdup((const char *)info->list->data);
+ if (info->appid == NULL) {
+ _E("Out of memory");
+ ret = AUL_SVC_RET_ERROR;
+ goto end;
}
- } else if (pkg_count < 1) {
- __free_resolve_info_data(&info);
- __put_cache(checksum, "^", uid);
- g_free(checksum);
- return AUL_SVC_RET_ENOMATCH;
+ __put_cache(info->checksum, info->appid, info->uid);
+ } else if (count < 1) {
+ __put_cache(info->checksum, "^", info->uid);
+ ret = AUL_SVC_RET_ENOMATCH;
} else {
- bundle_add(b, AUL_SVC_K_URI_R_INFO, info.scheme);
- __put_cache_with_info(checksum, info.scheme, uid);
- ret = __run_svc_with_pkgname(APP_SELECTOR, b, request_code,
- cbfunc, err_cb, data, uid, sync);
+ bundle_add(info->b, AUL_SVC_K_URI_R_INFO, info->uri_r_info);
+ __put_cache_with_info(info->checksum, info->uri_r_info,
+ info->uid);
+ info->appid = strdup(APP_SELECTOR);
+ if (info->appid == NULL) {
+ _E("Out of memory");
+ ret = AUL_SVC_RET_ERROR;
+ }
}
end:
- __free_pkg_list(pkg_list);
- __free_resolve_info_data(&info);
- g_free(checksum);
+ __free_pkg_list(info->list);
+ __free_resolve_info_data(&info->ri);
+ g_free(info->checksum);
+ return ret;
+}
+
+static int __get_appid(bundle *b, uid_t uid, char **appid)
+{
+ static const resolution_handler handlers[] = {
+ __resolution_pre,
+ __resolution_uri,
+ __resolution_scheme_and_host,
+ __resolution_scheme,
+ __resolution_post,
+ };
+ resolution_info_t info = { 0, };
+ char *id;
+ char *op;
+ int ret;
+ int i;
+
+ if (b == NULL || appid == NULL) {
+ _E("Invalid parameter");
+ return AUL_SVC_RET_EINVAL;
+ }
+
+ op = (char *)aul_svc_get_operation(b);
+ id = (char *)aul_svc_get_pkgname(b);
+ if (id) {
+ if (!op)
+ aul_svc_set_operation(b, AUL_SVC_OPERATION_DEFAULT);
+ *appid = strdup(id);
+ if (*appid == NULL) {
+ _E("Out of memory");
+ return AUL_SVC_RET_ERROR;
+ }
+ return AUL_SVC_RET_OK;
+ }
+
+ if (TIZEN_FEATURE_SHARE_PANEL &&
+ (op && (!strcmp(op, AUL_SVC_OPERATION_SHARE) ||
+ !strcmp(op, AUL_SVC_OPERATION_MULTI_SHARE) ||
+ !strcmp(op, AUL_SVC_OPERATION_SHARE_TEXT)))) {
+ *appid = strdup(SHARE_PANEL);
+ if (*appid == NULL) {
+ _E("Out of memory");
+ return AUL_SVC_RET_ERROR;
+ }
+ return AUL_SVC_RET_OK;
+ }
+
+ info.b = b;
+ info.uid = uid;
+
+ for (i = 0; i < ARRAY_SIZE(handlers); i++) {
+ if (handlers[i]) {
+ ret = handlers[i](&info);
+ if (ret != AUL_SVC_RET_OK)
+ return ret;
+ }
+ }
+
+ *appid = info.appid;
+
+
+ return AUL_SVC_RET_OK;
+}
+
+static int __run_service(bundle *b, int request_code,
+ aul_svc_res_fn cbfunc, aul_svc_err_cb err_cb,
+ void *data, uid_t uid, bool sync)
+{
+ char *appid = NULL;
+ int ret;
+
+ ret = __get_appid(b, uid, &appid);
+ if (ret != AUL_SVC_RET_OK) {
+ _E("Faile dto get appid");
+ return ret;
+ }
+
+ ret = __run_svc_with_pkgname(appid, b, request_code,
+ cbfunc, err_cb, data, uid, sync);
+ free(appid);
return ret;
}
return __run_service(b, request_code, cbfunc, err_cb, user_data,
uid, false);
}
+
+API int aul_svc_send_launch_request_sync_for_uid(bundle *b, int request_code,
+ bundle **res_b, aul_svc_result_val *res, uid_t uid)
+{
+ const char *pkgname = NULL;
+ const char *val;
+ char *appid = NULL;
+ int ret;
+
+ ret = __get_appid(b, uid, &appid);
+ if (ret != AUL_SVC_RET_OK) {
+ _E("Failed to find appid");
+ return ret;
+ }
+
+ pkgname = appid;
+ if (bundle_get_type(b, AUL_SVC_K_SELECTOR_EXTRA_LIST) != BUNDLE_TYPE_NONE) {
+ if (!aul_svc_get_pkgname(b))
+ pkgname = APP_SELECTOR;
+ }
+
+ if (bundle_get_val(b, AUL_K_FORCE_LAUNCH_APP_SELECTOR))
+ pkgname = APP_SELECTOR;
+
+ if (__is_special_app(pkgname) || __is_special_operation(b)) {
+ bundle_del(b, AUL_SVC_K_CAN_BE_LEADER);
+ bundle_add_str(b, AUL_SVC_K_CAN_BE_LEADER, "true");
+ bundle_del(b, AUL_SVC_K_REROUTE);
+ bundle_add_str(b, AUL_SVC_K_REROUTE, "true");
+ bundle_del(b, AUL_SVC_K_RECYCLE);
+ bundle_add_str(b, AUL_SVC_K_RECYCLE, "true");
+ }
+
+ ret = aul_send_launch_request_sync_for_uid(pkgname, b, uid, res_b);
+ if (ret > 0) {
+ val = bundle_get_val(*res_b, AUL_SVC_K_RES_VAL);
+ *res = (val == NULL) ? AUL_SVC_RES_NOT_OK : atoi(val);
+ } else {
+ *res = AUL_SVC_RES_CANCEL;
+ }
+ free(appid);
+
+ return ret;
+}