Refactor legacy C code for pkgmgr_event 13/287813/4
authorInkyun Kil <inkyun.kil@samsung.com>
Tue, 7 Feb 2023 01:26:58 +0000 (10:26 +0900)
committerInkyun Kil <inkyun.kil@samsung.com>
Mon, 13 Feb 2023 02:21:15 +0000 (11:21 +0900)
changes:
- C -> C++
- Reduces needless function call
- Improve trivial structure

Change-Id: Ief1e95c6ad3b942908b3093980418d0d20bc5c1a
Signed-off-by: Inkyun Kil <inkyun.kil@samsung.com>
13 files changed:
include/pkgmgr.h [deleted file]
src/CMakeLists.txt
src/notification_service.c
src/pkgmgr.c [deleted file]
src/pkgmgr_app_event_args.cc [new file with mode: 0644]
src/pkgmgr_app_event_args.hh [new file with mode: 0644]
src/pkgmgr_client.cc [new file with mode: 0644]
src/pkgmgr_client.hh [new file with mode: 0644]
src/pkgmgr_event_args.cc [new file with mode: 0644]
src/pkgmgr_event_args.hh [new file with mode: 0644]
src/service_common.c [deleted file]
src/service_common.cc [new file with mode: 0644]
tests/unit_tests/CMakeLists.txt

diff --git a/include/pkgmgr.h b/include/pkgmgr.h
deleted file mode 100755 (executable)
index 2fc3c3f..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2016  Samsung Electronics Co., Ltd
- *
- * 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 PKGMGR_H_
-#define PKGMGR_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum pkgmgr_event_type {
-       PKGMGR_EVENT_DOWNLOAD,
-       PKGMGR_EVENT_INSTALL,
-       PKGMGR_EVENT_UPDATE,
-       PKGMGR_EVENT_UNINSTALL,
-       PKGMGR_EVENT_RECOVER,
-       PKGMGR_EVENT_APP_ENABLE,
-       PKGMGR_EVENT_APP_DISABLE,
-};
-
-enum pkgmgr_status {
-       PKGMGR_STATUS_START,
-       PKGMGR_STATUS_PROCESSING,
-       PKGMGR_STATUS_COMMAND,
-       PKGMGR_STATUS_END,
-       PKGMGR_STATUS_ERROR,
-};
-
-extern int pkgmgr_init(void);
-extern int pkgmgr_fini(void);
-
-extern int pkgmgr_add_event_callback(enum pkgmgr_event_type type, int (*cb)(uid_t uid, const char *pkgname, enum pkgmgr_status status, double value, void *data), void *data);
-extern void *pkgmgr_del_event_callback(enum pkgmgr_event_type type, int (*cb)(uid_t uid, const char *pkgname, enum pkgmgr_status status, double value, void *data), void *data);
-#ifdef __cplusplus
-}
-#endif
-
-#endif //PKGMGR_H_
\ No newline at end of file
index e439599..fbf76de 100644 (file)
@@ -28,13 +28,14 @@ FOREACH(flag ${pkgs_CFLAGS})
 ENDFOREACH(flag)
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wall -Werror -Winline")
 
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=c++14")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=c++17")
 SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
 SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
 
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/.)
 
-AUX_SOURCE_DIRECTORY(../src SOURCES)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCES)
 ADD_EXECUTABLE(${PROJECT_NAME} ${SOURCES})
 
 SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS} -fPIE")
index 88dd344..50bb5b5 100644 (file)
@@ -27,7 +27,6 @@
 #include <alarm.h>
 #include <aul.h>
 
-#include "pkgmgr.h"
 #include "service_common.h"
 #include "notification_service.h"
 #include "debug.h"
@@ -2669,7 +2668,6 @@ HAPI int notification_service_init(int restart_count)
 
 HAPI int notification_service_fini(void)
 {
-       pkgmgr_fini();
        DBG("Successfully Finalized");
        return NOTIFICATION_ERROR_NONE;
 }
