From: Hwankyu Jhun Date: Tue, 2 Jun 2020 04:45:13 +0000 (+0900) Subject: Refactor app context X-Git-Tag: submit/tizen/20200615.072923~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=759b71a71602495862da43b15e7b168454408466;p=platform%2Fcore%2Fapi%2Fapp-manager.git Refactor app context Change-Id: I2225b586fdc7122b08326a3144a4bf563eaab087 Signed-off-by: Hwankyu Jhun --- diff --git a/src/app_context.c b/src/app_context.c index 82f859c..e2fd286 100644 --- a/src/app_context.c +++ b/src/app_context.c @@ -1,80 +1,64 @@ /* - * Copyright (c) 2011 - 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2011 - 2020 Samsung Electronics Co., Ltd All Rights Reserved * - * Licensed under the Apache License, Version 2.0 (the License); + * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, + * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ - +#include +#include #include #include #include #include -#include - -#include #include +#include +#include #include -#include -#include #include "app_context.h" #include "app_manager.h" #include "app_manager_internal.h" +#include "log_private.h" -#ifdef LOG_TAG -#undef LOG_TAG -#endif - -#define LOG_TAG "CAPI_APPFW_APP_MANAGER" - -#define APPID_MAX 128 +#define HANDLE_TO_AUL_HANDLE(h) ((aul_app_context_h)(app_context_h)(h)) +#define AUL_HANDLE_TO_HANDLE(h) ((app_context_h)(aul_app_context_h)(h)) -static int app_context_create(const char *app_id, pid_t pid, const char *pkg_id, app_state_e app_state, bool is_sub_app, const char *instance_id, app_context_h *app_context); - -struct app_context_s { - char *app_id; - pid_t pid; - char *pkg_id; - app_state_e app_state; - bool is_sub_app; - char *instance_id; -}; - -typedef struct _foreach_context_ { - app_manager_app_context_cb callback; - void *user_data; - bool iteration; -} foreach_context_s; - -typedef struct _retrieval_context_ { - const char *app_id; - pid_t pid; - char *pkg_id; - app_state_e app_state; - bool is_sub_app; - bool matched; - const char *instance_id; -} retrieval_context_s; - -struct status_listen_info { - status_listen_h handle; +typedef struct app_event_info_s { + aul_app_event_h handle; char *appid; app_manager_app_context_status_cb callback; void *user_data; -}; +} app_event_info_t; -static GList *status_listen_list; +static GList *__event_info_list; + +static int __aul_error_convert(int res) +{ + switch (res) { + case AUL_R_EINVAL: + return APP_MANAGER_ERROR_INVALID_PARAMETER; + case AUL_R_ENOAPP: + case AUL_R_ENOENT: + return APP_MANAGER_ERROR_NO_SUCH_APP; + case AUL_R_ENOMEM: + return APP_MANAGER_ERROR_OUT_OF_MEMORY; + case AUL_R_EILLACC: + return APP_MANAGER_ERROR_PERMISSION_DENIED; + default: + return APP_MANAGER_ERROR_IO_ERROR; + } +} static app_state_e app_context_get_app_status(int status) { @@ -102,242 +86,79 @@ static app_state_e app_context_get_app_status(int status) return app_state; } -static int app_context_foreach_app_context_cb(const aul_app_info *aul_app_context, void *cb_data) +int app_context_foreach_app_context(app_manager_app_context_cb callback, + void *user_data) { - foreach_context_s *foreach_context = cb_data; - app_context_h app_context; - app_state_e app_state; - bool is_sub_app = false; + int ret; - if (foreach_context == NULL) { - app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); /* LCOV_EXCL_LINE */ - return 0; + if (!callback) { + _E("Invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; } - if (foreach_context->iteration == true) { - app_state = app_context_get_app_status(aul_app_context->status); - - if (aul_app_context->is_sub_app) - is_sub_app = true; - - if (app_context_create(aul_app_context->appid, - aul_app_context->pid, - aul_app_context->pkgid, - app_state, - is_sub_app, - aul_app_context->instance_id, - &app_context) == APP_MANAGER_ERROR_NONE) { - foreach_context->iteration = foreach_context->callback(app_context, foreach_context->user_data); - app_context_destroy(app_context); - } + ret = aul_app_manager_foreach_app_context( + (aul_app_manager_app_context_cb)callback, + user_data); + if (ret != AUL_R_OK) { + _E("Failed to retrieve app context. error(%d)", ret); + return APP_MANAGER_ERROR_IO_ERROR; } - return 0; -} - -int app_context_foreach_app_context(app_manager_app_context_cb callback, void *user_data) -{ - foreach_context_s foreach_context = { - .callback = callback, - .user_data = user_data, - .iteration = true - }; - - if (callback == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - - if (aul_app_get_running_app_info(app_context_foreach_app_context_cb, &foreach_context) != AUL_R_OK) - return app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); /* LCOV_EXCL_LINE */ - return APP_MANAGER_ERROR_NONE; } -static int app_context_foreach_running_app_context_cb(const aul_app_info *aul_app_context, void *cb_data) +int app_context_foreach_running_app_context(app_manager_app_context_cb callback, + void *user_data) { - foreach_context_s *foreach_context = cb_data; - app_context_h app_context; - app_state_e app_state; - bool is_sub_app = false; + int ret; - if (foreach_context == NULL) { - app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); /* LCOV_EXCL_LINE */ - return 0; + if (!callback) { + _E("Invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; } - if (foreach_context->iteration == true) { - app_state = app_context_get_app_status(aul_app_context->status); - - if (aul_app_context->is_sub_app) - is_sub_app = true; - - if (app_context_create(aul_app_context->appid, - aul_app_context->pid, - aul_app_context->pkgid, - app_state, - is_sub_app, - aul_app_context->instance_id, - &app_context) == APP_MANAGER_ERROR_NONE) { - foreach_context->iteration = foreach_context->callback(app_context, foreach_context->user_data); - app_context_destroy(app_context); - } + ret = aul_app_manager_foreach_all_app_context( + (aul_app_manager_app_context_cb)callback, + user_data); + if (ret != AUL_R_OK) { + _E("Failed to retrieve all app context. error(%d)", ret); + return APP_MANAGER_ERROR_IO_ERROR; } - return 0; -} - -int app_context_foreach_running_app_context(app_manager_app_context_cb callback, void *user_data) -{ - int ret; - foreach_context_s foreach_context = { - .callback = callback, - .user_data = user_data, - .iteration = true - }; - - if (callback == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - - ret = aul_app_get_all_running_app_info(app_context_foreach_running_app_context_cb, &foreach_context); - if (ret != AUL_R_OK) - return app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); /* LCOV_EXCL_LINE */ - return APP_MANAGER_ERROR_NONE; } -static int app_context_retrieve_app_context(const aul_app_info *aul_app_context, void *cb_data) -{ - retrieval_context_s *retrieval_context = cb_data; - app_state_e app_state; - - if (aul_app_context != NULL && retrieval_context != NULL && retrieval_context->matched == false) { - if (retrieval_context->instance_id && retrieval_context->app_id && - !strcmp(aul_app_context->instance_id, retrieval_context->instance_id) && - !strcmp(aul_app_context->appid, retrieval_context->app_id)) { - app_state = app_context_get_app_status(aul_app_context->status); - - retrieval_context->pid = aul_app_context->pid; - retrieval_context->pkg_id = strdup(aul_app_context->pkgid); - retrieval_context->app_state = app_state; - if (aul_app_context->is_sub_app) - retrieval_context->is_sub_app = true; - retrieval_context->matched = true; - } else if (retrieval_context->instance_id == NULL && retrieval_context->app_id && - !strcmp(aul_app_context->appid, retrieval_context->app_id)) { - app_state = app_context_get_app_status(aul_app_context->status); - - retrieval_context->pid = aul_app_context->pid; - retrieval_context->pkg_id = strdup(aul_app_context->pkgid); - retrieval_context->app_state = app_state; - if (aul_app_context->is_sub_app) - retrieval_context->is_sub_app = true; - retrieval_context->matched = true; - } else if (retrieval_context->pid > 0 && retrieval_context->pid == aul_app_context->pid) { - app_state = app_context_get_app_status(aul_app_context->status); - - retrieval_context->app_id = strdup(aul_app_context->appid); - retrieval_context->pkg_id = strdup(aul_app_context->pkgid); - retrieval_context->app_state = app_state; - if (aul_app_context->is_sub_app) - retrieval_context->is_sub_app = true; - retrieval_context->matched = true; - } - } - - return 0; -} - int app_context_get_app_context(const char *app_id, app_context_h *app_context) { + aul_app_context_h handle; int ret; - retrieval_context_s retrieval_context = { - .app_id = app_id, - .pid = 0, - .pkg_id = NULL, - .app_state = APP_STATE_UNDEFINED, - .is_sub_app = false, - .matched = false, - .instance_id = NULL - }; - - if (app_id == NULL || app_context == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - - if (aul_app_is_running(app_id) == 0) - return app_manager_error(APP_MANAGER_ERROR_NO_SUCH_APP, __FUNCTION__, NULL); - - aul_app_get_running_app_info(app_context_retrieve_app_context, &retrieval_context); - - if (retrieval_context.matched == false) - return app_manager_error(APP_MANAGER_ERROR_NO_SUCH_APP, __FUNCTION__, NULL); - - ret = app_context_create(retrieval_context.app_id, - retrieval_context.pid, - retrieval_context.pkg_id, - retrieval_context.app_state, - retrieval_context.is_sub_app, - retrieval_context.instance_id, - app_context); - free(retrieval_context.pkg_id); - - return ret; -} - -static int app_context_create(const char *app_id, pid_t pid, const char *pkg_id, app_state_e app_state, bool is_sub_app, const char *instance_id, app_context_h *app_context) -{ - app_context_h app_context_created; - if (app_id == NULL || pid <= 0 || pkg_id == NULL || app_context == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); /* LCOV_EXCL_LINE */ - - app_context_created = calloc(1, sizeof(struct app_context_s)); - if (app_context_created == NULL) - return app_manager_error(APP_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); /* LCOV_EXCL_LINE */ - - app_context_created->app_id = strdup(app_id); - if (app_context_created->app_id == NULL) { - free(app_context_created); - return app_manager_error(APP_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); /* LCOV_EXCL_LINE */ - } - - app_context_created->pkg_id = strdup(pkg_id); - if (app_context_created->pkg_id == NULL) { - /* LCOV_EXCL_START */ - free(app_context_created->app_id); - free(app_context_created); - return app_manager_error(APP_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); - /* LCOV_EXCL_STOP */ + if (!app_id || !app_context) { + _E("Invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; } - if (instance_id) { - app_context_created->instance_id = strdup(instance_id); - if (app_context_created->instance_id == NULL) { - /* LCOV_EXCL_START */ - free(app_context_created->pkg_id); - free(app_context_created->app_id); - free(app_context_created); - return app_manager_error(APP_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); - /* LCOV_EXCL_STOP */ - } + ret = aul_app_context_create(app_id, &handle); + if (ret != AUL_R_OK) { + _E("Failed to create app context. error(%d)", ret); + return __aul_error_convert(ret); } - app_context_created->pid = pid; - app_context_created->app_state = app_state; - app_context_created->is_sub_app = is_sub_app; - - *app_context = app_context_created; + *app_context = AUL_HANDLE_TO_HANDLE(handle); - return APP_MANAGER_ERROR_NONE; + return ret; } API int app_context_destroy(app_context_h app_context) { - if (app_context == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context); - free(app_context->app_id); - free(app_context->pkg_id); - free(app_context->instance_id); - free(app_context); + if (!handle) { + _E("Invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; + } + + aul_app_context_destroy(handle); return APP_MANAGER_ERROR_NONE; } @@ -349,117 +170,151 @@ API int app_context_get_package(app_context_h app_context, char **package) return app_context_get_app_id(app_context, package); } - API int app_context_get_app_id(app_context_h app_context, char **app_id) { - char *app_id_dup; - - if (app_context == NULL || app_id == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context); + int ret; - app_id_dup = strdup(app_context->app_id); - if (app_id_dup == NULL) - return app_manager_error(APP_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); /* LCOV_EXCL_LINE */ + if (!app_context || !app_id) { + _E("Invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; + } - *app_id = app_id_dup; + ret = aul_app_context_get_app_id(handle, app_id); + if (ret != AUL_R_OK) + return __aul_error_convert(ret); return APP_MANAGER_ERROR_NONE; } API int app_context_get_pid(app_context_h app_context, pid_t *pid) { - if (app_context == NULL || pid == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context); + int ret; - *pid = app_context->pid; + if (!app_context || !pid) { + _E("Invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; + } + + ret = aul_app_context_get_pid(handle, pid); + if (ret != AUL_R_OK) + return __aul_error_convert(ret); return APP_MANAGER_ERROR_NONE; } API int app_context_get_package_id(app_context_h app_context, char **pkg_id) { - char *pkg_id_dup; - - if (app_context == NULL || pkg_id == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context); + int ret; - pkg_id_dup = strdup(app_context->pkg_id); - if (pkg_id_dup == NULL) - return app_manager_error(APP_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); /* LCOV_EXCL_LINE */ + if (!app_context || !pkg_id) { + _E("Invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; + } - *pkg_id = pkg_id_dup; + ret = aul_app_context_get_pkg_id(handle, pkg_id); + if (ret != AUL_R_OK) + return __aul_error_convert(ret); return APP_MANAGER_ERROR_NONE; } API int app_context_get_app_state(app_context_h app_context, app_state_e *state) { - if (app_context == NULL || state == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context); + int status; + int ret; - *state = app_context->app_state; + if (!app_context || !state) { + _E("Invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; + } + + ret = aul_app_context_get_status(handle, &status); + if (ret != AUL_R_OK) + return __aul_error_convert(ret); + + *state = app_context_get_app_status(status); return APP_MANAGER_ERROR_NONE; } API int app_context_is_terminated(app_context_h app_context, bool *terminated) { - char appid[APPID_MAX] = {0, }; + aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context); + bool is_running; + int ret; - if (app_context == NULL || terminated == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + if (!app_context || !terminated) { + _E("Invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; + } + + ret = aul_app_context_is_running(handle, &is_running); + if (ret != AUL_R_OK) + return __aul_error_convert(ret); - if (aul_app_is_running(app_context->app_id) == 1) { + if (is_running) *terminated = false; - } else { - if (aul_app_get_appid_bypid(app_context->pid, appid, sizeof(appid)) == AUL_R_OK) - *terminated = false; - else - *terminated = true; - } + else + *terminated = true; return APP_MANAGER_ERROR_NONE; } API int app_context_is_equal(app_context_h lhs, app_context_h rhs, bool *equal) { - if (lhs == NULL || rhs == NULL || equal == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + aul_app_context_h lh = HANDLE_TO_AUL_HANDLE(lhs); + aul_app_context_h rh = HANDLE_TO_AUL_HANDLE(rhs); + int ret; - if (!strcmp(lhs->app_id, rhs->app_id) && lhs->pid == rhs->pid) - *equal = true; - else - *equal = false; + if (!lhs || !rhs || !equal) { + _E("Invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; + } + + ret = aul_app_context_is_equal(lh, rh, equal); + if (ret != AUL_R_OK) + return __aul_error_convert(ret); return APP_MANAGER_ERROR_NONE; } API int app_context_is_sub_app(app_context_h app_context, bool *is_sub_app) { - if (app_context == NULL || is_sub_app == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context); + int ret; - *is_sub_app = app_context->is_sub_app; + if (!app_context || !is_sub_app) { + _E("Invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; + } + + ret = aul_app_context_is_sub_app(handle, is_sub_app); + if (ret != AUL_R_OK) + return __aul_error_convert(ret); return APP_MANAGER_ERROR_NONE; } API int app_context_clone(app_context_h *clone, app_context_h app_context) { - int retval; + aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context); + aul_app_context_h new_handle; + int ret; - if (clone == NULL || app_context == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + if (!clone || !app_context) { + _E("Invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; + } - retval = app_context_create(app_context->app_id, - app_context->pid, - app_context->pkg_id, - app_context->app_state, - app_context->is_sub_app, - app_context->instance_id, - clone); - if (retval != APP_MANAGER_ERROR_NONE) - return app_manager_error(retval, __FUNCTION__, NULL); /* LCOV_EXCL_LINE */ + ret = aul_app_context_clone(handle, &new_handle); + if (ret != AUL_R_OK) + return __aul_error_convert(ret); + + *clone = AUL_HANDLE_TO_HANDLE(new_handle); return APP_MANAGER_ERROR_NONE; } @@ -483,105 +338,84 @@ static void app_context_unlock_event_cb_context() pthread_mutex_unlock(&event_cb_context_mutex); } -static bool app_context_load_all_app_context_cb_locked(app_context_h app_context, void *user_data) +static bool __load_all_app_context_cb_locked(app_context_h app_context, + void *user_data) { app_context_h app_context_cloned; + char *app_id = NULL; + int pid; + int ret; - if (app_context_clone(&app_context_cloned, app_context) == APP_MANAGER_ERROR_NONE) { - SECURE_LOGI("[%s] app_id(%s), pid(%d)", __FUNCTION__, app_context->app_id, app_context->pid); - - if (event_cb_context != NULL && event_cb_context->pid_table != NULL) { - g_hash_table_insert(event_cb_context->pid_table, GINT_TO_POINTER(&(app_context_cloned->pid)), app_context_cloned); - } else { - /* LCOV_EXCL_START */ - app_context_destroy(app_context_cloned); - app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, "invalid callback context"); - /* LCOV_EXCL_STOP */ - } + ret = app_context_clone(&app_context_cloned, app_context); + if (ret != APP_MANAGER_ERROR_NONE) { + _E("Failed to clone app context"); + return false; } - return true; -} + app_context_get_app_id(app_context, &app_id); + app_context_get_pid(app_context, &pid); + SECURE_LOGI("app_id(%s), pid(%d)", app_id, pid); + free(app_id); -static void app_context_pid_table_entry_destroyed_cb(void *data) -{ - app_context_h app_context = data; - - if (app_context != NULL) - app_context_destroy(app_context); + g_hash_table_insert(event_cb_context->pid_table, GINT_TO_POINTER(pid), + app_context_cloned); + return true; } -static int app_context_get_pkgid_by_appid(const char *app_id, char **pkg_id) +static int app_context_launched_event_cb(pid_t pid, const char *app_id, + void *data) { - pkgmgrinfo_appinfo_h appinfo; - char *pkg_id_dup; - - if (app_id == NULL || pkg_id == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - - if (pkgmgrinfo_appinfo_get_usr_appinfo(app_id, getuid(), &appinfo) < 0) - return app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, "fail to get appinfo"); /* LCOV_EXCL_LINE */ + app_context_h app_context; + int ret; - if (pkgmgrinfo_appinfo_get_pkgid(appinfo, &pkg_id_dup) < 0) { - /* LCOV_EXCL_START */ - pkgmgrinfo_appinfo_destroy_appinfo(appinfo); - return app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, "fail to get pkgid"); - /* LCOV_EXCL_STOP */ + if (pid < 0 || app_id == NULL) { + _E("Invalid parameter"); + return -1; } - *pkg_id = strdup(pkg_id_dup); - - pkgmgrinfo_appinfo_destroy_appinfo(appinfo); - return APP_MANAGER_ERROR_NONE; -} - -static int app_context_launched_event_cb(pid_t pid, const char *app_id, void *data) -{ - app_context_h app_context = NULL; - char *pkg_id = NULL; - - if (pid < 0 || app_id == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - - if (app_context_get_pkgid_by_appid(app_id, &pkg_id) < 0) - return app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, "no such pkg_id"); /* LCOV_EXCL_LINE */ + ret = app_context_get_app_context_by_pid(pid, &app_context); + if (ret != APP_MANAGER_ERROR_NONE) { + _E("Failed to create app context. pid(%d), error(%d)", + pid, ret); + return ret; + } app_context_lock_event_cb_context(); - if (app_context_create(app_id, pid, pkg_id, APP_STATE_UNDEFINED, false, NULL, &app_context) == APP_MANAGER_ERROR_NONE) { - if (event_cb_context != NULL && event_cb_context->pid_table != NULL) { - g_hash_table_insert(event_cb_context->pid_table, GINT_TO_POINTER(&(app_context->pid)), app_context); - event_cb_context->callback(app_context, APP_CONTEXT_EVENT_LAUNCHED, event_cb_context->user_data); - } else { - /* LCOV_EXCL_START */ - app_context_destroy(app_context); - app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, "invalid callback context"); - /* LCOV_EXCL_STOP */ - } + if (event_cb_context && event_cb_context->pid_table) { + g_hash_table_insert(event_cb_context->pid_table, + GINT_TO_POINTER(pid), app_context); + event_cb_context->callback(app_context, + APP_CONTEXT_EVENT_LAUNCHED, + event_cb_context->user_data); + } else { + _E("Invalid context"); + app_context_destroy(app_context); } app_context_unlock_event_cb_context(); - free(pkg_id); return 0; } static int app_context_terminated_event_cb(pid_t pid, void *data) { app_context_h app_context; - int lookup_key = pid; app_context_lock_event_cb_context(); - if (event_cb_context != NULL && event_cb_context->pid_table != NULL) { - app_context = g_hash_table_lookup(event_cb_context->pid_table, GINT_TO_POINTER(&lookup_key)); - - if (app_context != NULL) { - event_cb_context->callback(app_context, APP_CONTEXT_EVENT_TERMINATED, event_cb_context->user_data); - g_hash_table_remove(event_cb_context->pid_table, GINT_TO_POINTER(&(app_context->pid))); + if (event_cb_context && event_cb_context->pid_table) { + app_context = g_hash_table_lookup(event_cb_context->pid_table, + GINT_TO_POINTER(pid)); + if (app_context) { + event_cb_context->callback(app_context, + APP_CONTEXT_EVENT_TERMINATED, + event_cb_context->user_data); + g_hash_table_remove(event_cb_context->pid_table, + GINT_TO_POINTER(pid)); } } else { - app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, "invalid callback context"); /* LCOV_EXCL_LINE */ + _E("Invalid context"); } app_context_unlock_event_cb_context(); @@ -589,38 +423,64 @@ static int app_context_terminated_event_cb(pid_t pid, void *data) return 0; } -int app_context_set_event_cb(app_manager_app_context_event_cb callback, void *user_data) +static void __event_cb_context_fini(void) { - if (callback == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + if (!event_cb_context) + return; - app_context_lock_event_cb_context(); + aul_listen_app_dead_signal(NULL, NULL); + aul_listen_app_launch_signal_v2(NULL, NULL); + if (event_cb_context->pid_table) + g_hash_table_destroy(event_cb_context->pid_table); + + free(event_cb_context); + event_cb_context = NULL; +} + +static int __event_cb_context_init(void) +{ + if (event_cb_context) + return APP_MANAGER_ERROR_NONE; + + event_cb_context = calloc(1, sizeof(event_cb_context_s)); if (event_cb_context == NULL) { - event_cb_context = calloc(1, sizeof(event_cb_context_s)); + _E("Out of memory"); + return APP_MANAGER_ERROR_OUT_OF_MEMORY; + } - if (event_cb_context == NULL) { - /* LCOV_EXCL_START */ - app_context_unlock_event_cb_context(); - return app_manager_error(APP_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); - /* LCOV_EXCL_STOP */ - } + event_cb_context->pid_table = g_hash_table_new_full(g_direct_hash, + g_direct_equal, NULL, + (GDestroyNotify)app_context_destroy); + if (event_cb_context->pid_table == NULL) { + _E("Failed to create hash table"); + __event_cb_context_fini(); + return APP_MANAGER_ERROR_OUT_OF_MEMORY; + } - event_cb_context->pid_table = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, app_context_pid_table_entry_destroyed_cb); - if (event_cb_context->pid_table == NULL) { - /* LCOV_EXCL_START */ - free(event_cb_context); - event_cb_context = NULL; - app_context_unlock_event_cb_context(); - return app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, "failed to initialize pid-table"); - /* LCOV_EXCL_STOP */ - } + app_context_foreach_app_context(__load_all_app_context_cb_locked, NULL); + aul_listen_app_dead_signal(app_context_terminated_event_cb, NULL); + aul_listen_app_launch_signal_v2(app_context_launched_event_cb, NULL); - app_context_foreach_app_context(app_context_load_all_app_context_cb_locked, NULL); + return APP_MANAGER_ERROR_NONE; +} - aul_listen_app_dead_signal(app_context_terminated_event_cb, NULL); - aul_listen_app_launch_signal_v2(app_context_launched_event_cb, NULL); +int app_context_set_event_cb(app_manager_app_context_event_cb callback, + void *user_data) +{ + int ret; + if (!callback) { + _E("Invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; + } + + app_context_lock_event_cb_context(); + + ret = __event_cb_context_init(); + if (ret != APP_MANAGER_ERROR_NONE) { + app_context_unlock_event_cb_context(); + return ret; } event_cb_context->callback = callback; @@ -634,54 +494,38 @@ int app_context_set_event_cb(app_manager_app_context_event_cb callback, void *us void app_context_unset_event_cb(void) { app_context_lock_event_cb_context(); - - if (event_cb_context != NULL) { - aul_listen_app_dead_signal(NULL, NULL); - aul_listen_app_launch_signal_v2(NULL, NULL); - - g_hash_table_destroy(event_cb_context->pid_table); - free(event_cb_context); - event_cb_context = NULL; - } - + __event_cb_context_fini(); app_context_unlock_event_cb_context(); } -static struct status_listen_info *__find_status_listen_info(app_manager_app_context_status_cb callback, const char *appid) +static void __destroy_app_event_info(gpointer data) { - struct status_listen_info *info; - GList *iter; + app_event_info_t *info = data; - iter = g_list_first(status_listen_list); - while (iter) { - info = (struct status_listen_info *)iter->data; - if (info && info->callback == callback && !strcmp(info->appid, appid)) - return info; - iter = g_list_next(iter); - } + if (!info) + return; - return NULL; + free(info->appid); + free(info); } -static struct status_listen_info *__create_status_listen_info(app_manager_app_context_status_cb callback, const char *appid, void *user_data) +static app_event_info_t *__create_app_event_info(const char *appid, + app_manager_app_context_status_cb callback, + void *user_data) { - struct status_listen_info *info; + app_event_info_t *info; - info = calloc(1, sizeof(struct status_listen_info)); - if (info == NULL) { - /* LCOV_EXCL_START */ - LOGE("Out of memory"); + info = calloc(1, sizeof(app_event_info_t)); + if (!info) { + _E("Out of memory"); return NULL; - /* LCOV_EXCL_STOP */ } info->appid = strdup(appid); - if (info->appid == NULL) { - /* LCOV_EXCL_START */ - LOGE("Out of memory"); - free(info); + if (!info->appid) { + _E("Failed to duplicate application ID(%s)", appid); + __destroy_app_event_info(info); return NULL; - /* LCOV_EXCL_STOP */ } info->callback = callback; @@ -690,171 +534,186 @@ static struct status_listen_info *__create_status_listen_info(app_manager_app_co return info; } -static void __destroy_status_listen_info(struct status_listen_info *info) +static app_event_info_t *__pop_app_event_info(const char *appid, + app_manager_app_context_status_cb callback) { - if (info == NULL) - return; + app_event_info_t *info; + GList *iter; - if (info->appid) - free(info->appid); - free(info); + app_context_lock_event_cb_context(); + iter = __event_info_list; + while (iter) { + info = (app_event_info_t *)iter->data; + iter = g_list_next(iter); + if (info->callback == callback && + !strcmp(info->appid, appid)) { + __event_info_list = g_list_remove( + __event_info_list, info); + app_context_unlock_event_cb_context(); + return info; + } + } + app_context_unlock_event_cb_context(); + + return NULL; } -static int app_context_status_cb(aul_app_info *aul_app_context, int ctx_status, void *data) +static void __push_app_event_info(app_event_info_t *info) { - struct status_listen_info *info = (struct status_listen_info *)data; - app_context_h app_context = NULL; - app_context_status_e context_status; - int ret; + app_context_lock_event_cb_context(); + __event_info_list = g_list_append(__event_info_list, info); + app_context_unlock_event_cb_context(); +} - if (ctx_status == STATUS_TERMINATE) - context_status = APP_CONTEXT_STATUS_TERMINATED; - else - context_status = APP_CONTEXT_STATUS_LAUNCHED; +static bool __exist_app_event_info(app_event_info_t *info) +{ + GList *found; - ret = app_context_create(aul_app_context->appid, - aul_app_context->pid, - aul_app_context->pkgid, - app_context_get_app_status(aul_app_context->status), - aul_app_context->is_sub_app, - aul_app_context->instance_id, - &app_context); - if (ret != APP_MANAGER_ERROR_NONE) - return app_manager_error(ret, __FUNCTION__, NULL); + app_context_lock_event_cb_context(); + found = g_list_find(__event_info_list, info); + app_context_unlock_event_cb_context(); - info->callback(app_context, context_status, info->user_data); - app_context_destroy(app_context); + if (found) + return true; - return APP_MANAGER_ERROR_NONE; + return false; +} + +static void __aul_app_event_launched_cb(aul_app_context_h app_context, + void *user_data) +{ + app_event_info_t *info = user_data; + + if (!__exist_app_event_info(info)) { + _E("Invalid context"); + return; + } + + info->callback(AUL_HANDLE_TO_HANDLE(app_context), + APP_CONTEXT_STATUS_LAUNCHED, + info->user_data); +} + +static void __aul_app_event_terminated_cb(aul_app_context_h app_context, + void *user_data) +{ + app_event_info_t *info = user_data; + + if (!__exist_app_event_info(info)) { + _E("Invalid context"); + return; + } + + info->callback(AUL_HANDLE_TO_HANDLE(app_context), + APP_CONTEXT_STATUS_TERMINATED, + info->user_data); } -int app_context_set_status_cb(app_manager_app_context_status_cb callback, const char *appid, void *user_data) +int app_context_set_status_cb(app_manager_app_context_status_cb callback, + const char *appid, void *user_data) { + app_event_info_t *info; int ret; - struct status_listen_info *info; - if (callback == NULL || appid == NULL) + if (!callback || !appid) { + _E("Invalid parameter"); return APP_MANAGER_ERROR_INVALID_PARAMETER; - - info = __find_status_listen_info(callback, appid); - if (info) { - info->user_data = user_data; - return APP_MANAGER_ERROR_NONE; } - info = __create_status_listen_info(callback, appid, user_data); - if (info == NULL) + info = __create_app_event_info(appid, callback, user_data); + if (!info) return APP_MANAGER_ERROR_OUT_OF_MEMORY; - ret = aul_listen_app_status(appid, app_context_status_cb, info, &info->handle); + ret = aul_app_event_create(appid, + __aul_app_event_launched_cb, + __aul_app_event_terminated_cb, + info, + &info->handle); if (ret != AUL_R_OK) { - /* LCOV_EXCL_START */ - __destroy_status_listen_info(info); - if (ret == AUL_R_EINVAL) - return APP_MANAGER_ERROR_INVALID_PARAMETER; - - return APP_MANAGER_ERROR_IO_ERROR; - /* LCOV_EXCL_STOP */ + __destroy_app_event_info(info); + return __aul_error_convert(ret); } - status_listen_list = g_list_append(status_listen_list, info); + __push_app_event_info(info); return APP_MANAGER_ERROR_NONE; } -int app_context_get_app_context_by_instance_id(const char *app_id, const char *instance_id, app_context_h *app_context) +int app_context_unset_status_cb(app_manager_app_context_status_cb callback, + const char *appid) { - int ret; - retrieval_context_s retrieval_context = { - .app_id = app_id, - .pid = 0, - .pkg_id = NULL, - .app_state = APP_STATE_UNDEFINED, - .is_sub_app = false, - .matched = false, - .instance_id = instance_id - }; - - if (app_id == NULL || instance_id == NULL || app_context == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - - aul_app_get_running_app_instance_info(app_context_retrieve_app_context, &retrieval_context); - if (retrieval_context.matched == false) - return app_manager_error(APP_MANAGER_ERROR_NO_SUCH_APP, __FUNCTION__, NULL); /* LCOV_EXCL_LINE */ - - ret = app_context_create(retrieval_context.app_id, - retrieval_context.pid, - retrieval_context.pkg_id, - retrieval_context.app_state, - retrieval_context.is_sub_app, - retrieval_context.instance_id, - app_context); - free(retrieval_context.pkg_id); + app_event_info_t *info; - return ret; + if (!callback || !appid) { + _E("Invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; + } + + info = __pop_app_event_info(appid, callback); + if (!info) + return APP_MANAGER_ERROR_INVALID_PARAMETER; + + aul_app_event_destroy(info->handle); + __destroy_app_event_info(info); + + return APP_MANAGER_ERROR_NONE; } -int app_context_get_instance_id(app_context_h app_context, char **instance_id) +int app_context_get_app_context_by_instance_id(const char *app_id, + const char *instance_id, + app_context_h *app_context) { - if (app_context == NULL || app_context->instance_id == NULL || instance_id == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + aul_app_context_h handle; + int ret; - *instance_id = strdup(app_context->instance_id); - if (*instance_id == NULL) - return app_manager_error(APP_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); /* LCOV_EXCL_LINE */ + if (!app_id || !instance_id || !app_context) { + _E("Invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; + } + + ret = aul_app_context_create_with_inst_id(app_id, instance_id, &handle); + if (ret != AUL_R_OK) + return __aul_error_convert(ret); + + *app_context = AUL_HANDLE_TO_HANDLE(handle); return APP_MANAGER_ERROR_NONE; } -int app_context_get_app_context_by_pid(pid_t pid, app_context_h *app_context) +int app_context_get_instance_id(app_context_h app_context, char **instance_id) { + aul_app_context_h handle = HANDLE_TO_AUL_HANDLE(app_context); int ret; - retrieval_context_s retrieval_context = { - .app_id = NULL, - .pid = pid, - .pkg_id = NULL, - .app_state = APP_STATE_UNDEFINED, - .is_sub_app = false, - .matched = false, - .instance_id = NULL - }; - - if (pid <= 0 || app_context == NULL) - return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - - aul_app_get_running_app_instance_info(app_context_retrieve_app_context, &retrieval_context); - if (retrieval_context.matched == false) - return app_manager_error(APP_MANAGER_ERROR_NO_SUCH_APP, __FUNCTION__, NULL); - - ret = app_context_create(retrieval_context.app_id, - retrieval_context.pid, - retrieval_context.pkg_id, - retrieval_context.app_state, - retrieval_context.is_sub_app, - retrieval_context.instance_id, - app_context); - free((void *)retrieval_context.app_id); - free(retrieval_context.pkg_id); - return ret; + if (!app_context || !instance_id) { + _E("Invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; + } + + ret = aul_app_context_get_inst_id(handle, instance_id); + if (ret != AUL_R_OK) + return __aul_error_convert(ret); + + return APP_MANAGER_ERROR_NONE; } -int app_context_unset_status_cb(app_manager_app_context_status_cb callback, const char *appid) +int app_context_get_app_context_by_pid(pid_t pid, app_context_h *app_context) { - struct status_listen_info *info; + aul_app_context_h handle; + int ret; - if (callback == NULL || appid == NULL) + if (pid <= 0 || !app_context) { + _E("Invalid parameter"); return APP_MANAGER_ERROR_INVALID_PARAMETER; + } - info = __find_status_listen_info(callback, appid); - if (info == NULL) - return APP_MANAGER_ERROR_INVALID_PARAMETER; + ret = aul_app_context_create_with_pid(pid, &handle); + if (ret != AUL_R_OK) + return __aul_error_convert(ret); - status_listen_list = g_list_remove(status_listen_list, info); - aul_ignore_app_status(info->handle); - __destroy_status_listen_info(info); + *app_context = AUL_HANDLE_TO_HANDLE(handle); - return APP_MANAGER_ERROR_NONE; + return ret; } static void __foreach_window_info_cb(aul_window_info_h info, void *data) @@ -887,38 +746,29 @@ static void __foreach_window_info_cb(aul_window_info_h info, void *data) *list = g_list_append(*list, GINT_TO_POINTER(pid)); } -static int __foreach_app_context_cb(const aul_app_info *aul_app_context, void *data) +static bool __foreach_app_context_cb(aul_app_context_h aul_app_context, + void *user_data) { - GHashTable *app_context_table = (GHashTable *)data; - app_context_h app_context; - app_state_e app_state; + GHashTable *app_context_table = (GHashTable *)user_data; + aul_app_context_h app_context; + int pid; int ret; - if (aul_app_context == NULL || app_context_table == NULL) { - LOGE("Invalid parameter"); - return -1; - } - - app_state = app_context_get_app_status(aul_app_context->status); - ret = app_context_create(aul_app_context->appid, - aul_app_context->pid, - aul_app_context->pkgid, - app_state, - (bool)aul_app_context->is_sub_app, - aul_app_context->instance_id, - &app_context); - if (ret != APP_MANAGER_ERROR_NONE) { - LOGE("Failed to create app context - %s(%d)", - aul_app_context->appid, aul_app_context->pid); - return -1; + ret = aul_app_context_clone(aul_app_context, &app_context); + if (ret != AUL_R_OK) { + _E("Failed to clone app con text. error(%d)", ret); + return true; } - g_hash_table_insert(app_context_table, GINT_TO_POINTER(aul_app_context->pid), app_context); + aul_app_context_get_pid(aul_app_context, &pid); + g_hash_table_insert(app_context_table, GINT_TO_POINTER(pid), + app_context); - return 0; + return true; } -int app_context_foreach_visible_app_context(app_manager_app_context_cb callback, void *user_data) +int app_context_foreach_visible_app_context(app_manager_app_context_cb callback, + void *user_data) { aul_window_stack_h handle = NULL; GHashTable *app_context_table; @@ -933,25 +783,23 @@ int app_context_foreach_visible_app_context(app_manager_app_context_cb callback, app_context_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)app_context_destroy); if (app_context_table == NULL) - return APP_MANAGER_ERROR_OUT_OF_MEMORY; /* LCOV_EXCL_LINE */ + return APP_MANAGER_ERROR_OUT_OF_MEMORY; - ret = aul_app_get_all_running_app_info(__foreach_app_context_cb, app_context_table); + ret = aul_app_manager_foreach_all_app_context(__foreach_app_context_cb, + app_context_table); if (ret != AUL_R_OK) { - /* LCOV_EXCL_START */ g_hash_table_destroy(app_context_table); return APP_MANAGER_ERROR_IO_ERROR; - /* LCOV_EXCL_STOP */ } ret = aul_window_stack_get(&handle); if (ret < 0) { - /* LCOV_EXCL_START */ g_hash_table_destroy(app_context_table); return APP_MANAGER_ERROR_IO_ERROR; - /* LCOV_EXCL_STOP */ } - ret = aul_window_stack_foreach(handle, __foreach_window_info_cb, &pid_list); + ret = aul_window_stack_foreach(handle, + __foreach_window_info_cb, &pid_list); if (ret < 0) { aul_window_stack_del(handle); g_hash_table_destroy(app_context_table); @@ -961,7 +809,8 @@ int app_context_foreach_visible_app_context(app_manager_app_context_cb callback, iter = g_list_first(pid_list); while (iter) { - app_context = (app_context_h)g_hash_table_lookup(app_context_table, iter->data); + app_context = (app_context_h)g_hash_table_lookup( + app_context_table, iter->data); if (app_context) { if (!callback(app_context, user_data)) break; diff --git a/src/log_private.h b/src/log_private.h new file mode 100644 index 0000000..452e935 --- /dev/null +++ b/src/log_private.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LOG_PRIVATE_H__ +#define __LOG_PRIVATE_H__ + +#include + +#undef LOG_TAG +#define LOG_TAG "CAPI_APPFW_APP_MANAGER" + +#undef _E +#define _E LOGE + +#undef _W +#define _W LOGW + +#undef _I +#define _I LOGI + +#undef _D +#define _D LOGD + +#endif /* __LOG_PRIVATE_H__ */