From f66b61f571cec98ff4d8a72afabbaf267516ab54 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 23 Sep 2016 07:59:31 +0900 Subject: [PATCH] Add a new API to monitor the specified app status changes Some applications want to monitor the status changes of the specified applicatioin. The callback function will be invoked when the application is launched or terminated. - Requires https://review.tizen.org/gerrit/#/c/89150/ https://review.tizen.org/gerrit/#/c/89152/ Change-Id: I0b9c4fb16c94c3795867f0966ddec6f2a7e789ef Signed-off-by: Hwankyu Jhun --- include/app_manager_extension.h | 62 ++++++++++++++++++++++++++++++++--------- src/app_context.c | 57 +++++++++++++++++++++++++++++++++++-- src/app_manager.c | 12 ++++++++ src/app_manager_internal.h | 4 +++ 4 files changed, 120 insertions(+), 15 deletions(-) diff --git a/include/app_manager_extension.h b/include/app_manager_extension.h index b68c933..f66c814 100644 --- a/include/app_manager_extension.h +++ b/include/app_manager_extension.h @@ -35,38 +35,74 @@ extern "C" { */ /** + * @brief Enumeration for Application Context Status Event. + * @since_tizen 3.0 + */ +typedef enum { + APP_CONTEXT_STATUS_LAUNCHED, /**< The application is launched */ + APP_CONTEXT_STATUS_TERMINATED, /**< The application is terminated */ +} app_context_status_e; + +/** + * @brief Called when an application is launched or terminated. + * @since_tizen 3.0 + * @param[in] app_context The application context of the application launched or terminated + * @param[in] status The application context status + * @param[in] user_data The user data passed from app_manager_set_app_context_status_cb() + * @pre This function is called when an application gets launched or terminated, after you register this callback using app_manager_set_app_context_status_cb(). + * @see app_manager_set_app_context_status_cb() + */ +typedef void (*app_manager_app_context_status_cb)(app_context_h app_context, app_context_status_e status, void *user_data); + +/** * @brief Terminates the application. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @privlevel platform * @privilege %http://tizen.org/privilege/appmanager.kill * @param[in] app_context The application context - * @return @c 0 on success, + * @return @c 0 on success, * otherwise a negative error value - * @retval #APP_MANAGER_ERROR_NONE Successful - * @retval #APP_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #APP_MANAGER_ERROR_REQUEST_FAILED Internal terminate error - * @retval #APP_MANAGER_ERROR_PERMISSION_DENIED Permission denied + * @retval #APP_MANAGER_ERROR_NONE Successful + * @retval #APP_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_MANAGER_ERROR_REQUEST_FAILED Internal terminate error + * @retval #APP_MANAGER_ERROR_PERMISSION_DENIED Permission denied */ int app_manager_terminate_app(app_context_h app_context); /** * @brief Sets the display flag to enable/disable the splash screen. * @since_tizen 3.0 - * @privilege platform + * @privlevel platform * @privilege %http://tizen.org/privilege/packagemanager.admin * @param[in] app_id The ID of the application * @param[in] display The display flag to enable/disable the splash screen * - * @return @c 0 on success, - * otherwise a negative error value - * @retval #APP_MANAGER_ERROR_NONE Successful - * @retval #APP_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #APP_MANAGER_ERROR_OUT_OF_MEMORY Out of memory - * @retval #APP_MANAGER_ERROR_PERMISSION_DENIED Permission denied - * @retval #APP_MANAGER_ERROR_IO_ERROR Internal I/O error + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_MANAGER_ERROR_NONE Successful + * @retval #APP_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_MANAGER_ERROR_OUT_OF_MEMORY Out of memory + * @retval #APP_MANAGER_ERROR_PERMISSION_DENIED Permission denied + * @retval #APP_MANAGER_ERROR_IO_ERROR Internal I/O error */ int app_manager_set_splash_screen_display(const char *app_id, bool display); +/* + * @brief Registers a callback function to be invoked when the application change status. + * @since_tizen 3.0 + * @param[in] callback The callback function to register + * @param[in] appid The appid to get status + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_MANAGER_ERROR_NONE Successful + * @retval #APP_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_MANAGER_ERROR_IO_ERROR Internal I/O error + * @post It will invoke app_manager_app_context_event_cb() when the application is launched or terminated. + * @see app_manager_app_context_status_cb() + */ +int app_manager_set_app_context_status_cb(app_manager_app_context_status_cb callback, const char *appid, void *user_data); + /** * @} */ diff --git a/src/app_context.c b/src/app_context.c index 4f1c131..2eed5fe 100644 --- a/src/app_context.c +++ b/src/app_context.c @@ -39,7 +39,7 @@ #define APPID_MAX 128 -static int app_context_create(const char *app_id, pid_t pid, char *pkg_id, app_state_e app_state, bool is_sub_app, app_context_h *app_context); +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, app_context_h *app_context); struct app_context_s { char *app_id; @@ -64,6 +64,8 @@ typedef struct _retrieval_context_ { bool matched; } retrieval_context_s; +static app_manager_app_context_status_cb _status_cb; + static app_state_e app_context_get_app_status(int status) { app_state_e app_state; @@ -79,6 +81,9 @@ static app_state_e app_context_get_app_status(int status) case STATUS_SERVICE: app_state = APP_STATE_SERVICE; break; + case STATUS_TERMINATE: + app_state = APP_STATE_TERMINATED; + break; default: app_state = APP_STATE_UNDEFINED; break; @@ -239,7 +244,7 @@ int app_context_get_app_context(const char *app_id, app_context_h *app_context) app_context); } -static int app_context_create(const char *app_id, pid_t pid, char *pkg_id, app_state_e app_state, bool is_sub_app, app_context_h *app_context) +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, app_context_h *app_context) { app_context_h app_context_created; @@ -578,3 +583,51 @@ void app_context_unset_event_cb(void) app_context_unlock_event_cb_context(); } +static int app_context_status_cb(const char *appid, const char *pkgid, int pid, int status, int is_subapp, void *data) +{ + app_context_h app_context = NULL; + app_state_e state; + app_context_status_e context_status; + int ret; + + state = app_context_get_app_status(status); + if (state == APP_STATE_TERMINATED) + context_status = APP_CONTEXT_STATUS_TERMINATED; + else + context_status = APP_CONTEXT_STATUS_LAUNCHED; + + ret = app_context_create(appid, pid, pkgid, state, is_subapp, &app_context); + if (ret != APP_MANAGER_ERROR_NONE) + return app_manager_error(ret, __FUNCTION__, NULL); + + _status_cb(app_context, context_status, data); + app_context_destroy(app_context); + + return APP_MANAGER_ERROR_NONE; +} + +int app_context_set_status_cb(app_manager_app_context_status_cb callback, const char *appid, void *user_data) +{ + int ret; + + if (callback == NULL || appid == NULL) + return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + _status_cb = callback; + + ret = aul_listen_app_status(appid, app_context_status_cb, user_data); + switch (ret) { + case AUL_R_OK: + ret = APP_MANAGER_ERROR_NONE; + break; + case AUL_R_EINVAL: + ret = APP_MANAGER_ERROR_INVALID_PARAMETER; + break; + default: + ret = APP_MANAGER_ERROR_IO_ERROR; + break; + } + + return ret; +} + diff --git a/src/app_manager.c b/src/app_manager.c index 6f516b2..55ebad3 100644 --- a/src/app_manager.c +++ b/src/app_manager.c @@ -537,3 +537,15 @@ API int app_manager_event_destroy(app_manager_event_h handle) free(handle); return APP_MANAGER_ERROR_NONE; } + +API int app_manager_set_app_context_status_cb(app_manager_app_context_status_cb callback, const char *appid, void *user_data) +{ + int ret; + + ret = app_context_set_status_cb(callback, appid, user_data); + if (ret != APP_MANAGER_ERROR_NONE) + return app_manager_error(ret, __FUNCTION__, NULL); + + return APP_MANAGER_ERROR_NONE; +} + diff --git a/src/app_manager_internal.h b/src/app_manager_internal.h index 00c0c29..5dc4fe6 100644 --- a/src/app_manager_internal.h +++ b/src/app_manager_internal.h @@ -18,6 +18,8 @@ #define __TIZEN_APPFW_APP_MANAGER_INTERNAL_H #include "app_manager.h" +#include "app_context.h" +#include "app_manager_extension.h" #ifndef API #define API __attribute__ ((visibility("default"))) @@ -46,6 +48,8 @@ int app_context_get_app_context(const char *app_id, app_context_h *app_context); int app_context_set_event_cb(app_manager_app_context_event_cb callback, void *user_data); +int app_context_set_status_cb(app_manager_app_context_status_cb callback, const char *appid, void *user_data); + void app_context_unset_event_cb(void); int app_info_foreach_app_info(app_manager_app_info_cb callback, void *user_data); -- 2.7.4