"${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)
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)
)
ADD_SUBDIRECTORY(src)
+ADD_SUBDIRECTORY(modules)
ADD_SUBDIRECTORY(tests)
ADD_SUBDIRECTORY(benchmark)
--- /dev/null
+/*
+ * 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_
--- /dev/null
+ADD_SUBDIRECTORY(group)
--- /dev/null
+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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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, ¶m1);
+ char* param2_raw = nullptr;
+ rpc_port_parcel_read_string(parcel, ¶m2_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, ¶m1);
+ 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, ¶m1_raw);
+ std::string param1(param1_raw);
+ free(param1_raw);
+ bundle* param2_raw = nullptr;
+ rpc_port_parcel_read_bundle(parcel, ¶m2_raw);
+ Bundle param2(param2_raw, false, true);
+ bool param3;
+ rpc_port_parcel_read_bool(parcel, ¶m3);
+ 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, ¶m1_raw);
+ std::string param1(param1_raw);
+ free(param1_raw);
+ bundle* param2_raw = nullptr;
+ rpc_port_parcel_read_bundle(parcel, ¶m2_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, ¶m1_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, ¶m1_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 */
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+[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
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)
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
%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
#################################################
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)
#################################################
%files -n %{name}-unittests
%{_bindir}/%{name}-unittests
+%{_bindir}/%{name}-integtests
%{_bindir}/tizen-unittests/%{name}/run-unittest.sh
#################################################
%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
+
GLIB_DEPS
GIO_DEPS
PKGMGR_INFO_DEPS
+ PARCEL_DEPS
+ RPC_PORT_DEPS
)
SET_TARGET_PROPERTIES(${TARGET_EVENTSYSTEM} PROPERTIES SOVERSION ${MAJORVER})
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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, ¶m1_raw);
+ std::string param1(param1_raw);
+ free(param1_raw);
+
+ bundle* param2_raw = nullptr;
+ rpc_port_parcel_read_bundle(parcel, ¶m2_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;
+}
--- /dev/null
+/*
+ * 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
+++ /dev/null
-/**
- * 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,
- ®_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;
-}
ADD_SUBDIRECTORY(unit_tests)
+ADD_SUBDIRECTORY(integ_tests)
--- /dev/null
+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
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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;
+}
+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
\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
/*
- * 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.
#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;
#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);
}
/*
- * 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, ...) {
vprintf(fmt, ap);
va_end(ap);
printf("\n");
+
return 0;
}
-// LCOV_EXCL_STOP
+#endif
int main(int argc, char** argv) {
int ret = -1;
* 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);
+}
+*/
/*
- * 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_
+++ /dev/null
-/*
- * 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);
-}
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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); }
+++ /dev/null
-/*
- * 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_
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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_
--- /dev/null
+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
--- /dev/null
+#!/bin/bash
+tidlc -p -l C++ -i ./eventsystem.tidl -o es_proxy
+tidlc -s -l C++ -i ./eventsystem.tidl -o es_stub