Add global event listen api 69/38569/2 submit/tizen/20150511.111622
authorSangyoon Jang <s89.jang@samsung.com>
Wed, 22 Apr 2015 07:29:51 +0000 (16:29 +0900)
committerSangyoon Jang <s89.jang@samsung.com>
Wed, 22 Apr 2015 07:51:55 +0000 (16:51 +0900)
TC-2500

added:
package_manager_set_global_event_cb
package_manager_unset_global_event_cb

these api is allowed to non-regular users(such as system daemon).
existing api(package_manager_set_event_cb) can listen local event only.

Change-Id: I7f09bcf4fb6305498ac51e09ed5b392cada3d824
Signed-off-by: Sangyoon Jang <s89.jang@samsung.com>
include/package_manager.h
packaging/capi-appfw-package-manager.spec
src/package_manager.c
tool/CMakeLists.txt
tool/main.c

index 36c13c9..ab64d1a 100644 (file)
@@ -414,6 +414,33 @@ typedef void (*package_manager_event_cb) (
             void *user_data);
 
 /**
+ * @brief Called when the package is installed, uninstalled or updated, and the progress of the request to the package manager changes.
+ * @since_tizen 3.0
+ *
+ * @param[in] target_uid  The uid of the package event occured
+ * @param[in] type        The type of the package to be installed, uninstalled or updated
+ * @param[in] package     The name of the package to be installed, uninstalled or updated
+ * @param[in] event_type  The type of the request to the package manager
+ * @param[in] event_state The current state of the request to the package manager
+ * @param[in] progress    The progress for the request that is being processed by the package manager \n
+ *                        The range of progress is from @c 0 to @c 100.
+ * @param[in] error       The error code when the package manager failed to process the request
+ * @param[in] user_data   The user data passed from package_manager_set_event_cb()
+ *
+ * @see package_manager_set_global_event_cb()
+ * @see package_manager_unset_global_event_cb()
+ */
+typedef void (*package_manager_global_event_cb) (
+            uid_t target_uid,
+            const char *type,
+            const char *package,
+            package_manager_event_type_e event_type,
+            package_manager_event_state_e event_state,
+            int progress,
+            package_manager_error_e error,
+            void *user_data);
+
+/**
  * @brief Creates a package manager handle.
  * @since_tizen 2.3
  * @privlevel public
@@ -513,6 +540,48 @@ int package_manager_set_event_cb(package_manager_h manager,
 int package_manager_unset_event_cb(package_manager_h manager);
 
 /**
+ * @brief Registers a callback function to be invoked when the package is installed, uninstalled or updated.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/packagemanager.info
+ * @param[in] manager    The package manager handle
+ * @param[in] callback   The callback function to be registered
+ * @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 #PACKAGE_MANAGER_ERROR_NONE              Successful
+ * @retval #PACKAGE_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PACKAGE_MANAGER_ERROR_PERMISSION_DENIED Permission denied
+ * @post package_manager_global_event_cb() will be invoked.
+ *
+ * @see package_manager_set_event_status()
+ * @see package_manager_global_event_cb()
+ * @see package_manager_unset_global_event_cb()
+ */
+int package_manager_set_global_event_cb(package_manager_h manager,
+                 package_manager_global_event_cb callback,
+                 void *user_data);
+
+/**
+ * @brief Unregisters the callback function.
+ * @since_tizen 3.0
+ *
+ * @param[in] manager The package manager handle
+ *
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ *
+ * @retval #PACKAGE_MANAGER_ERROR_NONE              Successful
+ * @retval #PACKAGE_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see package_manager_global_event_cb()
+ * @see package_manager_set_global_event_cb()
+ */
+int package_manager_unset_global_event_cb(package_manager_h manager);
+
+/**
  * @brief Called to retrieve all packages.
  * @since_tizen 2.3
  *
index 011c782..b453dfc 100644 (file)
@@ -15,6 +15,7 @@ BuildRequires:        pkgconfig(vconf)
 BuildRequires: pkgconfig(aul)
 BuildRequires:  pkgconfig(capi-base-common)
 BuildRequires:  pkgconfig(libtzplatform-config)
+BuildRequires:  pkgconfig(glib-2.0)
 
 %description
 The Package Manager API provides functions to install, uninstall the package,
index face919..7eae074 100644 (file)
@@ -43,6 +43,7 @@ struct package_manager_s {
        pkgmgr_mode mode;
        event_info *head;
        package_manager_event_cb event_cb;
+       package_manager_global_event_cb global_event_cb;
        void *user_data;
 };
 
@@ -331,7 +332,7 @@ static int __remove_event_info(event_info **head request, int req_id)
 }
 */
 
