#include "aul_svc_priv_key.h"
#include "launch.h"
+#define MAX_CHECKSUM_BUF 2048
+
/* callback handling */
typedef struct _aul_svc_cb_info_t {
aul_svc_res_fn cb_func;
g_slist_free(list);
}
+static gchar *__make_checksum(const char *op, const char *uri, const char *mime)
+{
+ char buf[MAX_CHECKSUM_BUF];
+ gchar *checksum;
+
+ snprintf(buf, sizeof(buf), "%s:%s:%s", op, uri, mime);
+ checksum = g_compute_checksum_for_string(G_CHECKSUM_MD5, buf, -1);
+
+ return checksum;
+}
+
+static char *__get_cache(const char *checksum, uid_t uid)
+{
+ app_pkt_t *pkt = NULL;
+ int fd;
+ int ret;
+ bundle *b;
+ char buf[MAX_PID_STR_BUFSZ];
+ char *appid;
+
+ b = bundle_create();
+ if (b == NULL) {
+ _E("out of memory");
+ return NULL;
+ }
+
+ snprintf(buf, sizeof(buf), "%d", uid);
+ bundle_add(b, AUL_K_TARGET_UID, buf);
+ bundle_add(b, AUL_K_CHECKSUM, checksum);
+
+ fd = aul_sock_send_bundle(AUL_UTIL_PID, uid, APP_GET_APPID_FROM_CACHE,
+ b, AUL_SOCK_ASYNC);
+ bundle_free(b);
+ if (fd <= 0)
+ return NULL;
+
+ ret = aul_sock_recv_reply_pkt(fd, &pkt);
+ if (ret < 0 || pkt == NULL)
+ return NULL;
+
+ if (pkt->cmd == APP_GET_APPID_FROM_CACHE) {
+ if (!pkt->data)
+ return NULL;
+ if (pkt->data[0] == 0)
+ return NULL;
+ appid = strdup((const char *)(pkt->data));
+ free(pkt);
+ return appid;
+ }
+ free(pkt);
+
+ return NULL;
+}
+
+static void __put_cache(const char *checksum, const char *appid, uid_t uid)
+{
+ int ret;
+ bundle *b;
+ char buf[MAX_PID_STR_BUFSZ];
+
+ b = bundle_create();
+ if (!b) {
+ _E("out of memory");
+ return;
+ }
+
+ snprintf(buf, sizeof(buf), "%d", uid);
+ bundle_add(b, AUL_K_TARGET_UID, buf);
+ bundle_add(b, AUL_K_CHECKSUM, checksum);
+ bundle_add(b, AUL_K_APPID, appid);
+
+ ret = app_send_cmd_for_uid(AUL_UTIL_PID, uid, APP_SET_CACHE, b);
+
+ if (ret < 0)
+ _E("Failed to set cache : %d", ret);
+
+ bundle_free(b);
+}
+
+static void __invalidate_cache(uid_t uid)
+{
+ int ret;
+ bundle *b;
+ char buf[MAX_PID_STR_BUFSZ];
+
+ b = bundle_create();
+ if (!b) {
+ _E("out of memory");
+ return;
+ }
+
+ snprintf(buf, sizeof(buf), "%d", uid);
+ bundle_add(b, AUL_K_TARGET_UID, buf);
+ ret = app_send_cmd_for_uid(AUL_UTIL_PID, uid, APP_INVALIDATE_CACHE, b);
+
+ if (ret < 0)
+ _E("Failed to invalidate cache : %d", ret);
+
+ bundle_free(b);
+}
+
API int aul_svc_set_operation(bundle *b, const char *operation)
{
if (b == NULL) {
char *operation;
int pkg_count = 0;
int ret = -1;
+ char *appid;
GSList *pkg_list = NULL;
char *query = NULL;
char *query2 = NULL;
+ gchar *checksum;
if (b == NULL) {
_E("bundle for aul_svc_set_appid is NULL");
SECURE_LOGD("op - %s / mime - %s / scheme - %s\n",
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);
+
+ if (!strcmp(appid, "^")) {
+ free(appid);
+ g_free(checksum);
+ __free_resolve_info_data(&info);
+ return AUL_SVC_RET_ENOMATCH;
+ }
+
+ ret = __run_svc_with_pkgname(appid, b, request_code,
+ cbfunc, data, uid);
+ free(appid);
+ g_free(checksum);
+ __free_resolve_info_data(&info);
+ return ret;
+ }
+
ret = _svc_db_check_perm(uid, true);
if (ret < 0) {
_E("permission error : %d", ret);
/*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, data, uid);
free(pkgname);
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, data, uid);
goto end;
}
} else if (pkg_count > 1) {
bundle_add(b, AUL_SVC_K_URI_R_INFO, info.uri);
+ __put_cache(checksum, APP_SELECTOR, uid);
ret = __run_svc_with_pkgname(APP_SELECTOR, b, request_code,
cbfunc, data, uid);
goto end;
pkgname = _svc_db_get_app(info.op, info.origin_mime, info.uri_r_info, uid);
if (pkgname != NULL) {
+ __put_cache(checksum, pkgname, uid);
ret = __run_svc_with_pkgname(pkgname, b, request_code,
cbfunc, data, uid);
free(pkgname);
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, data, uid);
goto end;
}
} else if (pkg_count > 1) {
bundle_add(b, AUL_SVC_K_URI_R_INFO, info.uri_r_info);
+ __put_cache(checksum, APP_SELECTOR, uid);
ret = __run_svc_with_pkgname(APP_SELECTOR, b, request_code,
cbfunc, data, uid);
goto end;
pkgname = _svc_db_get_app(info.op, info.origin_mime, info.scheme, uid);
if (pkgname != NULL) {
+ __put_cache(checksum, pkgname, uid);
ret = __run_svc_with_pkgname(pkgname, b, request_code,
cbfunc, data, uid);
free(pkgname);
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, data, uid);
}
} else if (pkg_count < 1) {
__free_resolve_info_data(&info);
+ __put_cache(checksum, "^", uid);
+ g_free(checksum);
return AUL_SVC_RET_ENOMATCH;
} else {
bundle_add(b, AUL_SVC_K_URI_R_INFO, info.scheme);
+ __put_cache(checksum, APP_SELECTOR, uid);
ret = __run_svc_with_pkgname(APP_SELECTOR, b, request_code,
cbfunc, data, uid);
}
end:
__free_pkg_list(pkg_list);
__free_resolve_info_data(&info);
+ g_free(checksum);
return ret;
}
if (ret < 0)
return AUL_SVC_RET_ERROR;
+ __invalidate_cache(uid);
return AUL_SVC_RET_OK;
}