Refactor eventsystem 73/314073/60
authorjh9216.park <jh9216.park@samsung.com>
Fri, 5 Jul 2024 00:01:39 +0000 (20:01 -0400)
committerjh9216.park <jh9216.park@samsung.com>
Thu, 29 Aug 2024 01:30:51 +0000 (21:30 -0400)
- Replace dbus to TIDL
- Replace esd-mod-dbus to esd-mod-group
- Enhanced unit testes
- TCT passed
- Requires
  https://review.tizen.org/gerrit/#/c/platform/core/base/bundle/+/316457/
  https://review.tizen.org/gerrit/#/c/platform/core/appfw/rpc-port/+/316465/
  https://review.tizen.org/gerrit/#/c/platform/core/appfw/rpc-port/+/316771/

Change-Id: I34cd78445fa004c24a1b8839f5a34c2f6b160391
Signed-off-by: jh9216.park <jh9216.park@samsung.com>
55 files changed:
CMakeLists.txt
include/log_private.h [new file with mode: 0644]
modules/CMakeLists.txt [new file with mode: 0644]
modules/group/CMakeLists.txt [new file with mode: 0644]
modules/group/certificate_matcher.cc [new file with mode: 0644]
modules/group/certificate_matcher.hh [new file with mode: 0644]
modules/group/earlier_item.cc [new file with mode: 0644]
modules/group/earlier_item.hh [new file with mode: 0644]
modules/group/es_stub.cc [new file with mode: 0644]
modules/group/es_stub.h [new file with mode: 0644]
modules/group/esd_list_item.cc [new file with mode: 0644]
modules/group/esd_list_item.hh [new file with mode: 0644]
modules/group/event_launch.cc [new file with mode: 0644]
modules/group/event_launch.hh [new file with mode: 0644]
modules/group/event_system_service.cc [new file with mode: 0644]
modules/group/event_system_service.hh [new file with mode: 0644]
modules/group/group.cc [new file with mode: 0644]
modules/group/group_module.cc [new file with mode: 0644]
modules/group/group_module.hh [new file with mode: 0644]
modules/group/interface_event.hh [new file with mode: 0644]
modules/group/last_event_item.hh [new file with mode: 0644]
modules/group/privilege_checker.cc [new file with mode: 0644]
modules/group/privilege_checker.hh [new file with mode: 0644]
modules/group/vconf_event_handler.cc [new file with mode: 0644]
modules/group/vconf_event_handler.hh [new file with mode: 0644]
packaging/esd-group.socket [new file with mode: 0755]
packaging/eventsystem.spec
src/CMakeLists.txt
src/es.cc [new file with mode: 0644]
src/es_proxy.cc [new file with mode: 0644]
src/es_proxy.h [new file with mode: 0644]
src/eventsystem.c [deleted file]
tests/CMakeLists.txt
tests/integ_tests/CMakeLists.txt [new file with mode: 0644]
tests/integ_tests/eventsystem_test.cc [new file with mode: 0644]
tests/integ_tests/main.cc [new file with mode: 0644]
tests/unit_tests/CMakeLists.txt
tests/unit_tests/eventsystem_test.cc
tests/unit_tests/main.cc
tests/unit_tests/mock/aul_mock.cc
tests/unit_tests/mock/aul_mock.hh
tests/unit_tests/mock/gio_mock.cc [deleted file]
tests/unit_tests/mock/gio_mock.hh [deleted file]
tests/unit_tests/mock/libc_mock.cc [deleted file]
tests/unit_tests/mock/libc_mock.hh [deleted file]
tests/unit_tests/mock/pkgmgr_info_mock.cc [new file with mode: 0644]
tests/unit_tests/mock/pkgmgr_info_mock.hh [new file with mode: 0644]
tests/unit_tests/mock/rpc_port_mock.cc [new file with mode: 0644]
tests/unit_tests/mock/rpc_port_mock.hh [new file with mode: 0644]
tests/unit_tests/mock/security_manager_mock.cc [new file with mode: 0644]
tests/unit_tests/mock/security_manager_mock.hh [new file with mode: 0644]
tests/unit_tests/mock/vconf_mock.cc [new file with mode: 0644]
tests/unit_tests/mock/vconf_mock.hh [new file with mode: 0644]
tidl/eventsystem.tidl [new file with mode: 0755]
tidl/prebuild.sh [new file with mode: 0755]

index bf0370c3fbea3bc9f2c5cd68c71801d3ceb5166b..d8beb6df2bd53c26b434adfe02dd05b259c6b964 100644 (file)
@@ -25,8 +25,10 @@ SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
   "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
 
 SET(TARGET_EVENTSYSTEM "eventsystem")
+SET(TARGET_ESD_MOD_GROUP "esd-mod-group")
 SET(TARGET_EVENTSYSTEM_BENCHMARK "eventsystem-benchmark")
 SET(TARGET_EVENTSYSTEM_UNITTESTS "eventsystem-unittests")
+SET(TARGET_EVENTSYSTEM_INTEGTESTS "eventsystem-integtests")
 
 INCLUDE(FindPkgConfig)
 INCLUDE(ApplyPkgConfig)
@@ -38,7 +40,17 @@ PKG_CHECK_MODULES(DLOG_DEPS REQUIRED dlog)
 PKG_CHECK_MODULES(GLIB_DEPS REQUIRED glib-2.0)
 PKG_CHECK_MODULES(GIO_DEPS REQUIRED gio-2.0)
 PKG_CHECK_MODULES(GMOCK_DEPS REQUIRED gmock)
+PKG_CHECK_MODULES(CERT_SVC_VCORE_DEPS REQUIRED cert-svc-vcore)
 PKG_CHECK_MODULES(PKGMGR_INFO_DEPS REQUIRED pkgmgr-info)
+PKG_CHECK_MODULES(PARCEL_DEPS REQUIRED parcel)
+PKG_CHECK_MODULES(RPC_PORT_DEPS REQUIRED rpc-port)
+PKG_CHECK_MODULES(ESD_DEPS REQUIRED libesd)
+PKG_CHECK_MODULES(VCONF_DEPS REQUIRED vconf)
+PKG_CHECK_MODULES(PKGMGR_DEPS REQUIRED pkgmgr)
+PKG_CHECK_MODULES(LIBTZPLATFORM_CONFIG_DEPS REQUIRED libtzplatform-config)
+PKG_CHECK_MODULES(CYNARA_CLIENT_DEPS REQUIRED cynara-client)
+PKG_CHECK_MODULES(CYNARA_SESSION_DEPS REQUIRED cynara-session)
+PKG_CHECK_MODULES(SECURITY_MANAGER_DEPS REQUIRED security-manager)
 
 CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_EVENTSYSTEM}.pc.in
   ${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_EVENTSYSTEM}.pc @ONLY)
@@ -54,6 +66,7 @@ INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
 )
 
 ADD_SUBDIRECTORY(src)
+ADD_SUBDIRECTORY(modules)
 ADD_SUBDIRECTORY(tests)
 ADD_SUBDIRECTORY(benchmark)
 
diff --git a/include/log_private.h b/include/log_private.h
new file mode 100644 (file)
index 0000000..bfb6be9
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2024 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 EVENT_SYSTEM_LOG_PRIVATE_H_
+#define EVENT_SYSTEM_LOG_PRIVATE_H_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "EVENT_SYSTEM"
+
+#undef _E
+#define _E LOGE
+
+#undef _W
+#define _W LOGW
+
+#undef _I
+#define _I LOGI
+
+#undef _D
+#define _D LOGD
+
+#endif  // EVENT_SYSTEM_LOG_PRIVATE_H_
diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e43f751
--- /dev/null
@@ -0,0 +1 @@
+ADD_SUBDIRECTORY(group)
diff --git a/modules/group/CMakeLists.txt b/modules/group/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9314ffc
--- /dev/null
@@ -0,0 +1,25 @@
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} ESD_MOD_GROUP_SRCS)\r
+\r
+ADD_LIBRARY(${TARGET_ESD_MOD_GROUP} ${ESD_MOD_GROUP_SRCS})\r
+TARGET_INCLUDE_DIRECTORIES(${TARGET_ESD_MOD_GROUP} PUBLIC\r
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../include)\r
+\r
+TARGET_LINK_LIBRARIES(${TARGET_ESD_MOD_GROUP} PRIVATE ${TARGET_LIB_ESD})\r
+\r
+APPLY_PKG_CONFIG(${TARGET_ESD_MOD_GROUP} PUBLIC\r
+  DLOG_DEPS\r
+  ESD_DEPS\r
+  RPC_PORT_DEPS\r
+  CERT_SVC_VCORE_DEPS\r
+  PKGMGR_INFO_DEPS\r
+  PKGMGR_DEPS\r
+  VCONF_DEPS\r
+  AUL_DEPS\r
+  LIBTZPLATFORM_CONFIG_DEPS\r
+  SECURITY_MANAGER_DEPS\r
+  CYNARA_CLIENT_DEPS\r
+  CYNARA_SESSION_DEPS\r
+)\r
+\r
+INSTALL(TARGETS ${TARGET_ESD_MOD_GROUP} DESTINATION ${ESD_MODULES_DIR}/mod\r
+  COMPONENT RuntimeLibraries)\r
diff --git a/modules/group/certificate_matcher.cc b/modules/group/certificate_matcher.cc
new file mode 100644 (file)
index 0000000..0ae23d8
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2024 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 "certificate_matcher.hh"
+
+#include <bundle.h>
+#include <cert-svc/ccert.h>
+#include <cert-svc/cinstance.h>
+#include <pkgmgr-info.h>
+
+#include <memory>
+
+#include "eventsystem.h"
+#include "log_private.h"
+
+namespace esd::module {
+
+int CertificateMatcher::Match(const std::string& appid,
+                              const std::string& from_appid) {
+  _D("appid(%s), from_appid(%s)", appid.c_str(), from_appid.c_str());
+
+  pkgmgrinfo_cert_compare_result_type_e res;
+  int ret = pkgmgrinfo_pkginfo_compare_app_cert_info(appid.c_str(),
+                                                     from_appid.c_str(), &res);
+  if (ret < 0) {
+    /* LCOV_EXCL_START */
+    _E("failed to check certificate");
+    return ES_R_ERROR;
+    /* LCOV_EXCL_STOP */
+  }
+
+  if (res != PMINFO_CERT_COMPARE_MATCH) {
+    /* LCOV_EXCL_START */
+    _D("certificat not match (%s)", appid.c_str());
+    return ES_R_EINVAL;
+    /* LCOV_EXCL_STOP */
+  }
+
+  return ES_R_OK;
+}
+
+bool CertificateMatcher::IsPlatformCert(const std::string& pkgid, uid_t uid) {
+  _D("Checking if %s has a platform certification", pkgid.c_str());
+
+  int r;
+  const char* cert_value = nullptr;
+  pkgmgrinfo_certinfo_h certinfo;
+  CertSvcInstance instance;
+  CertSvcCertificate certificate;
+  CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC;
+
+  r = pkgmgrinfo_pkginfo_create_certinfo(&certinfo);
+  std::unique_ptr<std::remove_pointer<pkgmgrinfo_certinfo_h>::type,
+                  decltype(pkgmgrinfo_pkginfo_destroy_certinfo)*>
+      certinfo_auto(certinfo, pkgmgrinfo_pkginfo_destroy_certinfo);
+  if (r != PMINFO_R_OK) {
+    _E("Failed to create certinfo"); /* LCOV_EXCL_LINE */
+    return false;
+  }
+
+  r = pkgmgrinfo_pkginfo_load_certinfo(pkgid.c_str(), certinfo, uid);
+  if (r != PMINFO_R_OK) {
+    _E("Failed to load certinfo"); /* LCOV_EXCL_LINE */
+    return false;
+  }
+
+  r = pkgmgrinfo_pkginfo_get_cert_value(certinfo, PMINFO_DISTRIBUTOR_ROOT_CERT,
+                                        &cert_value);
+  if (r != PMINFO_R_OK || cert_value == nullptr) {
+    _E("Failed to get cert value"); /* LCOV_EXCL_LINE */
+    return false;
+  }
+
+  r = certsvc_instance_new(&instance);
+  if (r != CERTSVC_SUCCESS) {
+    _E("certsvc_instance_new() is failed."); /* LCOV_EXCL_LINE */
+    return false;
+  }
+
+  r = certsvc_certificate_new_from_memory(
+      instance, reinterpret_cast<const unsigned char*>(cert_value),
+      strlen(cert_value), CERTSVC_FORM_DER_BASE64, &certificate);
+  if (r != CERTSVC_SUCCESS) {
+    /* LCOV_EXCL_START */
+    _E("certsvc_certificate_new_from_memory() is failed.");
+    certsvc_instance_free(instance);
+    return false;
+    /* LCOV_EXCL_STOP */
+  }
+
+  r = certsvc_certificate_get_visibility(certificate, &visibility);
+  if (r != CERTSVC_SUCCESS)
+    _E("certsvc_certificate_get_visibility() is failed."); /* LCOV_EXCL_LINE */
+
+  certsvc_instance_free(instance);
+  certsvc_certificate_free(certificate);
+
+  _D("visibility is %d", visibility);
+  if (visibility & CERTSVC_VISIBILITY_PLATFORM) {
+    _D("%s has a platform certification", pkgid.c_str()); /* LCOV_EXCL_LINE */
+    return true;
+  }
+
+  return false;
+}
+
+}  // namespace esd::module
diff --git a/modules/group/certificate_matcher.hh b/modules/group/certificate_matcher.hh
new file mode 100644 (file)
index 0000000..ac6fb6e
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2024 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 LIBEVENTSYSTEM_MODULES_GROUP_CERTIFICATE_MATCHER_HH_
+#define LIBEVENTSYSTEM_MODULES_GROUP_CERTIFICATE_MATCHER_HH_
+
+#include <unistd.h>
+
+#include <string>
+
+namespace esd::module {
+
+class CertificateMatcher {
+ public:
+  static int Match(const std::string& appid, const std::string& from_appid);
+  static bool IsPlatformCert(const std::string& pkgid, uid_t uid);
+};
+
+}  // namespace esd::module
+
+#endif  // LIBEVENTSYSTEM_MODULES_GROUP_CERTIFICATE_MATCHER_HH_
diff --git a/modules/group/earlier_item.cc b/modules/group/earlier_item.cc
new file mode 100644 (file)
index 0000000..4cfc6a4
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2024 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 "earlier_item.hh"
+
+#include <eventsystem.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <vconf.h>
+
+#include <set>
+
+#include "log.hh"
+
+namespace {
+
+constexpr const char ESD_BOOT_COMPLETED[] = "/tmp/esd_ready";
+
+const std::set<std::string_view> earlier_event_list = {
+    SYS_EVENT_ESD_STATUS, SYS_EVENT_LOW_MEMORY, SYS_EVENT_BOOT_COMPLETED,
+    SYS_EVENT_SYSTEM_SHUTDOWN, SYS_EVENT_BATTERY_CHARGER_STATUS};
+
+}  // namespace
+
+namespace esd::module {
+
+EarlierItem::EarlierItem(tizen_base::Bundle data) : data_(std::move(data)) {}
+
+EarlierItem::~EarlierItem() = default;
+
+const tizen_base::Bundle& EarlierItem::GetData() const { return data_; }
+
+void EarlierItem::Notify(const std::string& event_name,
+                         const tizen_base::Bundle& data) {
+  _D("event_name(%s)", event_name.c_str());
+  if (earlier_event_list.find(event_name) == earlier_event_list.end()) return;
+  data_ = tizen_base::Bundle(data.GetHandle(), true, true);
+}
+
+std::map<std::string, std::unique_ptr<EarlierItem>> EarlierItem::CreateMap() {
+  int fd;
+  int ret;
+  std::map<std::string, std::unique_ptr<EarlierItem>> events;
+  int val;
+  int status;
+  int charger_status;
+  int charge_now;
+
+  _I("register events for earlier_data");
+  for (const auto& event_name : earlier_event_list) {
+    _I("event_name(%s)", event_name.data());
+
+    tizen_base::Bundle b;
+    if (event_name == SYS_EVENT_BOOT_COMPLETED) {
+      fd = open(ESD_BOOT_COMPLETED, O_RDONLY);
+      if (fd < 0) {
+        _E("open file error(%d)", fd);
+      } else {
+        b.Add(EVT_KEY_BOOT_COMPLETED, EVT_VAL_BOOT_COMPLETED_TRUE);
+        close(fd);
+      }
+    } else if (event_name == SYS_EVENT_SYSTEM_SHUTDOWN) {
+      ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val);
+      if (ret != VCONF_OK) {
+        _E("failed to get power_off status (%d)", ret); /* LCOV_EXCL_LINE */
+      } else {
+        if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT ||
+            val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) {
+          b.Add(EVT_KEY_SYSTEM_SHUTDOWN, EVT_VAL_SYSTEM_SHUTDOWN_TRUE);
+        }
+      }
+    } else if (event_name == SYS_EVENT_LOW_MEMORY) {
+      ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status);
+      if (ret != VCONF_OK) {
+        _E("failed to get low_memory status (%d)", ret); /* LCOV_EXCL_LINE */
+      } else {
+        if (status == VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING)
+          b.Add(EVT_KEY_LOW_MEMORY, EVT_VAL_MEMORY_SOFT_WARNING);
+        else if (status == VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING)
+          b.Add(EVT_KEY_LOW_MEMORY, EVT_VAL_MEMORY_HARD_WARNING);
+        else
+          b.Add(EVT_KEY_LOW_MEMORY, EVT_VAL_MEMORY_NORMAL);
+      }
+    } else if (event_name == SYS_EVENT_BATTERY_CHARGER_STATUS) {
+      ret = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &charger_status);
+      if (ret != VCONF_OK) {
+        _E("failed to get charger_status (%d)", ret); /* LCOV_EXCL_LINE */
+      } else {
+        ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &charge_now);
+        if (ret != VCONF_OK) _E("failed to get charge_now (%d)", ret);
+      }
+
+      if (ret == VCONF_OK) {
+        if (charger_status == VCONFKEY_SYSMAN_CHARGER_CONNECTED) {
+          if (charge_now == 0) {
+            b.Add(EVT_KEY_BATTERY_CHARGER_STATUS,
+                  EVT_VAL_BATTERY_CHARGER_DISCHARGING);
+          } else {
+            b.Add(EVT_KEY_BATTERY_CHARGER_STATUS,
+                  EVT_VAL_BATTERY_CHARGER_CHARGING);
+          }
+        } else {
+          b.Add(EVT_KEY_BATTERY_CHARGER_STATUS,
+                EVT_VAL_BATTERY_CHARGER_DISCONNECTED);
+        }
+      }
+    }
+
+    events[std::string(event_name)] =
+        std::make_unique<EarlierItem>(std::move(b));
+  }
+
+  return events;
+}
+
+}  // namespace esd::module
diff --git a/modules/group/earlier_item.hh b/modules/group/earlier_item.hh
new file mode 100644 (file)
index 0000000..b0c1505
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2024 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 LIBEVENTSYSTEM_MODULES_GROUP_EARLIER_ITEM_HH_
+#define LIBEVENTSYSTEM_MODULES_GROUP_EARLIER_ITEM_HH_
+
+#include <bundle_cpp.h>
+#include <glib.h>
+
+#include <list>
+#include <map>
+#include <memory>
+#include <string_view>
+#include <tuple>
+#include <utility>
+
+namespace esd::module {
+
+class EarlierItem {
+ public:
+  EarlierItem() = default;
+  explicit EarlierItem(tizen_base::Bundle data);
+  EarlierItem(const EarlierItem&) = delete;
+  EarlierItem& operator=(const EarlierItem&) = delete;
+  ~EarlierItem();
+
+  const tizen_base::Bundle& GetData() const;
+  void Notify(const std::string& event_name, const tizen_base::Bundle& data);
+
+  static std::map<std::string, std::unique_ptr<EarlierItem>> CreateMap();
+
+ private:
+  tizen_base::Bundle data_;
+};
+
+}  // namespace esd::module
+
+#endif  // LIBEVENTSYSTEM_MODULES_GROUP_EARLIER_ITEM_HH_
diff --git a/modules/group/es_stub.cc b/modules/group/es_stub.cc
new file mode 100644 (file)
index 0000000..c8e146b
--- /dev/null
@@ -0,0 +1,684 @@
+/*
+ * Copyright (c) 2024 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 "es_stub.h"
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <dlog.h>
+#include <glib.h>
+#include <libgen.h>
+#include <rpc-port-parcel-internal.h>
+#include <rpc-port-parcel.h>
+#include <rpc-port.h>
+#include <unistd.h>
+
+#include <map>
+#include <memory>
+#include <set>
+#include <stdexcept>
+#include <string>
+#include <unordered_map>
+#include <utility>
+
+#undef LOG_TAG
+#define LOG_TAG "RPC_PORT_STUB"
+
+#undef _E
+#define _E LOGE
+
+#undef _W
+#define _W LOGW
+
+#undef _I
+#define _I LOGI
+
+#undef _D
+#define _D LOGD
+
+#undef EXPORT_API
+#define EXPORT_API extern "C" __attribute__((visibility("default")))
+
+namespace {
+
+rpc_port_parcel_h Clone(rpc_port_parcel_h parcel) {
+  void* raw = nullptr;
+  unsigned int size = 0;
+  rpc_port_parcel_get_raw(parcel, &raw, &size);
+
+  rpc_port_parcel_h handle = nullptr;
+  rpc_port_parcel_create_from_raw_without_header(&handle, raw, size);
+  return handle;
+}
+
+/* LCOV_EXCL_START */
+bool IdleAddOnce(GMainContext* context, std::function<void()>* func) {
+  auto* source = g_idle_source_new();
+  if (source == nullptr) {
+    _E("Failed to create idle source");
+    return false;
+  }
+
+  g_source_set_callback(
+      source, static_cast<GSourceFunc>([](gpointer user_data) {
+        auto* cb = static_cast<std::function<void()>*>(user_data);
+        (*cb)();
+        delete cb;
+        return G_SOURCE_REMOVE;
+      }),
+      func, nullptr);
+  g_source_attach(source, context);
+  g_source_unref(source);
+  return true;
+}
+/* LCOV_EXCL_STOP */
+
+std::shared_ptr<rpc_port::es_stub::LocalExecution> EventSystem_context_;
+
+}  // namespace
+
+namespace rpc_port {
+namespace es_stub {
+
+LocalExecution::LocalExecution(std::string port_name,
+                               LocalExecution::IEvent* listener)
+    : port_name_(std::move(port_name)),
+      listener_(listener),
+      context_(g_main_context_ref_thread_default(), g_main_context_unref) {
+  LoadSymbols();
+}
+
+void LocalExecution::Connect(void* context, bool sync) {
+  if (connect_func_ != nullptr) connect_func_(context, sync);
+}
+
+void LocalExecution::Disconnect(void* context) {
+  if (disconnect_func_ != nullptr) disconnect_func_(context);
+}
+
+void LocalExecution::SendResult(void* context, rpc_port_parcel_h parcel) {
+  if (send_result_func_ != nullptr) send_result_func_(context, parcel);
+}
+
+void LocalExecution::InvokeCallback(void* context, rpc_port_parcel_h parcel) {
+  if (invoke_callback_func_ != nullptr) invoke_callback_func_(context, parcel);
+}
+
+void LocalExecution::OnConnected(void* context, const std::string& sender,
+                                 const std::string& instance, bool sync) {
+  if (listener_ != nullptr)
+    listener_->OnLocalConnected(context, sender, instance, sync);
+}
+
+void LocalExecution::OnDisconnected(void* context, const std::string& sender,
+                                    const std::string& instance) {
+  if (listener_ != nullptr)
+    listener_->OnLocalDisconnected(context, sender, instance);
+}
+
+void LocalExecution::OnReceived(void* context, rpc_port_parcel_h parcel) {
+  if (listener_ != nullptr) listener_->OnLocalReceived(context, parcel);
+}
+
+bool LocalExecution::LoadSymbols() {
+  if (loaded_) return true;
+
+  std::string symbol =
+      "rpc_port_proxy_eventsystem_lem_" + port_name_ + "_connect";
+  connect_func_ =
+      reinterpret_cast<ProxyConnectFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+  if (connect_func_ == nullptr) {
+    _E("Failed to find symbol"); /* LCOV_EXCL_LINE */
+    return false; /* LCOV_EXCL_LINE */
+  }
+
+  symbol = "rpc_port_proxy_eventsystem_lem_" + port_name_ + "_disconnect";
+  disconnect_func_ = reinterpret_cast<ProxyDisconnectFunc>(
+      dlsym(RTLD_DEFAULT, symbol.c_str()));
+  if (disconnect_func_ == nullptr) {
+    _E("Failed to find symbol"); /* LCOV_EXCL_LINE */
+    return false; /* LCOV_EXCL_LINE */
+  }
+
+  symbol = "rpc_port_proxy_eventsystem_lem_" + port_name_ + "_send_result";
+  send_result_func_ = reinterpret_cast<ProxySendResultFunc>(
+      dlsym(RTLD_DEFAULT, symbol.c_str()));
+  if (send_result_func_ == nullptr) {
+    _E("Failed to find symbol"); /* LCOV_EXCL_LINE */
+    return false; /* LCOV_EXCL_LINE */
+  }
+
+  symbol = "rpc_port_proxy_eventsystem_lem_" + port_name_ + "_invoke_callback";
+  invoke_callback_func_ = reinterpret_cast<ProxyInvokeCallbackFunc>(
+      dlsym(RTLD_DEFAULT, symbol.c_str()));
+  if (invoke_callback_func_ == nullptr) {
+    _E("Failed to find symbol"); /* LCOV_EXCL_LINE */
+    return false; /* LCOV_EXCL_LINE */
+  }
+
+  loaded_ = true;
+  return true;
+}
+
+void LocalExecution::SetListening(bool listening) { listening_ = listening; }
+
+bool LocalExecution::IsListening() const { return listening_; }
+
+GMainContext* LocalExecution::GetContext() const { return context_.get(); }
+
+Bundle::Bundle() {
+  handle_ = bundle_create();
+  if (handle_ == nullptr) throw new std::bad_alloc();
+}
+
+Bundle::Bundle(bundle* handle, bool copy, bool own)
+    : handle_(handle), own_(own) {
+  if (handle == nullptr) throw new std::invalid_argument("handle is nullptr");
+
+  if (copy) {
+    handle_ = bundle_dup(handle);
+    if (handle_ == nullptr) throw new std::bad_alloc();
+  }
+}
+
+Bundle::~Bundle() {
+  if (own_ && handle_) bundle_free(handle_);
+}
+
+Bundle::Bundle(Bundle&& b) noexcept {
+  handle_ = b.handle_;
+  b.handle_ = bundle_create();
+  own_ = b.own_;
+  b.own_ = true;
+}
+
+Bundle& Bundle::operator=(Bundle&& b) noexcept {
+  if (this != &b) {
+    if (handle_ && own_) bundle_free(handle_);
+
+    handle_ = b.handle_;
+    b.handle_ = bundle_create();
+    own_ = b.own_;
+  }
+
+  return *this;
+}
+
+bundle* Bundle::GetHandle() const { return handle_; }
+
+namespace stub {
+
+std::atomic<int> EventSystem::CallbackBase::seq_num_{0};
+
+EventSystem::CallbackBase::CallbackBase(int delegate_id, bool once)
+    : id_(delegate_id), once_(once) {
+  seq_id_ = seq_num_++;
+}
+
+int EventSystem::CallbackBase::GetId() const { return id_; }
+
+int EventSystem::CallbackBase::GetSeqId() const { return seq_id_; }
+
+bool EventSystem::CallbackBase::IsOnce() const { return once_; }
+
+rpc_port_parcel_h operator<<(rpc_port_parcel_h h,
+                             const EventSystem::CallbackBase& cb) {
+  rpc_port_parcel_write_int32(h, cb.id_);
+  rpc_port_parcel_write_int32(h, cb.seq_id_);
+  rpc_port_parcel_write_bool(h, cb.once_);
+
+  return h;
+}
+
+rpc_port_parcel_h operator>>(rpc_port_parcel_h h,
+                             EventSystem::CallbackBase& cb) {
+  rpc_port_parcel_read_int32(h, &cb.id_);
+  rpc_port_parcel_read_int32(h, &cb.seq_id_);
+  rpc_port_parcel_read_bool(h, &cb.once_);
+
+  return h;
+}
+
+void EventSystem::CallbackBase::SetContext(void* context) {
+  context_ = context;
+}
+
+void* EventSystem::CallbackBase::GetContext() const { return context_; }
+
+void EventSystem::EventListener::Invoke(std::string event_name, Bundle data) {
+  if (callback_port_ == nullptr && GetContext() == nullptr)
+    throw NotConnectedSocketException();
+
+  if (service_.lock().get() == nullptr) throw NotConnectedSocketException();
+
+  if (IsOnce() && !valid_) throw InvalidArgumentException();
+
+  rpc_port_parcel_h parcel_;
+  rpc_port_parcel_create_without_header(&parcel_);
+  rpc_port_parcel_write_int32(parcel_, static_cast<int>(MethodId::__Callback));
+  parcel_ << *this;
+  rpc_port_parcel_write_string(parcel_, event_name.c_str());
+  rpc_port_parcel_write_bundle(parcel_, data.GetHandle());
+
+  if (GetContext() != nullptr) {
+    EventSystem_context_->InvokeCallback(GetContext(), parcel_);
+    set_last_result(RPC_PORT_ERROR_NONE);
+  } else {
+    set_last_result(rpc_port_parcel_send(parcel_, callback_port_));
+  }
+
+  rpc_port_parcel_destroy(parcel_);
+  valid_ = false;
+}
+
+EventSystem::ServiceBase::ServiceBase(std::string sender, std::string instance)
+    : sender_(std::move(sender)), instance_(std::move(instance)) {}
+
+void EventSystem::ServiceBase::SetPort(rpc_port_h port) { port_ = port; }
+
+void EventSystem::ServiceBase::Disconnect() {
+  int ret = rpc_port_disconnect(port_);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    _E("Failed to disconnect the port. error(%d)", ret);
+    return;
+  }
+
+  port_ = nullptr;
+}
+
+void EventSystem::ServiceBase::Dispatch(rpc_port_h port,
+                                        rpc_port_h callback_port,
+                                        rpc_port_parcel_h parcel,
+                                        std::shared_ptr<ServiceBase> service) {
+  rpc_port_parcel_h result;
+  int cmd;
+  rpc_port_parcel_create_without_header(&result);
+  rpc_port_parcel_read_int32(parcel, &cmd);
+
+  switch (cmd) {
+    case static_cast<int>(MethodId::RegisterEvent): {
+      int param1;
+      rpc_port_parcel_read_int32(parcel, &param1);
+      char* param2_raw = nullptr;
+      rpc_port_parcel_read_string(parcel, &param2_raw);
+      std::string param2(param2_raw);
+      free(param2_raw);
+      std::unique_ptr<EventListener> param3(new EventListener(
+          callback_port, std::weak_ptr<ServiceBase>(this->shared_from_this())));
+      param3->SetContext(GetContext());
+      parcel >> *param3;
+      auto retVal = service->RegisterEvent(
+          static_cast<EventType>(param1), std::move(param2), std::move(param3));
+      rpc_port_parcel_write_int32(result, static_cast<int>(MethodId::__Result));
+      rpc_port_parcel_write_int32(result, retVal);
+      if (GetContext() != nullptr) {
+        EventSystem_context_->SendResult(GetContext(), result);
+      } else {
+        rpc_port_parcel_send(result, port);
+      }
+      break;
+    }
+
+    case static_cast<int>(MethodId::UnregisterEvent): {
+      int param1;
+      rpc_port_parcel_read_int32(parcel, &param1);
+      auto retVal = service->UnregisterEvent(param1);
+      rpc_port_parcel_write_int32(result, static_cast<int>(MethodId::__Result));
+      rpc_port_parcel_write_bool(result, retVal);
+      if (GetContext() != nullptr) {
+        EventSystem_context_->SendResult(GetContext(), result);
+      } else {
+        rpc_port_parcel_send(result, port);
+      }
+      break;
+    }
+
+    case static_cast<int>(MethodId::SendUserEvent): {
+      char* param1_raw = nullptr;
+      rpc_port_parcel_read_string(parcel, &param1_raw);
+      std::string param1(param1_raw);
+      free(param1_raw);
+      bundle* param2_raw = nullptr;
+      rpc_port_parcel_read_bundle(parcel, &param2_raw);
+      Bundle param2(param2_raw, false, true);
+      bool param3;
+      rpc_port_parcel_read_bool(parcel, &param3);
+      auto retVal =
+          service->SendUserEvent(std::move(param1), std::move(param2), param3);
+      rpc_port_parcel_write_int32(result, static_cast<int>(MethodId::__Result));
+      rpc_port_parcel_write_bool(result, retVal);
+      if (GetContext() != nullptr) {
+        EventSystem_context_->SendResult(GetContext(), result);
+      } else {
+        rpc_port_parcel_send(result, port);
+      }
+      break;
+    }
+
+    case static_cast<int>(MethodId::SendSystemEvent): {
+      char* param1_raw = nullptr;
+      rpc_port_parcel_read_string(parcel, &param1_raw);
+      std::string param1(param1_raw);
+      free(param1_raw);
+      bundle* param2_raw = nullptr;
+      rpc_port_parcel_read_bundle(parcel, &param2_raw);
+      Bundle param2(param2_raw, false, true);
+      auto retVal =
+          service->SendSystemEvent(std::move(param1), std::move(param2));
+      rpc_port_parcel_write_int32(result, static_cast<int>(MethodId::__Result));
+      rpc_port_parcel_write_bool(result, retVal);
+      if (GetContext() != nullptr) {
+        EventSystem_context_->SendResult(GetContext(), result);
+      } else {
+        rpc_port_parcel_send(result, port);
+      }
+      break;
+    }
+
+    case static_cast<int>(MethodId::KeepLastEventData): {
+      char* param1_raw = nullptr;
+      rpc_port_parcel_read_string(parcel, &param1_raw);
+      std::string param1(param1_raw);
+      free(param1_raw);
+      auto retVal = service->KeepLastEventData(std::move(param1));
+      rpc_port_parcel_write_int32(result, static_cast<int>(MethodId::__Result));
+      rpc_port_parcel_write_bool(result, retVal);
+      if (GetContext() != nullptr) {
+        EventSystem_context_->SendResult(GetContext(), result);
+      } else {
+        rpc_port_parcel_send(result, port);
+      }
+      break;
+    }
+
+    case static_cast<int>(MethodId::GetEarlierData): {
+      char* param1_raw = nullptr;
+      rpc_port_parcel_read_string(parcel, &param1_raw);
+      std::string param1(param1_raw);
+      free(param1_raw);
+      Bundle param2;
+      auto retVal = service->GetEarlierData(std::move(param1), param2);
+      rpc_port_parcel_write_int32(result, static_cast<int>(MethodId::__Result));
+      rpc_port_parcel_write_bundle(result, param2.GetHandle());
+      rpc_port_parcel_write_bool(result, retVal);
+      if (GetContext() != nullptr) {
+        EventSystem_context_->SendResult(GetContext(), result);
+      } else {
+        rpc_port_parcel_send(result, port);
+      }
+      break;
+    }
+
+    default:
+      _E("Unknown command(%d)", cmd);
+  }
+
+  rpc_port_parcel_destroy(result);
+}
+
+void EventSystem::ServiceBase::SetContext(void* context) { context_ = context; }
+
+void* EventSystem::ServiceBase::GetContext() const { return context_; }
+
+EventSystem::EventSystem() {
+  _W("EventSystem ctor");
+  int ret = rpc_port_stub_create(&stub_, "EventSystem");
+  if (ret != RPC_PORT_ERROR_NONE) {
+    _E("Failed to create stub. error(%d)", ret);
+    throw InvalidIOException();
+  }
+
+  rpc_port_stub_add_connected_event_cb(stub_, OnConnectedCb, this);
+  rpc_port_stub_add_disconnected_event_cb(stub_, OnDisconnectedCb, this);
+  rpc_port_stub_add_received_event_cb(stub_, OnReceivedCb, this);
+
+  EventSystem_context_ = std::make_unique<LocalExecution>("EventSystem", this);
+}
+
+EventSystem::~EventSystem() {
+  _W("EventSystem dtor");
+  for (auto& service : services_) {
+    service->OnTerminate();
+    if (EventSystem_context_)
+      EventSystem_context_->Disconnect(service->GetContext());
+  }
+
+  EventSystem_context_.reset();
+  if (stub_ != nullptr) rpc_port_stub_destroy(stub_);
+}
+
+void EventSystem::Listen(
+    std::shared_ptr<EventSystem::ServiceBase::Factory> service_factory) {
+  service_factory_ = std::move(service_factory);
+  int ret = rpc_port_stub_listen(stub_);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    /* LCOV_EXCL_START */
+    _E("Failed to listen stub. error(%d)", ret);
+    if (ret == RPC_PORT_ERROR_INVALID_PARAMETER ||
+        ret == RPC_PORT_ERROR_IO_ERROR)
+      throw InvalidIOException();
+    /* LCOV_EXCL_STOP */
+  }
+
+  EventSystem_context_->SetListening(true);
+}
+
+void EventSystem::OnConnectedCb(const char* sender, const char* instance,
+                                void* user_data) {
+  auto* handle = static_cast<EventSystem*>(user_data);
+  auto service = handle->service_factory_->CreateService(sender, instance);
+
+  rpc_port_h port;
+  int ret = rpc_port_stub_get_port(handle->stub_, RPC_PORT_PORT_CALLBACK,
+                                   instance, &port);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    /* LCOV_EXCL_START */
+    _E("Failed to get port. error(%d)", ret);
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+
+  service->SetPort(port);
+  service->OnCreate();
+  handle->services_.emplace_back(std::move(service));
+}
+
+void EventSystem::OnDisconnectedCb(const char* sender, const char* instance,
+                                   void* user_data) {
+  auto* handle = static_cast<EventSystem*>(user_data);
+  auto iter = handle->services_.begin();
+  while (iter != handle->services_.end()) {
+    if ((*iter)->GetInstance() == instance) {
+      (*iter)->OnTerminate();
+      iter = handle->services_.erase(iter);
+      break;
+    }
+
+    iter++;
+  }
+}
+
+int EventSystem::OnReceivedCb(const char* sender, const char* instance,
+                              rpc_port_h port, void* user_data) {
+  auto* handle = static_cast<EventSystem*>(user_data);
+  std::shared_ptr<ServiceBase> service;
+  for (auto& iter : handle->services_) {
+    if (iter->GetInstance() == instance) {
+      service = iter;
+      break;
+    }
+  }
+
+  if (service.get() == nullptr) {
+    _E("Failed to find EventSystem context. instance(%s)", instance);
+    return -1;
+  }
+
+  rpc_port_h callback_port;
+  int ret = rpc_port_stub_get_port(handle->stub_, RPC_PORT_PORT_CALLBACK,
+                                   instance, &callback_port);
+  if (ret != 0) {
+    _E("Failed to get callback port. error(%d)", ret);
+    return -1;
+  }
+
+  rpc_port_parcel_h parcel;
+  ret = rpc_port_parcel_create_from_port_without_header(&parcel, port);
+  if (ret != 0) {
+    _E("Failed to create parcel from port. error(%d)", ret);
+    return ret;
+  }
+
+  service->Dispatch(port, callback_port, parcel, service);
+  rpc_port_parcel_destroy(parcel);
+  return ret;
+}
+
+void EventSystem::OnLocalConnected(void* context, const std::string& sender,
+                                   const std::string& instance, bool sync) {
+  auto service = service_factory_->CreateService(sender, instance);
+  service->SetContext(context);
+  service->OnCreate();
+  services_.emplace_back(std::move(service));
+  EventSystem_context_->Connect(context, sync);
+}
+
+void EventSystem::OnLocalDisconnected(void* context, const std::string& sender,
+                                      const std::string& instance) {
+  auto iter = services_.begin();
+  while (iter != services_.end()) {
+    if ((*iter)->GetInstance() == instance) {
+      (*iter)->OnTerminate();
+      iter = services_.erase(iter);
+      break;
+    }
+
+    iter++;
+  }
+
+  EventSystem_context_->Disconnect(context);
+}
+
+void EventSystem::OnLocalReceived(void* context, rpc_port_parcel_h parcel) {
+  std::shared_ptr<ServiceBase> service;
+  for (auto& iter : services_) {
+    if (iter->GetContext() == context) {
+      service = iter;
+      break;
+    }
+  }
+
+  if (service.get() == nullptr) {
+    /* LCOV_EXCL_START */
+    _E("Failed to find EventSystem context. context(%p)", context);
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+
+  service->Dispatch(nullptr, nullptr, parcel, service);
+}
+
+}  // namespace stub
+}  // namespace es_stub
+}  // namespace rpc_port
+
+EXPORT_API int rpc_port_stub_eventsystem_lem_EventSystem_connect(
+    void* context, const char* sender, const char* instance, bool sync) {
+  if (EventSystem_context_.get() == nullptr ||
+      !EventSystem_context_->IsListening()) {
+    /* LCOV_EXCL_START */
+    _E("Server is not ready");
+    return RPC_PORT_ERROR_IO_ERROR;
+    /* LCOV_EXCL_STOP */
+  }
+
+  std::string sender_str(sender);
+  std::string instance_str(instance);
+  if (gettid() == getpid()) {
+    EventSystem_context_->OnConnected(context, sender, instance, sync);
+    return RPC_PORT_ERROR_NONE;
+  }
+
+  /* LCOV_EXCL_START */
+  auto* func = new std::function<void()>([context, sender_str, instance_str,
+                                          sync] {
+    EventSystem_context_->OnConnected(context, sender_str, instance_str, sync);
+  });
+  if (!IdleAddOnce(EventSystem_context_->GetContext(), func)) {
+    delete func;
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  }
+
+  return RPC_PORT_ERROR_NONE;
+  /* LCOV_EXCL_STOP */
+}
+
+EXPORT_API int rpc_port_stub_eventsystem_lem_EventSystem_disconnect(
+    void* context, const char* sender, const char* instance) {
+  if (EventSystem_context_.get() == nullptr ||
+      !EventSystem_context_->IsListening()) {
+    _E("Server is not ready");
+    return RPC_PORT_ERROR_IO_ERROR;
+  }
+
+  std::string sender_str(sender);
+  std::string instance_str(instance);
+  if (gettid() == getpid()) {
+    EventSystem_context_->OnDisconnected(context, sender, instance);
+    return RPC_PORT_ERROR_NONE;
+  }
+
+  /* LCOV_EXCL_START */
+  auto* func = new std::function<void()>([context, sender_str, instance_str] {
+    EventSystem_context_->OnDisconnected(context, sender_str, instance_str);
+  });
+  if (!IdleAddOnce(EventSystem_context_->GetContext(), func)) {
+    delete func;
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  }
+
+  return RPC_PORT_ERROR_NONE;
+  /* LCOV_EXCL_STOP */
+}
+
+EXPORT_API int rpc_port_stub_eventsystem_lem_EventSystem_send(
+    void* context, rpc_port_parcel_h parcel) {
+  if (EventSystem_context_.get() == nullptr ||
+      !EventSystem_context_->IsListening()) {
+    _E("Server is not ready");
+    return RPC_PORT_ERROR_IO_ERROR;
+  }
+
+  rpc_port_parcel_h cloned_parcel = Clone(parcel);
+  if (gettid() == getpid()) {
+    EventSystem_context_->OnReceived(context, cloned_parcel);
+    rpc_port_parcel_destroy(cloned_parcel);
+    return RPC_PORT_ERROR_NONE;
+  }
+
+  /* LCOV_EXCL_START */
+  auto* func = new std::function<void()>([context, cloned_parcel] {
+    EventSystem_context_->OnReceived(context, cloned_parcel);
+    rpc_port_parcel_destroy(cloned_parcel);
+  });
+  if (!IdleAddOnce(EventSystem_context_->GetContext(), func)) {
+    delete func;
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  }
+
+  return RPC_PORT_ERROR_NONE;
+  /* LCOV_EXCL_STOP */
+}
diff --git a/modules/group/es_stub.h b/modules/group/es_stub.h
new file mode 100644 (file)
index 0000000..49041ad
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2024 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.
+ */
+
+#pragma once
+
+#include <bundle.h>
+#include <glib.h>
+#include <rpc-port-parcel.h>
+#include <rpc-port.h>
+
+#include <atomic>
+#include <functional>
+#include <list>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <queue>
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+namespace rpc_port {
+namespace es_stub {
+
+class LocalExecution {
+ public:
+  class IEvent {
+   public:
+    virtual ~IEvent() = default;
+    virtual void OnLocalConnected(void* context, const std::string& sender,
+                                  const std::string& instance, bool sync) = 0;
+    virtual void OnLocalDisconnected(void* context, const std::string& sender,
+                                     const std::string& instance) = 0;
+    virtual void OnLocalReceived(void* context, rpc_port_parcel_h parcel) = 0;
+  };
+
+  LocalExecution(std::string port_name, IEvent* listener);
+  virtual ~LocalExecution() = default;
+
+  void Connect(void* context, bool sync);
+  void Disconnect(void* context);
+  void SendResult(void* context, rpc_port_parcel_h parcel);
+  void InvokeCallback(void* context, rpc_port_parcel_h parcel);
+
+  void OnConnected(void* context, const std::string& sender,
+                   const std::string& instance, bool sync);
+  void OnDisconnected(void* context, const std::string& sender,
+                      const std::string& instance);
+  void OnReceived(void* context, rpc_port_parcel_h parcel);
+
+  void SetListening(bool listening);
+  bool IsListening() const;
+
+  bool LoadSymbols();
+  GMainContext* GetContext() const;
+
+ private:
+  using ProxyConnectFunc = int (*)(void*, bool);
+  using ProxyDisconnectFunc = int (*)(void*);
+  using ProxySendResultFunc = int (*)(void*, rpc_port_parcel_h);
+  using ProxyInvokeCallbackFunc = int (*)(void*, rpc_port_parcel_h);
+
+ private:
+  std::string port_name_;
+  IEvent* listener_;
+  bool listening_ = false;
+  bool loaded_ = false;
+  ProxyConnectFunc connect_func_ = nullptr;
+  ProxyDisconnectFunc disconnect_func_ = nullptr;
+  ProxySendResultFunc send_result_func_ = nullptr;
+  ProxyInvokeCallbackFunc invoke_callback_func_ = nullptr;
+  std::unique_ptr<GMainContext, decltype(g_main_context_unref)*> context_;
+};
+
+class Bundle final {
+ public:
+  Bundle();
+  explicit Bundle(bundle* handle, bool copy = true, bool own = true);
+  ~Bundle();
+
+  Bundle(const Bundle& b) = delete;
+  Bundle& operator=(const Bundle&) = delete;
+
+  Bundle(Bundle&& b) noexcept;
+  Bundle& operator=(Bundle&&) noexcept;
+
+  bundle* GetHandle() const;
+
+ private:
+  bundle* handle_;
+  bool own_ = true;
+};
+
+namespace stub {
+
+class Exception {};
+class NotConnectedSocketException : public Exception {};
+class InvalidProtocolException : public Exception {};
+class InvalidIOException : public Exception {};
+class PermissionDeniedException : public Exception {};
+class InvalidIDException : public Exception {};
+class InvalidArgumentException : public Exception {};
+class OutOfMemoryException : public Exception {};
+
+class EventSystem : public LocalExecution::IEvent {
+ public:
+  enum class EventType : int {
+    User = 0,
+    System,
+  };
+
+  class ServiceBase;
+
+  class CallbackBase {
+   public:
+    CallbackBase(int delegate_id, bool once);
+    CallbackBase() = default;
+    virtual ~CallbackBase() = default;
+
+    int GetId() const;
+    int GetSeqId() const;
+    bool IsOnce() const;
+
+    void SetContext(void* context);
+    void* GetContext() const;
+
+   private:
+    friend rpc_port_parcel_h operator<<(rpc_port_parcel_h h,
+                                        const CallbackBase& cb);
+    friend rpc_port_parcel_h operator>>(rpc_port_parcel_h h, CallbackBase& cb);
+
+    static std::atomic<int> seq_num_;
+    int id_ = 0;
+    int seq_id_ = 0;
+    bool once_ = false;
+    void* context_ = nullptr;
+  };
+
+  class EventListener : public CallbackBase {
+   public:
+    EventListener(rpc_port_h callback_port, std::weak_ptr<ServiceBase> service)
+        : CallbackBase(static_cast<int>(DelegateId::EventListener), false),
+          callback_port_(callback_port),
+          service_(std::move(service)) {}
+
+    void Invoke(std::string event_name, Bundle data);
+
+   private:
+    rpc_port_h callback_port_;
+    std::weak_ptr<ServiceBase> service_;
+    bool valid_ = true;
+  };
+
+  class ServiceBase : public std::enable_shared_from_this<ServiceBase> {
+   public:
+    class Factory {
+     public:
+      virtual ~Factory() = default;
+
+      /// <summary>
+      /// The method for making service instances
+      /// </summary>
+      /// <param name="sender">The client app ID</param>
+      /// <param name="instance">The client instance ID</param>
+      virtual std::unique_ptr<ServiceBase> CreateService(
+          std::string sender, std::string instance) = 0;
+    };
+
+    virtual ~ServiceBase() = default;
+
+    /// <summary>
+    /// Gets client app ID
+    /// </summary>
+    const std::string& GetSender() const { return sender_; }
+
+    /// <summary>
+    /// Gets client instance ID
+    /// </summary>
+    const std::string& GetInstance() const { return instance_; }
+
+    /// <summary>
+    /// Sets the client app port
+    /// </summary>
+    /// <param name="port">The port of the client</param>
+    void SetPort(rpc_port_h port);
+
+    /// <summary>
+    /// Disconnects from the client app
+    /// </summary>
+    /// <exception cref="InvalidIOException">
+    /// Thrown when internal I/O error happen.
+    /// </exception>
+    void Disconnect();
+
+    /// <summary>
+    /// This method will be called when the client is connected
+    /// </summary>
+    virtual void OnCreate() = 0;
+
+    /// <summary>
+    /// This method will be called when the client is disconnected
+    /// </summary>
+    virtual void OnTerminate() = 0;
+
+    void SetContext(void* context);
+    void* GetContext() const;
+    void Dispatch(rpc_port_h port, rpc_port_h callback_port,
+                  rpc_port_parcel_h parcel,
+                  std::shared_ptr<ServiceBase> service);
+
+    virtual int RegisterEvent(EventSystem::EventType type,
+                              std::string event_name,
+                              std::unique_ptr<EventListener> cb) = 0;
+    virtual bool UnregisterEvent(int id) = 0;
+    virtual bool SendUserEvent(std::string event_name, Bundle data,
+                               bool is_trusted) = 0;
+    virtual bool SendSystemEvent(std::string event_name, Bundle data) = 0;
+    virtual bool KeepLastEventData(std::string event_name) = 0;
+    virtual bool GetEarlierData(std::string event_name, Bundle& data) = 0;
+
+   protected:
+    ServiceBase(std::string sender, std::string instance);
+
+   private:
+    std::string sender_;
+    std::string instance_;
+    rpc_port_h port_ = nullptr;
+    void* context_ = nullptr;
+  };
+
+  EventSystem();
+  ~EventSystem();
+
+  /// <summary>
+  /// Listens to client apps
+  /// </summary>
+  /// <param name="service_factory">The factory object for making service
+  /// instances</param> <exception cref="InvalidIOException"> Thrown when
+  /// internal I/O error happen.
+  /// </exception>
+  void Listen(std::shared_ptr<ServiceBase::Factory> service_factory);
+
+  /// <summary>
+  /// Gets service objects which are connected
+  /// </summary>
+  /// <returns>The list of service objects which are connected</returns>
+  const std::list<std::shared_ptr<ServiceBase>>& GetServices() const {
+    return services_;
+  }
+
+ private:
+  enum class MethodId : int {
+    __Result = 0,
+    __Callback = 1,
+    RegisterEvent = 2,
+    UnregisterEvent = 3,
+    SendUserEvent = 4,
+    SendSystemEvent = 5,
+    KeepLastEventData = 6,
+    GetEarlierData = 7,
+  };
+
+  enum class DelegateId : int {
+    EventListener = 1,
+  };
+
+  static void OnConnectedCb(const char* sender, const char* instance,
+                            void* user_data);
+  static void OnDisconnectedCb(const char* sender, const char* instance,
+                               void* user_data);
+  static int OnReceivedCb(const char* sender, const char* instance,
+                          rpc_port_h port, void* user_data);
+
+  void OnLocalConnected(void* context, const std::string& sender,
+                        const std::string& instance, bool sync) override;
+  void OnLocalDisconnected(void* context, const std::string& sender,
+                           const std::string& instance) override;
+  void OnLocalReceived(void* context, rpc_port_parcel_h parcel) override;
+
+ private:
+  rpc_port_stub_h stub_ = nullptr;
+  std::shared_ptr<ServiceBase::Factory> service_factory_;
+  std::list<std::shared_ptr<ServiceBase>> services_;
+};
+
+}  // namespace stub
+}  // namespace es_stub
+}  // namespace rpc_port
diff --git a/modules/group/esd_list_item.cc b/modules/group/esd_list_item.cc
new file mode 100644 (file)
index 0000000..e36afa4
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2024 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 "esd_list_item.hh"
+
+#include "log_private.h"
+
+namespace esd::module {
+
+EsdListItem::EsdListItem(std::string pkg_id, std::string app_id, uid_t uid)
+    : pkg_id_(std::move(pkg_id)), app_id_(std::move(app_id)), uid_(uid) {}
+
+void EsdListItem::Print(const std::string& event_name) {
+  _D("event_name(%s)-uid(%d)-app_id(%s)-pkg_id(%s)", event_name.c_str(), uid_,
+     app_id_.c_str(), pkg_id_.c_str());
+}
+
+const std::string& EsdListItem::GetAppId() const { return app_id_; }
+
+int EsdListItem::GetTrustedInfo() const { return trusted_info_; }
+
+void EsdListItem::SetTrustedInfo(int info) { trusted_info_ = info; }
+
+uid_t EsdListItem::GetUid() const { return uid_; }
+
+}  // namespace esd::module
diff --git a/modules/group/esd_list_item.hh b/modules/group/esd_list_item.hh
new file mode 100644 (file)
index 0000000..f1cda5e
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2024 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 LIBEVENTSYSTEM_MODULES_GROUP_ESD_LIST_ITEM_HH_
+#define LIBEVENTSYSTEM_MODULES_GROUP_ESD_LIST_ITEM_HH_
+
+#include <bundle_cpp.h>
+
+#include <list>
+#include <map>
+#include <string>
+#include <tuple>
+#include <utility>
+
+namespace esd::module {
+
+class EsdListItem {
+ public:
+  enum TrustedResult {
+    TRUSTED_UNKNOWN,
+    TRUSTED_ALLOWED,
+    TRUSTED_DENIED,
+  };
+
+  EsdListItem() = default;
+  EsdListItem(std::string pkg_id, std::string app_id, uid_t uid);
+
+  void Print(const std::string& event_name);
+  const std::string& GetAppId() const;
+  int GetTrustedInfo() const;
+  void SetTrustedInfo(int info);
+  uid_t GetUid() const;
+
+ private:
+  std::string pkg_id_;
+  std::string app_id_;
+  int trusted_info_ = TRUSTED_UNKNOWN;
+  uid_t uid_ = 0;
+};
+
+}  // namespace esd::module
+
+#endif  // LIBEVENTSYSTEM_MODULES_GROUP_ESD_LIST_ITEM_HH_
diff --git a/modules/group/event_launch.cc b/modules/group/event_launch.cc
new file mode 100644 (file)
index 0000000..033fe22
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2024 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 "event_launch.hh"
+
+#include <aul.h>
+#include <aul_svc.h>
+#include <bundle_internal.h>
+#include <eventsystem.h>
+
+#include <set>
+
+#include "certificate_matcher.hh"
+#include "log_private.h"
+
+namespace {
+
+constexpr const int ROOT_USER = 0;
+
+const std::set<std::string_view> event_launch_support_list = {
+    SYS_EVENT_BATTERY_CHARGER_STATUS, SYS_EVENT_USB_STATUS,
+    SYS_EVENT_EARJACK_STATUS,         SYS_EVENT_INCOMMING_MSG,
+    SYS_EVENT_OUTGOING_MSG,           SYS_EVENT_WIFI_STATE};
+
+}  // namespace
+
+namespace esd::module {
+
+EventLaunch::EventLaunch(std::string pkgid, std::string appid, uid_t uid)
+    : package_name_(std::move(pkgid)), uid_(uid) {
+  app_list_evtlaunch_.push_back(
+      EsdListItem(package_name_, std::move(appid), uid));
+}
+
+EventLaunch::~EventLaunch() = default;
+
+void EventLaunch::Add(std::string pkgid, std::string appid, uid_t uid) {
+  app_list_evtlaunch_.push_back(
+      EsdListItem(std::move(pkgid), std::move(appid), uid));
+}
+
+void EventLaunch::Print(const std::string& event_name) {
+  for (auto& i : app_list_evtlaunch_) i.Print(event_name);
+}
+
+uid_t EventLaunch::GetUid() const { return uid_; }
+
+const std::string& EventLaunch::GetPackageName() const { return package_name_; }
+
+bool EventLaunch::CheckEvent(std::string_view event_name,
+                             const tizen_base::Bundle& data) {
+  if (event_name == SYS_EVENT_BATTERY_CHARGER_STATUS) {
+    auto val = data.GetString(EVT_KEY_BATTERY_CHARGER_STATUS);
+    _D("charger val(%s)", val.c_str());
+    if (val != EVT_VAL_BATTERY_CHARGER_CONNECTED) return false;
+  } else if (event_name == SYS_EVENT_USB_STATUS) {
+    auto val = data.GetString(EVT_KEY_USB_STATUS);
+    _D("usb val(%s)", val.c_str());
+    if (val != EVT_VAL_USB_CONNECTED) return false;
+  } else if (event_name == SYS_EVENT_EARJACK_STATUS) {
+    auto val = data.GetString(EVT_KEY_EARJACK_STATUS);
+    _D("earjack val(%s)", val.c_str());
+    if (val != EVT_VAL_EARJACK_CONNECTED) return false;
+  } else if (event_name == SYS_EVENT_INCOMMING_MSG) {
+    auto msg_type = data.GetString(EVT_KEY_MSG_TYPE);
+    _D("msg_type(%s)", msg_type.c_str());
+    if (msg_type.empty()) return false;
+    auto msg_id = data.GetString(EVT_KEY_MSG_ID);
+    _D("msg_id(%s)", msg_id.c_str());
+    if (msg_id.empty()) return false;
+  } else if (event_name == SYS_EVENT_OUTGOING_MSG) {
+    auto msg_type = data.GetString(EVT_KEY_OUT_MSG_TYPE);
+    _D("msg_type(%s)", msg_type.c_str());
+    if (msg_type.empty()) return false;
+    auto msg_id = data.GetString(EVT_KEY_OUT_MSG_ID);
+    _D("msg_id(%s)", msg_id.c_str());
+    if (msg_id.empty()) return false;
+  } else if (event_name == SYS_EVENT_WIFI_STATE) {
+    auto val = data.GetString(EVT_KEY_WIFI_STATE);
+    if (val.empty()) return false;
+    _D("wifi_state(%s)", val.c_str());
+    if (val != EVT_VAL_WIFI_CONNECTED) return false;
+  }
+
+  return true;
+}
+
+void EventLaunch::Notify(const std::string& event_name,
+                         const tizen_base::Bundle& data, bool user_event,
+                         bool trusted, uid_t sender_uid,
+                         const std::string& sender_appid) {
+  _D("event_name(%s)", event_name.data());
+  if (app_list_evtlaunch_.empty()) return;
+  if (!user_event && !CheckEvent(event_name, data)) return;
+
+  static int req_id;
+  for (auto& i : app_list_evtlaunch_) {
+    _D("launch_on_event: app_id(%s), event_name(%s), uid(%d), is_user(%d),"
+       " trusted(%d)",
+       i.GetAppId().c_str(), event_name.c_str(), i.GetUid(), user_event,
+       trusted);
+
+    if (user_event && trusted) {
+      if (i.GetTrustedInfo() == EsdListItem::TRUSTED_UNKNOWN) {
+        int ret = CertificateMatcher::Match(i.GetAppId(), sender_appid.data());
+        if (ret == ES_R_EINVAL) {
+          i.SetTrustedInfo(EsdListItem::TRUSTED_DENIED);
+          continue;
+        } else if (ret == ES_R_ERROR) {
+          continue;
+        } else {
+          i.SetTrustedInfo(EsdListItem::TRUSTED_ALLOWED);
+        }
+      } else if (i.GetTrustedInfo() == EsdListItem::TRUSTED_DENIED) {
+        continue;
+      }
+    }
+
+    if (aul_app_is_running_for_uid(i.GetAppId().c_str(), i.GetUid())) {
+      _D("already is running or launch failed");
+      continue;
+    }
+
+    tizen_base::Bundle b(data);
+    std::string event_uri;
+    if (user_event) {
+      event_uri = USER_EVENT_NAME_PREFIX + std::string(event_name);
+    } else {
+      event_uri = SYSTEM_EVENT_NAME_PREFIX + std::string(event_name);
+    }
+
+    aul_svc_set_operation(b.GetHandle(), AUL_SVC_OPERATION_LAUNCH_ON_EVENT);
+    aul_svc_set_uri(b.GetHandle(), event_uri.c_str());
+    aul_svc_set_appid(b.GetHandle(), i.GetAppId().c_str());
+
+    int pid = aul_svc_run_service_async_for_uid(b.GetHandle(), req_id++,
+                                                nullptr, nullptr, i.GetUid());
+    _D("uid(%d), pid(%d)", i.GetUid(), pid);
+  }
+}
+
+}  // namespace esd::module
diff --git a/modules/group/event_launch.hh b/modules/group/event_launch.hh
new file mode 100644 (file)
index 0000000..72b114a
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2024 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 LIBEVENTSYSTEM_MODULES_GROUP_EVENT_LAUNCH_HH_
+#define LIBEVENTSYSTEM_MODULES_GROUP_EVENT_LAUNCH_HH_
+
+#include <bundle_cpp.h>
+#include <glib.h>
+
+#include <list>
+#include <map>
+#include <string>
+#include <string_view>
+#include <tuple>
+#include <utility>
+
+#include "esd_list_item.hh"
+
+namespace esd::module {
+
+class EventLaunch {
+ public:
+  EventLaunch() = default;
+  EventLaunch(std::string pkgid, std::string appid, uid_t uid);
+  EventLaunch(const EventLaunch&) = delete;
+  EventLaunch& operator=(const EventLaunch&) = delete;
+  ~EventLaunch();
+
+  void Print(const std::string& event_name);
+  uid_t GetUid() const;
+  const std::string& GetPackageName() const;
+  void Add(std::string pkgid, std::string appid, uid_t uid);
+
+  void Notify(const std::string& event_name, const tizen_base::Bundle& data,
+              bool user_event, bool trusted, uid_t sender_uid,
+              const std::string& sender_appid);
+
+ private:
+  bool CheckEvent(std::string_view event_name, const tizen_base::Bundle& data);
+
+  static void EsdEventHandlerCb(const char* event_name, bundle* data,
+                                void* user_data);
+
+ private:
+  std::string package_name_;
+  std::list<EsdListItem> app_list_evtlaunch_;
+  guint reg_id_ = 0;
+  uid_t uid_ = 0;
+};
+
+}  // namespace esd::module
+
+#endif  // LIBEVENTSYSTEM_MODULES_GROUP_EVENT_LAUNCH_HH_
diff --git a/modules/group/event_system_service.cc b/modules/group/event_system_service.cc
new file mode 100644 (file)
index 0000000..5daff9f
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2024 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 "event_system_service.hh"
+
+#include <unistd.h>
+
+#include "certificate_matcher.hh"
+#include "eventsystem.h"
+#include "log_private.h"
+
+namespace esd::module {
+
+namespace {}
+
+void EventSystemService::OnCreate() {}
+
+void EventSystemService::OnTerminate() {
+  evt_listener_.OnRequestRemoveData(GetSender());
+}
+
+int EventSystemService::RegisterEvent(
+    rpc_stub::EventSystem::EventType type, std::string event_name,
+    std::unique_ptr<rpc_stub::EventSystem::EventListener> cb) {
+  int id = cb->GetId();
+  listeners_[event_name] = {type, std::move(cb)};
+
+  if (type == rpc_stub::EventSystem::EventType::User) {
+    const auto* data = evt_listener_.OnRequestGetData(event_name);
+    if (data) NotifyEvent(event_name, *data);
+  }
+
+  return id;
+}
+
+bool EventSystemService::UnregisterEvent(int id) {
+  auto itr = std::find_if(
+      listeners_.begin(), listeners_.end(),
+      [id](const auto& pair) { return pair.second.listener_->GetId() == id; });
+
+  if (itr != listeners_.end()) {
+    listeners_.erase(itr);
+    return true;
+  }
+
+  return false;
+}
+
+bool EventSystemService::SendUserEvent(std::string event_name, rpc::Bundle data,
+                                       bool is_trusted) {
+  const auto& services = parent_.GetServices();
+  for (auto& s : services) {
+    auto* ptr = static_cast<EventSystemService*>(s.get());
+    if (is_trusted)
+      ptr->NotifyTrustedEvent(event_name, data, GetSender(), ptr->GetSender());
+    else
+      ptr->NotifyEvent(event_name, data);
+  }
+
+  evt_listener_.OnRequestSetData(event_name, data);
+  evt_listener_.OnEvent(event_name,
+                        tizen_base::Bundle(data.GetHandle(), false, false),
+                        true, is_trusted, GetSender());
+  return true;
+}
+
+bool EventSystemService::SendSystemEvent(std::string event_name,
+                                         rpc::Bundle data) {
+  const auto& services = parent_.GetServices();
+  for (auto& s : services) {
+    auto* ptr = static_cast<EventSystemService*>(s.get());
+    ptr->NotifyEvent(event_name, data);
+  }
+
+  evt_listener_.OnRequestSetData(event_name, data);
+  evt_listener_.OnEvent(event_name,
+                        tizen_base::Bundle(data.GetHandle(), false, false),
+                        false, false, GetSender());
+  return true;
+}
+
+bool EventSystemService::KeepLastEventData(std::string event_name) {
+  evt_listener_.OnRequestKeepData(event_name, GetSender());
+  return true;
+}
+
+bool EventSystemService::GetEarlierData(std::string event_name,
+                                        rpc::Bundle& data) {
+  tizen_base::Bundle b;
+  if (evt_listener_.OnRequestEarlierData(event_name, b)) {
+    data = rpc::Bundle(b.GetHandle());
+    return true;
+  }
+
+  return false;
+}
+
+void EventSystemService::NotifyEvent(const std::string& event_name,
+                                     const rpc::Bundle& data) {
+  auto i = listeners_.find(event_name);
+  if (i == listeners_.end()) return;
+  (*i).second.listener_->Invoke(event_name,
+                                rpc::Bundle(data.GetHandle(), false, false));
+}
+
+void EventSystemService::NotifyTrustedEvent(const std::string& event_name,
+                                            const rpc::Bundle& data,
+                                            const std::string& sender,
+                                            const std::string& receiver) {
+  auto i = listeners_.find(event_name);
+  if (i == listeners_.end()) return;
+
+  int val = CertificateMatcher::Match(sender, receiver);
+  if (val != ES_R_OK) {
+    _E("CertificateMatcher failed. Skip!");
+    return;
+  }
+
+  (*i).second.listener_->Invoke(event_name,
+                                rpc::Bundle(data.GetHandle(), false, false));
+}
+
+}  // namespace esd::module
diff --git a/modules/group/event_system_service.hh b/modules/group/event_system_service.hh
new file mode 100644 (file)
index 0000000..ecbd7cd
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2024 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 MODULES_GROUP_EVENT_SYSTEM_SERVICE_HH_
+#define MODULES_GROUP_EVENT_SYSTEM_SERVICE_HH_
+
+#include <imodule.hh>
+#include <list>
+#include <memory>
+#include <optional>
+#include <string>
+
+#include "es_stub.h"
+#include "interface_event.hh"
+
+namespace esd::module {
+
+namespace rpc_stub = rpc_port::es_stub::stub;
+namespace rpc = rpc_port::es_stub;
+
+class EventSystemService : public rpc_stub::EventSystem::ServiceBase {
+ public:
+  class Factory : public rpc_stub::EventSystem::ServiceBase::Factory {
+   public:
+    Factory(const rpc_stub::EventSystem& parent, IEvent& evt_listener)
+        : parent_(parent), evt_listener_(evt_listener) {}
+    virtual ~Factory() = default;
+
+    std::unique_ptr<rpc_stub::EventSystem::ServiceBase> CreateService(
+        std::string sender, std::string instance) {
+      return std::unique_ptr<rpc_stub::EventSystem::ServiceBase>(
+          new EventSystemService(sender, instance, parent_, evt_listener_));
+    }
+
+   private:
+    const rpc_stub::EventSystem& parent_;
+    IEvent& evt_listener_;
+  };
+
+  EventSystemService(std::string sender, std::string instance,
+                     const rpc_stub::EventSystem& parent, IEvent& evt_listener)
+      : rpc_stub::EventSystem::ServiceBase(sender, instance),
+        parent_(parent),
+        evt_listener_(evt_listener) {}
+
+  virtual ~EventSystemService() = default;
+
+  void OnCreate() override;
+  void OnTerminate() override;
+
+  int RegisterEvent(
+      rpc_stub::EventSystem::EventType type, std::string event_name,
+      std::unique_ptr<rpc_stub::EventSystem::EventListener> cb) override;
+  bool UnregisterEvent(int id) override;
+  bool SendUserEvent(std::string event_name, rpc::Bundle data,
+                     bool is_trusted) override;
+  bool SendSystemEvent(std::string event_name, rpc::Bundle data) override;
+  bool KeepLastEventData(std::string event_name) override;
+  bool GetEarlierData(std::string event_name, rpc::Bundle& data) override;
+
+  void NotifyEvent(const std::string& event_name, const rpc::Bundle& data);
+  void NotifyTrustedEvent(const std::string& event_name,
+                          const rpc::Bundle& data, const std::string& sender,
+                          const std::string& receiver);
+
+ private:
+  struct EventData {
+    rpc_stub::EventSystem::EventType type_;
+    std::unique_ptr<rpc_stub::EventSystem::EventListener> listener_;
+  };
+
+  const rpc_stub::EventSystem& parent_;
+  IEvent& evt_listener_;
+  std::map<std::string, EventData> listeners_;
+};
+
+}  // namespace esd::module
+
+#endif  // MODULES_GROUP_EVENT_SYSTEM_SERVICE_HH_
\ No newline at end of file
diff --git a/modules/group/group.cc b/modules/group/group.cc
new file mode 100644 (file)
index 0000000..7a703f5
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2024 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 "group_module.hh"
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+extern "C" EXPORT_API esd::api::IModule* ESD_GET_MODULE() {
+  return new esd::module::GroupModule();
+}
diff --git a/modules/group/group_module.cc b/modules/group/group_module.cc
new file mode 100644 (file)
index 0000000..c139300
--- /dev/null
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2024 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 "group_module.hh"
+
+#include <aul_svc.h>
+#include <rpc-port-internal.h>
+#include <tzplatform_config.h>
+
+#include "certificate_matcher.hh"
+#include "event_system_service.hh"
+#include "eventsystem.h"
+#include "eventsystem_internal.h"
+#include "log_private.h"
+#include "privilege_checker.hh"
+
+namespace esd::module {
+
+const uid_t GLOBAL_USER = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
+
+const std::set<std::string_view> event_launch_support_list = {
+    SYS_EVENT_BATTERY_CHARGER_STATUS, SYS_EVENT_USB_STATUS,
+    SYS_EVENT_EARJACK_STATUS,         SYS_EVENT_INCOMMING_MSG,
+    SYS_EVENT_OUTGOING_MSG,           SYS_EVENT_WIFI_STATE};
+
+bool GroupModule::FillEventLaunchTable(uid_t uid) {
+  pkgmgrinfo_appinfo_filter_h handle = nullptr;
+
+  _I("get user items for uid(%d)", uid);
+  event_launch_table_.clear();
+
+  int ret = pkgmgrinfo_appinfo_filter_create(&handle);
+  if (ret < 0) {
+    _E("failed to create appinfo filter");
+    return false;
+  }
+
+  std::unique_ptr<std::remove_pointer_t<pkgmgrinfo_appinfo_filter_h>,
+                  decltype(pkgmgrinfo_appinfo_filter_destroy)*>
+      handle_auto(handle, pkgmgrinfo_appinfo_filter_destroy);
+
+  ret = pkgmgrinfo_appinfo_filter_add_string(
+      handle, PMINFO_APPINFO_PROP_APP_COMPONENT, "svcapp");
+  if (ret < 0) {
+    _E("failed to add appinfo filter string");
+    return false;
+  }
+
+  ret = pkgmgrinfo_appinfo_filter_add_string(handle,
+                                             PMINFO_APPINFO_PROP_APP_OPERATION,
+                                             AUL_SVC_OPERATION_LAUNCH_ON_EVENT);
+  if (ret < 0) {
+    _E("failed to add appinfo filter string");
+    return false;
+  }
+
+  ret = pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(handle, AddAppInfoCb,
+                                                      this, uid);
+  if (ret < 0) {
+    _E("appinfo filter foreach error");
+    return false;
+  }
+
+  PrintLaunchTableItems();
+
+  return true;
+}
+
+int GroupModule::RemoveLaunchTableItems(std::string_view pkgid) {
+  for (auto& i : event_launch_table_) {
+    if (i.second->GetPackageName() == pkgid) {
+      event_launch_table_.erase(i.first);
+      break;
+    }
+  }
+
+  return ES_R_OK;
+}
+
+void GroupModule::PrintLaunchTableItems() {
+  for (auto& i : event_launch_table_) i.second->Print(i.first);
+}
+
+void GroupModule::AddLaunchItem(const std::string& event_name) {
+  auto it = event_launch_table_.find(event_name);
+
+  if (it != event_launch_table_.end()) {
+    auto& el = (*it).second;
+    el->Add(pkgid_, appid_, target_uid_);
+  } else {
+    _D("add new item (all)");
+    event_launch_table_[event_name] =
+        std::make_unique<EventLaunch>(pkgid_, appid_, target_uid_);
+  }
+}
+
+int GroupModule::AppControlCb(const char* operation, const char* uri,
+                              const char* mime, void* data) {
+  GroupModule* obj = static_cast<GroupModule*>(data);
+  std::string event_name;
+
+  _D("uid(%d), appid(%s), pkgid(%s), operation(%s), uri(%s), mime(%s)",
+     obj->target_uid_, obj->appid_.c_str(), obj->pkgid_.c_str(), operation, uri,
+     mime);
+
+  if (std::string_view(operation) == AUL_SVC_OPERATION_LAUNCH_ON_EVENT) {
+    if (uri && !strncmp(uri, SYSTEM_EVENT_NAME_PREFIX,
+                        strlen(SYSTEM_EVENT_NAME_PREFIX))) {
+      event_name = &uri[8];
+      _D("appid(%s), event_name(%s)", obj->appid_.c_str(), event_name.c_str());
+      if (event_launch_support_list.find(event_name) ==
+          event_launch_support_list.end()) {
+        _E("failed to add item (not support event)");
+      } else if (!PrivilegeChecker::AppHasPrivilege(obj->target_uid_,
+                                                    obj->appid_, event_name)) {
+        _E("failed to add item (no privilege)");
+      } else {
+        obj->AddLaunchItem(event_name);
+      }
+    } else if (uri && !strncmp(uri, USER_EVENT_NAME_PREFIX,
+                               strlen(USER_EVENT_NAME_PREFIX))) {
+      event_name = uri;
+      _D("appid(%s), event_name(%s)", obj->appid_.c_str(), event_name.c_str());
+      if (CertificateMatcher::IsPlatformCert(obj->pkgid_, obj->target_uid_)) {
+        obj->AddLaunchItem(event_name);
+      }
+    }
+  }
+
+  return 0;
+}
+
+int GroupModule::AddAppInfoCb(const pkgmgrinfo_appinfo_h handle, void* data) {
+  GroupModule* obj = static_cast<GroupModule*>(data);
+  char* appid = nullptr;
+  char* pkgid = nullptr;
+  int ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
+  if (ret < 0) {
+    /* LCOV_EXCL_START */
+    _E("failed to get appid");
+    return ES_R_ERROR;
+    /* LCOV_EXCL_STOP */
+  }
+
+  ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
+  if (ret < 0) {
+    /* LCOV_EXCL_START */
+    _E("failed to get appid");
+    return ES_R_ERROR;
+    /* LCOV_EXCL_STOP */
+  }
+
+  obj->appid_ = appid;
+  obj->pkgid_ = pkgid;
+  ret = pkgmgrinfo_appinfo_foreach_appcontrol(handle, AppControlCb, obj);
+  if (ret < 0) {
+    /* LCOV_EXCL_START */
+    _E("failed to get appcontrol info");
+    return ES_R_ERROR;
+    /* LCOV_EXCL_STOP */
+  }
+
+  return ES_R_OK;
+}
+
+bool GroupModule::Startup(api::ToolBox* tools) {
+  try {
+    es_.Listen(std::shared_ptr<rpc_stub::EventSystem::ServiceBase::Factory>(
+        new EventSystemService::Factory(es_, *this)));
+  } catch (const rpc_stub::InvalidIOException& e) { /* LCOV_EXCL_LINE */
+    /* LCOV_EXCL_START */
+    _E("InvalidIOException happened");
+    return false;
+    /* LCOV_EXCL_STOP */
+  }
+
+  if (!FillEventLaunchTable(GLOBAL_USER)) {
+    /* LCOV_EXCL_START */
+    _E("FillEventLaunchTable failed");
+    return false;
+    /* LCOV_EXCL_STOP */
+  }
+
+  auto* pkgmgr_client_raw = pkgmgr_client_new(PC_LISTENING);
+  if (pkgmgr_client_raw == nullptr) {
+    /* LCOV_EXCL_START */
+    _E("set pkgmgr client failed");
+    return false;
+    /* LCOV_EXCL_STOP */
+  }
+
+  pkgmgr_client_.reset(pkgmgr_client_raw);
+  int req_id =
+      pkgmgr_client_listen_status(pkgmgr_client_.get(), PkgmgrEventCb, this);
+  if (req_id < 0) {
+    /* LCOV_EXCL_START */
+    _E("pkgmgr client listen failed");
+    pkgmgr_client_.reset();
+    return false;
+    /* LCOV_EXCL_STOP */
+  }
+
+  vconf_handler_.SetDefaultEvents([this](const auto& name, auto* b) {
+    const auto& services = es_.GetServices();
+    rpc::Bundle bd(b, false, false);
+    for (auto& s : services) {
+      auto* ptr = static_cast<EventSystemService*>(s.get());
+      ptr->NotifyEvent(name, bd);
+    }
+  });
+
+  earlier_table_ = EarlierItem::CreateMap();
+  return true;
+}
+
+void GroupModule::Shutdown() {
+  event_launch_table_.clear();
+  earlier_table_.clear();
+  vconf_handler_.UnsetDefaultEvents();
+}
+
+int GroupModule::PkgmgrEventCb(uid_t target_uid, int req_id,
+                               const char* pkg_type, const char* pkgid,
+                               const char* k, const char* v, const void* pmsg,
+                               void* data) {
+  _D("target_uid(%d), req_id(%d), pkg_type(%s), pkgid(%s), key(%s), val(%s)",
+     target_uid, req_id, pkg_type, pkgid, k, v);
+
+  GroupModule* obj = static_cast<GroupModule*>(data);
+  auto key = std::string_view(k);
+  auto val = std::string_view(v);
+
+  if (key == "start") {
+    if (val == "install") {
+      _D("install start");
+      obj->pkg_event_type_ = INSTALL;
+    } else if (val == "uninstall") {
+      _D("unistall start");
+      obj->pkg_event_type_ = UNINSTALL;
+    } else if (val == "update") {
+      _D("update start");
+      obj->pkg_event_type_ = UPDATE;
+    } else {
+      _D("val(%s) start", val.data());
+    }
+  } else if (key == "end" && val == "ok") {
+    if (obj->pkg_event_type_ == INSTALL || obj->pkg_event_type_ == UPDATE) {
+      _D("install end (ok)");
+      pkgmgrinfo_pkginfo_h handle = nullptr;
+      int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &handle);
+      if (ret < 0) {
+        /* LCOV_EXCL_START */
+        _E("failed to get pkginfo");
+        return 0;
+        /* LCOV_EXCL_STOP */
+      }
+
+      obj->target_uid_ = target_uid;
+      ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_SVC_APP,
+                                            AddAppInfoCb, obj, target_uid);
+      if (ret < 0) {
+        /* LCOV_EXCL_START */
+        _E("failed to get appinfo");
+        pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+        return 0;
+        /* LCOV_EXCL_STOP */
+      }
+
+      ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+      if (ret < 0) {
+        /* LCOV_EXCL_START */
+        _E("failed to destroy pkginfo");
+        return 0;
+        /* LCOV_EXCL_STOP */
+      }
+    } else if (obj->pkg_event_type_ == UNINSTALL) {
+      _D("uninstall end (ok)");
+      obj->RemoveLaunchTableItems(pkgid);
+      obj->PrintLaunchTableItems();
+    }
+  } else if (key == "end" && val == "fail") {
+    _E("pkg_event(%d) falied", obj->pkg_event_type_);
+  }
+
+  return 0;
+}
+
+void GroupModule::OnEvent(const std::string& event_name,
+                          const tizen_base::Bundle& data, bool user_event,
+                          bool trusted, const std::string& sender_appid) const {
+  auto it = event_launch_table_.find(event_name);
+  if (it != event_launch_table_.end()) {
+    (*it).second->Notify(event_name, data, user_event, trusted, 5001,
+                         sender_appid);
+  }
+
+  auto it2 = earlier_table_.find(event_name);
+  if (it2 != earlier_table_.end()) {
+    (*it2).second->Notify(event_name, data);
+  }
+}
+
+bool GroupModule::OnRequestEarlierData(const std::string& event_name,
+                                       tizen_base::Bundle& data) const {
+  auto it = earlier_table_.find(event_name);
+  if (it != earlier_table_.end()) {
+    data = (*it).second->GetData();
+    return true;
+  }
+
+  return false;
+}
+
+void GroupModule::OnRequestKeepData(const std::string& event_name,
+                                    const std::string& owner) {
+  auto it = user_last_event_table_.find(event_name);
+  if (it == user_last_event_table_.end()) {
+    user_last_event_table_[event_name] = LastEventItem(owner, event_name);
+  } else {
+    (*it).second.SetOwner(owner);
+  }
+}
+
+void GroupModule::OnRequestRemoveData(const std::string& owner) {
+  for (auto it = user_last_event_table_.begin();
+       it != user_last_event_table_.end();) {
+    if ((*it).second.GetOwner() == owner) {
+      it = user_last_event_table_.erase(it);
+    } else {
+      it++;
+    }
+  }
+}
+
+void GroupModule::OnRequestSetData(const std::string& event_name,
+                                   const rpc::Bundle& b) {
+  auto it = user_last_event_table_.find(event_name);
+  if (it == user_last_event_table_.end()) return;
+
+  (*it).second.SetData(rpc::Bundle(b.GetHandle(), true, true));
+}
+
+const rpc::Bundle* GroupModule::OnRequestGetData(
+    const std::string& event_name) const {
+  auto it = user_last_event_table_.find(event_name);
+  if (it == user_last_event_table_.end()) return nullptr;
+
+  return &((*it).second.GetData().value());
+}
+
+}  // namespace esd::module
diff --git a/modules/group/group_module.hh b/modules/group/group_module.hh
new file mode 100644 (file)
index 0000000..1fb6220
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2024 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 MODULES_GROUP_GROUP_MODULE_HH_
+#define MODULES_GROUP_GROUP_MODULE_HH_
+
+#include <package-manager.h>
+#include <pkgmgr-info.h>
+
+#include <imodule.hh>
+#include <list>
+#include <map>
+#include <memory>
+#include <optional>
+#include <string>
+
+#include "earlier_item.hh"
+#include "es_stub.h"
+#include "event_launch.hh"
+#include "interface_event.hh"
+#include "last_event_item.hh"
+#include "vconf_event_handler.hh"
+
+namespace esd::module {
+
+namespace rpc_stub = rpc_port::es_stub::stub;
+namespace rpc = rpc_port::es_stub;
+
+class GroupModule : public api::IModule, public IEvent {
+ public:
+  GroupModule() = default;
+  virtual ~GroupModule() = default;
+
+  bool Startup(api::ToolBox* tools) override;
+  void Shutdown() override;
+  void OnEvent(const std::string& event_name, const tizen_base::Bundle& data,
+               bool user_event, bool trusted,
+               const std::string& sender_appid) const override;
+  bool OnRequestEarlierData(const std::string& event_name,
+                            tizen_base::Bundle& data) const override;
+  void OnRequestKeepData(const std::string& event_name,
+                         const std::string& owner) override;
+  void OnRequestRemoveData(const std::string& owner) override;
+  void OnRequestSetData(const std::string& event_name,
+                        const rpc::Bundle& b) override;
+  const rpc::Bundle* OnRequestGetData(
+      const std::string& event_name) const override;
+
+ private:
+  enum PkgEventType {
+    UNKNOWN = 0,
+    INSTALL,
+    UNINSTALL,
+    UPDATE,
+  };
+
+  void PrintLaunchTableItems();
+  int RemoveLaunchTableItems(std::string_view pkgid);
+  void AddLaunchItem(const std::string& event_name);
+  bool FillEventLaunchTable(uid_t uid);
+
+  static int PkgmgrEventCb(uid_t target_uid, int req_id, const char* pkg_type,
+                           const char* pkgid, const char* k, const char* v,
+                           const void* pmsg, void* data);
+  static int AddAppInfoCb(const pkgmgrinfo_appinfo_h handle, void* data);
+  static int AppControlCb(const char* operation, const char* uri,
+                          const char* mime, void* data);
+
+ private:
+  rpc_stub::EventSystem es_;
+  VconfEventHandler vconf_handler_;
+  std::unique_ptr<pkgmgr_client, decltype(pkgmgr_client_free)*> pkgmgr_client_ =
+      {nullptr, pkgmgr_client_free};
+  std::string pkg_event_pkgid_;
+  int pkg_event_type_ = 0;
+  uid_t target_uid_ = 0;
+  std::string appid_;
+  std::string pkgid_;
+  std::map<std::string, std::unique_ptr<EventLaunch>> event_launch_table_;
+  std::map<std::string, std::unique_ptr<EarlierItem>> earlier_table_;
+  std::map<std::string, LastEventItem> user_last_event_table_;
+};  // namespace esd::module
+
+}  // namespace esd::module
+
+#endif  // MODULES_GROUP_GROUP_MODULE_HH_
\ No newline at end of file
diff --git a/modules/group/interface_event.hh b/modules/group/interface_event.hh
new file mode 100644 (file)
index 0000000..070ebd2
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2024 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 LIBEVENTSYSTEM_MODULES_GROUP_INTERFACE_EVENT_HH_
+#define LIBEVENTSYSTEM_MODULES_GROUP_INTERFACE_EVENT_HH_
+
+#include <bundle_cpp.h>
+
+#include <optional>
+#include <string>
+
+#include "es_stub.h"
+
+namespace rpc = rpc_port::es_stub;
+
+namespace esd::module {
+
+class IEvent {
+ public:
+  virtual ~IEvent() = default;
+  virtual void OnEvent(const std::string& event_name,
+                       const tizen_base::Bundle& data, bool user_event,
+                       bool trusted, const std::string& sender_appid) const = 0;
+  virtual bool OnRequestEarlierData(const std::string& event_name,
+                                    tizen_base::Bundle& data) const = 0;
+  virtual void OnRequestKeepData(const std::string& event_name,
+                                 const std::string& owner) = 0;
+  virtual void OnRequestRemoveData(const std::string& owner) = 0;
+  virtual void OnRequestSetData(const std::string& event_name,
+                                const rpc::Bundle& b) = 0;
+  virtual const rpc::Bundle* OnRequestGetData(
+      const std::string& event_name) const = 0;
+};
+
+}  // namespace esd::module
+
+#endif  // LIBEVENTSYSTEM_MODULES_GROUP_INTERFACE_EVENT_HH_
diff --git a/modules/group/last_event_item.hh b/modules/group/last_event_item.hh
new file mode 100644 (file)
index 0000000..8024bbf
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2024 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 LIBEVENTSYSTEM_MODULES_GROUP_LAST_EVENT_ITEM_HH_
+#define LIBEVENTSYSTEM_MODULES_GROUP_LAST_EVENT_ITEM_HH_
+
+#include <optional>
+#include <string>
+#include <utility>
+
+#include "es_stub.h"
+
+namespace rpc = rpc_port::es_stub;
+
+namespace esd::module {
+
+class LastEventItem {
+ public:
+  LastEventItem() = default;
+  LastEventItem(std::string owner, std::string event_name)
+      : owner_(std::move(owner)), event_name_(std::move(event_name)) {}
+
+  void SetOwner(std::string owner) { owner_ = std::move(owner); }
+  const std::string& GetOwner() const { return owner_; }
+  const std::string& GetEventName() const { return event_name_; }
+  void SetData(rpc::Bundle b) { data_ = std::move(b); }
+  const std::optional<rpc::Bundle>& GetData() const { return data_; }
+
+ private:
+  std::string owner_;
+  std::string event_name_;
+  std::optional<rpc::Bundle> data_;
+};
+
+}  // namespace esd::module
+
+#endif  // LIBEVENTSYSTEM_MODULES_GROUP_LAST_EVENT_ITEM_HH_
diff --git a/modules/group/privilege_checker.cc b/modules/group/privilege_checker.cc
new file mode 100644 (file)
index 0000000..943f149
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2024 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 "privilege_checker.hh"
+
+#include <eventsystem_internal.h>
+#include <security-manager.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <fstream>
+#include <iostream>
+#include <map>
+#include <string>
+
+#include "log_private.h"
+
+namespace {
+
+const std::map<std::string, std::string> kPrivilegeInfoMap = {
+    {std::string(SYS_EVENT_DISPLAY_STATE),
+     std::string("http://tizen.org/privilege/display")},
+    {std::string(SYS_EVENT_WIFI_STATE),
+     std::string("http://tizen.org/privilege/network.get")},
+    {std::string(SYS_EVENT_INCOMMING_MSG),
+     std::string("http://tizen.org/privilege/message.read")},
+    {std::string(SYS_EVENT_OUTGOING_MSG),
+     std::string("http://tizen.org/privilege/message.read")}};
+
+}  // namespace
+
+namespace esd::module {
+
+bool PrivilegeChecker::AppHasPrivilege(uid_t uid, const std::string& appid,
+                                       const std::string& event_name) {
+  int result = 0;
+
+  _D("event_name(%s), uid(%d), appid(%s)", event_name.c_str(), uid,
+     appid.c_str());
+
+  std::string privilege_name = CheckPrivilegeName(event_name);
+  if (!privilege_name.empty()) {
+    int ret = security_manager_app_has_privilege(
+        appid.c_str(), privilege_name.c_str(), uid, &result);
+    if (ret != SECURITY_MANAGER_SUCCESS)
+      _E("failed to check privilege(%d)", ret);
+    _D("result(%d)", result);
+  } else {
+    result = 1;
+  }
+
+  return result;
+}
+
+std::string PrivilegeChecker::CheckPrivilegeName(
+    const std::string& event_name) {
+  const auto& it = kPrivilegeInfoMap.find(event_name);
+  if (it == kPrivilegeInfoMap.end())
+    return "";
+  else
+    return it->second;
+}
+
+}  // namespace esd::module
\ No newline at end of file
diff --git a/modules/group/privilege_checker.hh b/modules/group/privilege_checker.hh
new file mode 100644 (file)
index 0000000..5a20f95
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2024 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 LIBEVENTSYSTEM_MODULES_GROUP_PRIVILEGE_CHECKER_HH_
+#define LIBEVENTSYSTEM_MODULES_GROUP_PRIVILEGE_CHECKER_HH_
+
+#include <string>
+
+namespace esd::module {
+
+class PrivilegeChecker {
+ public:
+  static bool AppHasPrivilege(uid_t uid, const std::string& appid,
+                              const std::string& event_name);
+  static std::string CheckPrivilegeName(const std::string& event_name);
+};
+
+}  // namespace esd::module
+
+#endif  // LIBEVENTSYSTEM_MODULES_GROUP_PRIVILEGE_CHECKER_HH_
diff --git a/modules/group/vconf_event_handler.cc b/modules/group/vconf_event_handler.cc
new file mode 100644 (file)
index 0000000..d40e387
--- /dev/null
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) 2024 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 "vconf_event_handler.hh"
+
+#include <bundle_cpp.h>
+#include <bundle_internal.h>
+#include <eventsystem.h>
+
+#include <memory>
+
+#include "log_private.h"
+
+namespace esd::module {
+
+namespace {
+
+void LocationUseMyLocationCb(keynode_t* node, void* user_data) {
+  auto* ptr = static_cast<VconfEventHandler*>(user_data);
+  ptr->OnLocationUseMyLocation(node);
+}
+
+void LocationEnabledCb(keynode_t* node, void* user_data) {
+  auto* ptr = static_cast<VconfEventHandler*>(user_data);
+  ptr->OnLocationEnabled(node);
+}
+
+void LocationNetworkEnabledCb(keynode_t* node, void* user_data) {
+  auto* ptr = static_cast<VconfEventHandler*>(user_data);
+  ptr->OnLocationNetworkEnabled(node);
+}
+
+void LangsetCb(keynode_t* node, void* user_data) {
+  auto* ptr = static_cast<VconfEventHandler*>(user_data);
+  ptr->OnLangset(node);
+}
+
+void RegionFormatHourCb(keynode_t* node, void* user_data) {
+  auto* ptr = static_cast<VconfEventHandler*>(user_data);
+  ptr->OnRegionFormatHour(node);
+}
+
+void RegionFormatCb(keynode_t* node, void* user_data) {
+  auto* ptr = static_cast<VconfEventHandler*>(user_data);
+  ptr->OnRegionFormat(node);
+}
+
+void VibrationStatusCb(keynode_t* node, void* user_data) {
+  auto* ptr = static_cast<VconfEventHandler*>(user_data);
+  ptr->OnVibrationStatus(node);
+}
+
+void SoundStatusCb(keynode_t* node, void* user_data) {
+  auto* ptr = static_cast<VconfEventHandler*>(user_data);
+  ptr->OnSoundStatus(node);
+}
+
+void AutoRotateCb(keynode_t* node, void* user_data) {
+  auto* ptr = static_cast<VconfEventHandler*>(user_data);
+  ptr->OnAutoRotate(node);
+}
+
+void MobileDataStateCb(keynode_t* node, void* user_data) {
+  auto* ptr = static_cast<VconfEventHandler*>(user_data);
+  ptr->OnMobileDataState(node);
+}
+
+void RoamingStateCb(keynode_t* node, void* user_data) {
+  auto* ptr = static_cast<VconfEventHandler*>(user_data);
+  ptr->OnRoamingState(node);
+}
+
+void FontSetCb(keynode_t* node, void* user_data) {
+  auto* ptr = static_cast<VconfEventHandler*>(user_data);
+  ptr->OnFontSet(node);
+}
+
+}  // namespace
+
+VconfEventHandler::~VconfEventHandler() {
+  if (sender_) UnsetDefaultEvents();
+}
+
+void VconfEventHandler::OnLocationUseMyLocation(keynode_t* node) {
+  _D("OnLocationUseMyLocation called");
+
+  int enabled = 0;
+  int ret = vconf_get_int(VCONFKEY_LOCATION_USE_MY_LOCATION, &enabled);
+  if (ret != VCONF_OK) {
+    /* LCOV_EXCL_START */
+    _E("failed to get vconf (%d)", ret);
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+
+  const char* key = EVT_KEY_LOCATION_ENABLE_STATE;
+  const char* val = nullptr;
+  if (enabled)
+    val = EVT_VAL_LOCATION_ENABLED;
+  else
+    val = EVT_VAL_LOCATION_DISABLED;
+
+  SendSytemEvent(SYS_EVENT_LOCATION_ENABLE_STATE, {{key, val}}, key);
+}
+
+void VconfEventHandler::OnLocationEnabled(keynode_t* node) {
+  _D("OnLocationEnabled called");
+
+  int enabled = 0;
+  int ret = vconf_get_int(VCONFKEY_LOCATION_ENABLED, &enabled);
+  if (ret != VCONF_OK) {
+    /* LCOV_EXCL_START */
+    _E("failed to get vconf (%d)", ret);
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+
+  const char* key = EVT_KEY_GPS_ENABLE_STATE;
+  const char* val = nullptr;
+  if (enabled)
+    val = EVT_VAL_GPS_ENABLED;
+  else
+    val = EVT_VAL_GPS_DISABLED;
+
+  SendSytemEvent(SYS_EVENT_GPS_ENABLE_STATE, {{key, val}}, key);
+}
+
+void VconfEventHandler::OnLocationNetworkEnabled(keynode_t* node) {
+  _D("OnLocationNetworkEnabled called");
+
+  int enabled = 0;
+  int ret = vconf_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED, &enabled);
+  if (ret != VCONF_OK) {
+    /* LCOV_EXCL_START */
+    _E("failed to get vconf (%d)", ret);
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+
+  const char* key = EVT_KEY_NPS_ENABLE_STATE;
+  const char* val = nullptr;
+  if (enabled)
+    val = EVT_VAL_NPS_ENABLED;
+  else
+    val = EVT_VAL_NPS_DISABLED;
+
+  SendSytemEvent(SYS_EVENT_NPS_ENABLE_STATE, {{key, val}}, key);
+}
+
+void VconfEventHandler::OnLangset(keynode_t* node) {
+  _D("OnLangset called");
+
+  char* str_r = vconf_get_str(VCONFKEY_LANGSET);
+  if (str_r == nullptr) {
+    /* LCOV_EXCL_START */
+    _E("failed to get vconf str");
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+  std::string str = str_r;
+  free(str_r);
+
+  std::string key = EVT_KEY_LANGUAGE_SET;
+  SendSytemEvent(SYS_EVENT_LANGUAGE_SET, {{key, std::move(str)}}, key);
+}
+
+void VconfEventHandler::OnRegionFormatHour(keynode_t* node) {
+  _D("OnRegionFormatHour called");
+
+  int hours = 0;
+  int ret = vconf_get_int(VCONFKEY_REGIONFORMAT_TIME1224, &hours);
+  if (ret != VCONF_OK) {
+    /* LCOV_EXCL_START */
+    _E("failed to get vconf (%d)", ret);
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+
+  const char* key = EVT_KEY_HOUR_FORMAT;
+  const char* val = nullptr;
+  if (hours == VCONFKEY_TIME_FORMAT_24)
+    val = EVT_VAL_HOURFORMAT_24;
+  else
+    val = EVT_VAL_HOURFORMAT_12;
+
+  SendSytemEvent(SYS_EVENT_HOUR_FORMAT, {{key, val}}, key);
+}
+
+void VconfEventHandler::OnRegionFormat(keynode_t* node) {
+  _D("OnRegionFormat called");
+
+  char* str_r = vconf_get_str(VCONFKEY_REGIONFORMAT);
+  if (str_r == nullptr) {
+    /* LCOV_EXCL_START */
+    _E("failed to get vconf str");
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+
+  std::string str = str_r;
+  free(str_r);
+  std::string key = EVT_KEY_REGION_FORMAT;
+
+  SendSytemEvent(SYS_EVENT_REGION_FORMAT, {{key, std::move(str)}}, key);
+}
+
+void VconfEventHandler::OnVibrationStatus(keynode_t* node) {
+  int vibration_on = 0;
+  int sound_on = 0;
+  const char* key = nullptr;
+
+  _D("OnVibrationStatus called");
+
+  int ret =
+      vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibration_on);
+  if (ret != VCONF_OK) {
+    /* LCOV_EXCL_START */
+    _E("failed to get vconf (%d)", ret);
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+
+  ret = vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sound_on);
+  if (ret != VCONF_OK) {
+    /* LCOV_EXCL_START */
+    _E("failed to get vconf (%d)", ret);
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+
+  if (vibration_on) {
+    key = EVT_KEY_VIBRATION_STATE;
+    SendSytemEvent(SYS_EVENT_VIBRATION_STATE, {{key, EVT_VAL_VIBRATION_ON}},
+                   key);
+
+    key = EVT_KEY_SILENT_MODE;
+    SendSytemEvent(SYS_EVENT_SILENT_MODE, {{key, EVT_VAL_SILENTMODE_OFF}}, key);
+  } else {
+    key = EVT_KEY_VIBRATION_STATE;
+    SendSytemEvent(SYS_EVENT_VIBRATION_STATE, {{key, EVT_VAL_VIBRATION_OFF}},
+                   key);
+    if (!sound_on) {
+      key = EVT_KEY_SILENT_MODE;
+      SendSytemEvent(SYS_EVENT_SILENT_MODE, {{key, EVT_VAL_SILENTMODE_ON}},
+                     key);
+    }
+  }
+}
+
+void VconfEventHandler::OnSoundStatus(keynode_t* node) {
+  int vibration_on = 0;
+  int sound_on = 0;
+  const char* key = nullptr;
+
+  _D("OnSoundStatus called");
+
+  int ret =
+      vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibration_on);
+  if (ret != VCONF_OK) {
+    /* LCOV_EXCL_START */
+    _E("failed to get vconf (%d)", ret);
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+
+  ret = vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sound_on);
+  if (ret != VCONF_OK) {
+    /* LCOV_EXCL_START */
+    _E("failed to get vconf (%d)", ret);
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+
+  if (sound_on) {
+    key = EVT_KEY_VIBRATION_STATE;
+    SendSytemEvent(SYS_EVENT_VIBRATION_STATE, {{key, EVT_VAL_VIBRATION_OFF}},
+                   key);
+
+    key = EVT_KEY_SILENT_MODE;
+    SendSytemEvent(SYS_EVENT_SILENT_MODE, {{key, EVT_VAL_SILENTMODE_OFF}}, key);
+  } else {
+    if (!vibration_on) {
+      key = EVT_KEY_SILENT_MODE;
+      SendSytemEvent(SYS_EVENT_SILENT_MODE, {{key, EVT_VAL_SILENTMODE_ON}},
+                     key);
+    }
+  }
+}
+
+void VconfEventHandler::OnAutoRotate(keynode_t* node) {
+  _D("OnAutoRotate called");
+
+  int enabled = 0;
+  int ret = vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &enabled);
+  if (ret != VCONF_OK) {
+    /* LCOV_EXCL_START */
+    _E("failed to get vconf (%d)", ret);
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+
+  const char* key = EVT_KEY_SCREEN_AUTOROTATE_STATE;
+  const char* val = nullptr;
+  if (enabled)
+    val = EVT_VAL_SCREEN_AUTOROTATE_ON;
+  else
+    val = EVT_VAL_SCREEN_AUTOROTATE_OFF;
+
+  SendSytemEvent(SYS_EVENT_SCREEN_AUTOROTATE_STATE, {{key, val}}, key);
+}
+
+void VconfEventHandler::OnMobileDataState(keynode_t* node) {
+  _D("OnMobileDataState called");
+
+  int enabled = 0;
+  int ret = vconf_get_bool(VCONFKEY_3G_ENABLE, &enabled);
+  if (ret != VCONF_OK) {
+    /* LCOV_EXCL_START */
+    _E("failed to get vconf (%d)", ret);
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+
+  const char* key = EVT_KEY_MOBILE_DATA_STATE;
+  const char* val = nullptr;
+  if (enabled)
+    val = EVT_VAL_MOBILE_DATA_ON;
+  else
+    val = EVT_VAL_MOBILE_DATA_OFF;
+
+  SendSytemEvent(SYS_EVENT_MOBILE_DATA_STATE, {{key, val}}, key);
+}
+
+void VconfEventHandler::OnRoamingState(keynode_t* node) {
+  _D("OnRoamingState called");
+
+  int enabled = 0;
+  int ret = vconf_get_bool(VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL, &enabled);
+  if (ret != VCONF_OK) {
+    /* LCOV_EXCL_START */
+    _E("failed to get vconf (%d)", ret);
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+
+  const char* key = EVT_KEY_DATA_ROAMING_STATE;
+  const char* val = nullptr;
+  if (enabled)
+    val = EVT_VAL_DATA_ROAMING_ON;
+  else
+    val = EVT_VAL_DATA_ROAMING_OFF;
+
+  SendSytemEvent(SYS_EVENT_DATA_ROAMING_STATE, {{key, val}}, key);
+}
+
+void VconfEventHandler::OnFontSet(keynode_t* node) {
+  _D("OnFontSet called");
+
+  char* str_r = vconf_get_str(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME);
+  if (str_r == nullptr) {
+    /* LCOV_EXCL_START */
+    _E("failed to get vconf str");
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+
+  std::string str = str_r;
+  free(str_r);
+  const char* key = EVT_KEY_FONT_SET;
+
+  SendSytemEvent(SYS_EVENT_FONT_SET, {{key, std::move(str)}}, key);
+}
+
+void VconfEventHandler::SetDefaultEvents(
+    std::function<void(const std::string&, bundle*)> sender) {
+  sender_ = std::move(sender);
+  vconf_notify_key_changed(VCONFKEY_LOCATION_USE_MY_LOCATION,
+                           LocationUseMyLocationCb, this);
+  vconf_notify_key_changed(VCONFKEY_LOCATION_ENABLED, LocationEnabledCb, this);
+  vconf_notify_key_changed(VCONFKEY_LOCATION_NETWORK_ENABLED,
+                           LocationNetworkEnabledCb, this);
+  vconf_notify_key_changed(VCONFKEY_LANGSET, LangsetCb, this);
+  vconf_notify_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, RegionFormatHourCb,
+                           this);
+  vconf_notify_key_changed(VCONFKEY_REGIONFORMAT, RegionFormatCb, this);
+  vconf_notify_key_changed(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL,
+                           VibrationStatusCb, this);
+  vconf_notify_key_changed(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, SoundStatusCb,
+                           this);
+  vconf_notify_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
+                           AutoRotateCb, this);
+  vconf_notify_key_changed(VCONFKEY_3G_ENABLE, MobileDataStateCb, this);
+  vconf_notify_key_changed(VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL,
+                           RoamingStateCb, this);
+  vconf_notify_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, FontSetCb,
+                           this);
+}
+
+void VconfEventHandler::UnsetDefaultEvents() {
+  sender_ = nullptr;
+  vconf_ignore_key_changed(VCONFKEY_LOCATION_USE_MY_LOCATION,
+                           LocationUseMyLocationCb);
+  vconf_ignore_key_changed(VCONFKEY_LOCATION_ENABLED, LocationEnabledCb);
+  vconf_ignore_key_changed(VCONFKEY_LOCATION_NETWORK_ENABLED,
+                           LocationNetworkEnabledCb);
+  vconf_ignore_key_changed(VCONFKEY_LANGSET, LangsetCb);
+  vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, RegionFormatHourCb);
+  vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, RegionFormatCb);
+  vconf_ignore_key_changed(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL,
+                           VibrationStatusCb);
+  vconf_ignore_key_changed(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, SoundStatusCb);
+  vconf_ignore_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
+                           AutoRotateCb);
+  vconf_ignore_key_changed(VCONFKEY_3G_ENABLE, MobileDataStateCb);
+  vconf_ignore_key_changed(VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL,
+                           RoamingStateCb);
+  vconf_ignore_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, FontSetCb);
+  event_table_.clear();
+}
+
+void VconfEventHandler::SendSytemEvent(const std::string& event_name,
+                                       tizen_base::Bundle b,
+                                       const std::string& key) {
+  tizen_base::Bundle data;
+  const auto& it = event_table_.find(event_name);
+  if (it != event_table_.end()) data = it->second;
+
+  if (b == data) {
+    _D("skip send: same with previous data");
+  } else {
+    sender_(event_name, b.GetHandle());
+    event_table_[event_name] = b;
+  }
+}
+
+}  // namespace esd::module
\ No newline at end of file
diff --git a/modules/group/vconf_event_handler.hh b/modules/group/vconf_event_handler.hh
new file mode 100644 (file)
index 0000000..b0026dd
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2024 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 LIBEVENTSYSTEM_MODULES_GROUP_VCONF_EVENT_HANDLER_HH_
+#define LIBEVENTSYSTEM_MODULES_GROUP_VCONF_EVENT_HANDLER_HH_
+
+#include <bundle.h>
+#include <bundle_cpp.h>
+#include <vconf.h>
+
+#include <functional>
+#include <map>
+#include <string>
+
+namespace esd::module {
+
+class VconfEventHandler {
+ public:
+  ~VconfEventHandler();
+
+  void SetDefaultEvents(
+      std::function<void(const std::string&, bundle*)> sender);
+  void UnsetDefaultEvents();
+  void OnLocationUseMyLocation(keynode_t* node);
+  void OnLocationEnabled(keynode_t* node);
+  void OnLocationNetworkEnabled(keynode_t* node);
+  void OnLangset(keynode_t* node);
+  void OnRegionFormatHour(keynode_t* node);
+  void OnRegionFormat(keynode_t* node);
+  void OnVibrationStatus(keynode_t* node);
+  void OnSoundStatus(keynode_t* node);
+  void OnAutoRotate(keynode_t* node);
+  void OnMobileDataState(keynode_t* node);
+  void OnRoamingState(keynode_t* node);
+  void OnFontSet(keynode_t* node);
+
+ private:
+  void SendSytemEvent(const std::string& event_name, tizen_base::Bundle b,
+                      const std::string& key);
+
+ private:
+  std::map<std::string, tizen_base::Bundle> event_table_;
+  std::function<void(const std::string&, bundle*)> sender_;
+};
+
+}  // namespace esd::module
+
+#endif  // LIBEVENTSYSTEM_MODULES_GROUP_VCONF_EVENT_HANDLER_HH_
\ No newline at end of file
diff --git a/packaging/esd-group.socket b/packaging/esd-group.socket
new file mode 100755 (executable)
index 0000000..df534e9
--- /dev/null
@@ -0,0 +1,14 @@
+[Unit]
+Description=ESD Group Socket
+DefaultDependencies=no
+Before=sockets.target
+
+[Socket]
+ListenStream=/run/aul/rpcport/.d::org.tizen.appfw.service.esd::EventSystem
+SocketMode=0666
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+Service=esd.service
+
+[Install]
+WantedBy=sockets.target
index 3e035bf28c88e2c4d3224005367ac5b244a50cf4..810ce9b948c128c439f6dd9ed506affea73b5197 100644 (file)
@@ -5,6 +5,7 @@ Release:    1
 Group:      Application Framework/Libraries
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
+Source1:    esd-group.socket
 BuildRequires:  cmake
 BuildRequires:  pkgconfig(aul)
 BuildRequires:  pkgconfig(bundle)
@@ -14,6 +15,18 @@ BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(capi-base-common)
 BuildRequires:  pkgconfig(gmock)
 BuildRequires:  pkgconfig(pkgmgr-info)
+BuildRequires:  pkgconfig(cert-svc-vcore)
+BuildRequires: pkgconfig(rpc-port)
+BuildRequires: pkgconfig(parcel)
+BuildRequires: pkgconfig(libesd)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(pkgmgr)
+BuildRequires: pkgconfig(libtzplatform-config)
+BuildRequires:  pkgconfig(cynara-client)
+BuildRequires:  pkgconfig(cynara-session)
+BuildRequires:  pkgconfig(security-manager)
+
+%define _moddir %{_datadir}/esd
 
 %if 0%{?gcov:1}
 BuildRequires:  lcov
@@ -46,6 +59,14 @@ Requires:   %{name}
 %description -n %{name}-unittests
 GTest for EventSystem API
 
+%package -n esd-mod-group
+Summary:    ESD module for app events
+Group:      Application Framework/Service
+
+%description -n esd-mod-group
+This module is for app events
+
+
 #################################################
 # eventsystem-benchmark
 #################################################
@@ -87,22 +108,27 @@ export LDFLAGS+=" -lgcov"
 
 MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
 
-%cmake . -DFULLVER=%{version} -DMAJORVER=${MAJORVER}
-
+%cmake . -DFULLVER=%{version} \
+  -DMAJORVER=${MAJORVER} \
+  -DESD_MODULES_DIR=%{_moddir}
 make %{?jobs:-j%jobs}
 
 %check
-export LD_LIBRARY_PATH="../../src"
+export LD_LIBRARY_PATH="../../src:../../modules/group"
 ctest -V
 
 %if 0%{?gcov:1}
 lcov -c --ignore-errors mismatch,graph,unused --no-external -q -d . -o ${name}.info
+lcov -r ${name}.info "/unit_tests/*" -o ${name}.info
 genhtml ${name}.info -o out --legend --show-details
 %endif
 
 %install
 rm -rf %{buildroot}
 %make_install
+mkdir -p %{buildroot}%{_unitdir}/sockets.target.wants
+install -m 0644 %SOURCE1 %{buildroot}%{_unitdir}/esd-group.socket
+ln -sf ../esd.socket %{buildroot}%{_unitdir}/sockets.target.wants/esd-group.socket
 
 %if 0%{?gcov:1}
 builddir=$(basename $PWD)
@@ -160,6 +186,7 @@ install -m 0755 run-unittest.sh %{buildroot}%{_bindir}/tizen-unittests/%{name}/
 #################################################
 %files -n %{name}-unittests
 %{_bindir}/%{name}-unittests
+%{_bindir}/%{name}-integtests
 %{_bindir}/tizen-unittests/%{name}/run-unittest.sh
 
 #################################################
@@ -175,3 +202,11 @@ install -m 0755 run-unittest.sh %{buildroot}%{_bindir}/tizen-unittests/%{name}/
 %files gcov
 %{_datadir}/gcov/obj/*
 %endif
+
+%files -n esd-mod-group
+%manifest %{name}.manifest
+%{_unitdir}/esd-group.socket
+%license LICENSE
+%{_moddir}/mod/libesd-mod-group.so
+%{_unitdir}/sockets.target.wants/esd-group.socket
+
index dbfc9d41aa2084b46d58d1b5a7aec7a2fef18008..1b18e97fd8f59a266feb08963d93997d00b9e075 100644 (file)
@@ -10,6 +10,8 @@ APPLY_PKG_CONFIG(${TARGET_EVENTSYSTEM} PUBLIC
   GLIB_DEPS
   GIO_DEPS
   PKGMGR_INFO_DEPS
+  PARCEL_DEPS
+  RPC_PORT_DEPS
 )
 
 SET_TARGET_PROPERTIES(${TARGET_EVENTSYSTEM} PROPERTIES SOVERSION ${MAJORVER})
diff --git a/src/es.cc b/src/es.cc
new file mode 100644 (file)
index 0000000..ff73dfc
--- /dev/null
+++ b/src/es.cc
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2024 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 <eventsystem.h>
+
+#include "es_proxy.h"
+#include "log_private.h"
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace rpc = rpc_port::es_proxy;
+namespace rpc_proxy = rpc_port::es_proxy::proxy;
+
+namespace {
+
+constexpr const char SYS_EVENT_NAME_PREFIX[] = "tizen.system.event";
+
+std::unique_ptr<rpc_proxy::EventSystem> es_proxy_;
+
+class Event : public rpc_proxy::EventSystem::EventListener {
+ public:
+  Event(eventsystem_cb cb, void* data) : es_cb_(cb), data_(data) {}
+  Event(eventsystem_handler cb, void* data) : es_h(cb), data_(data) {}
+
+  void OnReceived(std::string event_name, const rpc::Bundle& data) override {
+    if (es_cb_) {
+      int len = 0;
+      bundle_raw* raw = nullptr;
+      bundle_encode(data.GetHandle(), &raw, &len);
+      std::unique_ptr<bundle_raw, decltype(free)*> raw_auto(raw, free);
+      es_cb_(event_name.c_str(), raw_auto.get(), len, data_);
+    } else if (es_h) {
+      es_h(event_name.c_str(), data.GetHandle(), data_);
+    }
+  }
+
+ private:
+  eventsystem_cb es_cb_ = nullptr;
+  eventsystem_handler es_h = nullptr;
+  void* data_;
+};
+
+class ESConnection : public rpc_proxy::EventSystem::IEventListener {
+ public:
+  void OnConnected() override { _D("OnConnected"); }
+
+  /* LCOV_EXCL_START */
+  void OnDisconnected() override {
+    es_proxy_.reset();
+    _E("OnDisconnected");
+  }
+
+  void OnRejected() override {
+    es_proxy_.reset();
+    _E("OnRejected");
+  }
+  /* LCOV_EXCL_STOP */
+} connection_listener_;
+
+void Connect() {
+  if (!es_proxy_) {
+    es_proxy_.reset(new rpc_proxy::EventSystem(
+        &connection_listener_, "d::org.tizen.appfw.service.esd"));
+    es_proxy_->Connect(true);
+  }
+}
+
+bool IsReservedEvent(const std::string& event_name) {
+  if (event_name.rfind(RESERVED_NAME_FOR_USER_PKGMGRSIGNAL, 0) == 0 ||
+      event_name == RESERVED_NAME_FOR_SYSTEM_PKGMGRSIGNAL)
+    return true; /* LCOV_EXCL_LINE */
+
+  return false;
+}
+
+int GetEventType(const std::string& event_name) {
+  if (event_name.rfind(SYS_EVENT_NAME_PREFIX, 0) == 0) return ES_TYPE_SYSTEM;
+  if (event_name.rfind(USER_EVENT_NAME_PREFIX, 0) == 0) return ES_TYPE_USER;
+
+  return ES_TYPE_UNKNOWN;
+}
+
+}  // namespace
+
+extern "C" EXPORT_API int eventsystem_send_user_event(const char* event_name,
+                                                      bundle* data,
+                                                      bool is_trusted) {
+  try {
+    ::Connect();
+    if (!es_proxy_->SendUserEvent(event_name, rpc::Bundle(data, false, false),
+                                  is_trusted)) {
+      _E("SendUserEvent() returns false"); /* LCOV_EXCL_LINE */
+      return ES_R_ERROR;
+    }
+  } catch (...) { /* LCOV_EXCL_LINE */
+    /* LCOV_EXCL_START */
+    es_proxy_.reset();
+    return ES_R_ERROR;
+    /* LCOV_EXCL_STOP */
+  }
+
+  return ES_R_OK;
+}
+
+extern "C" EXPORT_API int eventsystem_register_application_event(
+    const char* event_name, unsigned int* reg_id, int* event_type,
+    eventsystem_cb callback, void* user_data) {
+  try {
+    ::Connect();
+    auto ev = std::unique_ptr<rpc_proxy::EventSystem::EventListener>(
+        new Event(callback, user_data));
+    std::string name = event_name;
+    int id = es_proxy_->RegisterEvent(rpc_proxy::EventSystem::EventType::User,
+                                      name, std::move(ev));
+    if (id < 0) {
+      /* LCOV_EXCL_START */
+      _E("RegisterEvent() returns %d", id);
+      return ES_R_ERROR;
+      /* LCOV_EXCL_STOP */
+    }
+
+    if (!::IsReservedEvent(name)) {
+      rpc::Bundle data;
+      if (es_proxy_->GetEarlierData(name, data)) {
+        ::Event ev(callback, user_data);
+        ev.OnReceived(name, data);
+      }
+    }
+
+    *reg_id = id;
+    *event_type = ::GetEventType(name);
+  } catch (...) { /* LCOV_EXCL_LINE */
+    /* LCOV_EXCL_START */
+    es_proxy_.reset();
+    return ES_R_ERROR;
+    /* LCOV_EXCL_STOP */
+  }
+
+  return ES_R_OK;
+}
+
+extern "C" EXPORT_API int eventsystem_unregister_application_event(
+    unsigned int reg_id) {
+  return eventsystem_unregister_event(reg_id);
+}
+
+extern "C" EXPORT_API int eventsystem_application_finalize() {
+  if (!es_proxy_)
+    return 0;
+  es_proxy_->Disconnect();
+  es_proxy_.reset();
+  return 0;
+}
+
+extern "C" EXPORT_API int eventsystem_register_event(
+    const char* event_name, unsigned int* reg_id, eventsystem_handler callback,
+    void* user_data) {
+  try {
+    ::Connect();
+    auto ev = std::unique_ptr<rpc_proxy::EventSystem::EventListener>(
+        new Event(callback, user_data));
+    int id = es_proxy_->RegisterEvent(rpc_proxy::EventSystem::EventType::System,
+                                      event_name, std::move(ev));
+    if (id < 0) {
+      _E("RegisterEvent() returns %d", id); /* LCOV_EXCL_LINE */
+      return ES_R_ERROR;
+    }
+
+    *reg_id = id;
+  } catch (...) { /* LCOV_EXCL_LINE */
+    /* LCOV_EXCL_START */
+    es_proxy_.reset();
+    return ES_R_ERROR;
+    /* LCOV_EXCL_STOP */
+  }
+
+  return ES_R_OK;
+}
+
+extern "C" EXPORT_API int eventsystem_unregister_event(unsigned int reg_id) {
+  try {
+    ::Connect();
+    if (!es_proxy_->UnregisterEvent(reg_id)) {
+      _E("UnregisterEvent() returns false"); /* LCOV_EXCL_LINE */
+      return ES_R_ERROR;
+    }
+
+  } catch (...) { /* LCOV_EXCL_LINE */
+    /* LCOV_EXCL_START */
+    es_proxy_.reset();
+    return ES_R_ERROR;
+    /* LCOV_EXCL_STOP */
+  }
+
+  return ES_R_OK;
+}
+
+extern "C" EXPORT_API int eventsystem_send_system_event(const char* event_name,
+                                                        bundle* data) {
+  try {
+    ::Connect();
+    auto b = rpc::Bundle(data, false, false);
+
+    if (!es_proxy_->SendSystemEvent(event_name,
+                                    rpc::Bundle(data, false, false))) {
+      _E("SendSystemEvent() returns false"); /* LCOV_EXCL_LINE */
+      return ES_R_ERROR;
+    }
+  } catch (...) { /* LCOV_EXCL_LINE */
+    /* LCOV_EXCL_START */
+    es_proxy_.reset();
+    return ES_R_ERROR;
+    /* LCOV_EXCL_STOP */
+  }
+
+  return ES_R_OK;
+}
+
+extern "C" EXPORT_API int eventsystem_request_sending_system_event(
+    const char* event_name, bundle* data) {
+  return eventsystem_send_system_event(event_name, data);
+}
+
+extern "C" EXPORT_API int eventsystem_keep_last_event_data(
+    const char* event_name) {
+  try {
+    ::Connect();
+    if (!es_proxy_->KeepLastEventData(event_name)) {
+      _E("KeepLastEventData() returns false"); /* LCOV_EXCL_LINE */
+      return ES_R_ERROR;
+    }
+  } catch (...) { /* LCOV_EXCL_LINE */
+    /* LCOV_EXCL_START */
+    es_proxy_.reset();
+    return ES_R_ERROR;
+    /* LCOV_EXCL_STOP */
+  }
+
+  return ES_R_OK;
+}
diff --git a/src/es_proxy.cc b/src/es_proxy.cc
new file mode 100644 (file)
index 0000000..a73b0b5
--- /dev/null
@@ -0,0 +1,1004 @@
+/*
+ * Copyright (c) 2024 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 "es_proxy.h"
+
+#include <assert.h>
+#include <aul.h>
+#include <dlfcn.h>
+#include <dlog.h>
+#include <glib.h>
+#include <libgen.h>
+#include <rpc-port-parcel-internal.h>
+#include <rpc-port-parcel.h>
+#include <rpc-port.h>
+#include <unistd.h>
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <set>
+#include <stdexcept>
+#include <string>
+#include <unordered_map>
+#include <utility>
+
+#undef LOG_TAG
+#define LOG_TAG "RPC_PORT_PROXY"
+
+#undef _E
+#define _E LOGE
+
+#undef _W
+#define _W LOGW
+
+#undef _I
+#define _I LOGI
+
+#undef _D
+#define _D LOGD
+
+#undef EXPORT_API
+#define EXPORT_API extern "C" __attribute__((visibility("default")))
+
+namespace {
+
+constexpr int APPID_MAX = 1024;
+std::atomic<unsigned int> seq_{0};
+std::string appid_;
+
+const std::string& GetAppId() {
+  if (appid_.empty()) {
+    static char id_buf[APPID_MAX] = {
+        0,
+    };
+    int ret = aul_app_get_appid_bypid(getpid(), id_buf, sizeof(id_buf));
+    if (ret < 0) {
+      _E("Failed to get app id");
+      return appid_;
+    }
+
+    appid_ = id_buf;
+  }
+
+  return appid_;
+}
+
+rpc_port_parcel_h Clone(rpc_port_parcel_h parcel) {
+  void* raw = nullptr;
+  unsigned int size = 0;
+  if (rpc_port_parcel_get_raw(parcel, &raw, &size) != RPC_PORT_ERROR_NONE) {
+    _E("Failed to get raw");
+    return nullptr;
+  }
+
+  rpc_port_parcel_h handle = nullptr;
+  rpc_port_parcel_create_from_raw_without_header(&handle, raw, size);
+  return handle;
+}
+
+}  // namespace
+
+namespace rpc_port {
+namespace es_proxy {
+
+LocalExecution::LocalExecution(std::string port_name,
+                               LocalExecution::IEvent* listener)
+    : port_name_(std::move(port_name)),
+      listener_(listener),
+      context_(g_main_context_ref_thread_default(), g_main_context_unref) {
+  instance_ = GetAppId() + "::" + std::to_string(seq_++);
+}
+
+LocalExecution::~LocalExecution() {
+  while (!result_queue_.empty()) {
+    auto parcel = result_queue_.front();
+    result_queue_.pop();
+    rpc_port_parcel_destroy(parcel);
+  }
+
+  while (!request_queue_.empty()) {
+    auto parcel = request_queue_.front();
+    request_queue_.pop();
+    rpc_port_parcel_destroy(parcel);
+  }
+}
+
+int LocalExecution::Connect(bool sync) {
+  std::lock_guard<std::recursive_mutex> lock(mutex_);
+  if (connecting_) {
+    _E("Already connecting");
+    return RPC_PORT_ERROR_INVALID_PARAMETER;
+  }
+
+  if (connected_) {
+    _E("Already connected");
+    return RPC_PORT_ERROR_INVALID_PARAMETER;
+  }
+
+  if (connect_func_) {
+    int ret = connect_func_(this, GetAppId().c_str(), instance_.c_str(), sync);
+    if (ret != RPC_PORT_ERROR_NONE) return ret;
+  }
+
+  connecting_ = true;
+  return RPC_PORT_ERROR_NONE;
+}
+
+void LocalExecution::Disconnect() {
+  std::lock_guard<std::recursive_mutex> lock(mutex_);
+  connecting_ = false;
+  if (disconnect_func_)
+    disconnect_func_(this, GetAppId().c_str(), instance_.c_str());
+}
+
+int LocalExecution::Send(rpc_port_parcel_h request, rpc_port_parcel_h* result) {
+  if (send_func_) {
+    int ret = send_func_(this, request);
+    if (result != nullptr) {
+      int count = 0;
+      while (ResultQueueEmpty() && count++ < 100) usleep(100 * 1000);
+
+      if (ResultQueueEmpty()) {
+        _E("Failed to get result from server");
+        return RPC_PORT_ERROR_IO_ERROR;
+      }
+      *result = ResultQueuePop();
+    }
+
+    return ret;
+  }
+
+  return RPC_PORT_ERROR_NONE;
+}
+
+void LocalExecution::OnConnected() {
+  std::lock_guard<std::recursive_mutex> lock(mutex_);
+  connecting_ = false;
+  connected_ = true;
+  if (listener_ != nullptr) listener_->OnLocalConnected();
+}
+
+void LocalExecution::OnDisconnected() {
+  std::lock_guard<std::recursive_mutex> lock(mutex_);
+  connecting_ = false;
+  connected_ = false;
+  if (listener_ != nullptr) listener_->OnLocalDisconnected();
+}
+
+void LocalExecution::OnReceived(rpc_port_parcel_h parcel) {
+  if (listener_ != nullptr) listener_->OnLocalReceived(parcel);
+}
+
+bool LocalExecution::LoadSymbols() {
+  if (loaded_) return true;
+
+  if (connect_func_ == nullptr) {
+    std::string symbol =
+        "rpc_port_stub_eventsystem_lem_" + port_name_ + "_connect";
+    connect_func_ =
+        reinterpret_cast<StubConnectFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+    if (connect_func_ == nullptr) {
+      _E("Failed to find symbol(%s)", symbol.c_str()); /* LCOV_EXCL_LINE */
+      return false; /* LCOV_EXCL_LINE */
+    }
+  }
+
+  if (disconnect_func_ == nullptr) {
+    std::string symbol =
+        "rpc_port_stub_eventsystem_lem_" + port_name_ + "_disconnect";
+    disconnect_func_ = reinterpret_cast<StubDisconnectFunc>(
+        dlsym(RTLD_DEFAULT, symbol.c_str()));
+    if (disconnect_func_ == nullptr) {
+      _E("Failed to find symbol(%s)", symbol.c_str()); /* LCOV_EXCL_LINE */
+      return false; /* LCOV_EXCL_LINE */
+    }
+  }
+
+  if (send_func_ == nullptr) {
+    std::string symbol =
+        "rpc_port_stub_eventsystem_lem_" + port_name_ + "_send";
+    send_func_ =
+        reinterpret_cast<StubSendFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+    if (send_func_ == nullptr) {
+      _E("Failed to find symbol(%s)", symbol.c_str()); /* LCOV_EXCL_LINE */
+      return false; /* LCOV_EXCL_LINE */
+    }
+  }
+
+  loaded_ = true;
+  return true;
+}
+
+void LocalExecution::ResultQueuePush(rpc_port_parcel_h parcel) {
+  std::lock_guard<std::recursive_mutex> lock(mutex_);
+  result_queue_.push(parcel);
+}
+
+rpc_port_parcel_h LocalExecution::ResultQueuePop() {
+  std::lock_guard<std::recursive_mutex> lock(mutex_);
+  auto parcel = result_queue_.front();
+  result_queue_.pop();
+  return parcel;
+}
+
+bool LocalExecution::ResultQueueEmpty() const {
+  std::lock_guard<std::recursive_mutex> lock(mutex_);
+  return result_queue_.empty();
+}
+
+void LocalExecution::RequestQueuePush(rpc_port_parcel_h parcel) {
+  std::lock_guard<std::recursive_mutex> lock(mutex_);
+  request_queue_.push(parcel);
+}
+
+rpc_port_parcel_h LocalExecution::RequestQueuePop() {
+  std::lock_guard<std::recursive_mutex> lock(mutex_);
+  auto parcel = request_queue_.front();
+  request_queue_.pop();
+  return parcel;
+}
+
+GMainContext* LocalExecution::GetContext() const { return context_.get(); }
+
+Bundle::Bundle() {
+  handle_ = bundle_create();
+  if (handle_ == nullptr) throw new std::bad_alloc();
+}
+
+Bundle::Bundle(bundle* handle, bool copy, bool own)
+    : handle_(handle), own_(own) {
+  if (handle == nullptr) throw new std::invalid_argument("handle is nullptr");
+
+  if (copy) {
+    handle_ = bundle_dup(handle);
+    if (handle_ == nullptr) throw new std::bad_alloc();
+  }
+}
+
+Bundle::~Bundle() {
+  if (own_ && handle_) bundle_free(handle_);
+}
+
+Bundle::Bundle(Bundle&& b) noexcept {
+  handle_ = b.handle_;
+  b.handle_ = bundle_create();
+  own_ = b.own_;
+  b.own_ = true;
+}
+
+Bundle& Bundle::operator=(Bundle&& b) noexcept {
+  if (this != &b) {
+    if (handle_ && own_) bundle_free(handle_);
+
+    handle_ = b.handle_;
+    b.handle_ = bundle_create();
+    own_ = b.own_;
+  }
+
+  return *this;
+}
+
+bundle* Bundle::GetHandle() const { return handle_; }
+
+namespace proxy {
+
+std::atomic<int> EventSystem::CallbackBase::seq_num_{0};
+
+EventSystem::CallbackBase::CallbackBase(int delegate_id, bool once)
+    : id_(delegate_id), once_(once) {
+  seq_id_ = seq_num_++;
+}
+
+int EventSystem::CallbackBase::GetId() const { return id_; }
+
+int EventSystem::CallbackBase::GetSeqId() const { return seq_id_; }
+
+bool EventSystem::CallbackBase::IsOnce() const { return once_; }
+
+rpc_port_parcel_h operator<<(rpc_port_parcel_h h,
+                             const EventSystem::CallbackBase& cb) {
+  rpc_port_parcel_write_int32(h, cb.id_);
+  rpc_port_parcel_write_int32(h, cb.seq_id_);
+  rpc_port_parcel_write_bool(h, cb.once_);
+
+  return h;
+}
+
+EventSystem::EventListener::EventListener(bool once)
+    : CallbackBase(static_cast<int>(DelegateId::EventListener), once) {}
+
+void EventSystem::EventListener::OnReceivedEvent(rpc_port_parcel_h parcel) {
+  char* param1_raw = nullptr;
+  rpc_port_parcel_read_string(parcel, &param1_raw);
+  std::string param1(param1_raw);
+  free(param1_raw);
+
+  bundle* param2_raw = nullptr;
+  rpc_port_parcel_read_bundle(parcel, &param2_raw);
+  Bundle param2(param2_raw, false, true);
+
+  OnReceived(std::move(param1), std::move(param2));
+}
+
+EventSystem::EventSystem(EventSystem::IEventListener* listener,
+                         std::string target_appid)
+    : listener_(listener), target_appid_(std::move(target_appid)) {
+  _W("EventSystem ctor");
+  int ret = rpc_port_proxy_create(&proxy_);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    /* LCOV_EXCL_START */
+    _E("Failed to create proxy. error(%d)", ret);
+    throw InvalidIOException();
+    /* LCOV_EXCL_STOP */
+  }
+
+  rpc_port_proxy_add_connected_event_cb(proxy_, OnConnectedCb, this);
+  rpc_port_proxy_add_disconnected_event_cb(proxy_, OnDisconnectedCb, this);
+  rpc_port_proxy_add_rejected_event_cb(proxy_, OnRejectedCb, this);
+  rpc_port_proxy_add_received_event_cb(proxy_, OnReceivedCb, this);
+
+  if (GetAppId() == target_appid_) {
+    local_execution_ = std::make_unique<LocalExecution>("EventSystem", this);
+    local_execution_->LoadSymbols();
+  }
+}
+
+EventSystem::~EventSystem() {
+  _W("EventSystem dtor");
+  if (proxy_ != nullptr) rpc_port_proxy_destroy(proxy_);
+}
+
+void EventSystem::Connect(bool sync) {
+  int ret;
+  if (local_execution_.get() != nullptr && local_execution_->LoadSymbols()) {
+    ret = local_execution_->Connect(sync);
+  } else {
+    if (sync)
+      ret = rpc_port_proxy_connect_sync(proxy_, target_appid_.c_str(),
+                                        "EventSystem");
+    else
+      ret =
+          rpc_port_proxy_connect(proxy_, target_appid_.c_str(), "EventSystem");
+  }
+
+  if (ret != RPC_PORT_ERROR_NONE) {
+    /* LCOV_EXCL_START */
+    _E("Failed to connect to EventSystem. error(%d)", ret);
+    switch (ret) {
+      case RPC_PORT_ERROR_INVALID_PARAMETER: {
+        throw InvalidIDException();
+      }
+      case RPC_PORT_ERROR_IO_ERROR: {
+        throw InvalidIOException();
+      }
+      case RPC_PORT_ERROR_PERMISSION_DENIED: {
+        throw PermissionDeniedException();
+      }
+    }
+    /* LCOV_EXCL_STOP */
+  }
+}
+
+void EventSystem::Disconnect() {
+  if (local_execution_.get() != nullptr && local_execution_->IsConnected()) {
+    local_execution_->Disconnect();
+    return;
+  }
+
+  int ret = rpc_port_disconnect(port_);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    /* LCOV_EXCL_START */
+    _E("Failed to disconnect from EventSystem. error(%d)", ret);
+    throw InvalidIDException();
+    /* LCOV_EXCL_STOP */
+  }
+}
+
+int EventSystem::RegisterEvent(EventSystem::EventType type,
+                               std::string event_name,
+                               std::unique_ptr<EventListener> cb) {
+  if (port_ == nullptr &&
+      (local_execution_.get() == nullptr || !local_execution_->IsConnected())) {
+    /* LCOV_EXCL_START */
+    _E("Not connected");
+    throw NotConnectedSocketException();
+    /* LCOV_EXCL_STOP */
+  }
+
+  rpc_port_parcel_h parcel_;
+  rpc_port_parcel_create_without_header(&parcel_);
+
+  rpc_port_parcel_write_int32(parcel_,
+                              static_cast<int>(MethodId::RegisterEvent));
+  rpc_port_parcel_write_int32(parcel_, static_cast<int>(type));
+  rpc_port_parcel_write_string(parcel_, event_name.c_str());
+  parcel_ << *cb;
+
+  std::lock_guard<std::recursive_mutex> lock(mutex_);
+  delegate_list_.push_back(std::move(cb));
+
+  int ret_;
+  rpc_port_parcel_h result_parcel_ = nullptr;
+  if (local_execution_.get() != nullptr && local_execution_->IsConnected())
+    ret_ = local_execution_->Send(parcel_, &result_parcel_);
+  else
+    ret_ = rpc_port_parcel_send(parcel_, port_);
+
+  rpc_port_parcel_destroy(parcel_);
+  if (ret_ != RPC_PORT_ERROR_NONE) {
+    /* LCOV_EXCL_START */
+    _E("Failed to send parcel. error(%d)", ret_);
+    throw InvalidIOException();
+    /* LCOV_EXCL_STOP */
+  }
+
+  int ret;
+  rpc_port_parcel_h parcel_received = nullptr;
+  if (!result_parcel_) {
+    // Receive
+    ConsumeCommand(&parcel_received, port_);
+    if (parcel_received == nullptr) {
+      /* LCOV_EXCL_START */
+      _E("Invalid protocol");
+      throw InvalidProtocolException();
+      /* LCOV_EXCL_STOP */
+    }
+  } else {
+    parcel_received = result_parcel_;
+    int cmd = -1;
+    rpc_port_parcel_read_int32(parcel_received, &cmd);
+    if (cmd != static_cast<int>(MethodId::__Result)) {
+      /* LCOV_EXCL_START */
+      _E("Invalid protocol");
+      return -1;
+      /* LCOV_EXCL_STOP */
+    }
+  }
+
+  rpc_port_parcel_read_int32(parcel_received, &ret);
+  rpc_port_parcel_destroy(parcel_received);
+
+  return ret;
+}
+
+bool EventSystem::UnregisterEvent(int id) {
+  if (port_ == nullptr &&
+      (local_execution_.get() == nullptr || !local_execution_->IsConnected())) {
+    /* LCOV_EXCL_START */
+    _E("Not connected");
+    throw NotConnectedSocketException();
+    /* LCOV_EXCL_STOP */
+  }
+
+  rpc_port_parcel_h parcel_;
+  rpc_port_parcel_create_without_header(&parcel_);
+  rpc_port_parcel_write_int32(parcel_,
+                              static_cast<int>(MethodId::UnregisterEvent));
+  rpc_port_parcel_write_int32(parcel_, id);
+
+  std::lock_guard<std::recursive_mutex> lock(mutex_);
+  int ret_;
+  rpc_port_parcel_h result_parcel_ = nullptr;
+  if (local_execution_.get() != nullptr && local_execution_->IsConnected())
+    ret_ = local_execution_->Send(parcel_, &result_parcel_);
+  else
+    ret_ = rpc_port_parcel_send(parcel_, port_);
+
+  rpc_port_parcel_destroy(parcel_);
+  if (ret_ != RPC_PORT_ERROR_NONE) {
+    /* LCOV_EXCL_START */
+    _E("Failed to send parcel. error(%d)", ret_);
+    throw InvalidIOException();
+    /* LCOV_EXCL_STOP */
+  }
+
+  bool ret;
+  rpc_port_parcel_h parcel_received = nullptr;
+  if (!result_parcel_) {
+    // Receive
+    ConsumeCommand(&parcel_received, port_);
+    if (parcel_received == nullptr) {
+      /* LCOV_EXCL_START */
+      _E("Invalid protocol");
+      throw InvalidProtocolException();
+      /* LCOV_EXCL_STOP */
+    }
+  } else {
+    parcel_received = result_parcel_;
+    int cmd = -1;
+    rpc_port_parcel_read_int32(parcel_received, &cmd);
+    if (cmd != static_cast<int>(MethodId::__Result)) {
+      /* LCOV_EXCL_START */
+      _E("Invalid protocol");
+      return false;
+      /* LCOV_EXCL_STOP */
+    }
+  }
+
+  rpc_port_parcel_read_bool(parcel_received, &ret);
+  rpc_port_parcel_destroy(parcel_received);
+
+  return ret;
+}
+
+bool EventSystem::SendUserEvent(std::string event_name, Bundle data,
+                                bool is_trusted) {
+  if (port_ == nullptr &&
+      (local_execution_.get() == nullptr || !local_execution_->IsConnected())) {
+    /* LCOV_EXCL_START */
+    _E("Not connected");
+    throw NotConnectedSocketException();
+    /* LCOV_EXCL_STOP */
+  }
+
+  rpc_port_parcel_h parcel_;
+  rpc_port_parcel_create_without_header(&parcel_);
+  rpc_port_parcel_write_int32(parcel_,
+                              static_cast<int>(MethodId::SendUserEvent));
+  rpc_port_parcel_write_string(parcel_, event_name.c_str());
+  rpc_port_parcel_write_bundle(parcel_, data.GetHandle());
+  rpc_port_parcel_write_bool(parcel_, is_trusted);
+
+  std::lock_guard<std::recursive_mutex> lock(mutex_);
+
+  int ret_;
+  rpc_port_parcel_h result_parcel_ = nullptr;
+  if (local_execution_.get() != nullptr && local_execution_->IsConnected())
+    ret_ = local_execution_->Send(parcel_, &result_parcel_);
+  else
+    ret_ = rpc_port_parcel_send(parcel_, port_);
+
+  rpc_port_parcel_destroy(parcel_);
+  if (ret_ != RPC_PORT_ERROR_NONE) {
+    /* LCOV_EXCL_START */
+    _E("Failed to send parcel. error(%d)", ret_);
+    throw InvalidIOException();
+    /* LCOV_EXCL_STOP */
+  }
+
+  bool ret;
+  rpc_port_parcel_h parcel_received = nullptr;
+  if (!result_parcel_) {
+    // Receive
+    ConsumeCommand(&parcel_received, port_);
+    if (parcel_received == nullptr) {
+      /* LCOV_EXCL_START */
+      _E("Invalid protocol");
+      throw InvalidProtocolException();
+      /* LCOV_EXCL_STOP */
+    }
+  } else {
+    parcel_received = result_parcel_;
+    int cmd = -1;
+    rpc_port_parcel_read_int32(parcel_received, &cmd);
+    if (cmd != static_cast<int>(MethodId::__Result)) {
+      /* LCOV_EXCL_START */
+      _E("Invalid protocol");
+      return false;
+      /* LCOV_EXCL_STOP */
+    }
+  }
+
+  rpc_port_parcel_read_bool(parcel_received, &ret);
+  rpc_port_parcel_destroy(parcel_received);
+
+  return ret;
+}
+
+bool EventSystem::SendSystemEvent(std::string event_name, Bundle data) {
+  if (port_ == nullptr &&
+      (local_execution_.get() == nullptr || !local_execution_->IsConnected())) {
+    /* LCOV_EXCL_START */
+    _E("Not connected");
+    throw NotConnectedSocketException();
+    /* LCOV_EXCL_STOP */
+  }
+
+  rpc_port_parcel_h parcel_;
+  rpc_port_parcel_create_without_header(&parcel_);
+
+  rpc_port_parcel_write_int32(parcel_,
+                              static_cast<int>(MethodId::SendSystemEvent));
+  rpc_port_parcel_write_string(parcel_, event_name.c_str());
+  rpc_port_parcel_write_bundle(parcel_, data.GetHandle());
+
+  std::lock_guard<std::recursive_mutex> lock(mutex_);
+
+  int ret_;
+  rpc_port_parcel_h result_parcel_ = nullptr;
+  if (local_execution_.get() != nullptr && local_execution_->IsConnected()) {
+    ret_ = local_execution_->Send(parcel_, &result_parcel_);
+
+  } else
+    ret_ = rpc_port_parcel_send(parcel_, port_);
+
+  rpc_port_parcel_destroy(parcel_);
+  if (ret_ != RPC_PORT_ERROR_NONE) {
+    /* LCOV_EXCL_START */
+    _E("Failed to send parcel. error(%d)", ret_);
+    throw InvalidIOException();
+    /* LCOV_EXCL_STOP */
+  }
+
+  bool ret;
+  rpc_port_parcel_h parcel_received = nullptr;
+  if (!result_parcel_) {
+    // Receive
+    ConsumeCommand(&parcel_received, port_);
+    if (parcel_received == nullptr) {
+      /* LCOV_EXCL_START */
+      _E("Invalid protocol");
+      throw InvalidProtocolException();
+      /* LCOV_EXCL_STOP */
+    }
+  } else {
+    parcel_received = result_parcel_;
+    int cmd = -1;
+    rpc_port_parcel_read_int32(parcel_received, &cmd);
+    if (cmd != static_cast<int>(MethodId::__Result)) {
+      /* LCOV_EXCL_START */
+      _E("Invalid protocol");
+      return false;
+      /* LCOV_EXCL_STOP */
+    }
+  }
+
+  rpc_port_parcel_read_bool(parcel_received, &ret);
+  rpc_port_parcel_destroy(parcel_received);
+
+  return ret;
+}
+
+bool EventSystem::KeepLastEventData(std::string event_name) {
+  if (port_ == nullptr &&
+      (local_execution_.get() == nullptr || !local_execution_->IsConnected())) {
+    /* LCOV_EXCL_START */
+    _E("Not connected");
+    throw NotConnectedSocketException();
+    /* LCOV_EXCL_STOP */
+  }
+
+  rpc_port_parcel_h parcel_;
+  rpc_port_parcel_create_without_header(&parcel_);
+  rpc_port_parcel_write_int32(parcel_,
+                              static_cast<int>(MethodId::KeepLastEventData));
+  rpc_port_parcel_write_string(parcel_, event_name.c_str());
+
+  std::lock_guard<std::recursive_mutex> lock(mutex_);
+  int ret_;
+  rpc_port_parcel_h result_parcel_ = nullptr;
+  if (local_execution_.get() != nullptr && local_execution_->IsConnected())
+    ret_ = local_execution_->Send(parcel_, &result_parcel_);
+  else
+    ret_ = rpc_port_parcel_send(parcel_, port_);
+
+  rpc_port_parcel_destroy(parcel_);
+  if (ret_ != RPC_PORT_ERROR_NONE) {
+    /* LCOV_EXCL_START */
+    _E("Failed to send parcel. error(%d)", ret_);
+    throw InvalidIOException();
+    /* LCOV_EXCL_STOP */
+  }
+
+  bool ret;
+  rpc_port_parcel_h parcel_received = nullptr;
+  if (!result_parcel_) {
+    // Receive
+    ConsumeCommand(&parcel_received, port_);
+    if (parcel_received == nullptr) {
+      /* LCOV_EXCL_START */
+      _E("Invalid protocol");
+      throw InvalidProtocolException();
+      /* LCOV_EXCL_STOP */
+    }
+  } else {
+    parcel_received = result_parcel_;
+    int cmd = -1;
+    rpc_port_parcel_read_int32(parcel_received, &cmd);
+    if (cmd != static_cast<int>(MethodId::__Result)) {
+      /* LCOV_EXCL_START */
+      _E("Invalid protocol");
+      return false;
+      /* LCOV_EXCL_STOP */
+    }
+  }
+
+  rpc_port_parcel_read_bool(parcel_received, &ret);
+  rpc_port_parcel_destroy(parcel_received);
+
+  return ret;
+}
+
+bool EventSystem::GetEarlierData(std::string event_name, Bundle& data) {
+  if (port_ == nullptr &&
+      (local_execution_.get() == nullptr || !local_execution_->IsConnected())) {
+    /* LCOV_EXCL_START */
+    _E("Not connected");
+    throw NotConnectedSocketException();
+    /* LCOV_EXCL_STOP */
+  }
+
+  rpc_port_parcel_h parcel_;
+  rpc_port_parcel_create_without_header(&parcel_);
+  rpc_port_parcel_write_int32(parcel_,
+                              static_cast<int>(MethodId::GetEarlierData));
+  rpc_port_parcel_write_string(parcel_, event_name.c_str());
+
+  std::lock_guard<std::recursive_mutex> lock(mutex_);
+  int ret_;
+  rpc_port_parcel_h result_parcel_ = nullptr;
+  if (local_execution_.get() != nullptr && local_execution_->IsConnected())
+    ret_ = local_execution_->Send(parcel_, &result_parcel_);
+  else
+    ret_ = rpc_port_parcel_send(parcel_, port_);
+
+  rpc_port_parcel_destroy(parcel_);
+  if (ret_ != RPC_PORT_ERROR_NONE) {
+    /* LCOV_EXCL_START */
+    _E("Failed to send parcel. error(%d)", ret_);
+    throw InvalidIOException();
+    /* LCOV_EXCL_STOP */
+  }
+
+  bool ret;
+  rpc_port_parcel_h parcel_received = nullptr;
+  if (!result_parcel_) {
+    // Receive
+    ConsumeCommand(&parcel_received, port_);
+    if (parcel_received == nullptr) {
+      /* LCOV_EXCL_START */
+      _E("Invalid protocol");
+      throw InvalidProtocolException();
+      /* LCOV_EXCL_STOP */
+    }
+  } else {
+    parcel_received = result_parcel_;
+    int cmd = -1;
+    rpc_port_parcel_read_int32(parcel_received, &cmd);
+    if (cmd != static_cast<int>(MethodId::__Result)) {
+      /* LCOV_EXCL_START */
+      _E("Invalid protocol");
+      return false;
+      /* LCOV_EXCL_STOP */
+    }
+  }
+
+  bundle* data_raw = nullptr;
+  rpc_port_parcel_read_bundle(parcel_received, &data_raw);
+  data = Bundle(data_raw, false, true);
+  rpc_port_parcel_read_bool(parcel_received, &ret);
+  rpc_port_parcel_destroy(parcel_received);
+
+  return ret;
+}
+
+void EventSystem::OnLocalConnected() {
+  if (listener_) listener_->OnConnected();
+}
+
+void EventSystem::OnLocalDisconnected() {
+  if (listener_) listener_->OnDisconnected();
+}
+
+void EventSystem::OnLocalReceived(rpc_port_parcel_h parcel) {
+  int cmd = -1;
+  rpc_port_parcel_read_int32(parcel, &cmd);
+  if (cmd != static_cast<int>(MethodId::__Callback)) {
+    return;
+  }
+  ProcessReceivedEvent(parcel);
+}
+
+void EventSystem::ProcessReceivedEvent(rpc_port_parcel_h parcel) {
+  int id = 0;
+  int seq_id = 0;
+  bool once = false;
+
+  rpc_port_parcel_read_int32(parcel, &id);
+  rpc_port_parcel_read_int32(parcel, &seq_id);
+  rpc_port_parcel_read_bool(parcel, &once);
+
+  for (auto& i : delegate_list_) {
+    if (i->GetId() == id && i->GetSeqId() == seq_id) {
+      i->OnReceivedEvent(parcel);
+
+      if (i->IsOnce()) delegate_list_.remove(i);
+      break;
+    }
+  }
+}
+
+void EventSystem::ConsumeCommand(rpc_port_parcel_h* parcel, rpc_port_h port) {
+  do {
+    rpc_port_parcel_h p;
+    int ret = rpc_port_parcel_create_from_port_without_header(&p, port);
+    int cmd;
+
+    if (ret != 0) break;
+    rpc_port_parcel_read_int32(p, &cmd);
+    if (cmd == static_cast<int>(MethodId::__Result)) {
+      *parcel = p;
+      return;
+    }
+
+    rpc_port_parcel_destroy(p);
+    *parcel = nullptr;
+  } while (true);
+  *parcel = nullptr;
+}
+
+void EventSystem::OnConnectedCb(const char* endpoint, const char* port_name,
+                                rpc_port_h port, void* user_data) {
+  auto* handle = static_cast<EventSystem*>(user_data);
+  handle->port_ = port;
+  rpc_port_h cb_port = nullptr;
+  rpc_port_proxy_get_port(handle->proxy_, RPC_PORT_PORT_CALLBACK, &cb_port);
+  handle->callback_port_ = cb_port;
+  if (handle->listener_) handle->listener_->OnConnected();
+}
+
+void EventSystem::OnDisconnectedCb(const char* endpoint, const char* port_name,
+                                   void* user_data) {
+  auto* handle = static_cast<EventSystem*>(user_data);
+  handle->delegate_list_.clear();
+  if (handle->listener_) handle->listener_->OnDisconnected();
+}
+
+void EventSystem::OnRejectedCb(const char* endpoint, const char* port_name,
+                               void* user_data) {
+  auto* handle = static_cast<EventSystem*>(user_data);
+  if (handle->listener_) handle->listener_->OnRejected();
+}
+
+void EventSystem::OnReceivedCb(const char* endpoint, const char* port_name,
+                               void* user_data) {
+  EventSystem* l = static_cast<EventSystem*>(user_data);
+  int cmd;
+  rpc_port_parcel_h parcel_received;
+
+  if (rpc_port_parcel_create_from_port_without_header(&parcel_received,
+                                                      l->callback_port_) != 0) {
+    /* LCOV_EXCL_START */
+    _E("Failed to create parcel from port");
+    return;
+    /* LCOV_EXCL_STOP */
+  }
+
+  rpc_port_parcel_read_int32(parcel_received, &cmd);
+  if (cmd != static_cast<int>(MethodId::__Callback)) {
+    rpc_port_parcel_destroy(parcel_received);
+    return;
+  }
+
+  l->ProcessReceivedEvent(parcel_received);
+  rpc_port_parcel_destroy(parcel_received);
+}
+
+}  // namespace proxy
+}  // namespace es_proxy
+}  // namespace rpc_port
+
+EXPORT_API int rpc_port_proxy_eventsystem_lem_EventSystem_connect(void* h,
+                                                                  bool sync) {
+  auto* handle = static_cast<rpc_port::es_proxy::LocalExecution*>(h);
+  if (sync) {
+    handle->OnConnected();
+    return RPC_PORT_ERROR_NONE;
+  }
+
+  /* LCOV_EXCL_START */
+  auto* ptr = new std::weak_ptr<rpc_port::es_proxy::LocalExecution>(
+      handle->shared_from_this());
+  auto* source = g_idle_source_new();
+  if (source == nullptr) {
+    _E("Failed to create idle source");
+    delete ptr;
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  }
+
+  g_source_set_callback(
+      source, static_cast<GSourceFunc>([](gpointer user_data) {
+        auto* wp =
+            static_cast<std::weak_ptr<rpc_port::es_proxy::LocalExecution>*>(
+                user_data);
+        auto p = wp->lock();
+        if (p != nullptr) p->OnConnected();
+
+        delete wp;
+        return G_SOURCE_REMOVE;
+      }),
+      ptr, nullptr);
+  g_source_attach(source, handle->GetContext());
+  g_source_unref(source);
+  return RPC_PORT_ERROR_NONE;
+  /* LCOV_EXCL_STOP */
+}
+
+EXPORT_API int rpc_port_proxy_eventsystem_lem_EventSystem_disconnect(void* h) {
+  auto* handle = static_cast<rpc_port::es_proxy::LocalExecution*>(h);
+  auto* ptr = new std::weak_ptr<rpc_port::es_proxy::LocalExecution>(
+      handle->shared_from_this());
+  auto* source = g_idle_source_new();
+  if (source == nullptr) {
+    /* LCOV_EXCL_START */
+    _E("Failed to create idle source");
+    delete ptr;
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+    /* LCOV_EXCL_STOP */
+  }
+
+  g_source_set_callback(
+      source, static_cast<GSourceFunc>([](gpointer user_data) {
+        auto* wp =
+            static_cast<std::weak_ptr<rpc_port::es_proxy::LocalExecution>*>(
+                user_data);
+        auto p = wp->lock();
+        if (p != nullptr) p->OnDisconnected();
+
+        delete wp;
+        return G_SOURCE_REMOVE;
+      }),
+      ptr, nullptr);
+  g_source_attach(source, handle->GetContext());
+  g_source_unref(source);
+  return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_proxy_eventsystem_lem_EventSystem_invoke_callback(
+    void* h, rpc_port_parcel_h parcel) {
+  auto* handle = static_cast<rpc_port::es_proxy::LocalExecution*>(h);
+  auto* ptr = new std::weak_ptr<rpc_port::es_proxy::LocalExecution>(
+      handle->shared_from_this());
+  rpc_port_parcel_h cloned_parcel = ::Clone(parcel);
+  handle->RequestQueuePush(cloned_parcel);
+  auto* source = g_idle_source_new();
+  if (source == nullptr) {
+    /* LCOV_EXCL_START */
+    _E("Failed to create idle source");
+    delete ptr;
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+    /* LCOV_EXCL_END */
+  }
+
+  g_source_set_callback(
+      source, static_cast<GSourceFunc>([](gpointer user_data) {
+        auto* wp =
+            static_cast<std::weak_ptr<rpc_port::es_proxy::LocalExecution>*>(
+                user_data);
+        auto p = wp->lock();
+        if (p != nullptr) {
+          rpc_port_parcel_h request = p->RequestQueuePop();
+          p->OnReceived(request);
+          rpc_port_parcel_destroy(request);
+        }
+
+        delete wp;
+        return G_SOURCE_REMOVE;
+      }),
+      ptr, nullptr);
+  g_source_attach(source, handle->GetContext());
+  g_source_unref(source);
+  return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_proxy_eventsystem_lem_EventSystem_send_result(
+    void* h, rpc_port_parcel_h parcel) {
+  auto* handle = static_cast<rpc_port::es_proxy::LocalExecution*>(h);
+  rpc_port_parcel_h cloned_parcel = ::Clone(parcel);
+  handle->ResultQueuePush(cloned_parcel);
+  return RPC_PORT_ERROR_NONE;
+}
diff --git a/src/es_proxy.h b/src/es_proxy.h
new file mode 100644 (file)
index 0000000..172d5ce
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2024 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.
+ */
+
+#pragma once
+
+#include <bundle.h>
+#include <glib.h>
+#include <rpc-port-parcel.h>
+#include <rpc-port.h>
+
+#include <atomic>
+#include <functional>
+#include <list>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <queue>
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+namespace rpc_port {
+namespace es_proxy {
+
+class LocalExecution : public std::enable_shared_from_this<LocalExecution> {
+ public:
+  class IEvent {
+   public:
+    virtual ~IEvent() = default;
+    virtual void OnLocalConnected() = 0;
+    virtual void OnLocalDisconnected() = 0;
+    virtual void OnLocalReceived(rpc_port_parcel_h parcel) = 0;
+  };
+
+  LocalExecution(std::string port_name, IEvent* listener);
+  virtual ~LocalExecution();
+
+  int Connect(bool sync);
+  void Disconnect();
+  int Send(rpc_port_parcel_h request, rpc_port_parcel_h* result);
+
+  bool IsConnected() const { return connected_; }
+
+  void OnConnected();
+  void OnDisconnected();
+  void OnReceived(rpc_port_parcel_h parcel);
+
+  bool LoadSymbols();
+
+  void ResultQueuePush(rpc_port_parcel_h parcel);
+  rpc_port_parcel_h ResultQueuePop();
+  bool ResultQueueEmpty() const;
+
+  void RequestQueuePush(rpc_port_parcel_h parcel);
+  rpc_port_parcel_h RequestQueuePop();
+  GMainContext* GetContext() const;
+
+ private:
+  using StubConnectFunc = int (*)(void*, const char*, const char*, bool);
+  using StubDisconnectFunc = void (*)(void*, const char*, const char*);
+  using StubSendFunc = int (*)(void*, rpc_port_parcel_h);
+
+ private:
+  std::string port_name_;
+  IEvent* listener_;
+  std::string instance_;
+  bool connected_ = false;
+  bool connecting_ = false;
+  bool loaded_ = false;
+  StubConnectFunc connect_func_ = nullptr;
+  StubDisconnectFunc disconnect_func_ = nullptr;
+  StubSendFunc send_func_ = nullptr;
+  std::queue<rpc_port_parcel_h> result_queue_;
+  std::queue<rpc_port_parcel_h> request_queue_;
+  mutable std::recursive_mutex mutex_;
+  std::unique_ptr<GMainContext, decltype(g_main_context_unref)*> context_;
+};
+
+class Bundle final {
+ public:
+  Bundle();
+  explicit Bundle(bundle* handle, bool copy = true, bool own = true);
+  ~Bundle();
+
+  Bundle(const Bundle& b) = delete;
+  Bundle& operator=(const Bundle&) = delete;
+
+  Bundle(Bundle&& b) noexcept;
+  Bundle& operator=(Bundle&&) noexcept;
+
+  bundle* GetHandle() const;
+
+ private:
+  bundle* handle_;
+  bool own_ = true;
+};
+
+namespace proxy {
+
+class Exception {};
+class NotConnectedSocketException : public Exception {};
+class InvalidProtocolException : public Exception {};
+class InvalidIOException : public Exception {};
+class PermissionDeniedException : public Exception {};
+class InvalidIDException : public Exception {};
+class InvalidArgumentException : public Exception {};
+class OutOfMemoryException : public Exception {};
+
+class EventSystem : public LocalExecution::IEvent {
+ public:
+  enum class EventType : int {
+    User = 0,
+    System,
+  };
+
+  class CallbackBase {
+   public:
+    CallbackBase() = default;
+    CallbackBase(int delegate_id, bool once);
+    virtual ~CallbackBase() = default;
+
+    virtual void OnReceivedEvent(rpc_port_parcel_h port) = 0;
+    int GetId() const;
+    int GetSeqId() const;
+    bool IsOnce() const;
+
+   private:
+    friend rpc_port_parcel_h operator<<(rpc_port_parcel_h h,
+                                        const CallbackBase& cb);
+    friend rpc_port_parcel_h operator>>(rpc_port_parcel_h h, CallbackBase& cb);
+
+    static std::atomic<int> seq_num_;
+    int id_ = 0;
+    int seq_id_ = 0;
+    bool once_ = false;
+  };
+
+  class EventListener : public CallbackBase {
+   public:
+    EventListener(bool once = false);
+    virtual void OnReceived(std::string event_name, const Bundle& data) = 0;
+
+   private:
+    void OnReceivedEvent(rpc_port_parcel_h port) override;
+  };
+
+  class IEventListener {
+   public:
+    /// <summary>
+    /// This method will be invoked when the client app is connected to the
+    /// servicece app.
+    /// </summary>
+    virtual void OnConnected() = 0;
+
+    /// <summary>
+    /// This method will be invoked after the client app was disconnected from
+    /// the servicece app.
+    /// </summary>
+    virtual void OnDisconnected() = 0;
+
+    /// <summary>
+    /// This method will be invoked when the service app rejects the client app.
+    /// </summary>
+    virtual void OnRejected() = 0;
+  };
+
+  /// <summary>
+  /// Constructor for this class
+  /// </summary>
+  /// <param name="listener">The listener for events</param>
+  /// <param name="target_appid">The service app ID to connect</param>
+  EventSystem(IEventListener* listener, std::string target_appid);
+
+  /// <summary>
+  /// Destructor for this class
+  /// </summary>
+  virtual ~EventSystem();
+
+  /// <summary>
+  /// Connects to the service app.
+  /// </summary>
+  /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+  /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+  //  <param name="sync">if true, connects to the service app
+  //  synchornously</param>
+  /// <exception cref="InvalidIDException">
+  /// Thrown when the appid to connect is invalid.
+  /// </exception>
+  /// <exception cref="InvalidIOException">
+  /// Thrown when internal I/O error happen.
+  /// </exception>
+  /// <exception cref="PermissionDeniedException">
+  /// Thrown when the permission is denied.
+  /// </exception>
+  /// <remark> If you want to use this method, you must add privileges.</remark>
+  void Connect(bool sync = false);
+
+  /// <summary>
+  /// Disconnects from the service app.
+  /// </summary>
+  /// <exception cref="InvalidIDException">
+  /// Thrown when the stub port is invalid.
+  /// </exception>
+  void Disconnect();
+
+  int RegisterEvent(EventSystem::EventType type, std::string event_name,
+                    std::unique_ptr<EventListener> cb);
+
+  bool UnregisterEvent(int id);
+
+  bool SendUserEvent(std::string event_name, Bundle data, bool is_trusted);
+
+  bool SendSystemEvent(std::string event_name, Bundle data);
+
+  bool KeepLastEventData(std::string event_name);
+
+  bool GetEarlierData(std::string event_name, Bundle& data);
+
+ private:
+  enum class MethodId : int {
+    __Result = 0,
+    __Callback = 1,
+    RegisterEvent = 2,
+    UnregisterEvent = 3,
+    SendUserEvent = 4,
+    SendSystemEvent = 5,
+    KeepLastEventData = 6,
+    GetEarlierData = 7,
+  };
+
+  enum class DelegateId : int {
+    EventListener = 1,
+  };
+
+  void ProcessReceivedEvent(rpc_port_parcel_h parcel);
+  void ConsumeCommand(rpc_port_parcel_h* parcel, rpc_port_h port);
+  static void OnConnectedCb(const char* endpoint, const char* port_name,
+                            rpc_port_h port, void* user_data);
+  static void OnDisconnectedCb(const char* endpoint, const char* port_name,
+                               void* user_data);
+  static void OnRejectedCb(const char* endpoint, const char* port_name,
+                           void* user_data);
+  static void OnReceivedCb(const char* endpoint, const char* port_name,
+                           void* user_data);
+
+  void OnLocalConnected() override;
+  void OnLocalDisconnected() override;
+  void OnLocalReceived(rpc_port_parcel_h parcel) override;
+
+ private:
+  rpc_port_h port_ = nullptr;
+  rpc_port_h callback_port_ = nullptr;
+  rpc_port_proxy_h proxy_ = nullptr;
+  IEventListener* listener_ = nullptr;
+  std::recursive_mutex mutex_;
+  std::list<std::unique_ptr<CallbackBase>> delegate_list_;
+  std::string target_appid_;
+  std::shared_ptr<LocalExecution> local_execution_;
+};
+
+}  // namespace proxy
+}  // namespace es_proxy
+}  // namespace rpc_port
diff --git a/src/eventsystem.c b/src/eventsystem.c
deleted file mode 100644 (file)
index fbbc172..0000000
+++ /dev/null
@@ -1,2379 +0,0 @@
-/**
- * event system low-level API
- */
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <dlog.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <glib.h>
-#include <gio/gio.h>
-#include <eventsystem.h>
-#include <fcntl.h>
-#include <aul.h>
-
-#include "eventsystem.h"
-#include "eventsystem_internal.h"
-#include "eventsystem_private.h"
-
-#undef LOG_TAG
-#define LOG_TAG "eventsystem"
-
-#define SYS_EVENT_NAME_PREFIX "tizen.system.event"
-#define EVENT_SYSTEM_PREFIX "eventsystem.id_"
-#define EVENT_SYSTEM_PREFIX_LEN 15
-#define EVENT_SYSTEM_MEMBER "eventsystem"
-#define VALID_COUNT_OF_EVENTNAME_TOKEN 3
-#define VALID_LAST_COUNT_FOR_EVENTNAME (VALID_COUNT_OF_EVENTNAME_TOKEN + 1)
-#define MAX_COUNT_FOR_EVENTNAME_CHECK (VALID_LAST_COUNT_FOR_EVENTNAME + 1)
-
-#define REGULAR_USER 5000
-
-#define FREE_AND_NULL(ptr) do { \
-       if (ptr) { \
-               free((void *)ptr); \
-               ptr = NULL; \
-       } \
-} while (0)
-
-#define _E(fmt, arg...) LOGE(fmt, ##arg)
-#define _D(fmt, arg...) LOGD(fmt, ##arg)
-#define _W(fmt, arg...) LOGW(fmt, ##arg)
-#define _I(fmt, arg...) LOGI(fmt, ##arg)
-
-#define retvm_if(expr, val, fmt, arg...) do { \
-       if (expr) { \
-               _E(fmt, ##arg); \
-               _E("(%s) -> %s() return", #expr, __func__); \
-               return val; \
-       } \
-} while (0)
-
-#define retv_if(expr, val) do { \
-       if (expr) { \
-               _E("(%s) -> %s() return", #expr, __func__); \
-               return val; \
-       } \
-} while (0)
-
-#define tryvm_if(expr, val, fmt, arg...) do { \
-        if (expr) { \
-               _E("(%s) "fmt, #expr, ##arg); \
-               val; \
-               goto catch; \
-       } \
-} while (0)
-
-pthread_mutex_t send_sync_lock = PTHREAD_MUTEX_INITIALIZER;
-
-static GList *system_event_list;
-static int _initialized;
-static GHashTable *check_tbl;
-static GHashTable *filter_tbl;
-static GHashTable *last_data_tbl;
-
-struct last_data_item {
-       char *event_name;
-       GVariant *param;
-       GVariant *trusted_param;
-};
-
-typedef struct eventmap {
-       char *event_name;
-       char *interface_name;
-       char *member_name;
-       guint reg_id;
-       GBusType bus_type;
-       int event_type;
-       union {
-               eventsystem_cb es_cb;
-               eventsystem_handler ep_cb;
-       };
-       void *user_data;
-} eventmap_s;
-
-typedef struct eventinfo {
-       char *event_name;
-       char *destination_name;
-       char *interface_name;
-       char *object_path;
-       char *member_name;
-       bool is_user_event;
-       bool is_trusted;
-       bundle *event_data;
-} eventinfo_s;
-
-typedef struct sysevent_info {
-       guint owner_id;
-       guint owner_id_session;
-       char *own_name_system_bus;
-       char *own_name_session_bus;
-} sysevent_info_s;
-static sysevent_info_s s_info;
-
-static int __eventsystem_check_user_send_validation(const char *event_name);
-static int __eventsystem_request_destination_list(const char *event_name, GList **dest_list);
-static int __eventsystem_check_sender_validation(int sender_pid, uid_t sender_uid,
-               const char *event_name, char **sender);
-static eventmap_s *__create_eventmap(const char *interface_name,
-               const char *member_name, const char *event_name,
-               int event_type, eventsystem_cb callback, void *user_data);
-static void __destroy_eventmap(gpointer data);
-static int __eventsystem_launch_on_event_for_userevent(const char *event_name,
-               bundle *data, gboolean trusted);
-
-static GRecMutex __rec_mutex;
-static GDBusConnection *__conn_system;
-static GDBusConnection *__conn_session;
-
-EVENTSYSTEM_CTOR static void __eventsystem_init(void)
-{
-       g_rec_mutex_init(&__rec_mutex);
-}
-
-EVENTSYSTEM_DTOR static void __eventsystem_fini(void)
-{
-       g_rec_mutex_clear(&__rec_mutex);
-
-       if (__conn_system) {
-               g_object_unref(__conn_system);
-               __conn_system = NULL;
-       }
-
-       if (__conn_session) {
-               g_object_unref(__conn_session);
-               __conn_session = NULL;
-       }
-}
-
-static GDBusConnection *__get_system_connection(void)
-{
-       GError *error = NULL;
-
-       g_rec_mutex_lock(&__rec_mutex);
-       if (__conn_system) {
-               g_rec_mutex_unlock(&__rec_mutex);
-               return __conn_system;
-       }
-
-       __conn_system = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
-       if (!__conn_system) {
-               _E("g_bus_get_sync() is failed. error=%s", error ? error->message : "");
-               g_clear_error(&error);
-               g_rec_mutex_unlock(&__rec_mutex);
-               return NULL;
-       }
-
-       g_rec_mutex_unlock(&__rec_mutex);
-       return __conn_system;
-}
-
-static GDBusConnection *__get_session_connection(void)
-{
-       GError *error = NULL;
-
-       g_rec_mutex_lock(&__rec_mutex);
-       if (__conn_session) {
-               g_rec_mutex_unlock(&__rec_mutex);
-               return __conn_session;
-       }
-
-       __conn_session = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
-       if (!__conn_session) {
-               _E("g_bus_get_sync() is failed. error=%s", error ? error->message : "");
-               g_clear_error(&error);
-               g_rec_mutex_unlock(&__rec_mutex);
-               return NULL;
-       }
-
-       g_rec_mutex_unlock(&__rec_mutex);
-       return __conn_session;
-}
-
-static int __event_compare_reg_id_cb(gconstpointer a, gconstpointer b)
-{
-       eventmap_s *key1 = (eventmap_s *)a;
-       eventmap_s *key2 = (eventmap_s *)b;
-       return !(key1->reg_id == key2->reg_id);
-}
-
-static void __initialize(void)
-{
-#if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
-       g_type_init();
-#endif
-
-       _initialized = 1;
-}
-
-static int __eventsystem_get_sender_pid(GDBusConnection *conn, const char *sender_name)
-{
-       GDBusMessage *msg = NULL;
-       GDBusMessage *reply = NULL;
-       GError *err = NULL;
-       GVariant *body;
-       int pid = 0;
-
-       msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
-               "org.freedesktop.DBus", "GetConnectionUnixProcessID");
-       if (!msg) {
-               _E("Can't allocate 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(conn, msg,
-               G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
-
-       if (!reply) {
-               if (err != NULL) {
-                       _E("Failed to get pid [%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;
-}
-
-static uid_t __eventsystem_get_sender_uid(GDBusConnection *conn, const char *sender_name)
-{
-       GDBusMessage *msg = NULL;
-       GDBusMessage *reply = NULL;
-       GError *err = NULL;
-       GVariant *body;
-       uid_t uid = -1;
-
-       msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
-               "org.freedesktop.DBus", "GetConnectionUnixUser");
-       if (!msg) {
-               _E("Can't allocate 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(conn, msg,
-               G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
-
-       if (!reply) {
-               if (err != NULL) {
-                       _E("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;
-}
-
-static char *__get_object_path(char *interface_name)
-{
-       int i;
-       char *object_path = (char *)calloc(strlen(interface_name), sizeof(char) + 2);
-
-       if (object_path == NULL) {
-               _E("failed to allocate memory");
-               return NULL;
-       }
-
-       object_path[0] = '/';
-
-       for (i = 0; interface_name[i]; i++) {
-               if (interface_name[i] == '.')
-                       object_path[i + 1] = '/';
-               else
-                       object_path[i + 1] = interface_name[i];
-       }
-
-       return object_path;
-}
-
-static char *__get_encoded_interface_name(char *interface_name)
-{
-       char *evtid = NULL;
-       int evtid_len = 0;
-       gchar *encoded_value;
-
-       encoded_value = g_compute_checksum_for_string(G_CHECKSUM_MD5,
-               interface_name, strlen(interface_name));
-       if (encoded_value == NULL) {
-               _E("g_compute_checksum_for_string failed");
-               return NULL;
-       }
-
-       evtid_len = EVENT_SYSTEM_PREFIX_LEN + strlen(encoded_value) + 1;
-
-       evtid = (char *)calloc(evtid_len, sizeof(char));
-       if (evtid == NULL) {
-               _E("memory alloc failed");
-               g_free(encoded_value);
-               return NULL;
-       }
-
-       snprintf(evtid, evtid_len, "%s%s", EVENT_SYSTEM_PREFIX, (char *)encoded_value);
-
-       g_free(encoded_value);
-
-       return evtid;
-}
-
-static char *__get_member_name_from_eventname(char *event_name)
-{
-       char *ptr = NULL;
-       char *ptr_last = NULL;
-       char *temp_name = NULL;
-       char *member_name = NULL;
-       char *save_ptr = NULL;
-       int count = 0;
-
-       temp_name = strdup(event_name);
-       if (temp_name == NULL) {
-               _E("out of memory");
-               return NULL;
-       }
-
-       ptr = strtok_r(temp_name, ".", &save_ptr);
-       if (ptr == NULL) {
-               _E("invalid event_name(%s), count(%d)", event_name, count);
-               FREE_AND_NULL(temp_name);
-               return NULL;
-       }
-       count++;
-
-       while (count < MAX_COUNT_FOR_EVENTNAME_CHECK) {
-               ptr = strtok_r(NULL, ".", &save_ptr);
-               if (ptr == NULL)
-                       break;
-               /* _D("(%d)ptr(%s)(%d)", count, ptr, strlen(ptr)); */
-               ptr_last = ptr;
-               count++;
-       }
-
-       if (count != VALID_LAST_COUNT_FOR_EVENTNAME) {
-               _E("invalid event_name(%s), count(%d)", event_name, count);
-               FREE_AND_NULL(temp_name);
-               return NULL;
-       }
-
-       if (ptr_last) {
-               /* _D("new member_name(%s)(%d)", ptr_last, strlen(ptr_last)); */
-               member_name = strdup(ptr_last);
-               if (!member_name) {
-                       _E("out_of_memory");
-                       FREE_AND_NULL(temp_name);
-                       return NULL;
-               }
-       } else {
-               _E("ptr_last is NULL");
-               FREE_AND_NULL(temp_name);
-               return NULL;
-       }
-
-       _D("member_name(%s)", member_name);
-
-       FREE_AND_NULL(temp_name);
-       return member_name;
-}
-
-static int __check_validation_usrevent_sender(int sender_pid, uid_t sender_uid,
-               const char *interface_name, const char *event_name)
-{
-       char *sender_id = NULL;
-       char *key = NULL;
-       char *val = NULL;
-
-       if (__eventsystem_check_sender_validation(sender_pid, sender_uid,
-               event_name, &sender_id) < 0) {
-               _E("invalid user-event sender");
-               return ES_R_EINVAL;
-       }
-
-       if (sender_id == NULL) {
-               _E("sender_id is null");
-               return ES_R_EINVAL;
-       }
-
-       key = strdup(interface_name);
-       if (key == NULL) {
-               _E("out of memory");
-               free(sender_id);
-               return ES_R_ENOMEM;
-       }
-
-       val = strdup(sender_id);
-       if (val == NULL) {
-               _E("out of memory");
-               free(key);
-               free(sender_id);
-               return ES_R_ENOMEM;
-       }
-
-       g_hash_table_insert(filter_tbl, key, val);
-       free(sender_id);
-
-       return ES_R_OK;
-}
-
-static int __check_validation_user_defined_name(const char *event_name)
-{
-       char *event_id = NULL;
-       char *key = NULL;
-       int ret = 1;
-
-       if (check_tbl == NULL)
-               check_tbl = g_hash_table_new(g_str_hash, g_str_equal);
-
-       event_id = (char *)g_hash_table_lookup(check_tbl, event_name);
-       if (event_id == NULL) {
-               if (__eventsystem_check_user_send_validation(event_name) < 0) {
-                       _E("invalid user-event name");
-                       ret = 0;
-               } else {
-                       key = strdup(event_name);
-                       if (key == NULL) {
-                               _E("out_of_memory");
-                               ret = 0;
-                       } else {
-                               g_hash_table_insert(check_tbl, key, key);
-                       }
-               }
-       }
-
-       return ret;
-}
-
-static bool __is_pkgmgr_signal_user_event(const char *event_name)
-{
-       int reserved_name_len = strlen(RESERVED_NAME_FOR_USER_PKGMGRSIGNAL);
-
-       if (strncmp(event_name, RESERVED_NAME_FOR_USER_PKGMGRSIGNAL, reserved_name_len) == 0)
-               return true;
-
-       return false;
-}
-
-static bool __is_pkgmgr_signal_system_event(const char *event_name)
-{
-       return (strcmp(event_name, RESERVED_NAME_FOR_SYSTEM_PKGMGRSIGNAL) == 0);
-}
-
-static int __check_interface_validation_user(char *interface_name)
-{
-       int len = strlen(EVENT_SYSTEM_PREFIX);
-
-       if (strncmp(interface_name, EVENT_SYSTEM_PREFIX, len) != 0)
-               return 0;
-
-       return 1;
-}
-
-static int __check_eventname_validation_user(char *event_name)
-{
-       int len = strlen(USER_EVENT_NAME_PREFIX);
-
-       if (strncmp(event_name, USER_EVENT_NAME_PREFIX, len) != 0)
-               return 0;
-
-       return 1;
-}
-
-static int __check_eventname_validation_system(char *event_name)
-{
-       int len = strlen(SYS_EVENT_NAME_PREFIX);
-
-       if (strncmp(event_name, SYS_EVENT_NAME_PREFIX, len) != 0)
-               return 0;
-
-       return 1;
-}
-
-static int __get_gdbus_shared_connection(GDBusConnection **connection, GBusType bus_type,
-               eventsystem_event_type event_type)
-{
-       guint owner_id = 0;
-       gchar *guid = NULL;
-       char own_name[128] = {0, };
-       GDBusConnection *conn_system = NULL;
-
-       if (!_initialized)
-               __initialize();
-
-       if (bus_type == G_BUS_TYPE_SYSTEM)
-               *connection = __get_system_connection();
-       else
-               *connection = __get_session_connection();
-
-       if (*connection == NULL)
-               return ES_R_ERROR;
-
-       if (((bus_type == G_BUS_TYPE_SYSTEM && !s_info.owner_id) ||
-               (bus_type == G_BUS_TYPE_SESSION && !s_info.owner_id_session))) {
-               guid = g_dbus_generate_guid();
-               if (guid == NULL) {
-                       _E("failed to get guid");
-                       return ES_R_ERROR;
-               }
-               snprintf(own_name, 128, "%s.%s.id%s_%d_%d", "event.busname",
-                       (bus_type == G_BUS_TYPE_SESSION ? "session" : "system"),
-                       guid, getuid(), getpid());
-               g_free(guid);
-
-               _D("bus_name is [%s]", own_name);
-               owner_id = g_bus_own_name_on_connection(*connection, own_name,
-                       G_BUS_NAME_OWNER_FLAGS_NONE,
-                       NULL, NULL, NULL, NULL);
-               if (!owner_id) {
-                       _E("g_bus_own_name_on_connection, error");
-                       return ES_R_ERROR;
-               }
-
-               if (bus_type == G_BUS_TYPE_SESSION && event_type == ES_TYPE_USER) {
-                       /* set same name on system-bus */
-                       conn_system = __get_system_connection();
-                       if (conn_system == NULL) {
-                               _E("failed to get system connection");
-                               return ES_R_ERROR;
-                       }
-
-                       owner_id = g_bus_own_name_on_connection(conn_system,
-                                       own_name, G_BUS_NAME_OWNER_FLAGS_NONE,
-                                       NULL, NULL, NULL, NULL);
-                       if (!owner_id) {
-                               _E("g_bus_own_name_on_connection(for system), error");
-                               return ES_R_ERROR;
-                       }
-               }
-
-               if (bus_type == G_BUS_TYPE_SESSION) {
-                       s_info.owner_id_session = owner_id;
-                       s_info.own_name_session_bus = strdup(own_name);
-                       if (s_info.own_name_session_bus == NULL) {
-                               _E("out of memory");
-                               return ES_R_ERROR;
-                       }
-               } else {
-                       s_info.owner_id = owner_id;
-                       s_info.own_name_system_bus = strdup(own_name);
-                       if (s_info.own_name_system_bus == NULL) {
-                               _E("out of memory");
-                               return ES_R_ERROR;
-                       }
-               }
-       }
-
-       return ES_R_OK;
-}
-
-static void __eventsystem_event_handler(GDBusConnection *connection,
-               const gchar *sender_name, const gchar *object_path,
-               const gchar *interface_name, const gchar *signal_name,
-               GVariant *parameters, gpointer user_data)
-{
-       int len;
-       eventmap_s *em = (eventmap_s *)user_data;
-       GList *cb_list = NULL;
-       bundle *buf = NULL;
-       bundle_raw *raw = NULL;
-
-       if (!em) {
-               _E("Critical error!");
-               return;
-       }
-
-       _D("sender_name(%s), interface_name(%s), signal_name(%s)",
-               sender_name, interface_name, signal_name);
-
-       cb_list = g_list_find(system_event_list, em);
-       if (cb_list == NULL)
-               return;
-
-       g_variant_get(parameters, "(us)", &len, &raw);
-
-       buf = bundle_decode((bundle_raw *)raw, len);
-
-       if (em->ep_cb)
-               em->ep_cb(em->event_name, buf, em->user_data);
-
-       bundle_free_encoded_rawdata(&raw);
-       bundle_free(buf);
-}
-
-static void __eventsystem_application_event_handler(int sender_pid,
-               uid_t sender_uid, const gchar *interface_name, const gchar *signal_name,
-               GVariant *parameters, gpointer user_data)
-{
-       GList *cb_list;
-       eventmap_s *em = (eventmap_s *)user_data;
-       bundle_raw *raw = NULL;
-       int len;
-
-       if (!em) {
-               _E("Critical error!");
-               return;
-       }
-
-       cb_list = g_list_find(system_event_list, em);
-       if (cb_list == NULL) {
-               _E("not interested event");
-               return;
-       }
-
-       if (sender_pid > 0 && sender_uid > 0 &&
-                       __check_interface_validation_user((char *)interface_name)) {
-               if (__check_validation_usrevent_sender(sender_pid, sender_uid,
-                       (const char *)interface_name, em->event_name) < 0) {
-                       _E("invalid sender");
-                       return;
-               }
-       }
-
-       g_variant_get(parameters, "(us)", &len, &raw);
-       if (em->es_cb)
-               em->es_cb(em->event_name, raw, len, em->user_data);
-
-       bundle_free_encoded_rawdata(&raw);
-}
-
-/**
- * application-use filter for user-event
- */
-static void __eventsystem_filter_userevent_for_application(GDBusConnection *connection,
-               const gchar *sender_name, const gchar *object_path,
-               const gchar *interface_name, const gchar *signal_name,
-               GVariant *parameters, gpointer user_data)
-{
-       char *sender_id = NULL;
-       int sender_pid = -1;
-       uid_t sender_uid = -1;
-
-       _D("sender_name(%s), interface_name(%s)", sender_name, interface_name);
-
-       g_rec_mutex_lock(&__rec_mutex);
-
-       if (filter_tbl == NULL)
-               filter_tbl = g_hash_table_new(g_str_hash, g_str_equal);
-
-       sender_id = (char *)g_hash_table_lookup(filter_tbl, interface_name);
-       if (sender_id == NULL) {
-               sender_pid = __eventsystem_get_sender_pid(connection, sender_name);
-               if (sender_pid <= 0) {
-                       _E("failed to get pid of sender(%s)", sender_name);
-                       g_rec_mutex_unlock(&__rec_mutex);
-                       return;
-               }
-
-               sender_uid = __eventsystem_get_sender_uid(connection, sender_name);
-               if (sender_uid <= 0) {
-                       _E("failed to get uid of sender(%s)", sender_name);
-                       g_rec_mutex_unlock(&__rec_mutex);
-                       return;
-               }
-               _D("sender_pid(%d), sender_uid(%d)", sender_pid, sender_uid);
-       }
-
-       __eventsystem_application_event_handler(sender_pid, sender_uid, interface_name,
-               signal_name, parameters, user_data);
-
-       g_rec_mutex_unlock(&__rec_mutex);
-}
-
-/**
- * application-use filter for system-event
- */
-static void __eventsystem_filter_sysevent_for_application(GDBusConnection *connection,
-               const gchar *sender_name, const gchar *object_path,
-               const gchar *interface_name, const gchar *signal_name,
-               GVariant *parameters, gpointer user_data)
-{
-       _D("sender_name(%s), interface_name(%s)", sender_name, interface_name);
-
-       g_rec_mutex_lock(&__rec_mutex);
-
-       __eventsystem_application_event_handler(-1, -1, interface_name,
-               signal_name, parameters, user_data);
-
-       g_rec_mutex_unlock(&__rec_mutex);
-}
-
-/**
- * internal-use filter for user-event
- */
-static void __eventsystem_filter_userevent_for_internal(GDBusConnection *connection,
-               const gchar *sender_name, const gchar *object_path,
-               const gchar *interface_name, const gchar *signal_name,
-               GVariant *parameters, gpointer user_data)
-{
-       _D("sender_name(%s), interface_name(%s), signal_name(%s)",
-               sender_name, interface_name, signal_name);
-
-       g_rec_mutex_lock(&__rec_mutex);
-
-       __eventsystem_event_handler(connection, sender_name,
-               object_path, interface_name, signal_name, parameters, user_data);
-
-       g_rec_mutex_unlock(&__rec_mutex);
-}
-
-/**
- * internal-use filter for system-event
- */
-static void __eventsystem_filter_sysevent_for_internal(GDBusConnection *connection,
-               const gchar *sender_name, const gchar *object_path,
-               const gchar *interface_name, const gchar *signal_name,
-               GVariant *parameters, gpointer user_data)
-{
-       _D("sender_name(%s), interface_name(%s), signal_name(%s)",
-               sender_name, interface_name, signal_name);
-
-       g_rec_mutex_lock(&__rec_mutex);
-
-       __eventsystem_event_handler(connection, sender_name,
-               object_path, interface_name, signal_name, parameters, user_data);
-
-       g_rec_mutex_unlock(&__rec_mutex);
-}
-
-static int __eventsystem_register_event_internal(const char *event_name,
-               eventmap_s **em_s, void *user_data)
-{
-       eventmap_s *em;
-       char *interface_name;
-       char *object_path;
-       char *member_name;
-       GDBusSignalCallback filter;
-       GBusType bus_type;
-       guint subscription_id = 0;
-       int ret = 0;
-       int evt_type = ES_TYPE_UNKNOWN;
-       GDBusConnection *conn = NULL;
-
-       if (__check_eventname_validation_system((char *)event_name)) {
-               evt_type = ES_TYPE_SYSTEM;
-       } else if (__check_eventname_validation_user((char *)event_name)) {
-               evt_type = ES_TYPE_USER;
-       } else {
-               evt_type = ES_TYPE_UNKNOWN;
-               _E("unknown type event(%s)", event_name);
-               return ES_R_EINVAL;
-       }
-
-       if (evt_type == ES_TYPE_SYSTEM) {
-               interface_name = strdup(SYS_EVENT_NAME_PREFIX);
-               if (interface_name == NULL) {
-                       _E("out of memory");
-                       return ES_R_ENOMEM;
-               }
-
-               member_name = __get_member_name_from_eventname((char *)event_name);
-               if (member_name == NULL) {
-                       _E("invalid member_name");
-                       ret = ES_R_ERROR;
-                       goto out_2;
-               }
-
-               if (!g_dbus_is_member_name(member_name)) {
-                       _E("invalid member name");
-                       ret = ES_R_EINVAL;
-                       goto out_3;
-               }
-               filter = __eventsystem_filter_sysevent_for_internal;
-       } else {
-               interface_name = __get_encoded_interface_name((char *)event_name);
-               if (!interface_name) {
-                       _E("interface_name is NULL");
-                       return ES_R_ERROR;
-               }
-               if (!g_dbus_is_interface_name(interface_name)) {
-                       _E("invalid interface_name(%s)", interface_name);
-                       ret = ES_R_EINVAL;
-                       goto out_2;
-               }
-               member_name = strdup(EVENT_SYSTEM_MEMBER);
-               if (!member_name) {
-                       _E("out_of_memory");
-                       ret = ES_R_ERROR;
-                       goto out_2;
-               }
-               filter = __eventsystem_filter_userevent_for_internal;
-       }
-
-       object_path = __get_object_path(interface_name);
-       if (!object_path) {
-               _E("object_path is NULL");
-               ret = ES_R_ERROR;
-               goto out_3;
-       }
-
-       bus_type = G_BUS_TYPE_SYSTEM;
-
-       if (__get_gdbus_shared_connection(&conn, bus_type, evt_type) < 0) {
-               _E("getting gdbus-connetion error");
-               goto out_4;
-       }
-
-       em = __create_eventmap(interface_name, member_name, event_name,
-                       evt_type, NULL, user_data);
-       if (!em) {
-               ret = ES_R_ENOMEM;
-               goto out_4;
-       }
-
-       subscription_id = g_dbus_connection_signal_subscribe(conn,
-               NULL, /* sender */
-               interface_name,
-               member_name, /* member */
-               object_path, /* object_path */
-               NULL, /* arg0 */
-               G_DBUS_SIGNAL_FLAGS_NONE,
-               filter,
-               em,
-               NULL); /* user_data_free_func */
-
-       _D("event_name(%s), interface_name(%s)", event_name, interface_name);
-       _D("member_name(%s), subscription_id(%d), bus_type(%d)",
-               member_name, subscription_id, bus_type);
-
-       if (subscription_id != 0) {
-               em->bus_type = bus_type;
-               em->reg_id = subscription_id;
-
-               *em_s = em;
-               ret = ES_R_OK;
-       } else {
-               _D("dbus subscribe: error(%d), event(%s)", subscription_id, event_name);
-               __destroy_eventmap(em);
-               ret = ES_R_ERROR;
-       }
-
-out_4:
-       FREE_AND_NULL(object_path);
-out_3:
-       FREE_AND_NULL(member_name);
-out_2:
-       FREE_AND_NULL(interface_name);
-
-       return ret;
-}
-
-/**
- * function : register the event
- */
-API int eventsystem_register_event(const char *event_name, unsigned int *reg_id,
-               eventsystem_handler callback, void *user_data)
-{
-       eventmap_s *em = NULL;
-       int ret = ES_R_ERROR;
-
-       retvm_if(!g_dbus_is_interface_name(event_name), ES_R_EINVAL,
-               "Invalid argument : event_name(%s)", event_name);
-       retvm_if(!reg_id, ES_R_EINVAL, "Invalid argument : reg_id");
-       retvm_if(!callback, ES_R_EINVAL, "Invalid argument : callback");
-
-       if (!_initialized)
-               __initialize();
-
-       ret = __eventsystem_register_event_internal(event_name, &em, user_data);
-       if (ret == ES_R_OK && em) {
-               g_rec_mutex_lock(&__rec_mutex);
-               em->ep_cb = callback;
-               system_event_list = g_list_append(system_event_list, em);
-               *reg_id = em->reg_id;
-               g_rec_mutex_unlock(&__rec_mutex);
-               ret = ES_R_OK;
-       } else {
-               _E("error, ret(%d), event_name(%s)", ret, event_name);
-       }
-
-       return ret;
-}
-
-/**
- * function : unregister the event
- */
-API int eventsystem_unregister_event(unsigned int reg_id)
-{
-       eventmap_s em;
-       eventmap_s *em_data = NULL;
-       GBusType bus_type;
-       GList *cb_list = NULL;
-       GDBusConnection *conn = NULL;
-       eventsystem_event_type evt_type;
-
-       retvm_if(reg_id == 0, ES_R_EINVAL, "Invalid argument : reg_id");
-
-       g_rec_mutex_lock(&__rec_mutex);
-
-       if (!_initialized)
-               __initialize();
-
-       em.reg_id = reg_id;
-       cb_list = g_list_find_custom(system_event_list, &em,
-               (GCompareFunc)__event_compare_reg_id_cb);
-       if (cb_list) {
-               em_data = (eventmap_s *)cb_list->data;
-
-               bus_type = em_data->bus_type;
-               evt_type = em_data->event_type;
-
-               _D("unsubscribe: reg_id(%d), bus_type(%d)", reg_id, bus_type);
-
-               if (__get_gdbus_shared_connection(&conn, bus_type, evt_type) < 0) {
-                       _E("getting gdbus-connetion error");
-                       g_rec_mutex_unlock(&__rec_mutex);
-                       return ES_R_ERROR;
-               }
-               g_dbus_connection_signal_unsubscribe(conn, reg_id);
-
-               system_event_list = g_list_remove(system_event_list, cb_list->data);
-
-               __destroy_eventmap(em_data);
-       }
-
-       g_rec_mutex_unlock(&__rec_mutex);
-
-       return ES_R_OK;
-}
-
-static int __eventsystem_send_event(GDBusConnection *conn, eventinfo_s *evti, bundle *data)
-{
-       GError *error = NULL;
-       GVariant *param = NULL;
-       gboolean ret;
-
-       bundle_raw *raw = NULL;
-       bundle *buf = data;
-       int len;
-
-       bundle_encode(buf, &raw, &len);
-
-       param = g_variant_new("(us)", len, raw);
-       ret = g_dbus_connection_emit_signal(conn,
-               evti->destination_name,
-               evti->object_path,
-               evti->interface_name,
-               evti->member_name,
-               param,
-               &error);
-
-       _D("interface_name(%s)", evti->interface_name);
-       _D("object_path(%s)", evti->object_path);
-       _D("member_name(%s)", evti->member_name);
-
-       bundle_free_encoded_rawdata(&raw);
-
-       if (ret == FALSE) {
-               _E("Unable to connect to dbus: %s", error ? error->message : "");
-               g_clear_error(&error);
-               return ES_R_ERROR;
-       } else {
-               if (g_dbus_connection_flush_sync(conn, NULL, &error) == FALSE) {
-                       _E("g_dbus_connection_flush_sync() is failed. err(%s)",
-                                       error ? error->message : "");
-                       g_clear_error(&error);
-               }
-       }
-
-       return ES_R_OK;
-}
-
-static void __eventsystem_free_trusted_list(gpointer data)
-{
-       char *name = (char *)data;
-
-       FREE_AND_NULL(name);
-}
-
-static int __eventsystem_send_trusted_event(GDBusConnection *conn, eventinfo_s *evti,
-               bundle *data, GList *dest_list)
-{
-       GList *tmp_list = NULL;
-       int ret = ES_R_OK;
-       char *dest_name;
-
-       if (dest_list) {
-               tmp_list = g_list_first(dest_list);
-
-               while (tmp_list != NULL) {
-                       dest_name = (char *)tmp_list->data;
-                       if (dest_name && dest_name[0] != '\0') {
-                               _D("dest_name(%s)", dest_name);
-                               evti->destination_name = dest_name;
-                               ret = __eventsystem_send_event(conn, evti, data);
-                               if (ret != ES_R_OK) {
-                                       _E("send error");
-                                       ret = ES_R_ERROR;
-                                       break;
-                               }
-                       }
-                       tmp_list = g_list_next(tmp_list);
-               }
-       } else {
-               _E("dest_list is null");
-       }
-
-       return ret;
-}
-
-static int __update_last_data_item(eventinfo_s *evti, bundle *data)
-{
-       struct last_data_item *item;
-       bundle_raw *raw = NULL;
-       int len;
-
-       if (!last_data_tbl)
-               return ES_R_OK;
-
-       item = (struct last_data_item *)g_hash_table_lookup(last_data_tbl,
-                       evti->event_name);
-       if (item == NULL)
-               return ES_R_OK;
-
-       if (bundle_encode(data, &raw, &len)) {
-               _E("Unable to encode bundle");
-               return ES_R_ERROR;
-       }
-
-       if (!evti->is_trusted) {
-               if (item->param)
-                       g_variant_unref(item->param);
-               item->param = g_variant_new("(us)", len, raw);
-       }
-
-       if (item->trusted_param)
-               g_variant_unref(item->trusted_param);
-       item->trusted_param = g_variant_new("(us)", len, raw);
-
-       bundle_free_encoded_rawdata(&raw);
-
-       _D("Update last data");
-
-       return ES_R_OK;
-}
-
-/**
- * function : send the user-event
- */
-API int eventsystem_send_user_event(const char *event_name, bundle *data,
-               bool is_trusted)
-{
-       int ret = ES_R_OK;
-       eventinfo_s *evti = NULL;
-       GDBusConnection *conn = NULL;
-       GList *trusted_dest_list = NULL;
-
-       /* check validation */
-       retvm_if(!event_name, ES_R_EINVAL, "Invalid argument : event_name is NULL");
-       retvm_if(!data, ES_R_EINVAL, "Invalid argument : data is NULL");
-       retvm_if(!__check_eventname_validation_user((char *)event_name), ES_R_EINVAL,
-               "Invalid argument : event_name(%s)", event_name);
-
-       g_rec_mutex_lock(&__rec_mutex);
-
-       if (!__check_validation_user_defined_name(event_name)) {
-               _E("Invalid event name(%s)", event_name);
-               g_rec_mutex_unlock(&__rec_mutex);
-               return ES_R_EINVAL;
-       }
-
-       evti = calloc(1, sizeof(eventinfo_s));
-       if (!evti) {
-               _E("memory alloc failed");
-               g_rec_mutex_unlock(&__rec_mutex);
-               return ES_R_ENOMEM;
-       }
-       evti->event_name = strdup(event_name);
-       if (!evti->event_name) {
-               _E("memory alloc failed");
-               ret = ES_R_ENOMEM;
-               goto out;
-       }
-
-       evti->interface_name = __get_encoded_interface_name(evti->event_name);
-       if (!evti->interface_name) {
-               _E("interface_name is NULL");
-               ret = ES_R_ERROR;
-               goto out;
-       }
-       evti->member_name = strdup(EVENT_SYSTEM_MEMBER);
-       if (!evti->member_name) {
-               _E("memory alloc failed");
-               ret = ES_R_ENOMEM;
-               goto out;
-       }
-
-       evti->object_path = __get_object_path(evti->interface_name);
-       if (!evti->object_path) {
-               _E("object_path is NULL");
-               ret = ES_R_ERROR;
-               goto out;
-       }
-
-       evti->destination_name = NULL;
-       evti->is_user_event = true;
-       evti->is_trusted = is_trusted;
-
-       if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SESSION, ES_TYPE_USER) == ES_R_OK) {
-               ret = __update_last_data_item(evti, data);
-               if (ret != ES_R_OK)
-                       goto out;
-
-               if (is_trusted) {
-                       if (__eventsystem_request_destination_list(evti->event_name, &trusted_dest_list) < 0) {
-                               _E("failed to get dest list");
-                               ret = ES_R_ERROR;
-                               goto out;
-                       }
-                       if (__eventsystem_send_trusted_event(conn, evti, data, trusted_dest_list) < 0) {
-                               _E("failed to send trusted event");
-                               ret = ES_R_ERROR;
-                               goto out;
-                       }
-
-                       if (__eventsystem_launch_on_event_for_userevent(evti->event_name, data, TRUE) < 0)
-                               _E("Failed to launch on event for userevent");
-               } else {
-                       if (__eventsystem_send_event(conn, evti, data) < 0) {
-                               _E("failed to send event");
-                               ret = ES_R_ERROR;
-                               goto out;
-                       }
-
-                       if (__eventsystem_launch_on_event_for_userevent(evti->event_name, data, FALSE) < 0)
-                               _E("Failed to launch on event for userevent");
-               }
-       } else {
-               _E("getting gdbus-connetion error");
-               ret = ES_R_ERROR;
-       }
-
-out:
-       if (trusted_dest_list)
-               g_list_free_full(trusted_dest_list, __eventsystem_free_trusted_list);
-
-       FREE_AND_NULL(evti->object_path);
-       FREE_AND_NULL(evti->member_name);
-       FREE_AND_NULL(evti->interface_name);
-       FREE_AND_NULL(evti->event_name);
-       FREE_AND_NULL(evti);
-
-       g_rec_mutex_unlock(&__rec_mutex);
-
-       return ret;
-}
-
-/**
- * function : send the system-event
- */
-API int eventsystem_send_system_event(const char *event_name, bundle *data)
-{
-       int ret = 0;
-       eventinfo_s *evti = NULL;
-       GDBusConnection *conn = NULL;
-
-       pthread_mutex_lock(&send_sync_lock);
-
-       /* check validation */
-       tryvm_if(!event_name, ret = ES_R_EINVAL, "Invalid argument : event_name is NULL");
-       tryvm_if(!data, ret = ES_R_EINVAL, "Invalid argument : data is NULL");
-       tryvm_if(!__check_eventname_validation_system((char *)event_name), ret = ES_R_EINVAL,
-               "Invalid argument : event_name(%s)", event_name);
-       tryvm_if(!g_dbus_is_interface_name(event_name), ret = ES_R_EINVAL,
-               "Invalid argument : event_name(%s)", event_name);
-
-       _D("event_name(%s)", event_name);
-
-       evti = calloc(1, sizeof(eventinfo_s));
-       if (!evti) {
-               _E("memory alloc failed");
-               pthread_mutex_unlock(&send_sync_lock);
-               return ES_R_ENOMEM;
-       }
-       evti->event_name = strdup(event_name);
-       if (!evti->event_name) {
-               _E("out_of_memory");
-               ret = ES_R_ENOMEM;
-               goto out_1;
-       }
-       evti->interface_name = strdup(SYS_EVENT_NAME_PREFIX);
-       if (!evti->interface_name) {
-               _E("out of memory");
-               ret = ES_R_ENOMEM;
-               goto out_2;
-       }
-       evti->member_name = __get_member_name_from_eventname(evti->event_name);
-       if (!evti->member_name) {
-               _E("member_name is NULL");
-               ret = ES_R_ERROR;
-               goto out_3;
-       }
-       if (!g_dbus_is_member_name(evti->member_name)) {
-               _E("Invalid member_name(%s)", evti->member_name);
-               ret = ES_R_EINVAL;
-               goto out_4;
-       }
-       evti->object_path = __get_object_path(evti->interface_name);
-       if (!evti->object_path) {
-               _E("object_path is NULL");
-               ret = ES_R_ERROR;
-               goto out_4;
-       }
-       evti->destination_name = NULL;
-       evti->is_user_event = false;
-
-       if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) == ES_R_OK) {
-               ret = __eventsystem_send_event(conn, evti, data);
-       } else {
-               _E("getting gdbus-connection error");
-               ret = ES_R_ERROR;
-       }
-
-       FREE_AND_NULL(evti->object_path);
-out_4:
-       FREE_AND_NULL(evti->member_name);
-out_3:
-       FREE_AND_NULL(evti->interface_name);
-out_2:
-       FREE_AND_NULL(evti->event_name);
-out_1:
-       FREE_AND_NULL(evti);
-
-catch:
-       pthread_mutex_unlock(&send_sync_lock);
-
-       return ret;
-}
-
-/**
- * function : request sending the event
- */
-API int eventsystem_request_sending_system_event(const char *event_name,
-               bundle *data)
-{
-       int ret = 0;
-       GDBusConnection *conn = NULL;
-       GError *error = NULL;
-       GDBusProxy *proxy = NULL;
-       GVariant *param = NULL;
-       GVariant *value = NULL;
-       gint result = 0;
-       bundle_raw *raw = NULL;
-       int len = 0;
-
-       _D("event_name(%s)", event_name);
-
-       if (!_initialized)
-               __initialize();
-
-       if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) < 0) {
-               _E("getting gdbus-connetion error");
-               return ES_R_ERROR;
-       }
-
-       proxy = g_dbus_proxy_new_sync(conn,
-               G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
-               ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
-               NULL, &error);
-       if (proxy == NULL) {
-               _E("failed to create new proxy, error(%s)", error ? error->message : "");
-               g_clear_error(&error);
-               return ES_R_ERROR;
-       }
-
-       bundle_encode(data, &raw, &len);
-
-       param = g_variant_new("(ssi)", event_name, raw, len);
-       value = g_dbus_proxy_call_sync(proxy, "RequestSendingEvent", param,
-               G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
-       if (error != NULL) {
-               _E("proxy call sync error(%s)", error->message);
-               g_clear_error(&error);
-               ret = ES_R_ERROR;
-               goto out_2;
-       }
-
-       g_variant_get(value, "(i)", &result);
-
-       _D("result(%d)", result);
-
-       ret = ES_R_OK;
-
-out_2:
-       g_object_unref(proxy);
-       g_variant_unref(value);
-       bundle_free_encoded_rawdata(&raw);
-
-       return ret;
-}
-
-static int __check_userevent_name_validation(const char *event_name,
-               const char *app_id)
-{
-       size_t event_name_len;
-       size_t last_dot_pos;
-       char valid_name[256];
-       char event_name_substr[256];
-
-       if (event_name == NULL || app_id == NULL) {
-                       _E("invalid param\n");
-                       return -1;
-       }
-
-       event_name_len = strlen(event_name);
-       if (event_name_len == 0 || event_name_len > 256) {
-               _E("invalid length of event name\n");
-               return -1;
-       }
-
-       const char *p = strrchr(event_name, '.');
-       if (p == NULL) {
-               return -1;
-       }
-
-       last_dot_pos = p - event_name;
-       strncpy(event_name_substr, event_name, last_dot_pos);
-       event_name_substr[last_dot_pos] = '\0';
-
-       snprintf(valid_name, sizeof(valid_name), "%s%s",
-                       USER_EVENT_NAME_PREFIX, app_id);
-
-       if (strcmp(valid_name, event_name_substr) != 0) {
-                       _E("%s is not valid[%s] for appid : %s", event_name, valid_name, app_id);
-                       return -1;
-       }
-
-       return 0;
-}
-
-static int __eventsystem_check_sender_validation(int sender_pid,
-               uid_t sender_uid, const char *event_name, char **sender_id)
-{
-       int ret = 0;
-       char app_id[128] = {0, };
-
-       if (!_initialized)
-               __initialize();
-
-       ret = aul_app_get_appid_bypid_for_uid(sender_pid, app_id, sizeof(app_id), sender_uid);
-       if (ret != AUL_R_OK) {
-               _E("failed to get appid by pid");
-               return ES_R_ERROR;
-       }
-
-       _D("pid(%d)-uid(%d)-appid(%s)", sender_pid, sender_uid, app_id);
-       *sender_id = strdup(app_id);
-
-       if (__check_userevent_name_validation(event_name, app_id) != 0) {
-               free(*sender_id);
-               *sender_id = NULL;
-               return ES_R_ERROR;
-       }
-
-       return ES_R_OK;
-}
-
-static int __eventsystem_check_user_send_validation(const char *event_name)
-{
-       int ret = ES_R_EINVAL;
-       GDBusConnection *conn = NULL;
-       GError *error = NULL;
-       GDBusProxy *proxy = NULL;
-       GVariant *param = NULL;
-       GVariant *value = NULL;
-       gint result = 0;
-
-       if (!_initialized)
-               __initialize();
-
-       if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) < 0) {
-               _E("getting gdbus-connetion error");
-               return ES_R_ERROR;
-       }
-
-       proxy = g_dbus_proxy_new_sync(conn,
-               G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
-               ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
-               NULL, &error);
-       if (proxy == NULL) {
-               _E("failed to create new proxy, error(%s)", error ? error->message : "");
-               g_clear_error(&error);
-               return ES_R_ERROR;
-       }
-
-       param = g_variant_new("(s)", event_name);
-       value = g_dbus_proxy_call_sync(proxy, "CheckUserSendValidation", param,
-               G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
-       if (error != NULL) {
-               _E("proxy call sync error(%s)", error->message);
-               g_clear_error(&error);
-               ret = ES_R_ERROR;
-               goto out_2;
-       }
-
-       g_variant_get(value, "(i)", &result);
-
-       _D("result(%d)", result);
-
-       if (result == 1)
-               ret = ES_R_OK;
-out_2:
-       g_object_unref(proxy);
-       g_variant_unref(value);
-
-       return ret;
-}
-
-static int __eventsystem_check_privilege_validation(const char *event_name)
-{
-       int ret = ES_R_ENOTPERMITTED;
-       GDBusConnection *conn = NULL;
-       GError *error = NULL;
-       GDBusProxy *proxy = NULL;
-       GVariant *param = NULL;
-       GVariant *value = NULL;
-       gint result = 0;
-       pid_t pid = getpid();
-       uid_t uid = getuid();
-       char app_id[128] = {0, };
-
-       if (!_initialized)
-               __initialize();
-
-       if (uid < REGULAR_USER)
-               return ES_R_OK;
-
-       /* This feature is specific to the 'pkgcmd' command.
-                example) TCT is executed in a 5001 user environment, but it cannot have privileges. */
-       ret = aul_app_get_appid_bypid_for_uid(pid, app_id, sizeof(app_id), uid);
-       if (ret == AUL_R_ERROR) {
-               _W("failed to get appid by pid[%d]. Because it is not app, so bypass it", pid);
-               return ES_R_OK;
-       }
-
-       if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) < 0) {
-               _E("getting gdbus-connetion error");
-               return ES_R_ERROR;
-       }
-
-       proxy = g_dbus_proxy_new_sync(conn,
-               G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
-               ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
-               NULL, &error);
-       if (proxy == NULL) {
-               _E("failed to create new proxy, error(%s)", error ? error->message : "");
-               g_clear_error(&error);
-               return ES_R_ERROR;
-       }
-
-       param = g_variant_new("(s)", event_name);
-       value = g_dbus_proxy_call_sync(proxy, "CheckPrivilegeValidation", param,
-               G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
-       if (error != NULL) {
-               _E("proxy call sync error(%s)", error->message);
-               g_clear_error(&error);
-               ret = ES_R_ERROR;
-               goto out_2;
-       }
-
-       g_variant_get(value, "(i)", &result);
-
-       _D("result(%d)", result);
-
-       if (result == 1)
-               ret = ES_R_OK;
-out_2:
-       g_object_unref(proxy);
-       g_variant_unref(value);
-
-       return ret;
-}
-
-static int __eventsystem_setup_trusted_peer(const char *event_name, const char *dest_bus_name)
-{
-       int ret = ES_R_ERROR;
-       GDBusConnection *conn = NULL;
-       GError *error = NULL;
-       GDBusProxy *proxy = NULL;
-       GVariant *param = NULL;
-       GVariant *value = NULL;
-       gint result = 0;
-
-       if (!_initialized)
-               __initialize();
-
-       if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) < 0) {
-               _E("getting gdbus-connetion error");
-               return ES_R_ERROR;
-       }
-
-       proxy = g_dbus_proxy_new_sync(conn,
-               G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
-               ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
-               NULL, &error);
-       if (proxy == NULL) {
-               _E("failed to create new proxy, error(%s)", error ? error->message : "");
-               g_clear_error(&error);
-               return ES_R_ERROR;
-       }
-
-       param = g_variant_new("(ss)", event_name, dest_bus_name);
-       value = g_dbus_proxy_call_sync(proxy, "SetupTrustedPeer", param,
-               G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
-       if (error != NULL) {
-               _E("proxy call sync error(%s)", error->message);
-               g_clear_error(&error);
-               ret = ES_R_ERROR;
-               goto out_2;
-       }
-
-       g_variant_get(value, "(i)", &result);
-
-       _D("result(%d)", result);
-
-       if (result == 1)
-               ret = ES_R_OK;
-out_2:
-       g_object_unref(proxy);
-       g_variant_unref(value);
-
-       return ret;
-}
-
-static int __eventsystem_request_destination_list(const char *event_name, GList **dest_list)
-{
-       int ret = ES_R_ERROR;
-       GDBusConnection *conn = NULL;
-       GError *error = NULL;
-       GDBusProxy *proxy = NULL;
-       GVariant *param = NULL;
-       GVariant *value = NULL;
-       GVariantIter *iter;
-       gchar *str;
-       char *dest_name = NULL;
-       gint result = 0;
-
-       if (!_initialized)
-               __initialize();
-
-       if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) < 0) {
-               _E("getting gdbus-connetion error");
-               return ES_R_ERROR;
-       }
-
-       proxy = g_dbus_proxy_new_sync(conn,
-               G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
-               ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
-               NULL, &error);
-       if (proxy == NULL) {
-               _E("failed to create new proxy, error(%s)", error ? error->message : "");
-               g_clear_error(&error);
-               return ES_R_ERROR;
-       }
-
-       param = g_variant_new("(s)", event_name);
-       value = g_dbus_proxy_call_sync(proxy, "GetTrustedPeerList", param,
-               G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
-       if (error != NULL) {
-               _E("proxy call sync error(%s)", error->message);
-               g_clear_error(&error);
-               ret = ES_R_ERROR;
-               goto out_2;
-       }
-
-       g_variant_get(value, "(ias)", &result, &iter);
-
-       _D("result(%d)", result);
-
-       if (result == 1) {
-               ret = ES_R_OK;
-               while (g_variant_iter_loop(iter, "s", &str)) {
-                       dest_name = strdup((char *)str);
-                       if (dest_name) {
-                               _D("dest name(%s)", str);
-                               *dest_list = g_list_append(*dest_list, dest_name);
-                       } else {
-                               _E("out of memory");
-                               ret = ES_R_ENOMEM;
-                               break;
-                       }
-               }
-       }
-       g_variant_iter_free(iter);
-
-out_2:
-       g_object_unref(proxy);
-       g_variant_unref(value);
-
-       return ret;
-}
-
-#ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
-typedef struct callback_data {
-       char *event_name;
-       bundle_raw *bundle_data;
-       int len;
-       eventsystem_cb callback;
-       void *user_data;
-} callback_data_s;
-
-static gboolean __g_idle_cb_for_handler(gpointer data)
-{
-       callback_data_s *cb_data = (callback_data_s *)data;
-       if (!cb_data->callback) {
-               LOGE("handler is NULL. It may be already destroyed by user.");
-               free(cb_data->bundle_data);
-               free(cb_data->event_name);
-               free(cb_data);
-               return G_SOURCE_REMOVE;
-       }
-
-       cb_data->callback(cb_data->event_name, cb_data->bundle_data, cb_data->len,
-                       cb_data->user_data);
-       free(cb_data->bundle_data);
-       free(cb_data->event_name);
-       free(cb_data);
-       return G_SOURCE_REMOVE;
-}
-
-static int __eventsystem_request_earlier_data(const char *event_name,
-               eventsystem_cb callback, void *user_data)
-{
-       int ret = 0;
-       GDBusConnection *conn = NULL;
-       GError *error = NULL;
-       GDBusProxy *proxy = NULL;
-       GVariant *param = NULL;
-       GVariant *value = NULL;
-       gint result = 0;
-       bundle_raw *raw = NULL;
-       int len = 0;
-       callback_data_s *cb_data = NULL;
-       GMainContext* context = g_main_context_get_thread_default();
-       GSource* source = NULL;
-
-       if (!_initialized)
-               __initialize();
-
-       if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) < 0) {
-               _E("getting gdbus-connetion error");
-               return ES_R_ERROR;
-       }
-
-       proxy = g_dbus_proxy_new_sync(conn,
-               G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
-               ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
-               NULL, &error);
-
-       if (proxy == NULL) {
-               _E("failed to create new proxy, error(%s)", error ? error->message : "");
-               g_clear_error(&error);
-               return ES_R_ERROR;
-       }
-
-       param = g_variant_new("(s)", event_name);
-       value = g_dbus_proxy_call_sync(proxy, "GetEarlierData", param,
-               G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
-       if (error != NULL) {
-               _E("proxy call sync error(%s)", error->message);
-               g_clear_error(&error);
-               ret = ES_R_ERROR;
-               goto out_2;
-       }
-
-       g_variant_get(value, "(ii&s)", &result, &len, &raw);
-
-       _D("result(%d), len(%d)", result, len);
-
-       if (!result && raw && len > 0) {
-               cb_data = calloc(1, sizeof(callback_data_s));
-               if (cb_data == NULL) {
-                       LOGE("calloc failed");
-                       ret = ES_R_ENOMEM;
-                       goto out_2;
-               }
-
-               cb_data->bundle_data = calloc(1, len);
-               if (cb_data->bundle_data == NULL) {
-                       LOGE("calloc failed");
-                       free(cb_data);
-                       ret = ES_R_ENOMEM;
-                       goto out_2;
-               }
-               memcpy(cb_data->bundle_data, raw, len);
-
-               cb_data->event_name = strdup(event_name);
-               if (cb_data->event_name == NULL) {
-                       LOGE("strdup failed");
-                       free(cb_data->bundle_data);
-                       free(cb_data);
-                       ret = ES_R_ENOMEM;
-                       goto out_2;
-               }
-
-               cb_data->len = len;
-               cb_data->callback = callback;
-               cb_data->user_data = user_data;
-
-               source = g_idle_source_new();
-               if (source == NULL) {
-                       _E("g_idle_source_new() is failed");
-                       free(cb_data->bundle_data);
-                       free(cb_data->event_name);
-                       free(cb_data);
-                       ret = ES_R_ENOMEM;
-                       goto out_2;
-               }
-
-               g_source_set_callback(source, __g_idle_cb_for_handler, cb_data, NULL);
-               g_source_set_priority(source, G_PRIORITY_HIGH);
-               g_source_attach(source, context);
-               g_source_unref(source);
-
-               ret = ES_R_OK;
-       } else {
-               ret = ES_R_ERROR;
-       }
-
-out_2:
-       g_object_unref(proxy);
-       g_variant_unref(value);
-
-       return ret;
-}
-#endif
-
-static int __request_esd_for_last_data(const char *event_name, bool check)
-{
-       int ret = 0;
-       GDBusConnection *conn = NULL;
-       GError *error = NULL;
-       GDBusProxy *proxy = NULL;
-       GVariant *param = NULL;
-       GVariant *value = NULL;
-       gint result = 0;
-
-       if (!_initialized)
-               __initialize();
-
-       if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM,
-                               ES_TYPE_SYSTEM) < 0) {
-               _E("getting gdbus-connetion error");
-               return ES_R_ERROR;
-       }
-
-       proxy = g_dbus_proxy_new_sync(conn,
-               G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
-               ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
-               NULL, &error);
-
-       if (proxy == NULL) {
-               _E("failed to create new proxy, error(%s)", error ? error->message : "");
-               g_clear_error(&error);
-               return ES_R_ERROR;
-       }
-
-       param = g_variant_new("(ss)", event_name,
-                       check ? s_info.own_name_session_bus :
-                       s_info.own_name_system_bus);
-       value = g_dbus_proxy_call_sync(proxy,
-                       check ? "CheckLastData" : "KeepLastData", param,
-                       G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
-
-       if (error != NULL) {
-               _E("proxy call sync error(%s)", error->message);
-               g_clear_error(&error);
-               ret = ES_R_ERROR;
-               goto out_2;
-       }
-
-       g_variant_get(value, "(i)", &result);
-
-       _D("result(%d)", result);
-
-       ret = result;
-
-out_2:
-       g_object_unref(proxy);
-       g_variant_unref(value);
-
-       return ret;
-}
-
-static int __eventsystem_launch_on_event_for_userevent(const char *event_name,
-               bundle *data, gboolean trusted)
-{
-       int ret = ES_R_EINVAL;
-       GDBusConnection *conn = NULL;
-       GError *error = NULL;
-       GDBusProxy *proxy = NULL;
-       GVariant *param = NULL;
-       GVariant *value = NULL;
-       gint result = 0;
-       bundle_raw *raw = NULL;
-       bundle *buf = data;
-       int len;
-
-       if (!_initialized)
-               __initialize();
-
-       if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) < 0) {
-               _E("getting gdbus-connetion error");
-               return ES_R_ERROR;
-       }
-
-       proxy = g_dbus_proxy_new_sync(conn,
-               G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
-               ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
-               NULL, &error);
-       if (proxy == NULL) {
-               _E("failed to create new proxy, error(%s)", error ? error->message : "");
-               g_clear_error(&error);
-               return ES_R_ERROR;
-       }
-
-       bundle_encode(buf, &raw, &len);
-
-       param = g_variant_new("(ssib)", event_name, raw, len, trusted);
-       value = g_dbus_proxy_call_sync(proxy, "LaunchOnEventFromUserEvent", param,
-               G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
-       if (error != NULL) {
-               _E("proxy call sync error(%s)", error->message);
-               g_clear_error(&error);
-               ret = ES_R_ERROR;
-               goto out_2;
-       }
-
-       _D("Launch on event from user event (%s)", event_name);
-
-       g_variant_get(value, "(i)", &result);
-
-       _D("result(%d)", result);
-
-       ret = result;
-
-out_2:
-       bundle_free_encoded_rawdata(&raw);
-       g_object_unref(proxy);
-       g_variant_unref(value);
-
-       return ret;
-}
-
-
-static void _send_last_user_event(const char *event_name,
-               bundle *data, void *user_data)
-{
-       GDBusConnection *conn = NULL;
-       GError *error = NULL;
-       eventinfo_s *evti = NULL;
-       int ret;
-       struct last_data_item *item;
-       const char *is_trusted;
-
-       _D("send last data");
-
-       if (g_strcmp0(event_name, SYS_EVENT_REQUEST_LAST_DATA) != 0)
-               return;
-
-       evti = calloc(1, sizeof(eventinfo_s));
-       if (!evti) {
-               _E("memory alloc failed");
-               return;
-       }
-
-       g_rec_mutex_lock(&__rec_mutex);
-
-       evti->event_name = (char *)bundle_get_val(data,
-                       EVT_KEY_KEPT_EVENT_NAME);
-       if (!evti->event_name) {
-               _E("memory alloc failed");
-               goto out_1;
-       }
-
-       item = (struct last_data_item *)g_hash_table_lookup(last_data_tbl,
-                       evti->event_name);
-       if (!item)
-               goto out_1;
-
-       evti->interface_name = __get_encoded_interface_name(evti->event_name);
-       if (!evti->interface_name) {
-               _E("interface_name is NULL");
-               goto out_1;
-       }
-
-       evti->member_name = strdup(EVENT_SYSTEM_MEMBER);
-       if (!evti->member_name) {
-               _E("memory alloc failed");
-               goto out_2;
-       }
-
-       evti->object_path = __get_object_path(evti->interface_name);
-       if (!evti->object_path) {
-               _E("object_path is NULL");
-               goto out_3;
-       }
-
-       evti->destination_name = (char *)bundle_get_val(data,
-                       EVT_KEY_KEPT_OWN_NAME);
-       if (!evti->destination_name) {
-               _E("object_path is NULL");
-               goto out_4;
-       }
-
-       is_trusted = bundle_get_val(data, EVT_KEY_KEPT_IS_TRUSTED);
-       if (!is_trusted) {
-               _E("object_path is NULL");
-               goto out_4;
-       }
-
-       if (strncmp("true", is_trusted, sizeof("true")) != 0) {
-                       if (!item->trusted_param)
-                               goto out_4;
-                       evti->is_trusted = true;
-       } else {
-                       if (!item->param)
-                               goto out_4;
-                       evti->is_trusted = false;
-       }
-
-       if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SESSION,
-                               ES_TYPE_USER) == ES_R_OK) {
-               ret = g_dbus_connection_emit_signal(conn,
-                               evti->destination_name,
-                               evti->object_path,
-                               evti->interface_name,
-                               evti->member_name,
-                               evti->is_trusted ? item->trusted_param : item->param,
-                               &error);
-               if (ret == FALSE) {
-                       _E("Unable to connect to dbus: %s", error ? error->message : "");
-                       g_clear_error(&error);
-               } else {
-                       if (g_dbus_connection_flush_sync(conn, NULL, &error) == FALSE) {
-                               _E("g_dbus_connection_flush_sync() is failed. err(%s)",
-                                               error ? error->message : "");
-                               g_clear_error(&error);
-                       }
-               }
-       }
-
-out_4:
-       FREE_AND_NULL(evti->object_path);
-out_3:
-       FREE_AND_NULL(evti->member_name);
-out_2:
-       FREE_AND_NULL(evti->interface_name);
-out_1:
-       FREE_AND_NULL(evti);
-
-       g_rec_mutex_unlock(&__rec_mutex);
-}
-
-API int eventsystem_keep_last_event_data(const char *event_name)
-{
-       int ret = 0;
-       unsigned int reg_id;
-       struct last_data_item *item;
-
-       g_rec_mutex_lock(&__rec_mutex);
-
-       if (last_data_tbl == NULL)
-               last_data_tbl = g_hash_table_new(g_str_hash, g_str_equal);
-
-       ret = __request_esd_for_last_data(event_name, false);
-       if (ret != ES_R_OK) {
-               g_rec_mutex_unlock(&__rec_mutex);
-               return ret;
-       }
-
-       item = calloc(1, sizeof(*item));
-       if (!item) {
-               g_rec_mutex_unlock(&__rec_mutex);
-               return ES_R_ENOMEM;
-       }
-
-       item->event_name = strdup(event_name);
-       item->param = NULL;
-       item->trusted_param = NULL;
-
-       g_hash_table_insert(last_data_tbl, item->event_name, item);
-
-       g_rec_mutex_unlock(&__rec_mutex);
-
-       ret = eventsystem_register_event(SYS_EVENT_REQUEST_LAST_DATA,
-                       &reg_id, _send_last_user_event, NULL);
-
-       return ret;
-}
-
-static void __destroy_eventmap(gpointer data)
-{
-       eventmap_s *em = (eventmap_s *)data;
-
-       if (!em)
-               return;
-
-       if (em->interface_name)
-               free(em->interface_name);
-       if (em->member_name)
-               free(em->member_name);
-       if (em->event_name)
-               free(em->event_name);
-       free(em);
-}
-
-static eventmap_s *__create_eventmap(const char *interface_name,
-               const char *member_name, const char *event_name,
-               int event_type, eventsystem_cb callback, void *user_data)
-{
-       eventmap_s *em;
-
-       em = calloc(1, sizeof(eventmap_s));
-       if (!em) {
-               _E("Out of memory");
-               return NULL;
-       }
-
-       em->interface_name = strdup(interface_name);
-       if (!em->interface_name) {
-               _E("Failed to duplicate interface name");
-               __destroy_eventmap(em);
-               return NULL;
-       }
-
-       em->member_name = strdup(member_name);
-       if (!em->member_name) {
-               _E("Failed to duplicate member name");
-               __destroy_eventmap(em);
-               return NULL;
-       }
-
-       em->event_name = strdup(event_name);
-       if (!em->event_name) {
-               _E("Failed to duplicate event name");
-               __destroy_eventmap(em);
-               return NULL;
-       }
-
-       em->event_type = event_type;
-       em->es_cb = callback;
-       em->user_data = user_data;
-
-       return em;
-}
-
-API int eventsystem_register_application_event(const char *event_name,
-               unsigned int *reg_id, int *event_type,
-               eventsystem_cb callback, void *user_data)
-{
-       eventmap_s *em;
-       char *interface_name;
-       char *object_path;
-       char *member_name;
-       GDBusSignalCallback filter;
-       GBusType bus_type;
-       guint subscription_id = 0;
-       int ret = 0;
-       GDBusConnection *conn = NULL;
-
-       if (!_initialized)
-               __initialize();
-
-       if (__check_eventname_validation_system((char *)event_name)) {
-               if (__eventsystem_check_privilege_validation(event_name) != ES_R_OK) {
-                       _E("invalid privilege(%s)", event_name);
-                       return ES_R_ENOTPERMITTED;
-               }
-               *event_type = ES_TYPE_SYSTEM;
-       } else if (__check_eventname_validation_user((char *)event_name)) {
-               *event_type = ES_TYPE_USER;
-       } else {
-               *event_type = ES_TYPE_UNKNOWN;
-               _E("unknown type event(%s)", event_name);
-               return ES_R_EINVAL;
-       }
-
-       if (*event_type == ES_TYPE_SYSTEM) {
-               interface_name = strdup(SYS_EVENT_NAME_PREFIX);
-               if (interface_name == NULL) {
-                       _E("out of memory");
-                       return ES_R_ENOMEM;
-               }
-               if (!g_dbus_is_interface_name(interface_name)) {
-                       _E("invalid interface_name(%s)", interface_name);
-                       FREE_AND_NULL(interface_name);
-                       return ES_R_EINVAL;
-               }
-               member_name = __get_member_name_from_eventname((char *)event_name);
-               if (member_name == NULL) {
-                       _E("member_name is NULL(%s)", event_name);
-                       FREE_AND_NULL(interface_name);
-                       return ES_R_ERROR;
-               }
-               if (!g_dbus_is_member_name(member_name)) {
-                       _E("Invalid member_name(%s)", member_name);
-                       FREE_AND_NULL(interface_name);
-                       FREE_AND_NULL(member_name);
-                       return ES_R_ERROR;
-               }
-               filter = __eventsystem_filter_sysevent_for_application;
-               bus_type = G_BUS_TYPE_SYSTEM;
-       } else {
-               interface_name = __get_encoded_interface_name((char *)event_name);
-               if (!interface_name) {
-                       _E("interface_name is NULL");
-                       return ES_R_ERROR;
-               }
-               if (!g_dbus_is_interface_name(interface_name)) {
-                       _E("invalid interface_name(%s)", interface_name);
-                       FREE_AND_NULL(interface_name);
-                       return ES_R_EINVAL;
-               }
-               member_name = strdup(EVENT_SYSTEM_MEMBER);
-               if (!member_name) {
-                       _E("out_of_memory");
-                       FREE_AND_NULL(interface_name);
-                       return ES_R_ERROR;
-               }
-               filter = __eventsystem_filter_userevent_for_application;
-               bus_type = G_BUS_TYPE_SESSION;
-       }
-
-       object_path = __get_object_path(interface_name);
-       if (!object_path) {
-               _E("failed get object_path");
-               ret = ES_R_ERROR;
-               goto end;
-       }
-
-       _D("interface_name(%s), object_path(%s)", interface_name, object_path);
-       _D(" member_name(%s), type(%d), bus_type(%d)",
-               member_name, *event_type, bus_type);
-
-       if (__get_gdbus_shared_connection(&conn, bus_type, *event_type) < 0) {
-               _E("getting gdbus-connetion error");
-               ret = ES_R_ERROR;
-               goto end;
-       }
-
-#ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
-       if (__check_eventname_validation_system((char *)event_name) &&
-                       !__is_pkgmgr_signal_system_event(event_name) &&
-                       !__is_pkgmgr_signal_user_event(event_name))
-               __eventsystem_request_earlier_data(event_name, callback, user_data);
-#endif
-
-       g_rec_mutex_lock(&__rec_mutex);
-
-       em = __create_eventmap(interface_name, member_name, event_name,
-                       *event_type, callback, user_data);
-       if (!em) {
-               ret = ES_R_ENOMEM;
-               g_rec_mutex_unlock(&__rec_mutex);
-               goto end;
-       }
-
-       subscription_id = g_dbus_connection_signal_subscribe(conn,
-               NULL, /* sender */
-               interface_name,
-               member_name, /* member */
-               object_path, /* object_path */
-               NULL, /* arg0 */
-               G_DBUS_SIGNAL_FLAGS_NONE,
-               filter,
-               em,
-               NULL); /* user_data_free_func */
-
-       _D("event_name(%s), subscription_id(%d)", event_name, subscription_id);
-
-       if (subscription_id != 0) {
-               em->bus_type = bus_type;
-               em->reg_id = subscription_id;
-
-               system_event_list = g_list_append(system_event_list, em);
-               *reg_id = subscription_id;
-
-               ret = ES_R_OK;
-
-               if (em->bus_type == G_BUS_TYPE_SESSION &&
-                               em->event_type == ES_TYPE_USER) {
-                       if (s_info.own_name_session_bus == NULL) {
-                               _E("session bus is not ready");
-                               ret = ES_R_ERROR;
-                               g_dbus_connection_signal_unsubscribe(conn, subscription_id);
-                               __destroy_eventmap(em);
-                       } else {
-                               if (!__is_pkgmgr_signal_user_event(event_name) &&
-                                               __eventsystem_setup_trusted_peer(event_name,
-                                               s_info.own_name_session_bus) < 0) {
-                                       _E("failed to setup trusted peer");
-                                       ret = ES_R_ERROR;
-                                       g_dbus_connection_signal_unsubscribe(conn, subscription_id);
-                                       __destroy_eventmap(em);
-                               }
-                       }
-               }
-       } else {
-               _E("dbus subscribe: error(%d)", subscription_id);
-               __destroy_eventmap(em);
-               ret = ES_R_ERROR;
-       }
-
-       if (*event_type == ES_TYPE_USER &&
-                       !__is_pkgmgr_signal_user_event(event_name) &&
-                       !__is_pkgmgr_signal_system_event(event_name))
-               __request_esd_for_last_data(event_name, true);
-
-       g_rec_mutex_unlock(&__rec_mutex);
-
-end:
-       FREE_AND_NULL(interface_name);
-       FREE_AND_NULL(object_path);
-       FREE_AND_NULL(member_name);
-
-       return ret;
-}
-
-API int eventsystem_unregister_application_event(unsigned int reg_id)
-{
-       eventmap_s em;
-       eventmap_s *em_data;
-       GBusType bus_type;
-       GList *cb_list;
-       GDBusConnection *conn = NULL;
-       eventsystem_event_type evt_type;
-
-       retvm_if(reg_id == 0, ES_R_EINVAL, "Invalid argument : reg_id");
-
-       g_rec_mutex_lock(&__rec_mutex);
-
-       if (!_initialized)
-               __initialize();
-
-       em.reg_id = reg_id;
-       cb_list = g_list_find_custom(system_event_list, &em,
-                       (GCompareFunc)__event_compare_reg_id_cb);
-       if (!cb_list) {
-               _E("not found matched item");
-               g_rec_mutex_unlock(&__rec_mutex);
-               return ES_R_ERROR;
-       }
-
-       em_data = (eventmap_s *)cb_list->data;
-
-       bus_type = em_data->bus_type;
-       evt_type = em_data->event_type;
-
-       _D("unsubscribe: reg_id(%d), bus_type(%d)", reg_id, bus_type);
-
-       if (__get_gdbus_shared_connection(&conn, bus_type, evt_type) < 0) {
-               _E("getting gdbus-connetion error");
-               g_rec_mutex_unlock(&__rec_mutex);
-               return ES_R_ERROR;
-       }
-       g_dbus_connection_signal_unsubscribe(conn, reg_id);
-
-       system_event_list = g_list_remove(system_event_list, cb_list->data);
-
-       __destroy_eventmap(em_data);
-       g_rec_mutex_unlock(&__rec_mutex);
-
-       return ES_R_OK;
-}
-
-API int eventsystem_application_finalize(void)
-{
-       gpointer key;
-       gpointer value;
-       GHashTableIter iter;
-       char *key_item;
-       char *val_item;
-       struct last_data_item *last_item;
-
-       _D("release all resouces");
-       g_rec_mutex_lock(&__rec_mutex);
-
-       if (system_event_list)
-               g_list_free(system_event_list);
-
-       if (check_tbl) {
-               g_hash_table_iter_init(&iter, check_tbl);
-
-               while (g_hash_table_iter_next(&iter, &key, &value)) {
-                       val_item = (char *)value;
-                       if (val_item)
-                               free(val_item);
-                       else
-                               _E("check_tbl, val_item is NULL");
-                       g_hash_table_iter_remove(&iter);
-               }
-               g_hash_table_unref(check_tbl);
-       }
-
-       if (filter_tbl) {
-               g_hash_table_iter_init(&iter, filter_tbl);
-
-               while (g_hash_table_iter_next(&iter, &key, &value)) {
-                       key_item = (char *)key;
-                       if (key_item)
-                               free(key_item);
-                       else
-                               _E("filter_tbl, key_item is NULL");
-
-                       val_item = (char *)value;
-                       if (val_item)
-                               free(val_item);
-                       else
-                               _E("filter_tbl, val_item is NULL");
-
-                       g_hash_table_iter_remove(&iter);
-               }
-               g_hash_table_unref(filter_tbl);
-       }
-
-       if (last_data_tbl) {
-               g_hash_table_iter_init(&iter, last_data_tbl);
-
-               while (g_hash_table_iter_next(&iter, &key, &value)) {
-                       last_item = (struct last_data_item *)value;
-                       if (last_item) {
-                               if (last_item->event_name)
-                                       free(last_item->event_name);
-                               if (last_item->param)
-                                       g_variant_unref(last_item->param);
-                               if (last_item->trusted_param)
-                                       g_variant_unref(last_item->trusted_param);
-                               free(last_item);
-                       } else {
-                               _E("last_data_tbl, val_item is NULL");
-                       }
-                       g_hash_table_iter_remove(&iter);
-               }
-               g_hash_table_unref(last_data_tbl);
-       }
-
-       FREE_AND_NULL(s_info.own_name_system_bus);
-       FREE_AND_NULL(s_info.own_name_session_bus);
-
-       g_rec_mutex_unlock(&__rec_mutex);
-
-       return 0;
-}
index c90fac83ca5e8e0ed45809ebae9cab7a418c15fd..afb82c4ec28d796246693d11ea2ea5f1715a7207 100644 (file)
@@ -1 +1,2 @@
 ADD_SUBDIRECTORY(unit_tests)
+ADD_SUBDIRECTORY(integ_tests)
diff --git a/tests/integ_tests/CMakeLists.txt b/tests/integ_tests/CMakeLists.txt
new file mode 100644 (file)
index 0000000..46862e0
--- /dev/null
@@ -0,0 +1,27 @@
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../include)\r
+\r
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} INTEG_TEST_SRCS)\r
+\r
+ADD_EXECUTABLE(${TARGET_EVENTSYSTEM_INTEGTESTS}\r
+  ${INTEG_TEST_SRCS}\r
+)\r
+\r
+APPLY_PKG_CONFIG(${TARGET_EVENTSYSTEM_INTEGTESTS} PUBLIC\r
+  AUL_DEPS\r
+  RPC_PORT_DEPS\r
+  BUNDLE_DEPS\r
+  DLOG_DEPS\r
+  GMOCK_DEPS\r
+  ESD_DEPS\r
+  PKGMGR_INFO_DEPS\r
+  PKGMGR_DEPS\r
+)\r
+\r
+TARGET_LINK_LIBRARIES(${TARGET_EVENTSYSTEM_INTEGTESTS} PUBLIC\r
+  ${TARGET_EVENTSYSTEM} ${TARGET_ESD_MOD_GROUP})\r
+SET_TARGET_PROPERTIES(${TARGET_EVENTSYSTEM_INTEGTESTS} PROPERTIES\r
+  COMPILE_FLAGS "-fPIE")\r
+SET_TARGET_PROPERTIES(${TARGET_EVENTSYSTEM_INTEGTESTS} PROPERTIES\r
+  LINK_FLAGS "-pie")\r
+\r
+INSTALL(TARGETS ${TARGET_EVENTSYSTEM_INTEGTESTS} DESTINATION bin)\r
diff --git a/tests/integ_tests/eventsystem_test.cc b/tests/integ_tests/eventsystem_test.cc
new file mode 100644 (file)
index 0000000..0aa5f54
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2024 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 "include/eventsystem.h"
+
+#include <aul.h>
+#include <bundle_cpp.h>
+#include <dlog.h>
+#include <glib.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <memory>
+#include <string>
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+
+class EventSystemTest : public ::testing::Test  {
+ public:
+  EventSystemTest() {
+  }
+  virtual ~EventSystemTest() {}
+
+  static void SetUpTestSuite() {
+  }
+
+  static void TearDownTestSuite() {
+  }
+
+  virtual void SetUp() {
+  }
+
+  virtual void TearDown() {
+    eventsystem_application_finalize();
+  }
+
+};
+
+static void SystemEventCb(const char* event_name, bundle* data,
+                          void* user_data) {}
+static void AppEventCb(const char* event_name, bundle_raw* event_data, int len,
+                       void* user_data) {}
+
+TEST_F(EventSystemTest, eventsystem_register_system_event) {
+  unsigned int id;
+  int ret = eventsystem_register_event("tizen.system.event.test", &id,
+                                       SystemEventCb, nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+}
+
+TEST_F(EventSystemTest, eventsystem_register_system_event2) {
+  unsigned int id;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_event(
+      "tizen.system.event.test", &id,
+      [](const char* event_name, bundle* data, void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  tizen_base::Bundle data;
+  ret = eventsystem_send_system_event("tizen.system.event.test",
+                                      data.GetHandle());
+  EXPECT_EQ(ret, ES_R_OK);
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, "tizen.system.event.test");
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_register_user_event) {
+  unsigned int id;
+  int ret =
+      eventsystem_register_event("event.test", &id, SystemEventCb, nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+}
+
+TEST_F(EventSystemTest, eventsystem_unregister_event) {
+  unsigned int id;
+  int ret = eventsystem_register_event("tizen.system.event.test", &id,
+                                       SystemEventCb, nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+
+  ret = eventsystem_unregister_event(id);
+  EXPECT_EQ(ret, ES_R_OK);
+}
+
+TEST_F(EventSystemTest, eventsystem_send_user_event) {
+  tizen_base::Bundle data;
+  int ret = eventsystem_send_user_event("event.test", data.GetHandle(), false);
+  EXPECT_EQ(ret, ES_R_OK);
+}
+
+TEST_F(EventSystemTest, eventsystem_send_system_event) {
+  tizen_base::Bundle data;
+  int ret = eventsystem_send_system_event("tizen.system.event.test",
+                                          data.GetHandle());
+  EXPECT_EQ(ret, ES_R_OK);
+}
+
+TEST_F(EventSystemTest, eventsystem_request_sending_system_event) {
+  tizen_base::Bundle data;
+  int ret =
+      eventsystem_request_sending_system_event("event.test", data.GetHandle());
+  EXPECT_EQ(ret, ES_R_OK);
+}
+
+TEST_F(EventSystemTest, eventsystem_register_application_event) {
+  unsigned int id;
+  int type;
+  int ret = eventsystem_register_application_event(
+      "tizen.system.event.test", &id, &type, AppEventCb, nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+}
+
+TEST_F(EventSystemTest, eventsystem_register_application_event2) {
+  unsigned int id;
+  int type;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_application_event(
+      "tizen.system.event.test", &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  tizen_base::Bundle data;
+  ret = eventsystem_send_system_event("tizen.system.event.test",
+                                      data.GetHandle());
+  EXPECT_EQ(ret, ES_R_OK);
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, "tizen.system.event.test");
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_unregister_application_event) {
+  unsigned int id;
+  int type;
+  int ret = eventsystem_register_application_event(
+      "tizen.system.event.test", &id, &type, AppEventCb, nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+
+  ret = eventsystem_unregister_application_event(id);
+  EXPECT_EQ(ret, ES_R_OK);
+}
+
+TEST_F(EventSystemTest, eventsystem_keep_last_event_data) {
+  int ret = eventsystem_keep_last_event_data("tizen.system.event.test_keep");
+  EXPECT_EQ(ret, ES_R_OK);
+
+  tizen_base::Bundle data;
+  ret = eventsystem_send_system_event("tizen.system.event.test_keep",
+                                      data.GetHandle());
+  EXPECT_EQ(ret, ES_R_OK);
+
+  unsigned int id;
+  int type;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  ret = eventsystem_register_application_event(
+      "tizen.system.event.test_keep", &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, "tizen.system.event.test_keep");
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_application_finalize) {
+  int ret = eventsystem_application_finalize();
+  EXPECT_EQ(ret, ES_R_OK);
+}
diff --git a/tests/integ_tests/main.cc b/tests/integ_tests/main.cc
new file mode 100644 (file)
index 0000000..571dd0b
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2024 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 <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+//#define LOG_INTERNAL
+
+#ifdef LOG_INTERNAL
+#include <dlog.h>
+
+extern "C" int __dlog_print(log_id_t log_id, int prio, const char* tag,
+                            const char* fmt, ...) {
+  printf("%s:", tag);
+  va_list ap;
+  va_start(ap, fmt);
+  vprintf(fmt, ap);
+  va_end(ap);
+  printf("\n");
+
+  return 0;
+}
+#endif
+
+int main(int argc, char** argv) {
+  int ret = -1;
+
+  try {
+    testing::InitGoogleTest(&argc, argv);
+  } catch (...) {
+    std::cout << "Exception occurred" << std::endl;
+  }
+
+  try {
+    ret = RUN_ALL_TESTS();
+  } catch (const ::testing::internal::GoogleTestFailureException& e) {
+    ret = -1;
+    std::cout << "GoogleTestFailureException was thrown:" << e.what()
+              << std::endl;
+  }
+
+  return ret;
+}
index d0d79379dc4dca12c0fa8edecc1bcc0068ec9789..a27a38268052be2489093b81e706de3a9e0ba435 100644 (file)
@@ -1,3 +1,6 @@
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../mock)\r
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../include)\r
+\r
 AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} UNIT_TEST_SRCS)\r
 AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/mock MOCK_SRCS)\r
 \r
@@ -8,25 +11,17 @@ ADD_EXECUTABLE(${TARGET_EVENTSYSTEM_UNITTESTS}
 \r
 APPLY_PKG_CONFIG(${TARGET_EVENTSYSTEM_UNITTESTS} PUBLIC\r
   AUL_DEPS\r
+  RPC_PORT_DEPS\r
   BUNDLE_DEPS\r
   DLOG_DEPS\r
-  GLIB_DEPS\r
-  GIO_DEPS\r
   GMOCK_DEPS\r
+  ESD_DEPS\r
   PKGMGR_INFO_DEPS\r
-)\r
-\r
-TARGET_INCLUDE_DIRECTORIES(${TARGET_EVENTSYSTEM_UNITTESTS} PUBLIC\r
-  ${CMAKE_CURRENT_SOURCE_DIR}\r
-  ${CMAKE_CURRENT_SOURCE_DIR}/src\r
-  ${CMAKE_CURRENT_SOURCE_DIR}/mock\r
-  ${CMAKE_CURRENT_SOURCE_DIR}/../\r
-  ${CMAKE_CURRENT_SOURCE_DIR}/../../src\r
-  ${CMAKE_CURRENT_SOURCE_DIR}/../../include\r
+  PKGMGR_DEPS\r
 )\r
 \r
 TARGET_LINK_LIBRARIES(${TARGET_EVENTSYSTEM_UNITTESTS} PUBLIC\r
-  ${TARGET_EVENTSYSTEM})\r
+  ${TARGET_EVENTSYSTEM} ${TARGET_ESD_MOD_GROUP})\r
 SET_TARGET_PROPERTIES(${TARGET_EVENTSYSTEM_UNITTESTS} PROPERTIES\r
   COMPILE_FLAGS "-fPIE")\r
 SET_TARGET_PROPERTIES(${TARGET_EVENTSYSTEM_UNITTESTS} PROPERTIES\r
index bf485e964ac2f1514866c6165accef921a1731fe..37b69ba018565d1faf3856fe133ca57e9d468d01 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 - 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -17,6 +17,7 @@
 #include "include/eventsystem.h"
 
 #include <aul.h>
+#include <bundle_cpp.h>
 #include <dlog.h>
 #include <glib.h>
 #include <gmock/gmock.h>
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <imodule.hh>
 #include <memory>
 #include <string>
 
 #include "mock/aul_mock.hh"
-#include "mock/gio_mock.hh"
-#include "mock/libc_mock.hh"
+#include "mock/pkgmgr_info_mock.hh"
+#include "mock/rpc_port_mock.hh"
+#include "mock/security_manager_mock.hh"
 #include "mock/test_fixture.hh"
+#include "mock/vconf_mock.hh"
 
-// using namespace tizen_base;
 using ::testing::_;
 using ::testing::DoAll;
 using ::testing::Invoke;
@@ -42,226 +45,1217 @@ using ::testing::SetArgPointee;
 #undef LOG_TAG
 #define LOG_TAG "ES_UNITTEST"
 
-namespace {
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+extern "C" EXPORT_API esd::api::IModule* ESD_GET_MODULE();
 
-gboolean FakeGDBusIsInterfaceName(const gchar* string) { return TRUE; }
+class Mocks : public ::testing::NiceMock<AulMock>,
+              public ::testing::NiceMock<RpcPortMock>,
+              public ::testing::NiceMock<PkgmgrInfoMock>,
+              public ::testing::NiceMock<SecurityManagerMock>,
+              public ::testing::NiceMock<VConfMock> {};
+std::unique_ptr<esd::api::IModule> module_;
 
-GDBusConnection* FakeGBusGetSync(GBusType type, GCancellable* cancellable,
-                                 GError** error) {
-  GDBusConnection* conn = reinterpret_cast<GDBusConnection*>(
-      g_object_new(G_TYPE_DBUS_CONNECTION, nullptr));
-  return conn;
+class EventSystemTest : public TestFixture {
+ public:
+  EventSystemTest() : TestFixture(std::make_unique<Mocks>()) {
+    setenv("AUL_APPID", "d::org.tizen.appfw.service.esd", 1);
+  }
+  virtual ~EventSystemTest() {}
+
+  static void SetUpTestSuite() {
+    auto* mod = ESD_GET_MODULE();
+    module_.reset(mod);
+  }
+
+  static void TearDownTestSuite() {
+    module_->Shutdown();
+    module_.reset();
+  }
+
+  virtual void SetUp() {
+    ON_CALL(GetMock<AulMock>(), aul_svc_get_appid_by_alias_appid(_, _))
+        .WillByDefault(Return(-1));
+    EXPECT_CALL(GetMock<RpcPortMock>(), rpc_port_stub_listen(_))
+        .WillOnce(Return(0));
+    ON_CALL(GetMock<PkgmgrInfoMock>(),
+            pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(_, _, _, _))
+        .WillByDefault(Invoke([](auto handle, pkgmgrinfo_app_list_cb callback,
+                                 void* user_data, uid_t uid) {
+          callback(nullptr, user_data);
+          return 0;
+        }));
+    ON_CALL(GetMock<PkgmgrInfoMock>(), pkgmgrinfo_appinfo_get_pkgid(_, _))
+        .WillByDefault(Invoke([](auto h, char** pkgid) {
+          *pkgid = strdup("testpkg");
+          return 0;
+        }));
+    ON_CALL(GetMock<PkgmgrInfoMock>(), pkgmgrinfo_appinfo_get_appid(_, _))
+        .WillByDefault(Invoke([](auto h, char** appid) {
+          *appid = strdup("testapp");
+          return 0;
+        }));
+  }
+
+  virtual void TearDown() {
+    if (run_) {
+      module_->Shutdown();
+      run_ = false;
+    }
+    eventsystem_application_finalize();
+  }
+
+  void RunModule() {
+    if (!run_) {
+      module_->Startup(nullptr);
+      run_ = true;
+    }
+  }
+
+ private:
+  bool run_ = false;
+};
+
+static void SystemEventCb(const char* event_name, bundle* data,
+                          void* user_data) {}
+
+static void AppEventCb(const char* event_name, bundle_raw* event_data, int len,
+                       void* user_data) {}
+
+TEST_F(EventSystemTest, eventsystem_register_system_event) {
+  unsigned int id;
+  RunModule();
+  int ret = eventsystem_register_event("tizen.system.event.test", &id,
+                                       SystemEventCb, nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
 }
 
-guint FakeGDBusConnectionSignalSubscribe(
-    GDBusConnection* connection, const gchar* sender,
-    const gchar* interface_name, const gchar* member, const gchar* object_path,
-    const gchar* arg0, GDBusSignalFlags flags, GDBusSignalCallback callback,
-    gpointer user_data, GDestroyNotify user_data_free_func) {
-  return 1;
+TEST_F(EventSystemTest, eventsystem_register_system_event2) {
+  unsigned int id;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_event(
+      "tizen.system.event.test", &id,
+      [](const char* event_name, bundle* data, void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  tizen_base::Bundle data;
+  ret = eventsystem_send_system_event("tizen.system.event.test",
+                                      data.GetHandle());
+  EXPECT_EQ(ret, ES_R_OK);
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, "tizen.system.event.test");
+  g_main_loop_unref(loop);
 }
 
-guint FakeGBusOwnNameOnConnection(
-    GDBusConnection* connection, const gchar* name, GBusNameOwnerFlags flags,
-    GBusNameAcquiredCallback name_acquired_handler,
-    GBusNameLostCallback name_lost_handler, gpointer user_data,
-    GDestroyNotify user_data_free_func) {
-  return 1;
+TEST_F(EventSystemTest, eventsystem_register_user_event) {
+  unsigned int id;
+  RunModule();
+  int ret =
+      eventsystem_register_event("event.test", &id, SystemEventCb, nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
 }
 
-GDBusProxy* FakeGDBusProxyNewSync(
-    GDBusConnection* connection, GDBusProxyFlags flags,
-    GDBusInterfaceInfo* info, const gchar* name, const gchar* object_path,
-    const gchar* interface_name, GCancellable* cancellable, GError** error) {
-  GDBusProxy* proxy =
-      reinterpret_cast<GDBusProxy*>(g_object_new(G_TYPE_OBJECT, nullptr));
-  return proxy;
+TEST_F(EventSystemTest, eventsystem_unregister_event) {
+  unsigned int id;
+  RunModule();
+  int ret = eventsystem_register_event("tizen.system.event.test", &id,
+                                       SystemEventCb, nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+
+  ret = eventsystem_unregister_event(id);
+  EXPECT_EQ(ret, ES_R_OK);
 }
 
-GVariant* FakeGDBusProxyCallSync(GDBusProxy* proxy, const gchar* method_name,
-                                 GVariant* parameters, GDBusCallFlags flags,
-                                 gint timeout_msec, GCancellable* cancellable,
-                                 GError** error) {
-  *error = nullptr;
-  return g_variant_new("(i)", 1);
+TEST_F(EventSystemTest, eventsystem_send_user_event) {
+  tizen_base::Bundle data;
+  RunModule();
+  int ret = eventsystem_send_user_event("event.test", data.GetHandle(), false);
+  EXPECT_EQ(ret, ES_R_OK);
 }
 
-gboolean FakeGDBusConnectionEmitSignal(
-    GDBusConnection* connection, const gchar* destination_bus_name,
-    const gchar* object_path, const gchar* interface_name,
-    const gchar* signal_name, GVariant* parameters, GError** error) {
-  return TRUE;
+TEST_F(EventSystemTest, eventsystem_send_system_event) {
+  tizen_base::Bundle data;
+  RunModule();
+  int ret = eventsystem_send_system_event("tizen.system.event.test",
+                                          data.GetHandle());
+  EXPECT_EQ(ret, ES_R_OK);
 }
 
-void FakeGDBusConnectionSignalUnsubscribe(GDBusConnection* connection,
-                                               guint subscription_id) {
+TEST_F(EventSystemTest, eventsystem_request_sending_system_event) {
+  tizen_base::Bundle data;
+  RunModule();
+  int ret =
+      eventsystem_request_sending_system_event("event.test", data.GetHandle());
+  EXPECT_EQ(ret, ES_R_OK);
 }
 
-gboolean FakeGDBusConnectionFlushSync(GDBusConnection* connection,
-                                           GCancellable* cancellable,
-                                           GError** error) {
-  return TRUE;
+TEST_F(EventSystemTest, eventsystem_register_application_event) {
+  unsigned int id;
+  int type;
+  RunModule();
+  int ret = eventsystem_register_application_event(
+      "tizen.system.event.test", &id, &type, AppEventCb, nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
 }
 
-int FakeAulAppGetAppidByPidForUid(int pid, char* appid, int len, uid_t uid) {
-  return AUL_R_OK;
+TEST_F(EventSystemTest, eventsystem_register_application_event2) {
+  unsigned int id;
+  int type;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_application_event(
+      "tizen.system.event.test", &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  tizen_base::Bundle data;
+  ret = eventsystem_send_system_event("tizen.system.event.test",
+                                      data.GetHandle());
+  EXPECT_EQ(ret, ES_R_OK);
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, "tizen.system.event.test");
+  g_main_loop_unref(loop);
 }
 
-int FakeGetUid(void) { return 5001; }
+TEST_F(EventSystemTest, eventsystem_unregister_application_event) {
+  unsigned int id;
+  int type;
+  RunModule();
+  int ret = eventsystem_register_application_event(
+      "tizen.system.event.test", &id, &type, AppEventCb, nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
 
-}  // namespace
+  ret = eventsystem_unregister_application_event(id);
+  EXPECT_EQ(ret, ES_R_OK);
+}
 
-class Mocks : public ::testing::NiceMock<GioMock>,
-              public ::testing::NiceMock<AulMock>,
-              public ::testing::NiceMock<LibcMock> {};
+TEST_F(EventSystemTest, eventsystem_keep_last_event_data) {
+  RunModule();
+  int ret = eventsystem_keep_last_event_data("tizen.system.event.test_keep");
+  EXPECT_EQ(ret, ES_R_OK);
 
-class EventSystemTest : public TestFixture {
- public:
-  EventSystemTest() : TestFixture(std::make_unique<Mocks>()) {}
-  virtual ~EventSystemTest() {}
+  tizen_base::Bundle data;
+  ret = eventsystem_send_system_event("tizen.system.event.test_keep",
+                                      data.GetHandle());
+  EXPECT_EQ(ret, ES_R_OK);
 
-  virtual void SetUp() { SetFakeFuncs(); }
-  virtual void TearDown() {}
-
-  void SetFakeFuncs() {
-    EXPECT_CALL(GetMock<GioMock>(), g_dbus_is_interface_name(_))
-        .WillRepeatedly(Invoke(FakeGDBusIsInterfaceName));
-    EXPECT_CALL(GetMock<GioMock>(), g_bus_get_sync(_, _, _))
-        .WillRepeatedly(Invoke(FakeGBusGetSync));
-    EXPECT_CALL(GetMock<GioMock>(),
-                g_bus_own_name_on_connection(_, _, _, _, _, _, _))
-        .WillRepeatedly(Invoke(FakeGBusOwnNameOnConnection));
-    EXPECT_CALL(GetMock<GioMock>(), g_dbus_connection_signal_subscribe(
-                                        _, _, _, _, _, _, _, _, _, _))
-        .WillRepeatedly(Invoke(FakeGDBusConnectionSignalSubscribe));
-    EXPECT_CALL(GetMock<GioMock>(),
-                g_dbus_proxy_new_sync(_, _, _, _, _, _, _, _))
-        .WillRepeatedly(Invoke(FakeGDBusProxyNewSync));
-    EXPECT_CALL(GetMock<GioMock>(), g_dbus_proxy_call_sync(_, _, _, _, _, _, _))
-        .WillRepeatedly(Invoke(FakeGDBusProxyCallSync));
-    EXPECT_CALL(GetMock<GioMock>(),
-                g_dbus_connection_emit_signal(_, _, _, _, _, _, _))
-        .WillRepeatedly(Invoke(FakeGDBusConnectionEmitSignal));
-    EXPECT_CALL(GetMock<GioMock>(), g_dbus_connection_signal_unsubscribe(_, _))
-        .WillRepeatedly(Invoke(FakeGDBusConnectionSignalUnsubscribe));
-    EXPECT_CALL(GetMock<GioMock>(), g_dbus_connection_flush_sync(_, _, _))
-        .WillRepeatedly(Invoke(FakeGDBusConnectionFlushSync));
-
-    EXPECT_CALL(GetMock<AulMock>(), aul_app_get_appid_bypid_for_uid(_, _, _, _))
-        .WillRepeatedly(Invoke(FakeAulAppGetAppidByPidForUid));
-
-    EXPECT_CALL(GetMock<LibcMock>(), getuid())
-        .WillRepeatedly(Invoke(FakeGetUid));
-  }
-};
+  unsigned int id;
+  int type;
+  static GMainLoop* loop;
+  static std::string g_event_name;
 
-static void UserEventCb(const char* event_name, bundle* data, void* user_data) {
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  ret = eventsystem_register_application_event(
+      "tizen.system.event.test_keep", &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, "tizen.system.event.test_keep");
+  g_main_loop_unref(loop);
 }
 
-static void SystemEventCb(const char* event_name, bundle_raw* event_data,
-                          int len, void* user_data) {}
+TEST_F(EventSystemTest, eventsystem_application_finalize) {
+  RunModule();
+  int ret = eventsystem_application_finalize();
+  EXPECT_EQ(ret, ES_R_OK);
+}
 
-TEST_F(EventSystemTest, eventsystem_register_system_event) {
+TEST_F(EventSystemTest, eventsystem_vconf_event_location_enable_state) {
   unsigned int id;
-  int ret = eventsystem_register_event("tizen.system.event.test", &id,
-                                       UserEventCb, nullptr);
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_event(
+      SYS_EVENT_LOCATION_ENABLE_STATE, &id,
+      [](const char* event_name, bundle* data, void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
   EXPECT_EQ(ret, ES_R_OK);
+  GetMock<VConfMock>().ChangeInt(VCONFKEY_LOCATION_USE_MY_LOCATION, 1);
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_LOCATION_ENABLE_STATE);
+  g_main_loop_unref(loop);
 }
 
-TEST_F(EventSystemTest, eventsystem_register_user_event) {
+TEST_F(EventSystemTest, eventsystem_vconf_event_gps_enable_state) {
   unsigned int id;
-  int ret = eventsystem_register_event("event.test", &id, UserEventCb, nullptr);
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_event(
+      SYS_EVENT_GPS_ENABLE_STATE, &id,
+      [](const char* event_name, bundle* data, void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
   EXPECT_EQ(ret, ES_R_OK);
+  GetMock<VConfMock>().ChangeInt(VCONFKEY_LOCATION_ENABLED, 1);
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_GPS_ENABLE_STATE);
+  g_main_loop_unref(loop);
 }
 
-TEST_F(EventSystemTest, eventsystem_unregister_event) {
+TEST_F(EventSystemTest, eventsystem_vconf_event_nps_enable_state) {
   unsigned int id;
-  int ret = eventsystem_register_event("tizen.system.event.test", &id,
-                                       UserEventCb, nullptr);
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_event(
+      SYS_EVENT_NPS_ENABLE_STATE, &id,
+      [](const char* event_name, bundle* data, void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
   EXPECT_EQ(ret, ES_R_OK);
+  GetMock<VConfMock>().ChangeInt(VCONFKEY_LOCATION_NETWORK_ENABLED, 1);
+  g_main_loop_run(loop);
 
-  ret = eventsystem_unregister_event(id);
+  EXPECT_EQ(g_event_name, SYS_EVENT_NPS_ENABLE_STATE);
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_vconf_event_language_set) {
+  unsigned int id;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_event(
+      SYS_EVENT_LANGUAGE_SET, &id,
+      [](const char* event_name, bundle* data, void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
   EXPECT_EQ(ret, ES_R_OK);
+  EXPECT_CALL(GetMock<VConfMock>(), vconf_get_str(_))
+      .WillOnce(Return(strdup("kr")));
+  GetMock<VConfMock>().ChangeStr(VCONFKEY_LANGSET, "Kr");
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_LANGUAGE_SET);
+  g_main_loop_unref(loop);
 }
 
-TEST_F(EventSystemTest, eventsystem_send_user_event) {
-  bundle* data = bundle_create();
-  int ret = eventsystem_send_user_event("event.test", data, false);
+TEST_F(EventSystemTest, eventsystem_vconf_event_hour_format) {
+  unsigned int id;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_event(
+      SYS_EVENT_HOUR_FORMAT, &id,
+      [](const char* event_name, bundle* data, void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
   EXPECT_EQ(ret, ES_R_OK);
+  GetMock<VConfMock>().ChangeInt(VCONFKEY_REGIONFORMAT_TIME1224, 123);
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_HOUR_FORMAT);
+  g_main_loop_unref(loop);
 }
 
-TEST_F(EventSystemTest, eventsystem_send_system_event) {
-  bundle* data = bundle_create();
-  int ret = eventsystem_send_system_event("tizen.system.event.test", data);
+TEST_F(EventSystemTest, eventsystem_vconf_event_region_format) {
+  unsigned int id;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_event(
+      SYS_EVENT_REGION_FORMAT, &id,
+      [](const char* event_name, bundle* data, void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
   EXPECT_EQ(ret, ES_R_OK);
+  EXPECT_CALL(GetMock<VConfMock>(), vconf_get_str(_))
+      .WillOnce(Return(strdup("kr")));
+  GetMock<VConfMock>().ChangeStr(VCONFKEY_REGIONFORMAT, "kr");
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_REGION_FORMAT);
+  g_main_loop_unref(loop);
 }
 
-TEST_F(EventSystemTest, eventsystem_request_sending_system_event) {
-  bundle* data = bundle_create();
-  int ret = eventsystem_request_sending_system_event("event.test", data);
+TEST_F(EventSystemTest, eventsystem_vconf_event_vibration_state) {
+  unsigned int id;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_event(
+      SYS_EVENT_VIBRATION_STATE, &id,
+      [](const char* event_name, bundle* data, void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
   EXPECT_EQ(ret, ES_R_OK);
+  GetMock<VConfMock>().ChangeBool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, true);
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_VIBRATION_STATE);
+  g_main_loop_unref(loop);
 }
 
-TEST_F(EventSystemTest, eventsystem_register_application_event) {
-  EXPECT_CALL(GetMock<GioMock>(), g_dbus_proxy_call_sync(_, _, _, _, _, _, _))
-      .WillOnce(Invoke([&](GDBusProxy* p, const gchar* method, GVariant* v,
-                           GDBusCallFlags flag, gint msec, GCancellable* c,
-                           GError** e) -> GVariant* {
-        *e = nullptr;
-        return g_variant_new("(i)", 1);
-      }))
-      .WillOnce(Invoke([&](GDBusProxy* p, const gchar* method, GVariant* v,
-                           GDBusCallFlags flag, gint msec, GCancellable* c,
-                           GError** e) -> GVariant* {
-        *e = nullptr;
-        return g_variant_new("(iis)", 1, 1, "a");
+TEST_F(EventSystemTest, eventsystem_vconf_event_silent_mode) {
+  unsigned int id;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_event(
+      SYS_EVENT_SILENT_MODE, &id,
+      [](const char* event_name, bundle* data, void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  GetMock<VConfMock>().ChangeBool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, true);
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_SILENT_MODE);
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_vconf_event_autorotate_state) {
+  unsigned int id;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_event(
+      SYS_EVENT_SCREEN_AUTOROTATE_STATE, &id,
+      [](const char* event_name, bundle* data, void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  GetMock<VConfMock>().ChangeBool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
+                                  true);
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_SCREEN_AUTOROTATE_STATE);
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_vconf_event_mobile_data_state) {
+  unsigned int id;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_event(
+      SYS_EVENT_MOBILE_DATA_STATE, &id,
+      [](const char* event_name, bundle* data, void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  GetMock<VConfMock>().ChangeBool(VCONFKEY_3G_ENABLE, true);
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_MOBILE_DATA_STATE);
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_vconf_event_roaming_state) {
+  unsigned int id;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_event(
+      SYS_EVENT_DATA_ROAMING_STATE, &id,
+      [](const char* event_name, bundle* data, void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  GetMock<VConfMock>().ChangeBool(VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL,
+                                  true);
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_DATA_ROAMING_STATE);
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_vconf_event_font_set) {
+  unsigned int id;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_event(
+      SYS_EVENT_FONT_SET, &id,
+      [](const char* event_name, bundle* data, void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  EXPECT_CALL(GetMock<VConfMock>(), vconf_get_str(_))
+      .WillOnce(Return(strdup("font")));
+  GetMock<VConfMock>().ChangeStr(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME,
+                                 "font");
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_FONT_SET);
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_earlier_event_shutdown) {
+  unsigned int id;
+  int type;
+  static std::string g_event_name;
+
+  EXPECT_CALL(GetMock<VConfMock>(), vconf_get_int(_, _))
+      .WillRepeatedly(Invoke([&](const char* in_key, int* val) {
+        *val = VCONFKEY_SYSMAN_POWER_OFF_RESTART;
+        return 0;
       }));
+
+  RunModule();
+  g_event_name = "";
+  GetMock<VConfMock>().ChangeInt(VCONFKEY_SYSMAN_POWER_OFF_STATUS,
+                                 VCONFKEY_SYSMAN_POWER_OFF_RESTART);
+  int ret = eventsystem_register_application_event(
+      SYS_EVENT_SYSTEM_SHUTDOWN, &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) { g_event_name = event_name; },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_SYSTEM_SHUTDOWN);
+}
+
+TEST_F(EventSystemTest, eventsystem_earlier_event_low_memory1) {
   unsigned int id;
   int type;
+  static std::string g_event_name;
+
+  EXPECT_CALL(GetMock<VConfMock>(), vconf_get_int(_, _))
+      .WillRepeatedly(Invoke([&](const char* in_key, int* val) {
+        *val = VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING;
+        return 0;
+      }));
+
+  RunModule();
+  g_event_name = "";
+  GetMock<VConfMock>().ChangeInt(VCONFKEY_SYSMAN_LOW_MEMORY,
+                                 VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING);
   int ret = eventsystem_register_application_event(
-      "tizen.system.event.test", &id, &type, SystemEventCb, NULL);
+      SYS_EVENT_LOW_MEMORY, &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) { g_event_name = event_name; },
+      nullptr);
   EXPECT_EQ(ret, ES_R_OK);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_LOW_MEMORY);
 }
 
-TEST_F(EventSystemTest, eventsystem_unregister_application_event) {
-  EXPECT_CALL(GetMock<GioMock>(), g_dbus_proxy_call_sync(_, _, _, _, _, _, _))
-      .WillOnce(Invoke([&](GDBusProxy* p, const gchar* method, GVariant* v,
-                           GDBusCallFlags flag, gint msec, GCancellable* c,
-                           GError** e) -> GVariant* {
-        *e = nullptr;
-        return g_variant_new("(i)", 1);
-      }))
-      .WillOnce(Invoke([&](GDBusProxy* p, const gchar* method, GVariant* v,
-                           GDBusCallFlags flag, gint msec, GCancellable* c,
-                           GError** e) -> GVariant* {
-        *e = nullptr;
-        return g_variant_new("(iis)", 1, 1, "a");
+TEST_F(EventSystemTest, eventsystem_earlier_event_low_memory2) {
+  unsigned int id;
+  int type;
+  static std::string g_event_name;
+
+  EXPECT_CALL(GetMock<VConfMock>(), vconf_get_int(_, _))
+      .WillRepeatedly(Invoke([&](const char* in_key, int* val) {
+        *val = VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING;
+        return 0;
       }));
 
+  RunModule();
+  g_event_name = "";
+  GetMock<VConfMock>().ChangeInt(VCONFKEY_SYSMAN_LOW_MEMORY,
+                                 VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING);
+  int ret = eventsystem_register_application_event(
+      SYS_EVENT_LOW_MEMORY, &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) { g_event_name = event_name; },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_LOW_MEMORY);
+}
+
+TEST_F(EventSystemTest, eventsystem_earlier_event_low_memory3) {
   unsigned int id;
   int type;
+  static std::string g_event_name;
+
+  EXPECT_CALL(GetMock<VConfMock>(), vconf_get_int(_, _))
+      .WillRepeatedly(Invoke([&](const char* in_key, int* val) {
+        *val = VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING + 1;
+        return 0;
+      }));
+
+  RunModule();
+  g_event_name = "";
+  GetMock<VConfMock>().ChangeInt(VCONFKEY_SYSMAN_LOW_MEMORY,
+                                 VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING + 1);
   int ret = eventsystem_register_application_event(
-      "tizen.system.event.test", &id, &type, SystemEventCb, NULL);
+      SYS_EVENT_LOW_MEMORY, &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) { g_event_name = event_name; },
+      nullptr);
   EXPECT_EQ(ret, ES_R_OK);
 
-  ret = eventsystem_unregister_application_event(id);
+  EXPECT_EQ(g_event_name, SYS_EVENT_LOW_MEMORY);
+}
+
+TEST_F(EventSystemTest, eventsystem_earlier_event_charger_status1) {
+  unsigned int id;
+  int type;
+  static std::string g_event_name;
+
+  RunModule();
+  g_event_name = "";
+  GetMock<VConfMock>().ChangeInt(VCONFKEY_SYSMAN_CHARGER_STATUS,
+                                 VCONFKEY_SYSMAN_CHARGER_CONNECTED);
+  int ret = eventsystem_register_application_event(
+      SYS_EVENT_BATTERY_CHARGER_STATUS, &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) { g_event_name = event_name; },
+      nullptr);
   EXPECT_EQ(ret, ES_R_OK);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_BATTERY_CHARGER_STATUS);
 }
 
-TEST_F(EventSystemTest, eventsystem_keep_last_event_data) {
-  EXPECT_CALL(GetMock<GioMock>(), g_dbus_proxy_call_sync(_, _, _, _, _, _, _))
-      .WillRepeatedly(Invoke([&](GDBusProxy* p, const gchar* method,
-                                 GVariant* v, GDBusCallFlags flag, gint msec,
-                                 GCancellable* c, GError** e) -> GVariant* {
-        *e = nullptr;
-        return g_variant_new("(i)", 0);
+TEST_F(EventSystemTest, eventsystem_earlier_event_charger_status2) {
+  unsigned int id;
+  int type;
+  static std::string g_event_name;
+  EXPECT_CALL(GetMock<VConfMock>(), vconf_get_int(_, _))
+      .WillRepeatedly(Invoke([&](const char* in_key, int* val) {
+        *val = VCONFKEY_SYSMAN_CHARGER_CONNECTED;
+        return 0;
       }));
 
-  int ret = eventsystem_keep_last_event_data("tizen.system.event.test");
+  RunModule();
+  g_event_name = "";
+  GetMock<VConfMock>().ChangeInt(VCONFKEY_SYSMAN_CHARGER_STATUS,
+                                 VCONFKEY_SYSMAN_CHARGER_CONNECTED);
+  int ret = eventsystem_register_application_event(
+      SYS_EVENT_BATTERY_CHARGER_STATUS, &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) { g_event_name = event_name; },
+      nullptr);
   EXPECT_EQ(ret, ES_R_OK);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_BATTERY_CHARGER_STATUS);
 }
 
-TEST_F(EventSystemTest, eventsystem_application_finalize) {
-  int ret = eventsystem_application_finalize();
+TEST_F(EventSystemTest, eventsystem_earlier_event_boot_completed) {
+  unsigned int id;
+  int type;
+  static std::string g_event_name;
+
+  RunModule();
+  g_event_name = "";
+  tizen_base::Bundle data;
+  eventsystem_send_system_event(SYS_EVENT_BOOT_COMPLETED, data.GetHandle());
+
+  int ret = eventsystem_register_application_event(
+      SYS_EVENT_BOOT_COMPLETED, &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) { g_event_name = event_name; },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_BOOT_COMPLETED);
+}
+
+TEST_F(EventSystemTest, eventsystem_launch_event_battery_charger_status) {
+  unsigned int id;
+  int type;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+              pkgmgrinfo_appinfo_foreach_appcontrol(_, _, _))
+      .WillOnce(Invoke([](auto handle, pkgmgrinfo_app_control_list_cb callback,
+                          void* user_data) {
+        std::string uri = std::string(SYSTEM_EVENT_NAME_PREFIX) +
+                          SYS_EVENT_BATTERY_CHARGER_STATUS;
+        callback(AUL_SVC_OPERATION_LAUNCH_ON_EVENT, uri.c_str(), "test_mime",
+                 user_data);
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<AulMock>(),
+              aul_svc_run_service_async_for_uid(_, _, _, _, _))
+      .Times(1);
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_application_event(
+      SYS_EVENT_BATTERY_CHARGER_STATUS, &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  tizen_base::Bundle data = {
+      {EVT_KEY_BATTERY_CHARGER_STATUS, EVT_VAL_BATTERY_CHARGER_CONNECTED}};
+  eventsystem_send_system_event(SYS_EVENT_BATTERY_CHARGER_STATUS,
+                                data.GetHandle());
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_BATTERY_CHARGER_STATUS);
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_launch_event_usb_status) {
+  unsigned int id;
+  int type;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+              pkgmgrinfo_appinfo_foreach_appcontrol(_, _, _))
+      .WillOnce(Invoke([](auto handle, pkgmgrinfo_app_control_list_cb callback,
+                          void* user_data) {
+        std::string uri =
+            std::string(SYSTEM_EVENT_NAME_PREFIX) + SYS_EVENT_USB_STATUS;
+        callback(AUL_SVC_OPERATION_LAUNCH_ON_EVENT, uri.c_str(), "test_mime",
+                 user_data);
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<AulMock>(),
+              aul_svc_run_service_async_for_uid(_, _, _, _, _))
+      .Times(1);
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_application_event(
+      SYS_EVENT_USB_STATUS, &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  tizen_base::Bundle data = {{EVT_KEY_USB_STATUS, EVT_VAL_USB_CONNECTED}};
+  eventsystem_send_system_event(SYS_EVENT_USB_STATUS, data.GetHandle());
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_USB_STATUS);
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_launch_event_earjack_status) {
+  unsigned int id;
+  int type;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+              pkgmgrinfo_appinfo_foreach_appcontrol(_, _, _))
+      .WillOnce(Invoke([](auto handle, pkgmgrinfo_app_control_list_cb callback,
+                          void* user_data) {
+        std::string uri =
+            std::string(SYSTEM_EVENT_NAME_PREFIX) + SYS_EVENT_EARJACK_STATUS;
+        callback(AUL_SVC_OPERATION_LAUNCH_ON_EVENT, uri.c_str(), "test_mime",
+                 user_data);
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<AulMock>(),
+              aul_svc_run_service_async_for_uid(_, _, _, _, _))
+      .Times(1);
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_application_event(
+      SYS_EVENT_EARJACK_STATUS, &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  tizen_base::Bundle data = {
+      {EVT_KEY_EARJACK_STATUS, EVT_VAL_EARJACK_CONNECTED}};
+  eventsystem_send_system_event(SYS_EVENT_EARJACK_STATUS, data.GetHandle());
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_EARJACK_STATUS);
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_launch_event_incomming_msg) {
+  unsigned int id;
+  int type;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+              pkgmgrinfo_appinfo_foreach_appcontrol(_, _, _))
+      .WillOnce(Invoke([](auto handle, pkgmgrinfo_app_control_list_cb callback,
+                          void* user_data) {
+        std::string uri =
+            std::string(SYSTEM_EVENT_NAME_PREFIX) + SYS_EVENT_INCOMMING_MSG;
+        callback(AUL_SVC_OPERATION_LAUNCH_ON_EVENT, uri.c_str(), "test_mime",
+                 user_data);
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<AulMock>(),
+              aul_svc_run_service_async_for_uid(_, _, _, _, _))
+      .Times(1);
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_application_event(
+      SYS_EVENT_INCOMMING_MSG, &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  tizen_base::Bundle data = {{EVT_KEY_MSG_TYPE, "val"},
+                             {EVT_KEY_MSG_ID, "val"}};
+  eventsystem_send_system_event(SYS_EVENT_INCOMMING_MSG, data.GetHandle());
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_INCOMMING_MSG);
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_launch_event_outgoing_msg) {
+  unsigned int id;
+  int type;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+              pkgmgrinfo_appinfo_foreach_appcontrol(_, _, _))
+      .WillOnce(Invoke([](auto handle, pkgmgrinfo_app_control_list_cb callback,
+                          void* user_data) {
+        std::string uri =
+            std::string(SYSTEM_EVENT_NAME_PREFIX) + SYS_EVENT_OUTGOING_MSG;
+        callback(AUL_SVC_OPERATION_LAUNCH_ON_EVENT, uri.c_str(), "test_mime",
+                 user_data);
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<AulMock>(),
+              aul_svc_run_service_async_for_uid(_, _, _, _, _))
+      .Times(1);
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_application_event(
+      SYS_EVENT_OUTGOING_MSG, &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  tizen_base::Bundle data = {{EVT_KEY_OUT_MSG_TYPE, "val"},
+                             {EVT_KEY_OUT_MSG_ID, "val"}};
+  eventsystem_send_system_event(SYS_EVENT_OUTGOING_MSG, data.GetHandle());
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_OUTGOING_MSG);
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_launch_event_wifi_state) {
+  unsigned int id;
+  int type;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+              pkgmgrinfo_appinfo_foreach_appcontrol(_, _, _))
+      .WillOnce(Invoke([](auto handle, pkgmgrinfo_app_control_list_cb callback,
+                          void* user_data) {
+        std::string uri =
+            std::string(SYSTEM_EVENT_NAME_PREFIX) + SYS_EVENT_WIFI_STATE;
+        callback(AUL_SVC_OPERATION_LAUNCH_ON_EVENT, uri.c_str(), "test_mime",
+                 user_data);
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<AulMock>(),
+              aul_svc_run_service_async_for_uid(_, _, _, _, _))
+      .Times(1);
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_application_event(
+      SYS_EVENT_WIFI_STATE, &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
   EXPECT_EQ(ret, ES_R_OK);
+  tizen_base::Bundle data = {{EVT_KEY_WIFI_STATE, EVT_VAL_WIFI_CONNECTED}};
+  eventsystem_send_system_event(SYS_EVENT_WIFI_STATE, data.GetHandle());
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, SYS_EVENT_WIFI_STATE);
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_launch_event_user_event1) {
+  unsigned int id;
+  int type;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+              pkgmgrinfo_appinfo_foreach_appcontrol(_, _, _))
+      .WillOnce(Invoke([](auto handle, pkgmgrinfo_app_control_list_cb callback,
+                          void* user_data) {
+        std::string uri = "event.test";
+        callback(AUL_SVC_OPERATION_LAUNCH_ON_EVENT, uri.c_str(), "test_mime",
+                 user_data);
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<AulMock>(),
+              aul_svc_run_service_async_for_uid(_, _, _, _, _))
+      .Times(1);
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_application_event(
+      "event.test", &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  tizen_base::Bundle data;
+  eventsystem_send_user_event("event.test", data.GetHandle(), false);
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, "event.test");
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_launch_event_user_event2) {
+  unsigned int id;
+  int type;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+              pkgmgrinfo_appinfo_foreach_appcontrol(_, _, _))
+      .WillOnce(Invoke([](auto handle, pkgmgrinfo_app_control_list_cb callback,
+                          void* user_data) {
+        std::string uri = "event.test";
+        callback(AUL_SVC_OPERATION_LAUNCH_ON_EVENT, uri.c_str(), "test_mime",
+                 user_data);
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+              pkgmgrinfo_pkginfo_compare_usr_app_cert_info(_, _, _, _))
+      .WillRepeatedly(Invoke([](const char*, const char*, uid_t,
+                                pkgmgrinfo_cert_compare_result_type_e* ret) {
+        *ret = PMINFO_CERT_COMPARE_MATCH;
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<AulMock>(),
+              aul_svc_run_service_async_for_uid(_, _, _, _, _))
+      .Times(1);
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_application_event(
+      "event.test", &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  tizen_base::Bundle data;
+  eventsystem_send_user_event("event.test", data.GetHandle(), true);
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, "event.test");
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_uninstall_event) {
+  unsigned int id;
+  int type;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+              pkgmgrinfo_appinfo_foreach_appcontrol(_, _, _))
+      .WillOnce(Invoke([](auto handle, pkgmgrinfo_app_control_list_cb callback,
+                          void* user_data) {
+        std::string uri = "event.test";
+        callback(AUL_SVC_OPERATION_LAUNCH_ON_EVENT, uri.c_str(), "test_mime",
+                 user_data);
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(), pkgmgr_client_listen_status(_, _, _))
+      .WillOnce(Invoke([](pkgmgr_client*, pkgmgr_handler cb, void* data) {
+        cb(0, 1, "tpk", "testpkg", "start", "uninstall", nullptr, data);
+        cb(0, 1, "tpk", "testpkg", "end", "ok", nullptr, data);
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<AulMock>(),
+              aul_svc_run_service_async_for_uid(_, _, _, _, _))
+      .Times(0);
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_application_event(
+      "event.test", &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  tizen_base::Bundle data;
+  eventsystem_send_system_event("event.test", data.GetHandle());
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, "event.test");
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_install_event) {
+  unsigned int id;
+  int type;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+              pkgmgrinfo_appinfo_foreach_appcontrol(_, _, _))
+      .WillRepeatedly(
+          Invoke([](auto handle, pkgmgrinfo_app_control_list_cb callback,
+                    void* user_data) {
+            std::string uri = "event.test";
+            callback(AUL_SVC_OPERATION_LAUNCH_ON_EVENT, uri.c_str(),
+                     "test_mime", user_data);
+            return 0;
+          }));
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(), pkgmgr_client_listen_status(_, _, _))
+      .WillOnce(Invoke([](pkgmgr_client*, pkgmgr_handler cb, void* data) {
+        cb(0, 1, "tpk", "test2pkg", "start", "install", nullptr, data);
+        cb(0, 1, "tpk", "test2pkg", "end", "ok", nullptr, data);
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+              pkgmgrinfo_appinfo_get_usr_list(_, _, _, _, _))
+      .WillOnce(Invoke([](pkgmgrinfo_pkginfo_h, pkgmgrinfo_app_component,
+                          pkgmgrinfo_app_list_cb cb, void* data, uid_t) {
+        cb(nullptr, data);
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<AulMock>(),
+              aul_svc_run_service_async_for_uid(_, _, _, _, _))
+      .Times(2);
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_application_event(
+      "event.test", &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  tizen_base::Bundle data;
+  eventsystem_send_system_event("event.test", data.GetHandle());
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, "event.test");
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_update_event) {
+  unsigned int id;
+  int type;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+              pkgmgrinfo_appinfo_foreach_appcontrol(_, _, _))
+      .WillRepeatedly(
+          Invoke([](auto handle, pkgmgrinfo_app_control_list_cb callback,
+                    void* user_data) {
+            std::string uri = "event.test";
+            callback(AUL_SVC_OPERATION_LAUNCH_ON_EVENT, uri.c_str(),
+                     "test_mime", user_data);
+            return 0;
+          }));
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(), pkgmgr_client_listen_status(_, _, _))
+      .WillOnce(Invoke([](pkgmgr_client*, pkgmgr_handler cb, void* data) {
+        cb(0, 1, "tpk", "test2pkg", "start", "update", nullptr, data);
+        cb(0, 1, "tpk", "test2pkg", "end", "ok", nullptr, data);
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+              pkgmgrinfo_appinfo_get_usr_list(_, _, _, _, _))
+      .WillOnce(Invoke([](pkgmgrinfo_pkginfo_h, pkgmgrinfo_app_component,
+                          pkgmgrinfo_app_list_cb cb, void* data, uid_t) {
+        cb(nullptr, data);
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<AulMock>(),
+              aul_svc_run_service_async_for_uid(_, _, _, _, _))
+      .Times(2);
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_application_event(
+      "event.test", &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  tizen_base::Bundle data;
+  eventsystem_send_system_event("event.test", data.GetHandle());
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, "event.test");
+  g_main_loop_unref(loop);
+}
+
+TEST_F(EventSystemTest, eventsystem_install_fail_event) {
+  unsigned int id;
+  int type;
+  static GMainLoop* loop;
+  static std::string g_event_name;
+
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+              pkgmgrinfo_appinfo_foreach_appcontrol(_, _, _))
+      .WillRepeatedly(
+          Invoke([](auto handle, pkgmgrinfo_app_control_list_cb callback,
+                    void* user_data) {
+            std::string uri = "event.test";
+            callback(AUL_SVC_OPERATION_LAUNCH_ON_EVENT, uri.c_str(),
+                     "test_mime", user_data);
+            return 0;
+          }));
+  EXPECT_CALL(GetMock<PkgmgrInfoMock>(), pkgmgr_client_listen_status(_, _, _))
+      .WillOnce(Invoke([](pkgmgr_client*, pkgmgr_handler cb, void* data) {
+        cb(0, 1, "tpk", "test2pkg", "start", "install", nullptr, data);
+        cb(0, 1, "tpk", "test2pkg", "end", "fail", nullptr, data);
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<AulMock>(),
+              aul_svc_run_service_async_for_uid(_, _, _, _, _))
+      .Times(1);
+
+  RunModule();
+  g_event_name = "";
+  loop = g_main_loop_new(nullptr, FALSE);
+  int ret = eventsystem_register_application_event(
+      "event.test", &id, &type,
+      [](const char* event_name, bundle_raw* event_data, int len,
+         void* user_data) {
+        g_event_name = event_name;
+        g_main_loop_quit(loop);
+      },
+      nullptr);
+  EXPECT_EQ(ret, ES_R_OK);
+  tizen_base::Bundle data;
+  eventsystem_send_system_event("event.test", data.GetHandle());
+  g_main_loop_run(loop);
+
+  EXPECT_EQ(g_event_name, "event.test");
+  g_main_loop_unref(loop);
 }
index edaac0d87bce7e14679978ecdcc7799b13f0043b..571dd0be767f5da11e4632a9b151cd7e2ef25873 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 - 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
  * limitations under the License.
  */
 
-#include <dlog.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
-#include <stdarg.h>
-#include <stdio.h>
 
-// LCOV_EXCL_START
-extern "C" int __dlog_sec_print(log_id_t log_id, int prio, const char* tag,
-                                const char* fmt, ...) {
-  printf("%s:", tag);
-  va_list ap;
-  va_start(ap, fmt);
-  vprintf(fmt, ap);
-  va_end(ap);
-  printf("\n");
-  return 0;
-}
+//#define LOG_INTERNAL
 
-extern "C" int dlog_vprint(log_priority prio, const char* tag, const char* fmt,
-                           va_list ap) {
-  printf("%s:", tag);
-  vprintf(fmt, ap);
-  printf("\n");
-  return 0;
-}
+#ifdef LOG_INTERNAL
+#include <dlog.h>
 
 extern "C" int __dlog_print(log_id_t log_id, int prio, const char* tag,
                             const char* fmt, ...) {
@@ -48,9 +30,10 @@ extern "C" int __dlog_print(log_id_t log_id, int prio, const char* tag,
   vprintf(fmt, ap);
   va_end(ap);
   printf("\n");
+
   return 0;
 }
-// LCOV_EXCL_STOP
+#endif
 
 int main(int argc, char** argv) {
   int ret = -1;
index 7a5d4d3784c196cf2651d4e1285c409e090ee99f..611ca9c0554558d8a48f7f6c728f70fb49766b66 100644 (file)
  * limitations under the License.
  */
 
-#include "mock/aul_mock.hh"
+#include "aul_mock.hh"
 
-#include "mock/mock_hook.hh"
-#include "mock/test_fixture.hh"
+#include "mock_hook.hh"
+#include "test_fixture.hh"
 
-extern "C" int aul_app_get_appid_bypid_for_uid(int pid, char* appid, int len,
-                                               uid_t uid) {
-  return MOCK_HOOK_P4(AulMock, aul_app_get_appid_bypid_for_uid, pid, appid,
-                      len, uid);
+extern "C" int aul_svc_get_appid_by_alias_appid(const char* arg0, char** arg1) {
+  return MOCK_HOOK_P2(AulMock, aul_svc_get_appid_by_alias_appid, arg0, arg1);
 }
+
+extern "C" int aul_svc_run_service_async_for_uid(bundle* arg0, int arg1,
+                                                 aul_svc_res_fn arg2,
+                                                 void* arg3, uid_t arg4) {
+  return MOCK_HOOK_P5(AulMock, aul_svc_run_service_async_for_uid, arg0, arg1,
+                      arg2, arg3, arg4);
+}
+
+/*
+extern "C" int aul_app_is_running_for_uid(const char* arg0, uid_t arg1) {
+  return MOCK_HOOK_P2(AulMock, aul_app_is_running_for_uid, arg0, arg1);
+}
+
+extern "C" int aul_app_get_appid_bypid_for_uid(int arg0, char* arg1, int arg2,
+                                               uid_t arg3) {
+  return MOCK_HOOK_P4(AulMock, aul_app_get_appid_bypid_for_uid, arg0, arg1,
+                      arg2, arg3);
+}
+
+extern "C" int aul_app_get_appid_bypid(int pid, char* appid, int size) {
+  return MOCK_HOOK_P3(AulMock, aul_app_get_appid_bypid, pid, appid, size);
+}
+*/
index 9ee2e47e073512b638529191c5c89e4f4952d276..e48b866cca94bd3cc79cb38a4359ed58186971d6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
  * limitations under the License.
  */
 
-#ifndef UNIT_TESTS_MOCK_AUL_MOCK_HH_
-#define UNIT_TESTS_MOCK_AUL_MOCK_HH_
+#ifndef MOCK_AUL_MOCK_H_
+#define MOCK_AUL_MOCK_H_
 
 #include <aul.h>
+#include <aul_svc.h>
 #include <gmock/gmock.h>
 
-#include "mock/module_mock.hh"
+#include "module_mock.hh"
 
 class AulMock : public virtual ModuleMock {
  public:
-  AulMock() {}
   virtual ~AulMock() {}
 
-  MOCK_METHOD4(aul_app_get_appid_bypid_for_uid, int(int, char*, int, uid_t));
+  MOCK_METHOD2(aul_svc_get_appid_by_alias_appid, int(const char*, char**));
+  MOCK_METHOD5(aul_svc_run_service_async_for_uid,
+               int(bundle*, int, aul_svc_res_fn, void*, uid_t));
+  //MOCK_METHOD2(aul_app_is_running_for_uid, int(const char*, uid_t));
+  //MOCK_METHOD4(aul_app_get_appid_bypid_for_uid, int(int, char*, int, uid_t));
+  //MOCK_METHOD3(aul_app_get_appid_bypid, int(int, char*, int));
 };
 
-#endif  // UNIT_TESTS_MOCK_AUL_MOCK_HH_
+#endif  // MOCK_AUL_MOCK_H_
diff --git a/tests/unit_tests/mock/gio_mock.cc b/tests/unit_tests/mock/gio_mock.cc
deleted file mode 100644 (file)
index 1debaec..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2022 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 "mock/gio_mock.hh"
-
-#include "mock/mock_hook.hh"
-#include "mock/test_fixture.hh"
-
-extern "C" gboolean g_dbus_is_interface_name(const gchar* arg0) {
-  return MOCK_HOOK_P1(GioMock, g_dbus_is_interface_name, arg0);
-}
-
-extern "C" GDBusConnection* g_bus_get_sync(GBusType type,
-    GCancellable* cancellable, GError** error) {
-  return MOCK_HOOK_P3(GioMock, g_bus_get_sync, type, cancellable, error);
-}
-
-extern "C" guint g_dbus_connection_signal_subscribe(GDBusConnection* arg0,
-    const gchar* arg1, const gchar* arg2, const gchar* arg3, const gchar* arg4,
-    const gchar* arg5, GDBusSignalFlags arg6, GDBusSignalCallback arg7,
-    gpointer arg8, GDestroyNotify arg9) {
-  return MOCK_HOOK_P10(GioMock, g_dbus_connection_signal_subscribe,
-      arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
-}
-
-extern "C" guint g_bus_own_name_on_connection(GDBusConnection* arg0,
-    const gchar* arg1, GBusNameOwnerFlags arg2, GBusNameAcquiredCallback arg3,
-    GBusNameLostCallback arg4, gpointer arg5, GDestroyNotify arg6) {
-  return MOCK_HOOK_P7(GioMock, g_bus_own_name_on_connection,
-      arg0, arg1, arg2, arg3, arg4, arg5, arg6);
-}
-
-extern "C" GDBusProxy* g_dbus_proxy_new_sync(GDBusConnection* arg0,
-    GDBusProxyFlags arg1, GDBusInterfaceInfo* arg2, const gchar* arg3,
-    const gchar* arg4, const gchar* arg5, GCancellable* arg6, GError** arg7) {
-  return MOCK_HOOK_P8(GioMock, g_dbus_proxy_new_sync,
-      arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
-}
-
-extern "C" GVariant* g_dbus_proxy_call_sync(GDBusProxy* arg1,
-    const gchar* arg2, GVariant* arg3, GDBusCallFlags arg4, gint arg5,
-    GCancellable* arg6, GError** arg7) {
-  return MOCK_HOOK_P7(GioMock, g_dbus_proxy_call_sync, arg1, arg2,
-      arg3, arg4, arg5, arg6, arg7);
-}
-
-extern "C" gboolean g_dbus_connection_emit_signal(GDBusConnection* arg1,
-    const gchar* arg2, const gchar* arg3, const gchar* arg4, const gchar* arg5,
-    GVariant* arg6, GError** arg7) {
-  return MOCK_HOOK_P7(GioMock, g_dbus_connection_emit_signal, arg1, arg2,
-      arg3, arg4, arg5, arg6, arg7);
-}
-
-extern "C" void g_dbus_connection_signal_unsubscribe(
-    GDBusConnection* arg0, guint arg1) {
-  return MOCK_HOOK_P2(GioMock, g_dbus_connection_signal_unsubscribe,
-      arg0, arg1);
-}
-
-extern "C" gboolean g_dbus_connection_flush_sync(GDBusConnection* arg1,
-                                                 GCancellable* arg2,
-                                                 GError** arg3) {
-  return MOCK_HOOK_P3(GioMock, g_dbus_connection_flush_sync, arg1, arg2, arg3);
-}
diff --git a/tests/unit_tests/mock/gio_mock.hh b/tests/unit_tests/mock/gio_mock.hh
deleted file mode 100644 (file)
index 0a236aa..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2022 - 2024 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 UNIT_TESTS_MOCK_GIO_MOCK_HH_
-#define UNIT_TESTS_MOCK_GIO_MOCK_HH_
-
-#include <gio/gio.h>
-#include <gmock/gmock.h>
-
-#include "mock/module_mock.hh"
-
-class GioMock : public virtual ModuleMock {
- public:
-  GioMock() {}
-  virtual ~GioMock() {}
-
-  MOCK_METHOD1(g_dbus_is_interface_name, gboolean(const gchar *));
-  MOCK_METHOD3(g_bus_get_sync,
-               GDBusConnection *(GBusType, GCancellable *, GError **));
-  MOCK_METHOD7(g_bus_own_name_on_connection,
-               guint(GDBusConnection *, const gchar *, GBusNameOwnerFlags,
-                     GBusNameAcquiredCallback, GBusNameLostCallback, gpointer,
-                     GDestroyNotify));
-  MOCK_METHOD10(g_dbus_connection_signal_subscribe,
-                guint(GDBusConnection *, const gchar *, const gchar *,
-                      const gchar *, const gchar *, const gchar *,
-                      GDBusSignalFlags, GDBusSignalCallback, gpointer,
-                      GDestroyNotify));
-  MOCK_METHOD8(g_dbus_proxy_new_sync,
-               GDBusProxy *(GDBusConnection *, GDBusProxyFlags,
-                            GDBusInterfaceInfo *, const gchar *, const gchar *,
-                            const gchar *, GCancellable *, GError **));
-  MOCK_METHOD7(g_dbus_proxy_call_sync,
-               GVariant *(GDBusProxy *, const gchar *, GVariant *,
-                          GDBusCallFlags, gint, GCancellable *, GError **));
-  MOCK_METHOD7(g_dbus_connection_emit_signal,
-               gboolean(GDBusConnection *, const gchar *, const gchar *,
-                        const gchar *, const gchar *, GVariant *, GError **));
-  MOCK_METHOD2(g_dbus_connection_signal_unsubscribe,
-               void(GDBusConnection *, guint));
-  MOCK_METHOD3(g_dbus_connection_flush_sync,
-               gboolean(GDBusConnection *, GCancellable *, GError **));
-};
-
-#endif  // UNIT_TESTS_MOCK_GIO_MOCK_HH_
diff --git a/tests/unit_tests/mock/libc_mock.cc b/tests/unit_tests/mock/libc_mock.cc
deleted file mode 100644 (file)
index 5bb9dd8..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2024 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 "mock/libc_mock.hh"
-
-#include "mock/mock_hook.hh"
-#include "mock/test_fixture.hh"
-
-extern "C" uid_t getuid(void) { return MOCK_HOOK_P0(LibcMock, getuid); }
diff --git a/tests/unit_tests/mock/libc_mock.hh b/tests/unit_tests/mock/libc_mock.hh
deleted file mode 100644 (file)
index 6582255..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2024 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 UNIT_TESTS_MOCK_LIBC_MOCK_HH_
-#define UNIT_TESTS_MOCK_LIBC_MOCK_HH_
-
-#include <unistd.h>
-#include <gmock/gmock.h>
-
-#include "mock/module_mock.hh"
-
-class LibcMock : public virtual ModuleMock {
- public:
-  LibcMock() {}
-  virtual ~LibcMock() {}
-
-  MOCK_METHOD0(getuid, uid_t(void));
-};
-
-#endif  // UNIT_TESTS_MOCK_LIBC_MOCK_HH_
diff --git a/tests/unit_tests/mock/pkgmgr_info_mock.cc b/tests/unit_tests/mock/pkgmgr_info_mock.cc
new file mode 100644 (file)
index 0000000..46600d2
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2024 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 "pkgmgr_info_mock.hh"
+
+#include "mock_hook.hh"
+#include "test_fixture.hh"
+
+extern "C" int pkgmgrinfo_appinfo_get_appid(pkgmgrinfo_appinfo_h arg0,
+                                            char** arg1) {
+  return MOCK_HOOK_P2(PkgmgrInfoMock, pkgmgrinfo_appinfo_get_appid, arg0, arg1);
+}
+
+extern "C" int pkgmgrinfo_appinfo_get_pkgid(pkgmgrinfo_appinfo_h handle,
+                                            char** pkgid) {
+  return MOCK_HOOK_P2(PkgmgrInfoMock, pkgmgrinfo_appinfo_get_pkgid, handle,
+                      pkgid);
+}
+
+extern "C" int pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(
+    pkgmgrinfo_appinfo_filter_h handle, pkgmgrinfo_app_list_cb callback,
+    void* user_data, uid_t uid) {
+  return MOCK_HOOK_P4(PkgmgrInfoMock,
+                      pkgmgrinfo_appinfo_usr_filter_foreach_appinfo, handle,
+                      callback, user_data, uid);
+}
+
+extern "C" int pkgmgrinfo_appinfo_foreach_appcontrol(
+    pkgmgrinfo_appinfo_h arg0, pkgmgrinfo_app_control_list_cb arg1,
+    void* arg2) {
+  return MOCK_HOOK_P3(PkgmgrInfoMock, pkgmgrinfo_appinfo_foreach_appcontrol,
+                      arg0, arg1, arg2);
+}
+
+extern "C" int pkgmgrinfo_pkginfo_load_certinfo(const char* pkgid,
+                                                pkgmgrinfo_certinfo_h handle,
+                                                uid_t uid) {
+  return MOCK_HOOK_P3(PkgmgrInfoMock, pkgmgrinfo_pkginfo_load_certinfo, pkgid,
+                      handle, uid);
+}
+
+extern "C" int pkgmgrinfo_pkginfo_get_cert_value(pkgmgrinfo_certinfo_h handle,
+                                                 pkgmgrinfo_cert_type cert_type,
+                                                 const char** cert_value) {
+  return MOCK_HOOK_P3(PkgmgrInfoMock, pkgmgrinfo_pkginfo_get_cert_value, handle,
+                      cert_type, cert_value);
+}
+
+extern "C" int certsvc_certificate_new_from_memory(
+    CertSvcInstance instance, const unsigned char* memory, size_t len,
+    CertSvcCertificateForm form, CertSvcCertificate* certificate) {
+  return MOCK_HOOK_P5(PkgmgrInfoMock, certsvc_certificate_new_from_memory,
+                      instance, memory, len, form, certificate);
+}
+
+extern "C" int certsvc_certificate_get_visibility(
+    CertSvcCertificate certificate, CertSvcVisibility* visibility) {
+  return MOCK_HOOK_P2(PkgmgrInfoMock, certsvc_certificate_get_visibility,
+                      certificate, visibility);
+}
+
+extern "C" void certsvc_certificate_free(CertSvcCertificate certificate) {
+  return MOCK_HOOK_P1(PkgmgrInfoMock, certsvc_certificate_free, certificate);
+}
+
+extern "C" int pkgmgr_client_listen_status(pkgmgr_client* arg0,
+                                           pkgmgr_handler arg1, void* arg2) {
+  return MOCK_HOOK_P3(PkgmgrInfoMock, pkgmgr_client_listen_status, arg0, arg1,
+                      arg2);
+}
+
+extern "C" int pkgmgrinfo_pkginfo_compare_usr_app_cert_info(
+    const char* arg0, const char* arg1, uid_t arg2,
+    pkgmgrinfo_cert_compare_result_type_e* arg3) {
+  return MOCK_HOOK_P4(PkgmgrInfoMock,
+                      pkgmgrinfo_pkginfo_compare_usr_app_cert_info, arg0, arg1,
+                      arg2, arg3);
+}
+
+extern "C" int pkgmgrinfo_pkginfo_get_usr_pkginfo(const char* arg0, uid_t arg1,
+                                                  pkgmgrinfo_pkginfo_h* arg2) {
+  return MOCK_HOOK_P3(PkgmgrInfoMock, pkgmgrinfo_pkginfo_get_usr_pkginfo, arg0,
+                      arg1, arg2);
+}
+
+extern "C" int pkgmgrinfo_appinfo_get_usr_list(pkgmgrinfo_pkginfo_h arg0,
+                                               pkgmgrinfo_app_component arg1,
+                                               pkgmgrinfo_app_list_cb arg2,
+                                               void* arg3, uid_t arg4) {
+  return MOCK_HOOK_P5(PkgmgrInfoMock, pkgmgrinfo_appinfo_get_usr_list, arg0,
+                      arg1, arg2, arg3, arg4);
+}
+
+extern "C" int pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo_h arg0) {
+  return MOCK_HOOK_P1(PkgmgrInfoMock, pkgmgrinfo_pkginfo_destroy_pkginfo, arg0);
+}
diff --git a/tests/unit_tests/mock/pkgmgr_info_mock.hh b/tests/unit_tests/mock/pkgmgr_info_mock.hh
new file mode 100644 (file)
index 0000000..4dc5e54
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2024 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 TESTS_UNIT_TESTS_MOCK_PKGMGR_INFO_MOCK_HH_
+#define TESTS_UNIT_TESTS_MOCK_PKGMGR_INFO_MOCK_HH_
+
+#include <cert-svc/ccert.h>
+#include <cert-svc/cinstance.h>
+#include <gmock/gmock.h>
+#include <package-manager.h>
+#include <pkgmgr-info.h>
+
+#include "module_mock.hh"
+
+class PkgmgrInfoMock : public virtual ModuleMock {
+ public:
+  PkgmgrInfoMock() {
+    using ::testing::_;
+    using ::testing::Invoke;
+    using ::testing::Return;
+
+    ON_CALL(*this, pkgmgrinfo_pkginfo_get_cert_value(_, _, _))
+        .WillByDefault(
+            Invoke([](pkgmgrinfo_certinfo_h handle,
+                      pkgmgrinfo_cert_type cert_type, const char** cert_value) {
+              *cert_value = "test_cert_value";
+              return 0;
+            }));
+    ON_CALL(*this, certsvc_certificate_new_from_memory(_, _, _, _, _))
+        .WillByDefault(Return(CERTSVC_SUCCESS));
+    ON_CALL(*this, certsvc_certificate_get_visibility(_, _))
+        .WillByDefault(
+            Invoke([](CertSvcCertificate, CertSvcVisibility* visibility) {
+              *visibility = CERTSVC_VISIBILITY_PLATFORM;
+              return CERTSVC_SUCCESS;
+            }));
+  }
+
+  virtual ~PkgmgrInfoMock() {}
+
+  MOCK_METHOD2(pkgmgrinfo_appinfo_get_appid, int(pkgmgrinfo_appinfo_h, char**));
+  MOCK_METHOD2(pkgmgrinfo_appinfo_get_pkgid, int(pkgmgrinfo_appinfo_h, char**));
+  MOCK_METHOD4(pkgmgrinfo_appinfo_usr_filter_foreach_appinfo,
+               int(pkgmgrinfo_appinfo_filter_h, pkgmgrinfo_app_list_cb, void*,
+                   uid_t));
+  MOCK_METHOD3(pkgmgrinfo_appinfo_foreach_appcontrol,
+               int(pkgmgrinfo_appinfo_h, pkgmgrinfo_app_control_list_cb,
+                   void*));
+  MOCK_METHOD3(pkgmgrinfo_pkginfo_load_certinfo,
+               int(const char*, pkgmgrinfo_certinfo_h, uid_t));
+  MOCK_METHOD3(pkgmgrinfo_pkginfo_get_cert_value,
+               int(pkgmgrinfo_certinfo_h, pkgmgrinfo_cert_type, const char**));
+  MOCK_METHOD5(certsvc_certificate_new_from_memory,
+               int(CertSvcInstance, const unsigned char*, size_t,
+                   CertSvcCertificateForm, CertSvcCertificate*));
+  MOCK_METHOD2(certsvc_certificate_get_visibility,
+               int(CertSvcCertificate, CertSvcVisibility*));
+  MOCK_METHOD1(certsvc_certificate_free, void(CertSvcCertificate));
+
+  MOCK_METHOD3(pkgmgr_client_listen_status,
+               int(pkgmgr_client*, pkgmgr_handler, void*));
+  MOCK_METHOD4(pkgmgrinfo_pkginfo_compare_usr_app_cert_info,
+               int(const char*, const char*, uid_t,
+                   pkgmgrinfo_cert_compare_result_type_e*));
+  MOCK_METHOD3(pkgmgrinfo_pkginfo_get_usr_pkginfo,
+               int(const char*, uid_t, pkgmgrinfo_pkginfo_h*));
+  MOCK_METHOD5(pkgmgrinfo_appinfo_get_usr_list,
+               int(pkgmgrinfo_pkginfo_h, pkgmgrinfo_app_component,
+                   pkgmgrinfo_app_list_cb, void*, uid_t));
+  MOCK_METHOD1(pkgmgrinfo_pkginfo_destroy_pkginfo, int(pkgmgrinfo_pkginfo_h));
+};
+
+#endif  // TESTS_UNIT_TESTS_MOCK_PKGMGR_INFO_MOCK_HH_
diff --git a/tests/unit_tests/mock/rpc_port_mock.cc b/tests/unit_tests/mock/rpc_port_mock.cc
new file mode 100644 (file)
index 0000000..1019123
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024 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 "rpc_port_mock.hh"
+
+#include "mock_hook.hh"
+#include "test_fixture.hh"
+
+extern "C" int rpc_port_register_proc_info(const char* arg0, bundle* arg1) {
+  return MOCK_HOOK_P2(RpcPortMock, rpc_port_register_proc_info, arg0, arg1);
+}
+
+extern "C" int rpc_port_stub_listen(rpc_port_stub_h h) {
+  return MOCK_HOOK_P1(RpcPortMock, rpc_port_stub_listen, h);
+}
\ No newline at end of file
diff --git a/tests/unit_tests/mock/rpc_port_mock.hh b/tests/unit_tests/mock/rpc_port_mock.hh
new file mode 100644 (file)
index 0000000..862b0b6
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2024 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 MOCK_RPC_PORT_MOCK_H_
+#define MOCK_RPC_PORT_MOCK_H_
+
+#include <bundle.h>
+#include <gmock/gmock.h>
+#include <rpc-port.h>
+#include <tizen.h>
+
+#include "module_mock.hh"
+
+class RpcPortMock : public virtual ModuleMock {
+ public:
+  virtual ~RpcPortMock() {}
+
+  MOCK_METHOD2(rpc_port_register_proc_info, int(const char*, bundle*));
+  MOCK_METHOD1(rpc_port_stub_listen, int(rpc_port_stub_h));
+};
+
+#endif  // MOCK_RPC_PORT_MOCK_H_
diff --git a/tests/unit_tests/mock/security_manager_mock.cc b/tests/unit_tests/mock/security_manager_mock.cc
new file mode 100644 (file)
index 0000000..da21513
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2024 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 "security_manager_mock.hh"
+
+#include "mock_hook.hh"
+#include "test_fixture.hh"
+
+extern "C" int security_manager_app_has_privilege(const char* arg0,
+                                                  const char* arg1, uid_t arg2,
+                                                  int* arg3) {
+  return MOCK_HOOK_P4(SecurityManagerMock, security_manager_app_has_privilege,
+                      arg0, arg1, arg2, arg3);
+}
\ No newline at end of file
diff --git a/tests/unit_tests/mock/security_manager_mock.hh b/tests/unit_tests/mock/security_manager_mock.hh
new file mode 100644 (file)
index 0000000..63c7157
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2024 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 TESTS_UNIT_TESTS_MOCK_SECURITY_MANAGER_MOCK_HH_
+#define TESTS_UNIT_TESTS_MOCK_SECURITY_MANAGER_MOCK_HH_
+
+#include <gmock/gmock.h>
+#include <security-manager.h>
+
+#include "module_mock.hh"
+
+class SecurityManagerMock : public virtual ModuleMock {
+ public:
+  SecurityManagerMock() {
+    using ::testing::_;
+    using ::testing::Invoke;
+    using ::testing::Return;
+
+    ON_CALL(*this, security_manager_app_has_privilege(_, _, _, _))
+        .WillByDefault(
+            Invoke([&](const char*, const char*, uid_t, int* result) {
+              *result = 1;
+              return SECURITY_MANAGER_SUCCESS;
+            }));
+  }
+
+  virtual ~SecurityManagerMock() {}
+
+  MOCK_METHOD4(security_manager_app_has_privilege,
+               int(const char*, const char*, uid_t, int*));
+};
+
+#endif  // TESTS_UNIT_TESTS_MOCK_SECURITY_MANAGER_MOCK_HH_
\ No newline at end of file
diff --git a/tests/unit_tests/mock/vconf_mock.cc b/tests/unit_tests/mock/vconf_mock.cc
new file mode 100644 (file)
index 0000000..50490ea
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2024 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 "mock/vconf_mock.hh"
+
+#include <glib.h>
+
+#include "mock/mock_hook.hh"
+#include "mock/test_fixture.hh"
+
+extern "C" int vconf_notify_key_changed(const char* in_key,
+                                        vconf_callback_fn cb, void* user_data) {
+  return MOCK_HOOK_P3(VConfMock, vconf_notify_key_changed, in_key, cb,
+                      user_data);
+}
+
+extern "C" int vconf_ignore_key_changed(const char* in_key,
+                                        vconf_callback_fn cb) {
+  return MOCK_HOOK_P2(VConfMock, vconf_ignore_key_changed, in_key, cb);
+}
+
+extern "C" char* vconf_get_str(const char* in_key) {
+  return MOCK_HOOK_P1(VConfMock, vconf_get_str, in_key);
+}
+
+extern "C" int vconf_get_int(const char* in_key, int* val) {
+  return MOCK_HOOK_P2(VConfMock, vconf_get_int, in_key, val);
+}
+
+extern "C" int vconf_get_bool(const char* in_key, int* val) {
+  return MOCK_HOOK_P2(VConfMock, vconf_get_bool, in_key, val);
+}
diff --git a/tests/unit_tests/mock/vconf_mock.hh b/tests/unit_tests/mock/vconf_mock.hh
new file mode 100644 (file)
index 0000000..88e333f
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2024 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 TESTS_UNIT_TESTS_MOCK_VCONF_MOCK_HH_
+#define TESTS_UNIT_TESTS_MOCK_VCONF_MOCK_HH_
+
+#include <gmock/gmock.h>
+#include <vconf.h>
+
+#include <map>
+
+#include "mock/module_mock.hh"
+
+class VConfMock : public virtual ModuleMock {
+ public:
+  VConfMock() {
+    using ::testing::_;
+    using ::testing::Invoke;
+    using ::testing::Return;
+
+    ON_CALL(*this, vconf_notify_key_changed(_, _, _))
+        .WillByDefault(Invoke([&](const char* in_key, vconf_callback_fn cb,
+                                  void* user_data) -> int {
+          data_[in_key] = {cb, user_data};
+          return 0;
+        }));
+    ON_CALL(*this, vconf_ignore_key_changed(_, _))
+        .WillByDefault(
+            Invoke([&](const char* in_key, vconf_callback_fn cb) -> int {
+              data_.erase(in_key);
+              return 0;
+            }));
+    ON_CALL(*this, vconf_get_str(_)).WillByDefault(Return(nullptr));
+    ON_CALL(*this, vconf_get_int(_, _))
+        .WillByDefault(Invoke([&](const char* in_key, int* val) -> int {
+          *val = 0;
+          return 0;
+        }));
+    ON_CALL(*this, vconf_get_bool(_, _))
+        .WillByDefault(Invoke([&](const char* in_key, int* val) -> int {
+          *val = 0;
+          return 0;
+        }));
+  }
+
+  MOCK_METHOD3(vconf_notify_key_changed,
+               int(const char*, vconf_callback_fn, void*));
+  MOCK_METHOD2(vconf_ignore_key_changed, int(const char*, vconf_callback_fn));
+  MOCK_METHOD1(vconf_get_str, char*(const char*));
+  MOCK_METHOD2(vconf_get_int, int(const char*, int*));
+  MOCK_METHOD2(vconf_get_bool, int(const char*, int*));
+
+  void ChangeStr(const std::string& key, const std::string& val) {
+    if (data_.find(key) == data_.end()) return;
+
+    keynode_t node;
+    node.type = VCONF_TYPE_STRING;
+    node.keyname = const_cast<char*>(key.c_str());
+    node.value.s = const_cast<char*>(val.c_str());
+
+    data_[key].first(&node, data_[key].second);
+  }
+
+  void ChangeInt(const std::string& key, int val) {
+    if (data_.find(key) == data_.end()) return;
+
+    keynode_t node;
+    node.type = VCONF_TYPE_INT;
+    node.keyname = const_cast<char*>(key.c_str());
+    node.value.i = val;
+
+    data_[key].first(&node, data_[key].second);
+  }
+
+  void ChangeBool(const std::string& key, bool val) {
+    if (data_.find(key) == data_.end()) return;
+
+    keynode_t node;
+    node.type = VCONF_TYPE_BOOL;
+    node.keyname = const_cast<char*>(key.c_str());
+    node.value.b = val;
+
+    data_[key].first(&node, data_[key].second);
+  }
+
+ private:
+  std::map<std::string, std::pair<vconf_callback_fn, void*>> data_;
+};
+
+#endif  // TESTS_UNIT_TESTS_MOCK_VCONF_MOCK_HH_
diff --git a/tidl/eventsystem.tidl b/tidl/eventsystem.tidl
new file mode 100755 (executable)
index 0000000..4c65292
--- /dev/null
@@ -0,0 +1,17 @@
+protocol 2\r
+\r
+interface EventSystem {\r
+  enum EventType {\r
+    User = 0,\r
+    System\r
+  }\r
+\r
+  void EventListener(string event_name, bundle data) delegate;\r
+\r
+  int RegisterEvent(EventType type, string event_name, EventListener cb);\r
+  bool UnregisterEvent(int id);\r
+  bool SendUserEvent(string event_name, bundle data, bool is_trusted);\r
+  bool SendSystemEvent(string event_name, bundle data);\r
+  bool KeepLastEventData(string event_name);\r
+  bool GetEarlierData(string event_name, out bundle data);\r
+}\r
diff --git a/tidl/prebuild.sh b/tidl/prebuild.sh
new file mode 100755 (executable)
index 0000000..bc49f6b
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/bash
+tidlc -p -l C++ -i ./eventsystem.tidl -o es_proxy
+tidlc -s -l C++ -i ./eventsystem.tidl -o es_stub