-static int request_event_handler(int req_id, const char *pkg_type,
+static int request_event_handler(uid_t target_uid, int req_id, const char *pkg_type,
                                 const char *pkg_name, const char *key,
                                 const char *val, const void *pmsg, void *data)
 {
@@ -672,7 +673,32 @@ static int __update_event(event_info ** head, int req_id,
        return -1;
 }
 
-static int global_event_handler(int req_id, const char *pkg_type,
+/* App Event Listening Policy:
+ * +----------------+------------+---------------+------------------+
+ * |Listener \ Type |Global Event|My User's Event|Other user's Event|
+ * +----------------+------------+---------------+------------------+
+ * |User Process App|   Grant    |     Grant     |      Deny        |
+ * +----------------+------------+---------------+------------------+
+ * |Platform module |   Grant    |     Grant     |      Grant       |
+ * +----------------+------------+---------------+------------------+
+ * UID assignment policy:
+ * https://wiki.tizen.org/wiki/Security/User_and_group_ID_assignment_policy
+ */
+#define REGULAR_USER 5000
+static int __validate_event_signal(uid_t target_uid)
+{
+       uid_t self = getuid();
+
+       if (self == target_uid)
+               return 0;
+
+       if (self < REGULAR_USER)
+               return 0;
+
+       return -1;
+}
+
+static int global_event_handler(uid_t target_uid, int req_id, const char *pkg_type,
                                const char *pkg_name, const char *key,
                                const char *val, const void *pmsg, void *data)
 {
@@ -684,6 +710,9 @@ static int global_event_handler(int req_id, const char *pkg_type,
 
        package_manager_h manager = data;
 
+       if (__validate_event_signal(target_uid))
+               return PACKAGE_MANAGER_ERROR_NONE;
+
        if (strcasecmp(key, "start") == 0) {
                ret = package_manager_get_event_type(val, &event_type);
                if (ret != PACKAGE_MANAGER_ERROR_NONE)
@@ -692,11 +721,16 @@ static int global_event_handler(int req_id, const char *pkg_type,
                __add_event(&(manager->head), req_id, event_type,
                                 PACKAGE_MANAGER_EVENT_STATE_STARTED);
 
-               if (manager->event_cb)
+               if (manager->event_cb && getuid() == target_uid)
                        manager->event_cb(pkg_type, pkg_name,
                                          event_type,
                                          PACKAGE_MANAGER_EVENT_STATE_STARTED,
                                          0, PACKAGE_MANAGER_ERROR_NONE, manager->user_data);
+               if (manager->global_event_cb)
+                       manager->global_event_cb(target_uid, pkg_type, pkg_name,
+                                         event_type,
+                                         PACKAGE_MANAGER_EVENT_STATE_STARTED,
+                                         0, PACKAGE_MANAGER_ERROR_NONE, manager->user_data);
 
        } else if (strcasecmp(key, "install_percent") == 0
                   || strcasecmp(key, "progress_percent") == 0) {
@@ -706,13 +740,20 @@ static int global_event_handler(int req_id, const char *pkg_type,
                        __update_event(&(manager->head), req_id,
                                            event_type,
                                            PACKAGE_MANAGER_EVENT_STATE_PROCESSING);
-                       if (manager->event_cb)
+                       if (manager->event_cb && getuid() == target_uid)
                                manager->event_cb(pkg_type, pkg_name,
                                                  event_type,
                                                  PACKAGE_MANAGER_EVENT_STATE_PROCESSING,
                                                  atoi(val),
                                                  PACKAGE_MANAGER_ERROR_NONE,
                                                  manager->user_data);
+                       if (manager->global_event_cb)
+                               manager->global_event_cb(target_uid, pkg_type, pkg_name,
+                                                 event_type,
+                                                 PACKAGE_MANAGER_EVENT_STATE_PROCESSING,
+                                                 atoi(val),
+                                                 PACKAGE_MANAGER_ERROR_NONE,
+                                                 manager->user_data);
                }
 
        } else if (strcasecmp(key, "error") == 0) {
@@ -725,37 +766,58 @@ static int global_event_handler(int req_id, const char *pkg_type,
                                                    PACKAGE_MANAGER_EVENT_STATE_FAILED);
                        }
 
-                       if (manager->event_cb)
+                       if (manager->event_cb && getuid() == target_uid)
                                manager->event_cb(pkg_type,
                                                  pkg_name, event_type,
                                                  PACKAGE_MANAGER_EVENT_STATE_FAILED,
                                                  0,
                                                  PACKAGE_MANAGER_ERROR_NONE,
                                                  manager->user_data);
-
+                       if (manager->global_event_cb)
+                               manager->global_event_cb(target_uid, pkg_type,
+                                                 pkg_name, event_type,
+                                                 PACKAGE_MANAGER_EVENT_STATE_FAILED,
+                                                 0,
+                                                 PACKAGE_MANAGER_ERROR_NONE,
+                                                 manager->user_data);
                }
        } else if (strcasecmp(key, "end") == 0) {
                if (__find_event
                    (&(manager->head), req_id, &event_type,
                     &event_state) == 0) {
                        if (event_state != PACKAGE_MANAGER_EVENT_STATE_FAILED) {
-                               if (manager->event_cb)
+                               if (manager->event_cb && getuid() == target_uid)
                                        manager->event_cb(pkg_type,
                                                          pkg_name, event_type,
                                                          PACKAGE_MANAGER_EVENT_STATE_COMPLETED,
                                                          100,
                                                          PACKAGE_MANAGER_ERROR_NONE,
                                                          manager->user_data);
+                               if (manager->global_event_cb)
+                                       manager->global_event_cb(target_uid, pkg_type,
+                                                         pkg_name, event_type,
+                                                         PACKAGE_MANAGER_EVENT_STATE_COMPLETED,
+                                                         100,
+                                                         PACKAGE_MANAGER_ERROR_NONE,
+                                                         manager->user_data);
                        }
                } else {
-                       if (strcasecmp(key, "ok") != 0)
-                               if (manager->event_cb)
+                       if (strcasecmp(key, "ok") != 0) {
+                               if (manager->event_cb && getuid() == target_uid)
                                        manager->event_cb(pkg_type,
                                                          pkg_name, event_type,
                                                          PACKAGE_MANAGER_EVENT_STATE_FAILED,
                                                          0,
                                                          PACKAGE_MANAGER_ERROR_NONE,
                                                          manager->user_data);
+                               if (manager->global_event_cb)
+                                       manager->global_event_cb(target_uid, pkg_type,
+                                                         pkg_name, event_type,
+                                                         PACKAGE_MANAGER_EVENT_STATE_FAILED,
+                                                         0,
+                                                         PACKAGE_MANAGER_ERROR_NONE,
+                                                         manager->user_data);
+                       }
                }
        }
 
@@ -804,6 +866,36 @@ API int package_manager_unset_event_cb(package_manager_h manager)
        return PACKAGE_MANAGER_ERROR_NONE;
 }
 
+API int package_manager_set_global_event_cb(package_manager_h manager,
+                                package_manager_global_event_cb callback,
+                                void *user_data)
+{
+       if (package_manager_validate_handle(manager)) {
+               return
+                   package_manager_error
+                   (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
+                    NULL);
+       }
+
+       if (getuid() >= REGULAR_USER) {
+               _LOGE("Regular user is not allowed for this api");
+               return PACKAGE_MANAGER_ERROR_PERMISSION_DENIED;
+       }
+
+       manager->global_event_cb = callback;
+       manager->user_data = user_data;
+
+    pkgmgr_client_listen_status(manager->pc, global_event_handler, manager);
+
+       return PACKAGE_MANAGER_ERROR_NONE;
+}
+
+API int package_manager_unset_global_event_cb(package_manager_h manager)
+{
+       // TODO: Please implement this function.
+       return PACKAGE_MANAGER_ERROR_NONE;
+}
+
 API int package_manager_get_package_id_by_app_id(const char *app_id, char **package_id)
 {
        pkgmgrinfo_appinfo_h pkgmgrinfo_appinfo;
index 02b9dee..86096e3 100644 (file)
@@ -5,7 +5,7 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEST_CFLAGS}")
 INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
 
 INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs_test REQUIRED)
+pkg_check_modules(pkgs_test REQUIRED glib-2.0)
 FOREACH(flag ${pkgs_test_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
index 3bab302..91fc244 100644 (file)
@@ -29,6 +29,8 @@
 #include <sys/types.h>
 #include <fcntl.h>
 
+#include <glib.h>
+
 #include <package_manager.h>
 
 
@@ -114,11 +116,45 @@ static int _get_appinfo(const char *appid)
        return PACKAGE_MANAGER_ERROR_NONE;
 }
 
+static void _global_event_cb(uid_t target_uid, const char *type,
+               const char *package, package_manager_event_type_e event_type,
+               package_manager_event_state_e event_state, int progress,
+               package_manager_error_e error, void *user_data)
+{
+       fprintf(stderr, "uid[%u] type[%s] pkgid[%s] event_type[%d] "
+                       "event_state[%d] progress[%d] error[%d]\n",
+                       target_uid, type, package, event_type, event_state,
+                       progress, error);
+}
+
+static int _listen_event(void)
+{
+       int ret;
+       package_manager_h manager;
+
+       ret = package_manager_create(&manager);
+       if (ret != PACKAGE_MANAGER_ERROR_NONE)
+               return ret;
+
+       ret = package_manager_set_global_event_cb(manager, _global_event_cb,
+                       NULL);
+       if (ret != PACKAGE_MANAGER_ERROR_NONE)
+               return ret;
+
+       return PACKAGE_MANAGER_ERROR_NONE;
+}
+
 int main(int argc, char** argv)
 {
+       GMainLoop *loop;
        int ret = PACKAGE_MANAGER_ERROR_NONE;
 
-       if (2 == argc) {
+       if (1 == argc) {
+               if (_listen_event()) {
+                       fprintf(stderr, "Register event listener failed\n");
+                       return EXIT_FAILURE;
+               }
+       } else if (2 == argc) {
                ret = _get_packageinfo(argv[1]);
        } else if (3 == argc) {
                ret = _get_appinfo(argv[1]);
@@ -131,6 +167,12 @@ int main(int argc, char** argv)
 
        if (ret != PACKAGE_MANAGER_ERROR_NONE) {
                fprintf(stderr, "There are some problems\n");
+               return EXIT_FAILURE;
+       }
+
+       if (1 == argc) {
+               loop = g_main_loop_new(FALSE, NULL);
+               g_main_loop_run(loop);
        }
 
        return EXIT_SUCCESS;