Add a new API to monitor the specified app status changes 31/89231/3 accepted/tizen/common/20160926.154026 accepted/tizen/ivi/20160926.001035 accepted/tizen/mobile/20160926.000945 accepted/tizen/tv/20160926.001003 accepted/tizen/wearable/20160926.001021 submit/tizen/20160925.092015
authorHwankyu Jhun <h.jhun@samsung.com>
Thu, 22 Sep 2016 22:59:31 +0000 (07:59 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Fri, 23 Sep 2016 04:24:27 +0000 (13:24 +0900)
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 <h.jhun@samsung.com>
include/app_manager_extension.h
src/app_context.c
src/app_manager.c
src/app_manager_internal.h

index b68c933..f66c814 100644 (file)
@@ -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);
+
 /**
  * @}
  */
index 4f1c131..2eed5fe 100644 (file)
@@ -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;
+}
+
index 6f516b2..55ebad3 100644 (file)
@@ -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;
+}
+
index 00c0c29..5dc4fe6 100644 (file)
@@ -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);