diff --git a/src/pkgmgr.c b/src/pkgmgr.c
deleted file mode 100644 (file)
index af1512a..0000000
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- * Copyright 2016  Samsung Electronics Co., Ltd
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-
-#include <dlog.h>
-#include <package-manager.h>
-
-#include "service_common.h"
-#include "debug.h"
-#include "pkgmgr.h"
-#include "conf.h"
-
-#define PKGMGR_EVENT_MIN PKGMGR_EVENT_DOWNLOAD
-#define PKGMGR_EVENT_MAX PKGMGR_EVENT_APP_DISABLE
-
-struct item {
-       uid_t uid;
-       char *pkgname;
-       char *icon;
-
-       enum pkgmgr_event_type type;
-       enum pkgmgr_status status;
-};
-
-struct event_item {
-       int (*cb)(uid_t uid, const char *pkgname, enum pkgmgr_status status, double value, void *data);
-       void *data;
-};
-
-static struct {
-       pkgmgr_client *listen_pc;
-       GList *item_list;
-
-} s_info = {
-       .listen_pc = NULL,
-       .item_list = NULL,
-};
-
-static GList *event_list[PKGMGR_EVENT_MAX + 1];
-
-static inline void invoke_callback(uid_t uid, const char *pkgname, struct item *item, double value)
-{
-       GList *l;
-       struct event_item *e_item;
-
-       for (l = event_list[item->type]; l != NULL; l = g_list_next(l)) {
-               e_item = (struct event_item *)g_list_nth_data(l, 0);
-               if (e_item->cb)
-                       e_item->cb(uid, pkgname, item->status, value, e_item->data);
-       }
-}
-
-static inline int is_valid_status(struct item *item, const char *status)
-{
-       const char *expected_status;
-
-       switch (item->type) {
-       case PKGMGR_EVENT_DOWNLOAD:
-               expected_status = "download";
-               break;
-       case PKGMGR_EVENT_UNINSTALL:
-               expected_status = "uninstall";
-               break;
-       case PKGMGR_EVENT_INSTALL:
-               expected_status = "install";
-               break;
-       case PKGMGR_EVENT_UPDATE:
-               expected_status = "update";
-               break;
-       case PKGMGR_EVENT_RECOVER:
-               expected_status = "recover";
-               break;
-       case PKGMGR_EVENT_APP_ENABLE:
-               expected_status = "app_enable_app";
-               break;
-       case PKGMGR_EVENT_APP_DISABLE:
-               expected_status = "app_disable_app";
-               break;
-       default:
-               return 0;
-       }
-
-       return !strcasecmp(status, expected_status);
-}
-
-static struct item *find_item(const char *pkgname, uid_t uid)
-{
-       GList *l;
-       struct item *item;
-
-       if (!pkgname) {
-               ERR("Invalid pkgname");
-               return NULL;
-       }
-
-       for (l = s_info.item_list; l != NULL; l = g_list_next(l)) {
-               item = g_list_nth_data(l, 0);
-               if (uid != item->uid || strcmp(item->pkgname, pkgname))
-                       continue;
-
-               return item;
-       }
-
-       DBG("Package [%s] is not found", pkgname);
-       return NULL;
-}
-
-static int start_cb(uid_t uid, const char *pkgname, const char *val, void *data)
-{
-       struct item *item;
-
-       INFO("pkgname[%s] val[%s]", pkgname, val);
-
-       item = calloc(1, sizeof(*item));
-       if (!item) {
-               ERR("calloc [%d]", errno);
-               return SERVICE_COMMON_ERROR_OUT_OF_MEMORY;
-       }
-
-       item->pkgname = strdup(pkgname);
-       if (!item->pkgname) {
-               ERR("strdup [%d]", errno);
-               free(item);
-               return SERVICE_COMMON_ERROR_OUT_OF_MEMORY;
-       }
-
-       item->uid = uid;
-       item->status = PKGMGR_STATUS_START;
-
-       if (!strcasecmp(val, "download")) {
-               item->type = PKGMGR_EVENT_DOWNLOAD;
-       } else if (!strcasecmp(val, "uninstall")) {
-               item->type = PKGMGR_EVENT_UNINSTALL;
-       } else if (!strcasecmp(val, "install")) {
-               item->type = PKGMGR_EVENT_INSTALL;
-       } else if (!strcasecmp(val, "update")) {
-               item->type = PKGMGR_EVENT_UPDATE;
-       } else if (!strcasecmp(val, "recover")) {
-               item->type = PKGMGR_EVENT_RECOVER;
-       } else if (!strcasecmp(val, "enable_app")) {
-               item->type = PKGMGR_EVENT_APP_ENABLE;
-       } else if (!strcasecmp(val, "disable_app")) {
-               item->type = PKGMGR_EVENT_APP_DISABLE;
-       } else {
-               free(item->pkgname);
-               free(item);
-               ERR("Invalid val [%s]", val);
-               return SERVICE_COMMON_ERROR_INVALID_PARAMETER;
-       }
-       s_info.item_list = g_list_append(s_info.item_list, item);
-
-       invoke_callback(uid, pkgname, item, 0.0f);
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-static int icon_path_cb(uid_t uid, const char *pkgname, const char *val, void *data)
-{
-       struct item *item;
-
-       DBG("pkgname[%s] val[%s]", pkgname, val);
-
-       item = find_item(pkgname, uid);
-       if (!item)
-               return SERVICE_COMMON_ERROR_NOT_EXIST;
-
-       if (item->icon)
-               free(item->icon);
-
-       item->icon = strdup(val);
-       if (!item->icon) {
-               ERR("strdup [%d]", errno);
-               return SERVICE_COMMON_ERROR_OUT_OF_MEMORY;
-       }
-
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-static int command_cb(uid_t uid, const char *pkgname, const char *val, void *data)
-{
-       struct item *item;
-
-       DBG("pkgname[%s] val[%s]", pkgname, val);
-
-       item = find_item(pkgname, uid);
-       if (!item)
-               return SERVICE_COMMON_ERROR_NOT_EXIST;
-
-       if (!is_valid_status(item, val)) {
-               DBG("Invalid status[%d] val[%s]", item->type, val);
-               return SERVICE_COMMON_ERROR_INVALID_PARAMETER;
-       }
-
-       item->status = PKGMGR_STATUS_COMMAND;
-       invoke_callback(uid, pkgname, item, 0.0f);
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-static int error_cb(uid_t uid, const char *pkgname, const char *val, void *data)
-{
-       /* val = error */
-       struct item *item;
-
-       INFO("pkgname[%s] val[%s]", pkgname, val);
-
-       item = find_item(pkgname, uid);
-       if (!item)
-               return SERVICE_COMMON_ERROR_NOT_EXIST;
-
-       item->status = PKGMGR_STATUS_ERROR;
-       invoke_callback(uid, pkgname, item, 0.0f);
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-static int change_pkgname_cb(uid_t uid, const char *pkgname, const char *val, void *data)
-{
-       struct item *item;
-       char *new_pkgname;
-
-       INFO("pkgname[%s] val[%s]", pkgname, val);
-
-       item = find_item(pkgname, uid);
-       if (!item)
-               return SERVICE_COMMON_ERROR_NOT_EXIST;
-
-       new_pkgname = strdup(val);
-       if (!new_pkgname) {
-               ERR("strdup: %d", errno);
-               return SERVICE_COMMON_ERROR_OUT_OF_MEMORY;
-       }
-
-       free(item->pkgname);
-       item->pkgname = new_pkgname;
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-static int download_cb(uid_t uid, const char *pkgname, const char *val, void *data)
-{
-       /* val = integer */
-       struct item *item;
-       double value;
-
-       INFO("pkgname[%s] val[%s]", pkgname, val);
-
-       item = find_item(pkgname, uid);
-       if (!item) {
-               DBG("ITEM is not started from the start_cb");
-               return SERVICE_COMMON_ERROR_INVALID_PARAMETER;
-       }
-
-       if (item->type != PKGMGR_EVENT_DOWNLOAD) {
-               DBG("TYPE is not \"download\" [%d]", item->type);
-               item->type = PKGMGR_EVENT_DOWNLOAD;
-       }
-
-       switch (item->status) {
-       case PKGMGR_STATUS_START:
-       case PKGMGR_STATUS_COMMAND:
-               item->status = PKGMGR_STATUS_PROCESSING;
-       case PKGMGR_STATUS_PROCESSING:
-               break;
-       default:
-               ERR("Invalid status, pkgname[%s] val[%s]", pkgname, val);
-               return SERVICE_COMMON_ERROR_INVALID_PARAMETER;
-       }
-
-       if (val) {
-               if (sscanf(val, "%lf", &value) != 1)
-                       value = (double)SERVICE_COMMON_ERROR_INVALID_PARAMETER;
-       } else {
-               value = (double)SERVICE_COMMON_ERROR_INVALID_PARAMETER;
-       }
-
-       invoke_callback(uid, pkgname, item, value);
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-static int progress_cb(uid_t uid, const char *pkgname, const char *val, void *data)
-{
-       /* val = integer */
-       struct item *item;
-       double value;
-
-       item = find_item(pkgname, uid);
-       if (!item) {
-               ERR("ITEM is not started from the start_cb");
-               return SERVICE_COMMON_ERROR_INVALID_PARAMETER;
-       }
-
-       switch (item->status) {
-       case PKGMGR_STATUS_START:
-       case PKGMGR_STATUS_COMMAND:
-               item->status = PKGMGR_STATUS_PROCESSING;
-       case PKGMGR_STATUS_PROCESSING:
-               break;
-       default:
-               ERR("Invalid status, pkgname[%s] val[%s]", pkgname, val);
-               return SERVICE_COMMON_ERROR_INVALID_PARAMETER;
-       }
-
-       if (val) {
-               if (sscanf(val, "%lf", &value) != 1)
-                       value = (double)SERVICE_COMMON_ERROR_INVALID_PARAMETER;
-       } else {
-               value = (double)SERVICE_COMMON_ERROR_INVALID_PARAMETER;
-       }
-
-       invoke_callback(uid, pkgname, item, value);
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-static int end_cb(uid_t uid, const char *pkgname, const char *val, void *data)
-{
-       struct item *item;
-
-       DBG("[%s] %s", pkgname, val);
-
-       item = find_item(pkgname, uid);
-       if (!item)
-               return SERVICE_COMMON_ERROR_NOT_EXIST;
-
-       item->status = !strcasecmp(val, "ok") ? PKGMGR_STATUS_END : PKGMGR_STATUS_ERROR;
-
-       invoke_callback(uid, pkgname, item, 0.0f);
-
-       s_info.item_list = g_list_remove(s_info.item_list, item);
-       free(item->icon);
-       free(item->pkgname);
-       free(item);
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-static struct pkgmgr_handler {
-       const char *key;
-       int (*func)(uid_t uid, const char *package, const char *val, void *data);
-} handler[] = {
-       { "install_percent", progress_cb },
-       { "download_percent", download_cb },
-       { "start", start_cb },
-       { "end", end_cb },
-       { "change_pkg_name", change_pkgname_cb },
-       { "icon_path", icon_path_cb },
-       { "command", command_cb },
-       { "error", error_cb },
-       { NULL, NULL },
-};
-
-static int status_cb(uid_t target_uid, int req_id, const char *type,
-               const char *pkgname, const char *key, const char *val,
-               const void *pmsg, void *data)
-{
-       register int i;
-       int ret;
-
-       for (i = 0; handler[i].key; i++) {
-               if (strcasecmp(key, handler[i].key))
-                       continue;
-
-               ret = handler[i].func(target_uid, pkgname, val, data);
-               if (ret < 0) {
-                       DBG("REQ[%d] UID[%d] pkgname[%s] type[%s] key[%s] val[%s] ret[%d]",
-                                       req_id, target_uid, pkgname, type, key, val, ret);
-               }
-       }
-
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-static int app_status_cb(uid_t target_uid, int req_id, const char *pkg_type,
-               const char *pkgid, const char *appid, const char *key, const char *val,
-               const void *pmsg, void *data)
-{
-       register int i;
-       int ret;
-
-       for (i = 0; handler[i].key; i++) {
-               if (strcasecmp(key, handler[i].key))
-                       continue;
-
-               ret = handler[i].func(target_uid, appid, val, data);
-               if (ret < 0) {
-                       DBG("REQ[%d] UID[%d] appid[%s] type[%s] key[%s] val[%s] ret[%d]",
-                                       req_id, target_uid, appid, pkg_type, key, val, ret);
-               }
-       }
-
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-static void __free_event_data(gpointer data)
-{
-       struct event_item *item = (struct event_item *)data;
-
-       if (item)
-               free(item);
-}
-
-static void __free_item_data(gpointer data)
-{
-       struct item *ctx = (struct item *)data;
-
-       if (ctx) {
-               if (ctx->pkgname)
-                       free(ctx->pkgname);
-               if (ctx->icon)
-                       free(ctx->icon);
-               free(ctx);
-       }
-}
-
-HAPI int pkgmgr_init(void)
-{
-       if (s_info.listen_pc)
-               return SERVICE_COMMON_ERROR_ALREADY_EXIST;
-
-       s_info.listen_pc = pkgmgr_client_new(PC_LISTENING);
-       if (!s_info.listen_pc)
-               return SERVICE_COMMON_ERROR_FAULT;
-
-       /* the pkgmgr api returns an id greater than 1 */
-       if (pkgmgr_client_listen_status(s_info.listen_pc, status_cb, NULL) <= 0)
-               return SERVICE_COMMON_ERROR_FAULT;
-
-       if (pkgmgr_client_listen_app_status(s_info.listen_pc, app_status_cb, NULL) <= 0)
-               return SERVICE_COMMON_ERROR_FAULT;
-
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-HAPI int pkgmgr_fini(void)
-{
-       int i;
-
-       if (!s_info.listen_pc)
-               return SERVICE_COMMON_ERROR_INVALID_PARAMETER;
-
-       if (pkgmgr_client_free(s_info.listen_pc) != PKGMGR_R_OK)
-               return SERVICE_COMMON_ERROR_FAULT;
-
-       s_info.listen_pc = NULL;
-
-       for (i = PKGMGR_EVENT_MIN; i <= PKGMGR_EVENT_MAX; i++)
-               g_list_free_full(event_list[i], __free_event_data);
-
-       g_list_free_full(s_info.item_list, __free_item_data);
-
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-HAPI int pkgmgr_add_event_callback(enum pkgmgr_event_type type, int (*cb)(uid_t uid, const char *pkgname, enum pkgmgr_status status, double value, void *data), void *data)
-{
-       struct event_item *item;
-
-       item = calloc(1, sizeof(*item));
-       if (!item) {
-               ERR("calloc [%d]", errno);
-               return SERVICE_COMMON_ERROR_OUT_OF_MEMORY;
-       }
-
-       item->cb = cb;
-       item->data = data;
-
-       event_list[type] = g_list_prepend(event_list[type], item);
-
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-HAPI void *pkgmgr_del_event_callback(enum pkgmgr_event_type type, int (*cb)(uid_t uid, const char *pkgname, enum pkgmgr_status status, double value, void *data), void *data)
-{
-       struct event_item *item;
-       GList *l;
-       void *cbdata = NULL;
-
-       for (l = event_list[type]; l != NULL; l = g_list_next(l)) {
-               item = g_list_nth_data(l, 0);
-               if (item->cb == cb && item->data == data) {
-                       event_list[type] = g_list_remove(event_list[type], item);
-                       cbdata = item->data;
-                       free(item);
-                       break;
-               }
-       }
-
-       return cbdata;
-}
-
-/* End of a file */
diff --git a/src/pkgmgr_app_event_args.cc b/src/pkgmgr_app_event_args.cc
new file mode 100644 (file)
index 0000000..76b6775
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2023 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.
+ */
+
+#include "pkgmgr_app_event_args.hh"
+
+namespace dpm {
+
+PkgmgrAppEventArgs::PkgmgrAppEventArgs(uid_t target_uid,
+    std::string pkg_type, std::string pkgid, std::string appid,
+    std::string event_status, std::string event_name)
+    : target_uid_(target_uid),
+      pkg_type_(std::move(pkg_type)),
+      pkgid_(std::move(pkgid)),
+      appid_(std::move(appid)),
+      event_status_(std::move(event_status)),
+      event_name_(std::move(event_name)) {
+  tag_ = std::to_string(target_uid_) + "-" + pkgid_ + "-" + appid_;
+}
+
+uid_t PkgmgrAppEventArgs::GetTargetUid() const {
+  return target_uid_;
+}
+
+const std::string& PkgmgrAppEventArgs::GetPkgType() const {
+  return pkg_type_;
+}
+
+const std::string& PkgmgrAppEventArgs::GetPkgId() const {
+  return pkgid_;
+}
+
+const std::string& PkgmgrAppEventArgs::GetAppId() const {
+  return appid_;
+}
+
+const std::string& PkgmgrAppEventArgs::GetEventStatus() const {
+  return event_status_;
+}
+
+const std::string& PkgmgrAppEventArgs::GetEventName() const {
+  return event_name_;
+}
+
+const std::string& PkgmgrAppEventArgs::GetTag() const {
+  return tag_;
+}
+
+}  // namespace dpm
diff --git a/src/pkgmgr_app_event_args.hh b/src/pkgmgr_app_event_args.hh
new file mode 100644 (file)
index 0000000..1c3f52f
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2023 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 PKGMGR_EVENT_PKGMGR_APP_EVENT_ARGS_HH_
+#define PKGMGR_EVENT_PKGMGR_APP_EVENT_ARGS_HH_
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <string>
+
+namespace dpm {
+
+class PkgmgrAppEventArgs {
+ public:
+  PkgmgrAppEventArgs(uid_t target_uid, std::string pkg_type,
+      std::string pkgid, std::string appid, std::string event_status,
+      std::string event_name);
+  virtual ~PkgmgrAppEventArgs() = default;
+
+  uid_t GetTargetUid() const;
+  int GetReqId() const;
+  const std::string& GetPkgType() const;
+  const std::string& GetPkgId() const;
+  const std::string& GetAppId() const;
+  const std::string& GetEventStatus() const;
+  const std::string& GetEventName() const;
+  const std::string& GetTag() const;
+
+ private:
+  uid_t target_uid_;
+  std::string pkg_type_;
+  std::string pkgid_;
+  std::string appid_;
+  std::string event_status_;
+  std::string event_name_;
+  std::string tag_;
+};
+
+}  // namespace dpm
+
+#endif  // PKGMGR_EVENT_PKGMGR_APP_EVENT_ARGS_HH_
diff --git a/src/pkgmgr_client.cc b/src/pkgmgr_client.cc
new file mode 100644 (file)
index 0000000..8bbe930
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2023 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.
+ */
+
+#include "pkgmgr_client.hh"
+#include <dlog.h>
+#include <memory>
+
+namespace dpm {
+
+PkgmgrClient::PkgmgrClient() = default;
+
+PkgmgrClient::~PkgmgrClient() {
+  Ignore();
+}
+
+int PkgmgrClient::Listen(IEvent* listener) {
+  WARN("[PKGMGR] BEGIN");
+  listener_ = listener;
+
+  if (handle_ != nullptr)
+    return -1;
+
+  auto* handle = pkgmgr_client_new(PC_LISTENING);
+  if (handle == nullptr) {
+    ERR("pkgmgr_client_new() is failed");
+    return -1;
+  }
+  auto handle_auto =
+      std::unique_ptr<pkgmgr_client, decltype(pkgmgr_client_free)*>(
+          handle, pkgmgr_client_free);
+
+  int ret = pkgmgr_client_set_status_type(handle, PKGMGR_CLIENT_STATUS_ALL);
+  if (ret < 0) {
+    ERR("pkgmgr_client_set_status_type() is failed. error(%d)", ret);
+    return -1;
+  }
+
+  ret = pkgmgr_client_listen_status(handle, PkgmgrHandler, this);
+  if (ret < 0) {
+    ERR("pkgmgr_client_listen_status() is failed. error(%d)", ret);
+    return -1;
+  }
+
+  ret = pkgmgr_client_listen_app_status(handle, PkgmgrAppHandler, this);
+  if (ret < 0) {
+    ERR("pkgmgr_client_listen_app_status() is failed. error(%d)", ret);
+    return -1;
+  }
+
+  handle_ = handle_auto.release();
+  WARN("[PKGMGR] END");
+
+  return 0;
+}
+
+void PkgmgrClient::Ignore() {
+  if (handle_ != nullptr) {
+    pkgmgr_client_free(handle_);
+    handle_ = nullptr;
+  }
+}
+
+int PkgmgrClient::PkgmgrHandler(uid_t target_uid, int req_id,
+    const char* pkg_type, const char* pkgid, const char* key, const char* val,
+    const void* pmsg, void* user_data) {
+  auto* client = static_cast<PkgmgrClient*>(user_data);
+  auto* listener = client->listener_;
+  if (listener != nullptr) {
+    listener->OnPkgmgrEvent(std::make_shared<PkgmgrEventArgs>(
+        target_uid, req_id, pkg_type, pkgid, key, val));
+  }
+
+  return 0;
+}
+
+int PkgmgrClient::PkgmgrAppHandler(uid_t target_uid, int req_id,
+    const char* pkg_type, const char* pkgid, const char* appid,
+    const char* key, const char* val, const void* pmsg, void* user_data) {
+  auto* client = static_cast<PkgmgrClient*>(user_data);
+  auto* listener = client->listener_;
+  if (listener != nullptr) {
+    listener->OnPkgmgrAppEvent(std::make_shared<PkgmgrAppEventArgs>(
+          target_uid, pkg_type, pkgid, appid, key, val));
+  }
+
+  return 0;
+}
+
+}  // namespace dpm
diff --git a/src/pkgmgr_client.hh b/src/pkgmgr_client.hh
new file mode 100644 (file)
index 0000000..d29e05a
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2023 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 PKGMGR_EVENT_PKGMGR_CLIENT_HH_
+#define PKGMGR_EVENT_PKGMGR_CLIENT_HH_
+
+#include <package-manager.h>
+
+#include <memory>
+
+#include "debug.h"
+#include "pkgmgr_app_event_args.hh"
+#include "pkgmgr_event_args.hh"
+
+namespace dpm {
+
+class PkgmgrClient {
+ public:
+  class IEvent {
+   public:
+    virtual void OnPkgmgrEvent(std::shared_ptr<PkgmgrEventArgs> args) = 0;
+    virtual void OnPkgmgrAppEvent(std::shared_ptr<PkgmgrAppEventArgs> args) = 0;
+  };
+
+  PkgmgrClient();
+  virtual ~PkgmgrClient();
+
+  int Listen(IEvent* listener);
+  void Ignore();
+
+ private:
+  static int PkgmgrHandler(uid_t target_uid, int req_id, const char* pkg_type,
+      const char* pkgid, const char* key, const char* val, const void* pmsg,
+      void *user_data);
+  static int PkgmgrAppHandler(uid_t target_uid, int req_id,
+      const char* pkg_type, const char* pkgid, const char* appid,
+      const char* key, const char* val, const void* pmsg, void* user_data);
+
+ private:
+  pkgmgr_client* handle_ = nullptr;
+  IEvent* listener_ = nullptr;
+};
+
+}  // namespace dpm
+
+#endif  // PKGMGR_EVENT_PKGMGR_CLIENT_HH_
diff --git a/src/pkgmgr_event_args.cc b/src/pkgmgr_event_args.cc
new file mode 100644 (file)
index 0000000..9725d1b
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2023 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.
+ */
+
+#include "pkgmgr_event_args.hh"
+
+namespace dpm {
+
+PkgmgrEventArgs::PkgmgrEventArgs(uid_t target_uid, int req_id,
+    std::string pkg_type, std::string pkgid, std::string event_status,
+    std::string event_name)
+    : target_uid_(target_uid),
+      req_id_(req_id),
+      pkg_type_(std::move(pkg_type)),
+      pkgid_(std::move(pkgid)),
+      event_status_(std::move(event_status)),
+      event_name_(std::move(event_name)) {
+  tag_ = std::to_string(target_uid) + "-" + pkgid_;
+}
+
+uid_t PkgmgrEventArgs::GetTargetUid() const {
+  return target_uid_;
+}
+
+int PkgmgrEventArgs::GetReqId() const {
+  return req_id_;
+}
+
+const std::string& PkgmgrEventArgs::GetPkgType() const {
+  return pkg_type_;
+}
+
+const std::string& PkgmgrEventArgs::GetPkgId() const {
+  return pkgid_;
+}
+
+const std::string& PkgmgrEventArgs::GetEventStatus() const {
+  return event_status_;
+}
+
+const std::string& PkgmgrEventArgs::GetEventName() const {
+  return event_name_;
+}
+
+const std::string& PkgmgrEventArgs::GetTag() const {
+  return tag_;
+}
+
+}  // namespace dpm
diff --git a/src/pkgmgr_event_args.hh b/src/pkgmgr_event_args.hh
new file mode 100644 (file)
index 0000000..2920474
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2023 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 PKGMGR_EVENT_PKGMGR_EVENT_ARGS_HH_
+#define PKGMGR_EVENT_PKGMGR_EVENT_ARGS_HH_
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <string>
+
+namespace dpm {
+
+class PkgmgrEventArgs {
+ public:
+  PkgmgrEventArgs(uid_t target_uid, int req_id, std::string pkg_type,
+      std::string pkgid, std::string event_status, std::string event_name);
+  virtual ~PkgmgrEventArgs() = default;
+
+  uid_t GetTargetUid() const;
+  int GetReqId() const;
+  const std::string& GetPkgType() const;
+  const std::string& GetPkgId() const;
+  const std::string& GetEventStatus() const;
+  const std::string& GetEventName() const;
+  const std::string& GetTag() const;
+
+ private:
+  uid_t target_uid_;
+  int req_id_;
+  std::string pkg_type_;
+  std::string pkgid_;
+  std::string event_status_;
+  std::string event_name_;
+  std::string tag_;
+};
+
+}  // namespace dpm
+
+#endif  // PKGMGR_EVENT_PKGMGR_EVENT_ARGS_HH_
diff --git a/src/service_common.c b/src/service_common.c
deleted file mode 100644 (file)
index 7035207..0000000
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- * Copyright 2016  Samsung Electronics Co., Ltd
- *
- * 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.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <gio/gio.h>
-#include <dlog.h>
-#include <notification_setting.h>
-#include <notification_setting_internal.h>
-#include <notification_setting_service.h>
-#include <notification_noti.h>
-#include <badge_setting.h>
-#include <badge_setting_service.h>
-#include <badge_db.h>
-#include <package-manager.h>
-#include <tzplatform_config.h>
-#include <pkgmgr-info.h>
-
-#include "debug.h"
-#include "pkgmgr.h"
-#include "service_common.h"
-#include "notification_service.h"
-#include "badge_service.h"
-#include "shortcut_service.h"
-
-#define DBUS_NAME "org.freedesktop.DBus"
-#define DBUS_OBJECT_PATH "/org/freedesktop/DBus"
-#define DBUS_INTERFACE_NAME "org.freedesktop.DBus"
-
-#define PROVIDER_BUS_NAME "org.tizen.data_provider_service"
-#define PROVIDER_OBJECT_PATH "/org/tizen/data_provider_service"
-
-static GDBusConnection *_gdbus_conn;
-static GHashTable *_noti_pkg_privilege_info;
-static GHashTable *_badge_pkg_privilege_info;
-
-uid_t get_sender_uid(const char *sender_name)
-{
-       GDBusMessage *msg = NULL;
-       GDBusMessage *reply = NULL;
-       GError *err = NULL;
-       GVariant *body;
-       uid_t uid = 0;
-
-       msg = g_dbus_message_new_method_call(DBUS_NAME, DBUS_OBJECT_PATH,
-                       DBUS_INTERFACE_NAME, "GetConnectionUnixUser");
-       if (!msg) {
-               LOGE("Failed to alloc new method call");
-               goto out;
-       }
-
-       g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
-       reply = g_dbus_connection_send_message_with_reply_sync(_gdbus_conn, msg,
-                       G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
-
-       if (!reply) {
-               if (err != NULL) {
-                       LOGE("Failed to get uid [%s]", err->message);
-                       g_error_free(err);
-               }
-               goto out;
-       }
-
-       body = g_dbus_message_get_body(reply);
-       g_variant_get(body, "(u)", &uid);
-
-out:
-       if (msg)
-               g_object_unref(msg);
-       if (reply)
-               g_object_unref(reply);
-
-       return uid;
-}
-
-pid_t get_sender_pid(const char *sender_name)
-{
-       GDBusMessage *msg = NULL;
-       GDBusMessage *reply = NULL;
-       GError *err = NULL;
-       GVariant *body;
-       pid_t pid = 0;
-
-       msg = g_dbus_message_new_method_call(DBUS_NAME, DBUS_OBJECT_PATH,
-                       DBUS_INTERFACE_NAME, "GetConnectionUnixProcessID");
-       if (!msg) {
-               LOGE("Failed to alloc new method call");
-               goto out;
-       }
-
-       g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
-       reply = g_dbus_connection_send_message_with_reply_sync(_gdbus_conn, msg,
-                       G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
-
-       if (!reply) {
-               if (err != NULL) {
-                       LOGE("Failed to get uid [%s]", err->message);
-                       g_error_free(err);
-               }
-               goto out;
-       }
-
-       body = g_dbus_message_get_body(reply);
-       g_variant_get(body, "(u)", &pid);
-
-out:
-       if (msg)
-               g_object_unref(msg);
-       if (reply)
-               g_object_unref(reply);
-
-       return pid;
-}
-
-bool is_existed_busname(const char *sender_name)
-{
-       GDBusMessage *msg = NULL;
-       GDBusMessage *reply = NULL;
-       GError *err = NULL;
-       GVariant *body;
-       bool is_existed = false;
-
-       msg = g_dbus_message_new_method_call(DBUS_NAME, DBUS_OBJECT_PATH,
-                       DBUS_INTERFACE_NAME, "NameHasOwner");
-       if (!msg) {
-               LOGE("Failed to alloc new method call");
-               goto out;
-       }
-
-       g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
-       reply = g_dbus_connection_send_message_with_reply_sync(_gdbus_conn, msg,
-                       G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
-
-       if (!reply) {
-               if (err != NULL) {
-                       LOGE("Failed to get uid [%s]", err->message);
-                       g_error_free(err);
-               }
-               goto out;
-       }
-
-       body = g_dbus_message_get_body(reply);
-       g_variant_get(body, "(b)", &is_existed);
-
-out:
-       if (msg)
-               g_object_unref(msg);
-       if (reply)
-               g_object_unref(reply);
-
-       return is_existed;
-}
-
-int send_notify(GVariant *body, char *cmd, GHashTable **monitoring_hash, char *interface_name, uid_t uid)
-{
-       GError *err = NULL;
-       GList *monitoring_list = NULL;
-       GList *target_list;
-       char *target_bus_name;
-       int monitoring_count = 0;
-       bool is_existed = false;
-
-       monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(uid));
-       target_list = g_list_first(monitoring_list);
-       for (; target_list != NULL; ) {
-               err = NULL;
-               target_bus_name = target_list->data;
-               target_list = target_list->next;
-
-               if (g_variant_is_floating(body))
-                       g_variant_ref(body);
-
-               if (g_dbus_connection_emit_signal(_gdbus_conn,
-                                       target_bus_name,
-                                       PROVIDER_OBJECT_PATH,
-                                       interface_name,
-                                       cmd,
-                                       body,
-                                       &err) == FALSE) {
-                       if (err != NULL) {
-                               ERR("Emit signal err [%s]", err->message);
-                               g_error_free(err);
-                       }
-                       is_existed = is_existed_busname(target_bus_name);
-                       if (is_existed == false)
-                               delete_monitoring_list(monitoring_hash, target_bus_name, uid);
-                       ERR("Fail, emit signal to [%s]", target_bus_name);
-               }
-               monitoring_count++;
-               DBG("Success, emit signal to [%s]", target_bus_name);
-       }
-
-       DBG("Success, cmd[%s] monitoring count[%d]", cmd, monitoring_count);
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-int send_event_notify_by_busname(GVariant *body, char *cmd, char *busname, char *interface_name)
-{
-       GError *err = NULL;
-
-       if (g_variant_is_floating(body))
-               g_variant_ref(body);
-
-       if (g_dbus_connection_emit_signal(_gdbus_conn,
-                                         busname,
-                                         PROVIDER_OBJECT_PATH,
-                                         interface_name,
-                                         cmd,
-                                         body,
-                                         &err) == FALSE) {
-               if (err != NULL) {
-                       ERR("Emit signal err [%s]",
-                                       err->message);
-                       g_error_free(err);
-               }
-               ERR("Failed to emit signal to [%s]", busname);
-               return SERVICE_COMMON_ERROR_IO_ERROR;
-       }
-       DBG("Success, Emit signal to [%s] cmd[%s]", busname, cmd);
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-/* register service */
-
-static int _monitoring_app_list_compare_cb(gconstpointer a, gconstpointer b)
-{
-       return strcmp(a, b);
-}
-
-int service_register(GVariant *parameters, GVariant **reply_body, const gchar *sender,
-               GBusNameAppearedCallback name_appeared_handler,
-               GBusNameVanishedCallback name_vanished_handler,
-               GHashTable **monitoring_hash,
-               uid_t uid)
-{
-       GList *added_list = NULL;
-       const char *bus_name = sender;
-       monitoring_info_s *m_info = NULL;
-       uid_t request_uid = 0;
-       GList *monitoring_list = NULL;
-
-       if (sender == NULL)
-               return SERVICE_COMMON_ERROR_IO_ERROR;
-
-       g_variant_get(parameters, "(i)", &request_uid);
-       if (uid > NORMAL_UID_BASE && uid != request_uid)
-               return SERVICE_COMMON_ERROR_IO_ERROR;
-
-       DBG("service_register : uid %d , request_uid %d", uid, request_uid);
-       monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(request_uid));
-       added_list = g_list_find_custom(monitoring_list, bus_name,
-                       (GCompareFunc)_monitoring_app_list_compare_cb);
-
-       if (added_list == NULL) {
-               DBG("add new sender to list");
-               m_info = (monitoring_info_s *)calloc(1, sizeof(monitoring_info_s));
-               if (m_info == NULL) {
-                       ERR("Failed to alloc memory");
-                       return SERVICE_COMMON_ERROR_OUT_OF_MEMORY;
-               }
-
-               m_info->bus_name = strdup(bus_name);
-               m_info->uid = request_uid;
-               m_info->watcher_id = g_bus_watch_name_on_connection(
-                               _gdbus_conn,
-                               bus_name,
-                               G_BUS_NAME_WATCHER_FLAGS_NONE,
-                               name_appeared_handler,
-                               name_vanished_handler,
-                               m_info,
-                               NULL);
-               if (m_info->watcher_id == 0) {
-                       ERR("Fail to watch name [%s]", bus_name);
-                       free(m_info->bus_name);
-                       free(m_info);
-                       return SERVICE_COMMON_ERROR_IO_ERROR;
-               }
-               DBG("Watch on [%s] success", bus_name);
-
-               monitoring_list = g_list_append(monitoring_list, strdup(bus_name));
-               DBG("Success, sender[%s] length[%d]",
-                               sender, g_list_length(monitoring_list));
-               if (g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(request_uid)) == NULL)
-                       g_hash_table_insert(*monitoring_hash, GUINT_TO_POINTER(request_uid), monitoring_list);
-       } else {
-               ERR("Sender [%s] already exist", sender);
-       }
-
-       *reply_body = g_variant_new("()");
-       if (*reply_body == NULL) {
-               if (m_info) {
-                       if (m_info->bus_name)
-                               free(m_info->bus_name);
-                       free(m_info);
-               }
-               monitoring_list = g_list_remove(monitoring_list, bus_name);
-               ERR("Failed to make reply");
-               return SERVICE_COMMON_ERROR_OUT_OF_MEMORY;
-       }
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-int delete_monitoring_list(GHashTable **monitoring_hash, const char *sender, uid_t uid)
-{
-       GList *monitoring_list = NULL;
-       GList *del_list = NULL;
-       char *bus_name;
-
-       monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(uid));
-       if (monitoring_list == NULL) {
-               ERR("No uid[%d] in monitoring hash", uid);
-               return SERVICE_COMMON_ERROR_IO_ERROR;
-       }
-
-       monitoring_list = g_list_first(monitoring_list);
-       del_list = g_list_find_custom(monitoring_list, sender,
-                       (GCompareFunc)_monitoring_app_list_compare_cb);
-
-       if (del_list) {
-               DBG("Find delete list - uid[%d] sender[%s]", uid, sender);
-               bus_name = g_list_nth_data(del_list, 0);
-               if (bus_name)
-                       free(bus_name);
-               monitoring_list = g_list_delete_link(monitoring_list, del_list);
-
-               if (monitoring_list == NULL) {
-                       g_hash_table_steal(*monitoring_hash, GUINT_TO_POINTER(uid));
-               } else {
-                       monitoring_list = g_list_first(monitoring_list);
-                       g_hash_table_replace(*monitoring_hash, GUINT_TO_POINTER(uid), monitoring_list);
-               }
-       }
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-static int _dbus_init(void)
-{
-       GError *error = NULL;
-
-       if (_gdbus_conn == NULL) {
-               _gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
-               if (_gdbus_conn == NULL) {
-                       if (error != NULL) {
-                               ERR("Failed to get dbus [%s]", error->message);
-                               g_error_free(error);
-                       }
-                       return SERVICE_COMMON_ERROR_IO_ERROR;
-               }
-       }
-
-       return SERVICE_COMMON_ERROR_NONE;
-}
-
-int service_common_register_dbus_interface(char *introspection_xml, GDBusInterfaceVTable interface_vtable)
-{
-       int result;
-       int owner_id, noti_registration_id;
-       GError *error = NULL;
-       GDBusNodeInfo *introspection_data = NULL;
-
-       result = _dbus_init();
-       if (result != SERVICE_COMMON_ERROR_NONE) {
-                       ERR("Can't init dbus [%d]", result);
-                       result = SERVICE_COMMON_ERROR_IO_ERROR;
-                       goto out;
-       }
-
-       owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
-                       PROVIDER_BUS_NAME,
-                       G_BUS_NAME_OWNER_FLAGS_NONE,
-                       NULL,
-                       NULL,
-                       NULL,
-                       NULL, NULL);
-       if (!owner_id) {
-               ERR("Failed to own name");
-               result = SERVICE_COMMON_ERROR_IO_ERROR;
-               goto out;
-       }
-
-       DBG("Acquiring the own name [%d]", owner_id);
-       introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
-       if (!introspection_data) {
-               ERR("g_dbus_node_info_new_for_xml is failed.");
-               result = SERVICE_COMMON_ERROR_IO_ERROR;
-               if (error != NULL) {
-                       ERR("g_dbus_node_info_new_for_xml err [%s]", error->message);
-                       g_error_free(error);
-               }
-               goto out;
-       }
-
-       noti_registration_id = g_dbus_connection_register_object(_gdbus_conn,
-                       PROVIDER_OBJECT_PATH, introspection_data->interfaces[0],
-                       &interface_vtable, NULL, NULL, NULL);
-
-       DBG("registration id[%d]", noti_registration_id);
-       if (noti_registration_id == 0) {
-               ERR("Failed to g_dbus_connection_register_object");
-               result = SERVICE_COMMON_ERROR_IO_ERROR;
-               goto out;
-       }
-
-out:
-       if (introspection_data)
-               g_dbus_node_info_unref(introspection_data);
-
-       return result;
-}
-
-static int _init_pkg_privilege_info() {
-
-       if (_noti_pkg_privilege_info != NULL)
-               return 0;
-
-       _noti_pkg_privilege_info =
-               g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
-       _badge_pkg_privilege_info =
-               g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
-       DBG("init pkg privilege info done");
-       return 0;
-}
-
-static int _package_install_cb(uid_t uid, const char *pkgname, enum pkgmgr_status status, double value, void *data)
-{
-       int ret;
-       gpointer tmp;
-       int privilege_info;
-
-       if (status != PKGMGR_STATUS_END)
-               return 0;
-
-       if (uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER))
-               uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
-
-       _init_pkg_privilege_info();
-       if (g_hash_table_contains(_noti_pkg_privilege_info, pkgname)) {
-               tmp = g_hash_table_lookup(_noti_pkg_privilege_info, pkgname);
-               privilege_info = GPOINTER_TO_UINT(tmp);
-               if (privilege_info == 1)
-                       notification_setting_db_update_pkg_disabled(pkgname, false, uid);
-
-               g_hash_table_remove(_noti_pkg_privilege_info, pkgname);
-       } else {
-               /* In consideration of the reboot status, change the disable information. */
-               ret = notification_setting_db_update_pkg_disabled(pkgname, false, uid);
-               if (ret != NOTIFICATION_ERROR_NONE)
-                       notification_setting_insert_package_for_uid(pkgname, uid);
-       }
-
-       if (g_hash_table_contains(_badge_pkg_privilege_info, pkgname)) {
-               tmp = g_hash_table_lookup(_badge_pkg_privilege_info, pkgname);
-               privilege_info = GPOINTER_TO_UINT(tmp);
-               if (privilege_info == 1)
-                       badge_db_update_pkg_disabled(pkgname, false, uid);
-
-               g_hash_table_remove(_badge_pkg_privilege_info, pkgname);
-       } else {
-               /* In consideration of the reboot status, change the disable information. */
-               ret = badge_db_update_pkg_disabled(pkgname, false, uid);
-               if (ret != BADGE_ERROR_NONE)
-                       badge_setting_insert_package_for_uid(pkgname, uid);
-       }
-
-       return 0;
-}
-
-static int _package_uninstall_cb(uid_t uid, const char *pkgname, enum pkgmgr_status status, double value, void *data)
-{
-       int ret;
-       pkgmgrinfo_pkginfo_h pkginfo;
-
-       if (status != PKGMGR_STATUS_END)
-               return 0;
-
-       if (uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER))
-               uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
-
-       ret = pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(pkgname, uid, &pkginfo);
-       if (ret == PMINFO_R_OK) {
-               pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
-
-               _init_pkg_privilege_info();
-               ret = notification_setting_db_update_pkg_disabled(pkgname, true, uid);
-               if (ret == NOTIFICATION_ERROR_NONE)
-                       g_hash_table_insert(_noti_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(1));
-               else
-                       g_hash_table_insert(_noti_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(0));
-
-               ret = badge_db_update_pkg_disabled(pkgname, true, uid);
-               if (ret == BADGE_ERROR_NONE)
-                       g_hash_table_insert(_badge_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(1));
-               else
-                       g_hash_table_insert(_badge_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(0));
-       } else {
-               notification_setting_delete_package_for_uid(pkgname, uid);
-               badge_db_delete_by_pkgname(pkgname, uid);
-               badge_setting_delete_package_for_uid(pkgname, uid);
-               notification_noti_delete_template(pkgname);
-       }
-
-       return 0;
-}
-
-static int _app_enabled_cb(uid_t uid, const char *app_id, enum pkgmgr_status status, double value, void *data)
-{
-       if (status == PKGMGR_STATUS_END)
-               notification_setting_db_update_app_disabled(app_id, false, uid);
-
-       return 0;
-}
-
-static int _app_disabled_cb(uid_t uid, const char *app_id, enum pkgmgr_status status, double value, void *data)
-{
-       if (status == PKGMGR_STATUS_END) {
-               notification_delete_noti_by_app_id(app_id, uid);
-               notification_setting_db_update_app_disabled(app_id, true, uid);
-       }
-
-       return 0;
-}
-
-void service_common_init(void)
-{
-       pkgmgr_init();
-       pkgmgr_add_event_callback(PKGMGR_EVENT_INSTALL, _package_install_cb, NULL);
-       pkgmgr_add_event_callback(PKGMGR_EVENT_UPDATE, _package_install_cb, NULL);
-       pkgmgr_add_event_callback(PKGMGR_EVENT_UNINSTALL, _package_uninstall_cb, NULL);
-       pkgmgr_add_event_callback(PKGMGR_EVENT_APP_ENABLE, _app_enabled_cb, NULL);
-       pkgmgr_add_event_callback(PKGMGR_EVENT_APP_DISABLE, _app_disabled_cb, NULL);
-}
-
-void service_common_set_connection(GDBusConnection *conn)
-{
-       _gdbus_conn = conn;
-}
\ No newline at end of file
diff --git a/src/service_common.cc b/src/service_common.cc
new file mode 100644 (file)
index 0000000..529ae5b
--- /dev/null
@@ -0,0 +1,620 @@
+/*
+* Copyright 2023 Samsung Electronics Co., Ltd
+*
+* 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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <gio/gio.h>
+#include <dlog.h>
+#include <notification_setting.h>
+#include <notification_setting_internal.h>
+#include <notification_setting_service.h>
+#include <notification_noti.h>
+#include <badge_setting.h>
+#include <badge_setting_service.h>
+#include <badge_db.h>
+#include <package-manager.h>
+#include <tzplatform_config.h>
+#include <pkgmgr-info.h>
+
+#include <list>
+#include <set>
+#include <string>
+#include <string_view>
+#include <memory>
+
+#include "debug.h"
+#include "pkgmgr_client.hh"
+#include "service_common.h"
+#include "notification_service.h"
+#include "badge_service.h"
+#include "shortcut_service.h"
+
+#define DBUS_NAME "org.freedesktop.DBus"
+#define DBUS_OBJECT_PATH "/org/freedesktop/DBus"
+#define DBUS_INTERFACE_NAME "org.freedesktop.DBus"
+
+#define PROVIDER_BUS_NAME "org.tizen.data_provider_service"
+#define PROVIDER_OBJECT_PATH "/org/tizen/data_provider_service"
+
+using namespace dpm;
+
+static GDBusConnection *_gdbus_conn;
+static GHashTable *_noti_pkg_privilege_info;
+static GHashTable *_badge_pkg_privilege_info;
+std::unique_ptr<PkgmgrClient> pkgmgr_client_;
+std::list<std::shared_ptr<PkgmgrEventArgs>> pkgmgr_event_list_;
+std::list<std::shared_ptr<PkgmgrAppEventArgs>> pkgmgr_app_event_list_;
+
+const std::set<std::string_view> pkgmgr_installer_key_list_ = {
+  "install_percent",
+  "start",
+  "end"
+};
+
+const std::set<std::string_view> pkgmgr_installer_val_list_ = {
+  "install",
+  "uninstall",
+  "update",
+  "ebable_app",
+  "disable_app"
+};
+
+static int _package_install_cb(uid_t uid, const char *pkgname);
+static int _package_uninstall_cb(uid_t uid, const char *pkgname);
+static int _app_enabled_cb(uid_t uid, const char *app_id);
+static int _app_disabled_cb(uid_t uid, const char *app_id);
+
+class PackageEventListener : public PkgmgrClient::IEvent {
+public:
+  void OnPkgmgrEvent(std::shared_ptr<PkgmgrEventArgs> args) override;
+  void OnPkgmgrAppEvent(std::shared_ptr<PkgmgrAppEventArgs> args) override;
+};
+
+void PackageEventListener::OnPkgmgrEvent(std::shared_ptr<PkgmgrEventArgs> args) {
+  if (pkgmgr_installer_key_list_.find(args->GetEventStatus()) ==
+      pkgmgr_installer_key_list_.end())
+    return;
+
+  if (args->GetEventStatus().compare(std::string("start")) == 0 &&
+      pkgmgr_installer_val_list_.find(args->GetEventName()) !=
+      pkgmgr_installer_val_list_.end()) {
+    pkgmgr_event_list_.push_back(args);
+    return;
+  }
+
+  if (args->GetEventName().compare(std::string("ok")) == 0) {
+    for (auto& a : pkgmgr_event_list_) {
+      if (a->GetTargetUid() == args->GetTargetUid() &&
+          a->GetPkgId().compare(args->GetPkgId()) == 0) {
+        if (a->GetEventName().compare(std::string("install")) == 0)
+          _package_install_cb(args->GetTargetUid(), args->GetPkgId().c_str());
+        else if (a->GetEventName().compare(std::string("uninstall")) == 0)
+          _package_uninstall_cb(args->GetTargetUid(), args->GetPkgId().c_str());
+        else if (a->GetEventName().compare(std::string("enable_app")) == 0)
+          _app_enabled_cb(args->GetTargetUid(), args->GetPkgId().c_str());
+        else if (a->GetEventName().compare(std::string("disable_app")) == 0)
+          _app_disabled_cb(args->GetTargetUid(), args->GetPkgId().c_str());
+      }
+    }
+  }
+}
+
+void PackageEventListener::OnPkgmgrAppEvent(std::shared_ptr<PkgmgrAppEventArgs> args) {
+  if (pkgmgr_installer_key_list_.find(args->GetEventStatus()) ==
+      pkgmgr_installer_key_list_.end())
+    return;
+
+  if (args->GetEventStatus().compare(std::string("start")) == 0 &&
+      pkgmgr_installer_val_list_.find(args->GetEventName()) !=
+      pkgmgr_installer_val_list_.end()) {
+    pkgmgr_app_event_list_.push_back(args);
+    return;
+  }
+
+  if (args->GetEventName().compare(std::string("ok")) == 0) {
+    for (auto& a : pkgmgr_app_event_list_) {
+      if (a->GetTargetUid() == args->GetTargetUid() &&
+          a->GetPkgId().compare(args->GetPkgId()) == 0) {
+        if (a->GetEventName().compare(std::string("install")) == 0)
+          _package_install_cb(args->GetTargetUid(), args->GetPkgId().c_str());
+        else if (a->GetEventName().compare(std::string("uninstall")) == 0)
+          _package_uninstall_cb(args->GetTargetUid(), args->GetPkgId().c_str());
+        else if (a->GetEventName().compare(std::string("enable_app")) == 0)
+          _app_enabled_cb(args->GetTargetUid(), args->GetPkgId().c_str());
+        else if (a->GetEventName().compare(std::string("disable_app")) == 0)
+          _app_disabled_cb(args->GetTargetUid(), args->GetPkgId().c_str());
+      }
+    }
+  }
+}
+
+uid_t get_sender_uid(const char *sender_name) {
+  GDBusMessage *msg = nullptr;
+  GDBusMessage *reply = nullptr;
+  GError *err = nullptr;
+  GVariant *body;
+  uid_t uid = 0;
+
+  msg = g_dbus_message_new_method_call(DBUS_NAME, DBUS_OBJECT_PATH,
+      DBUS_INTERFACE_NAME, "GetConnectionUnixUser");
+  if (!msg) {
+    LOGE("Failed to alloc new method call");
+    goto out;
+  }
+
+  g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
+  reply = g_dbus_connection_send_message_with_reply_sync(_gdbus_conn, msg,
+      G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, nullptr, nullptr, &err);
+
+  if (!reply) {
+    if (err != nullptr) {
+      LOGE("Failed to get uid [%s]", err->message);
+      g_error_free(err);
+    }
+    goto out;
+  }
+
+  body = g_dbus_message_get_body(reply);
+  g_variant_get(body, "(u)", &uid);
+
+out:
+  if (msg)
+    g_object_unref(msg);
+  if (reply)
+    g_object_unref(reply);
+
+  return uid;
+}
+
+pid_t get_sender_pid(const char *sender_name) {
+  GDBusMessage *msg = nullptr;
+  GDBusMessage *reply = nullptr;
+  GError *err = nullptr;
+  GVariant *body;
+  pid_t pid = 0;
+
+  msg = g_dbus_message_new_method_call(DBUS_NAME, DBUS_OBJECT_PATH,
+      DBUS_INTERFACE_NAME, "GetConnectionUnixProcessID");
+  if (!msg) {
+    LOGE("Failed to alloc new method call");
+    goto out;
+  }
+
+  g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
+  reply = g_dbus_connection_send_message_with_reply_sync(_gdbus_conn, msg,
+      G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, nullptr, nullptr, &err);
+
+  if (!reply) {
+    if (err != nullptr) {
+      LOGE("Failed to get uid [%s]", err->message);
+      g_error_free(err);
+    }
+    goto out;
+  }
+
+  body = g_dbus_message_get_body(reply);
+  g_variant_get(body, "(u)", &pid);
+
+out:
+  if (msg)
+    g_object_unref(msg);
+  if (reply)
+    g_object_unref(reply);
+
+  return pid;
+}
+
+bool is_existed_busname(const char *sender_name) {
+  GDBusMessage *msg = nullptr;
+  GDBusMessage *reply = nullptr;
+  GError *err = nullptr;
+  GVariant *body;
+  bool is_existed = false;
+
+  msg = g_dbus_message_new_method_call(DBUS_NAME, DBUS_OBJECT_PATH,
+      DBUS_INTERFACE_NAME, "NameHasOwner");
+  if (!msg) {
+    LOGE("Failed to alloc new method call");
+    goto out;
+  }
+
+  g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
+  reply = g_dbus_connection_send_message_with_reply_sync(_gdbus_conn, msg,
+      G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, nullptr, nullptr, &err);
+
+  if (!reply) {
+    if (err != nullptr) {
+      LOGE("Failed to get uid [%s]", err->message);
+      g_error_free(err);
+    }
+    goto out;
+  }
+
+  body = g_dbus_message_get_body(reply);
+  g_variant_get(body, "(b)", &is_existed);
+
+out:
+  if (msg)
+    g_object_unref(msg);
+  if (reply)
+    g_object_unref(reply);
+
+  return is_existed;
+}
+
+int send_notify(GVariant *body, char *cmd, GHashTable **monitoring_hash,
+    char *interface_name, uid_t uid) {
+  GError *err = nullptr;
+  GList *monitoring_list = nullptr;
+  GList *target_list;
+  char *target_bus_name;
+  int monitoring_count = 0;
+  bool is_existed = false;
+
+  monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(uid));
+  target_list = g_list_first(monitoring_list);
+  for (; target_list != nullptr; ) {
+    err = nullptr;
+    target_bus_name = static_cast<char*>(target_list->data);
+    target_list = target_list->next;
+
+    if (g_variant_is_floating(body))
+      g_variant_ref(body);
+
+    if (g_dbus_connection_emit_signal(_gdbus_conn,
+          target_bus_name,
+          PROVIDER_OBJECT_PATH,
+          interface_name,
+          cmd,
+          body,
+          &err) == FALSE) {
+      if (err != nullptr) {
+        ERR("Emit signal err [%s]", err->message);
+        g_error_free(err);
+      }
+      is_existed = is_existed_busname(target_bus_name);
+      if (is_existed == false)
+        delete_monitoring_list(monitoring_hash, target_bus_name, uid);
+      ERR("Fail, emit signal to [%s]", target_bus_name);
+    }
+    monitoring_count++;
+    DBG("Success, emit signal to [%s]", target_bus_name);
+  }
+
+  DBG("Success, cmd[%s] monitoring count[%d]", cmd, monitoring_count);
+  return SERVICE_COMMON_ERROR_NONE;
+}
+
+int send_event_notify_by_busname(GVariant *body, char *cmd, char *busname,
+    char *interface_name) {
+  GError *err = nullptr;
+
+  if (g_variant_is_floating(body))
+    g_variant_ref(body);
+
+  if (g_dbus_connection_emit_signal(_gdbus_conn,
+            busname,
+            PROVIDER_OBJECT_PATH,
+            interface_name,
+            cmd,
+            body,
+            &err) == FALSE) {
+    if (err != nullptr) {
+      ERR("Emit signal err [%s]",
+          err->message);
+      g_error_free(err);
+    }
+    ERR("Failed to emit signal to [%s]", busname);
+    return SERVICE_COMMON_ERROR_IO_ERROR;
+  }
+  DBG("Success, Emit signal to [%s] cmd[%s]", busname, cmd);
+  return SERVICE_COMMON_ERROR_NONE;
+}
+
+/* register service */
+
+static int _monitoring_app_list_compare_cb(gconstpointer a, gconstpointer b) {
+  return strcmp(static_cast<const char*>(a), reinterpret_cast<const char*>(b));
+}
+
+int service_register(GVariant *parameters, GVariant **reply_body, const gchar *sender,
+    GBusNameAppearedCallback name_appeared_handler,
+    GBusNameVanishedCallback name_vanished_handler,
+    GHashTable **monitoring_hash,
+    uid_t uid) {
+  GList *added_list = nullptr;
+  const char *bus_name = sender;
+  monitoring_info_s *m_info = nullptr;
+  uid_t request_uid = 0;
+  GList *monitoring_list = nullptr;
+
+  if (sender == nullptr)
+    return SERVICE_COMMON_ERROR_IO_ERROR;
+
+  g_variant_get(parameters, "(i)", &request_uid);
+  if (uid > NORMAL_UID_BASE && uid != request_uid)
+    return SERVICE_COMMON_ERROR_IO_ERROR;
+
+  DBG("service_register : uid %d , request_uid %d", uid, request_uid);
+  monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(request_uid));
+  added_list = g_list_find_custom(monitoring_list, bus_name,
+      (GCompareFunc)_monitoring_app_list_compare_cb);
+
+  if (added_list == nullptr) {
+    DBG("add new sender to list");
+    m_info = (monitoring_info_s *)calloc(1, sizeof(monitoring_info_s));
+    if (m_info == nullptr) {
+      ERR("Failed to alloc memory");
+      return SERVICE_COMMON_ERROR_OUT_OF_MEMORY;
+    }
+
+    m_info->bus_name = strdup(bus_name);
+    m_info->uid = request_uid;
+    m_info->watcher_id = g_bus_watch_name_on_connection(
+        _gdbus_conn,
+        bus_name,
+        G_BUS_NAME_WATCHER_FLAGS_NONE,
+        name_appeared_handler,
+        name_vanished_handler,
+        m_info,
+        nullptr);
+    if (m_info->watcher_id == 0) {
+      ERR("Fail to watch name [%s]", bus_name);
+      free(m_info->bus_name);
+      free(m_info);
+      return SERVICE_COMMON_ERROR_IO_ERROR;
+    }
+    DBG("Watch on [%s] success", bus_name);
+
+    monitoring_list = g_list_append(monitoring_list, strdup(bus_name));
+    DBG("Success, sender[%s] length[%d]",
+        sender, g_list_length(monitoring_list));
+    if (g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(request_uid)) == nullptr)
+      g_hash_table_insert(*monitoring_hash, GUINT_TO_POINTER(request_uid), monitoring_list);
+  } else {
+    ERR("Sender [%s] already exist", sender);
+  }
+
+  *reply_body = g_variant_new("()");
+  if (*reply_body == nullptr) {
+    if (m_info) {
+      if (m_info->bus_name)
+        free(m_info->bus_name);
+      free(m_info);
+    }
+    monitoring_list = g_list_remove(monitoring_list, bus_name);
+    ERR("Failed to make reply");
+    return SERVICE_COMMON_ERROR_OUT_OF_MEMORY;
+  }
+  return SERVICE_COMMON_ERROR_NONE;
+}
+
+int delete_monitoring_list(GHashTable **monitoring_hash, const char *sender,
+    uid_t uid) {
+  GList *monitoring_list = nullptr;
+  GList *del_list = nullptr;
+  char *bus_name;
+
+  monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(uid));
+  if (monitoring_list == nullptr) {
+    ERR("No uid[%d] in monitoring hash", uid);
+    return SERVICE_COMMON_ERROR_IO_ERROR;
+  }
+
+  monitoring_list = g_list_first(monitoring_list);
+  del_list = g_list_find_custom(monitoring_list, sender,
+      (GCompareFunc)_monitoring_app_list_compare_cb);
+
+  if (del_list) {
+    DBG("Find delete list - uid[%d] sender[%s]", uid, sender);
+    bus_name = static_cast<char*>(g_list_nth_data(del_list, 0));
+    if (bus_name)
+      free(bus_name);
+    monitoring_list = g_list_delete_link(monitoring_list, del_list);
+
+    if (monitoring_list == nullptr) {
+      g_hash_table_steal(*monitoring_hash, GUINT_TO_POINTER(uid));
+    } else {
+      monitoring_list = g_list_first(monitoring_list);
+      g_hash_table_replace(*monitoring_hash, GUINT_TO_POINTER(uid), monitoring_list);
+    }
+  }
+  return SERVICE_COMMON_ERROR_NONE;
+}
+
+static int _dbus_init(void) {
+  GError *error = nullptr;
+
+  if (_gdbus_conn == nullptr) {
+    _gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
+    if (_gdbus_conn == nullptr) {
+      if (error != nullptr) {
+        ERR("Failed to get dbus [%s]", error->message);
+        g_error_free(error);
+      }
+      return SERVICE_COMMON_ERROR_IO_ERROR;
+    }
+  }
+
+  return SERVICE_COMMON_ERROR_NONE;
+}
+
+int service_common_register_dbus_interface(char *introspection_xml,
+    GDBusInterfaceVTable interface_vtable) {
+  int result;
+  int owner_id, noti_registration_id;
+  GError *error = nullptr;
+  GDBusNodeInfo *introspection_data = nullptr;
+
+  result = _dbus_init();
+  if (result != SERVICE_COMMON_ERROR_NONE) {
+      ERR("Can't init dbus [%d]", result);
+      result = SERVICE_COMMON_ERROR_IO_ERROR;
+      goto out;
+  }
+
+  owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
+      PROVIDER_BUS_NAME,
+      G_BUS_NAME_OWNER_FLAGS_NONE,
+      nullptr,
+      nullptr,
+      nullptr,
+      nullptr, nullptr);
+  if (!owner_id) {
+    ERR("Failed to own name");
+    result = SERVICE_COMMON_ERROR_IO_ERROR;
+    goto out;
+  }
+
+  DBG("Acquiring the own name [%d]", owner_id);
+  introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
+  if (!introspection_data) {
+    ERR("g_dbus_node_info_new_for_xml is failed.");
+    result = SERVICE_COMMON_ERROR_IO_ERROR;
+    if (error != nullptr) {
+      ERR("g_dbus_node_info_new_for_xml err [%s]", error->message);
+      g_error_free(error);
+    }
+    goto out;
+  }
+
+  noti_registration_id = g_dbus_connection_register_object(_gdbus_conn,
+      PROVIDER_OBJECT_PATH, introspection_data->interfaces[0],
+      &interface_vtable, nullptr, nullptr, nullptr);
+
+  DBG("registration id[%d]", noti_registration_id);
+  if (noti_registration_id == 0) {
+    ERR("Failed to g_dbus_connection_register_object");
+    result = SERVICE_COMMON_ERROR_IO_ERROR;
+    goto out;
+  }
+
+out:
+  if (introspection_data)
+    g_dbus_node_info_unref(introspection_data);
+
+  return result;
+}
+
+static int _init_pkg_privilege_info() {
+  if (_noti_pkg_privilege_info != nullptr)
+    return 0;
+
+  _noti_pkg_privilege_info =
+    g_hash_table_new_full(g_str_hash, g_str_equal, free, nullptr);
+  _badge_pkg_privilege_info =
+    g_hash_table_new_full(g_str_hash, g_str_equal, free, nullptr);
+  DBG("init pkg privilege info done");
+  return 0;
+}
+
+static int _package_install_cb(uid_t uid, const char *pkgname) {
+  int ret;
+  gpointer tmp;
+  int privilege_info;
+
+  if (uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER))
+    uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+
+  _init_pkg_privilege_info();
+  if (g_hash_table_contains(_noti_pkg_privilege_info, pkgname)) {
+    tmp = g_hash_table_lookup(_noti_pkg_privilege_info, pkgname);
+    privilege_info = GPOINTER_TO_UINT(tmp);
+    if (privilege_info == 1)
+      notification_setting_db_update_pkg_disabled(pkgname, false, uid);
+
+    g_hash_table_remove(_noti_pkg_privilege_info, pkgname);
+  } else {
+    /* In consideration of the reboot status, change the disable information. */
+    ret = notification_setting_db_update_pkg_disabled(pkgname, false, uid);
+    if (ret != NOTIFICATION_ERROR_NONE)
+      notification_setting_insert_package_for_uid(pkgname, uid);
+  }
+
+  if (g_hash_table_contains(_badge_pkg_privilege_info, pkgname)) {
+    tmp = g_hash_table_lookup(_badge_pkg_privilege_info, pkgname);
+    privilege_info = GPOINTER_TO_UINT(tmp);
+    if (privilege_info == 1)
+      badge_db_update_pkg_disabled(pkgname, false, uid);
+
+    g_hash_table_remove(_badge_pkg_privilege_info, pkgname);
+  } else {
+    /* In consideration of the reboot status, change the disable information. */
+    ret = badge_db_update_pkg_disabled(pkgname, false, uid);
+    if (ret != BADGE_ERROR_NONE)
+      badge_setting_insert_package_for_uid(pkgname, uid);
+  }
+
+  return 0;
+}
+
+static int _package_uninstall_cb(uid_t uid, const char *pkgname) {
+  int ret;
+  pkgmgrinfo_pkginfo_h pkginfo;
+
+  if (uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER))
+    uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+
+  ret = pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(pkgname, uid, &pkginfo);
+  if (ret == PMINFO_R_OK) {
+    pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
+
+    _init_pkg_privilege_info();
+    ret = notification_setting_db_update_pkg_disabled(pkgname, true, uid);
+    if (ret == NOTIFICATION_ERROR_NONE)
+      g_hash_table_insert(_noti_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(1));
+    else
+      g_hash_table_insert(_noti_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(0));
+
+    ret = badge_db_update_pkg_disabled(pkgname, true, uid);
+    if (ret == BADGE_ERROR_NONE)
+      g_hash_table_insert(_badge_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(1));
+    else
+      g_hash_table_insert(_badge_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(0));
+  } else {
+    notification_setting_delete_package_for_uid(pkgname, uid);
+    badge_db_delete_by_pkgname(pkgname, uid);
+    badge_setting_delete_package_for_uid(pkgname, uid);
+    notification_noti_delete_template(pkgname);
+  }
+
+  return 0;
+}
+
+static int _app_enabled_cb(uid_t uid, const char *app_id) {
+  notification_setting_db_update_app_disabled(app_id, false, uid);
+  return 0;
+}
+
+static int _app_disabled_cb(uid_t uid, const char *app_id) {
+  notification_delete_noti_by_app_id(app_id, uid);
+  notification_setting_db_update_app_disabled(app_id, true, uid);
+  return 0;
+}
+
+std::unique_ptr<PackageEventListener> listener_;
+
+void service_common_init(void) {
+  pkgmgr_client_ = std::make_unique<PkgmgrClient>();
+  listener_ = std::make_unique<PackageEventListener>();
+  pkgmgr_client_->Listen(listener_.get());
+}
+
+void service_common_set_connection(GDBusConnection *conn) {
+  _gdbus_conn = conn;
+}
\ No newline at end of file
index 22543ac..3df4016 100644 (file)
@@ -42,9 +42,11 @@ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../mock MOCK_SOURCES)
 SET(DPM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../../src/badge_service.c\r
     ${CMAKE_CURRENT_SOURCE_DIR}/../../src/notification_ex_service.cc\r
     ${CMAKE_CURRENT_SOURCE_DIR}/../../src/notification_service.c\r
-    ${CMAKE_CURRENT_SOURCE_DIR}/../../src/pkgmgr.c\r
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../src/pkgmgr_client.cc\r
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../src/pkgmgr_event_args.cc\r
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../src/pkgmgr_app_event_args.cc\r
     ${CMAKE_CURRENT_SOURCE_DIR}/../../src/shortcut_service.c\r
-    ${CMAKE_CURRENT_SOURCE_DIR}/../../src/service_common.c)\r
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../src/service_common.cc)\r
 \r
 ADD_EXECUTABLE(${PROJECT_NAME}\r
     ${TEST_SOURCES}\r