From a141d3e9fdf5db7af96ac46a54486d719878e2f7 Mon Sep 17 00:00:00 2001 From: Inkyun Kil Date: Thu, 19 Aug 2021 14:07:08 +0900 Subject: [PATCH] Add Cion Server - Discovery ondemand list for cion - Ondemand Launch Application for cion Related patch : https://review.tizen.org/gerrit/c/platform/core/appfw/cion/+/261308 https://review.tizen.org/gerrit/c/platform/core/appfw/cion/+/262199 Change-Id: I71ae650acf99c7cacef2b3e0bfbacb2bfe8b45d6 Signed-off-by: Inkyun Kil --- CMakeLists.txt | 8 +- include/eventsystem_daemon.h | 19 +- packaging/esd.spec | 3 + src/esd_cion/cion_ondemand_server.cc | 366 +++++++++++++++++++++++++++++++++++ src/esd_cion/cion_ondemand_server.h | 62 ++++++ src/esd_cion/cion_peer_info.cc | 35 ++++ src/esd_cion/cion_peer_info.h | 36 ++++ src/esd_cion/esd_cion.c | 316 ------------------------------ src/esd_cion/esd_cion.cc | 62 ++++++ src/esd_cion/esd_cion_db.c | 51 +++-- src/esd_main.c | 3 +- 11 files changed, 623 insertions(+), 338 deletions(-) create mode 100644 src/esd_cion/cion_ondemand_server.cc create mode 100644 src/esd_cion/cion_ondemand_server.h create mode 100644 src/esd_cion/cion_peer_info.cc create mode 100644 src/esd_cion/cion_peer_info.h delete mode 100644 src/esd_cion/esd_cion.c create mode 100644 src/esd_cion/esd_cion.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index cbdc5cb..d207d7c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(esd C) +PROJECT(esd C CXX) AUX_SOURCE_DIRECTORY(src/ SRCS) AUX_SOURCE_DIRECTORY(src/esd_cion/ CION_SRCS) @@ -23,6 +23,7 @@ INCLUDE(FindPkgConfig) pkg_check_modules(pkgs REQUIRED dlog bundle + parcel pkgmgr-info glib-2.0 gio-2.0 @@ -37,6 +38,8 @@ pkg_check_modules(pkgs REQUIRED security-manager sqlite3 uuid + cion + capi-system-info ) FOREACH(flag ${pkgs_CFLAGS}) @@ -48,6 +51,7 @@ ENDFOREACH(flag) ## Additional flag SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -Wall -Werror") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=c++14 -Werror") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") ## Linker flags @@ -56,7 +60,7 @@ SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed") ##build eventsystem daemon add_executable(esd ${SRCS} ${CION_SRCS}) TARGET_LINK_LIBRARIES(esd eventsystem pkgmgr-client ${pkgs_LDFLAGS}) -SET_TARGET_PROPERTIES(esd PROPERTIES COMPILE_FLAGS ${CFLAGS} "-fPIE") +SET_TARGET_PROPERTIES(esd PROPERTIES COMPILE_FLAGS ${CFLAGS} ${CXXFLAGS} "-fPIE") SET_TARGET_PROPERTIES(esd PROPERTIES LINK_FLAGS "-pie -Wl,-z,relro") # pkgconfig file diff --git a/include/eventsystem_daemon.h b/include/eventsystem_daemon.h index 879a62e..706a89b 100644 --- a/include/eventsystem_daemon.h +++ b/include/eventsystem_daemon.h @@ -25,6 +25,9 @@ extern "C" { #endif +#include +#include + #undef LOG_TAG #define LOG_TAG "ESD" @@ -48,9 +51,18 @@ extern "C" { #define SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED "StartupFinished" #define SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED "UserSessionStartupFinished" +typedef struct cion_service_info { + char *service_name; + char *appid; + char *display_name; +} cion_service_info_s; + int __esd_register_vconf_callbacks(void); -int __esd_cion_init(void); -void __esd_cion_finalize(void); + +int _esd_cion_init(void); +void _esd_cion_adds_enabled_app(const char *service_name, const char *app_id, + const char *display_name); +void _esd_cion_removes_enabled_app(const char *service_name, const char *app_id); int esd_cion_db_init(void); int esd_cion_get_uuid_with_generate(const char* appid, char** uuid); @@ -62,8 +74,7 @@ int esd_cion_set_enabled(const char *appid, const char *service_name, bool enabled); int esd_cion_get_enabled(const char *appid, const char *service_name, int *enabled); -int esd_cion_get_enabled_service_list(const char *service_name, - const char *display_name, GList **list); +int esd_cion_get_enabled_service_list(GList **list); #ifdef __cplusplus } diff --git a/packaging/esd.spec b/packaging/esd.spec index 6d7c3c5..4bcc907 100644 --- a/packaging/esd.spec +++ b/packaging/esd.spec @@ -9,6 +9,7 @@ Source1: esd.service BuildRequires: cmake BuildRequires: pkgconfig(aul) BuildRequires: pkgconfig(bundle) +BuildRequires: pkgconfig(parcel) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(pkgmgr-info) BuildRequires: pkgconfig(appsvc) @@ -26,6 +27,8 @@ BuildRequires: pkgconfig(cynara-session) BuildRequires: pkgconfig(security-manager) BuildRequires: pkgconfig(uuid) BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(cion) +BuildRequires: pkgconfig(capi-system-info) Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig diff --git a/src/esd_cion/cion_ondemand_server.cc b/src/esd_cion/cion_ondemand_server.cc new file mode 100644 index 0000000..0d5965e --- /dev/null +++ b/src/esd_cion/cion_ondemand_server.cc @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2021 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "eventsystem_daemon.h" +#include "cion_ondemand_server.h" +#include "cion_peer_info.h" + + +namespace { + +std::string GetAppVersion(const char* appid) { + char *pkgid; + char *pkg_version = NULL; + pkgmgrinfo_appinfo_h appinfo = NULL; + + int retval = pkgmgrinfo_appinfo_get_usr_appinfo(appid, getuid(), &appinfo); + if (retval != PMINFO_R_OK) + return {}; + + retval = pkgmgrinfo_appinfo_get_pkgid(appinfo, &pkgid); + if (retval != PMINFO_R_OK) { + pkgmgrinfo_appinfo_destroy_appinfo(appinfo); + return {}; + } + + pkgmgrinfo_pkginfo_h pkginfo = NULL; + retval = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkginfo); + if (retval != PMINFO_R_OK) { + pkgmgrinfo_appinfo_destroy_appinfo(appinfo); + return {}; + } + + retval = pkgmgrinfo_pkginfo_get_version(pkginfo, &pkg_version); + if (retval != PMINFO_R_OK) { + pkgmgrinfo_appinfo_destroy_appinfo(appinfo); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + return {}; + } + + std::string version(pkg_version); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + pkgmgrinfo_appinfo_destroy_appinfo(appinfo); + + return version; +} + +std::string GetSystemInfoPlatformString(const char* key) { + char* val = nullptr; + int ret = system_info_get_platform_string(key, &val); + if (ret != SYSTEM_INFO_ERROR_NONE || !val) + return {}; + + std::string val_str = val; + free(val); + + return val_str; +} + +std::string GetVconfString(const char* key) { + char* val = vconf_get_str(key); + if (val == nullptr) + return {}; + + std::string val_str = val; + free(val); + + return val_str; +} + +void FreeList(gpointer data) { + cion_service_info_s *info = (cion_service_info_s *)data; + + free(info->appid); + free(info->service_name); + if (info->display_name) + free(info->display_name); + free(info); +} + +std::string device_id = GetSystemInfoPlatformString("http://tizen.org/system/tizenid"); +std::string device_name = GetVconfString(VCONFKEY_SETAPPL_DEVICE_NAME_STR); +std::string device_platform = "Tizen"; +std::string device_platform_version = + GetSystemInfoPlatformString("http://tizen.org/feature/platform.version"); +std::string device_type = GetSystemInfoPlatformString("http://tizen.org/system/device_type"); + +} // namespace + +CionOndemandServer::CionOndemandServer(std::string service_name, + std::string display_name) + : cion::channel::ServerChannel(service_name, display_name) { + LoadOndemandServiceList(); +} + +CionOndemandServer::CionOndemandServer(std::string service_name, + std::string display_name, cion::SecurityInfo security) : + cion::channel::ServerChannel(service_name, display_name, + std::move(security)) { + LoadOndemandServiceList(); +} + +void CionOndemandServer::OnConnectionResult(std::shared_ptr info, + const cion::ConnectionResult& result) { +} + +void CionOndemandServer::OnDisconnected(std::shared_ptr peer) { +} + +std::vector CionOndemandServer::OnDataReceived( + const std::vector& data, std::shared_ptr peer) { + std::string return_data("returned"); + + std::vector v(return_data.begin(), return_data.end()); + return v; +} + +void CionOndemandServer::OnPayloadReceived(std::shared_ptr data, + std::shared_ptr peer, + IPayloadReceiver::PayloadTransferStatus status) { +} + +void CionOndemandServer::OnConnectionRequest( + std::shared_ptr peer) { +} + +void CionOndemandServer::OnOndemandListRequested( + std::shared_ptr data, + std::shared_ptr peer) { + std::vector raw; + + _D("[Request Ondemand List]"); + + if (data->GetType() == cion::IPayload::PayloadType::File) + return; + + std::shared_ptr data_payload = + std::dynamic_pointer_cast(data); + std::vector requested_data = data_payload->GetData(); + tizen_base::Parcel ondemand_parcel(requested_data.data(), + requested_data.size()); + + std::string list_header = ondemand_parcel.ReadString(); + std::string list_service_name = ondemand_parcel.ReadString(); + _D("Ondemand Service_name : %s", list_service_name.c_str()); + if (list_header == std::string("OndemandList")) { + raw = GetOndemandList(list_service_name).GetRaw(); + if (raw.size() == 0) + return; + } + + auto dpl = std::make_unique(); + std::vector listdata_vector(raw.begin(), raw.end()); + dpl->SetData(listdata_vector); + + SendPayloadAsync(dpl.get(), peer, [] ( + std::shared_ptr result) { + _I("result received !!! %s", result->GetPayloadID().c_str()); + }); +} + +int CionOndemandServer::OnOndemandLaunchRequested( + std::shared_ptr data, + std::shared_ptr peer) { + //TODO check privilege app_id + std::string app_id = peer->GetAppID(); + int ret = -20; + + cion::IPayload::PayloadType type = data->GetType(); + if (type == cion::IPayload::PayloadType::File) + return ret; + + std::shared_ptr data_payload = + std::dynamic_pointer_cast(data); + + std::vector getdata = data_payload->GetData(); + std::string launch_requested(getdata.begin(), getdata.end()); + + ret = OndemandLaunchApp(launch_requested); + if (ret != 0) { + _E("Faled to __esd_cion_launch_ondemand : %d", ret); + } + + return ret; +} + +int CionOndemandServer::OndemandLaunchApp(std::string appid) { + uid_t uid = getuid(); + tizen_base::Bundle b; + int ret = -20; + bool found = false; + + for (std::shared_ptr cs : ondemand_peer_list_) { + if (cs->GetAppID() == appid) { + found = true; + break; + } + } + + if (found == false) { + _E("%s is not found", appid.c_str()); + return ret; + } + + _D("cion launch ondemand: app_id(%s)", appid.c_str()); + + if (!aul_app_is_running_for_uid(appid.c_str(), uid)) { + aul_svc_set_operation(b.GetHandle(), AUL_SVC_OPERATION_DEFAULT); + aul_svc_set_appid(b.GetHandle(), appid.c_str()); + + ret = aul_svc_run_service_async_for_uid(b.GetHandle(), 0, NULL, NULL, uid); + if (ret < 0) + _E("Failed to launch app : %s", appid.c_str()); + + } else { + _D("already is running or launch failed"); + } + + return ret; +} + +void CionOndemandServer::LoadOndemandServiceList() { + GList *list = nullptr; + int ret = esd_cion_get_enabled_service_list(&list); + if (ret != 0 || list == nullptr) { + _E("Get list error"); + } else { + for (GList *it = g_list_first(list); it; it = g_list_next(it)) { + cion_service_info *cion_info = (cion_service_info_s *)(it->data); + char *app_id = cion_info->appid; + char *service_name = cion_info->service_name; + char *display_name = cion_info->display_name; + char *uuid; + ret = esd_cion_get_uuid_with_generate(app_id, &uuid); + if (ret != 0) { + _E("Get uuid for %s", app_id); + } + + std::string app_version = GetAppVersion(app_id); + + tizen_base::Parcel parcel; + parcel.WriteString(device_id); + parcel.WriteString(device_name); + parcel.WriteString(device_platform); + parcel.WriteString(device_platform_version); + parcel.WriteString(device_type); + parcel.WriteString(std::string(app_id)); + parcel.WriteString(app_version); + parcel.WriteString(std::string(uuid)); + parcel.WriteString(std::string(display_name)); + + std::shared_ptr pi = + std::make_shared(std::string(service_name), + parcel.GetRaw().data(), parcel.GetRaw().size()); + ondemand_peer_list_.emplace_back(pi); + + free(uuid); + } + } + + g_list_free_full(list, FreeList); +} + +void CionOndemandServer::AddOndemandServiceList(std::string service_name, + std::string appid, std::string display_name) { + for (auto peer : ondemand_peer_list_) { + if (peer->GetServiceName() == service_name && + peer->GetAppID() == appid) { + _W("%s is already exist", appid.c_str()); + return; + } + } + + char *uuid; + int ret = esd_cion_get_uuid_with_generate(appid.c_str(), &uuid); + if (ret != 0) { + _E("Get uuid for %s", appid.c_str()); + return; + } + + std::string app_version = GetAppVersion(appid.c_str()); + + tizen_base::Parcel parcel; + parcel.WriteString(device_id); + parcel.WriteString(device_name); + parcel.WriteString(device_platform); + parcel.WriteString(device_platform_version); + parcel.WriteString(device_type); + parcel.WriteString(appid); + parcel.WriteString(app_version); + parcel.WriteString(std::string(uuid)); + parcel.WriteString(display_name); + + std::shared_ptr pi = + std::make_shared(service_name, parcel.GetRaw().data(), + parcel.GetRaw().size()); + ondemand_peer_list_.emplace_back(pi); + _D("[%s:%s] is added to list", appid.c_str(), service_name.c_str()); +} + +void CionOndemandServer::RemoveOndemandServiceList(std::string service_name, + std::string appid) { + for (auto peer = ondemand_peer_list_.begin(); + peer != ondemand_peer_list_.end(); peer++) { + if (peer->get()->GetServiceName() == service_name && + peer->get()->GetAppID() == appid) { + ondemand_peer_list_.erase(peer); + _D("[%s:%s] is removed from list", appid.c_str(), service_name.c_str()); + break; + } + } +} + +tizen_base::Parcel CionOndemandServer::GetOndemandList( + std::string service_name) { + if (ondemand_peer_list_.size() == 0) { + _W("ondemand peer list is empty"); + return {}; + } + + std::string header("ODL:"); + tizen_base::Parcel parcel; + parcel.WriteString(header); + + for (auto peer : ondemand_peer_list_) { + if (peer->GetServiceName() != service_name || + aul_app_is_running(peer->GetAppID().c_str())) + continue; + + parcel.WriteBool(true); + std::vector peer_raw = peer->Serialize(); + parcel.WriteUInt32(peer_raw.size()); + parcel.Write(peer_raw.data(), peer_raw.size()); + } + + parcel.WriteBool(false); + + return parcel; +} \ No newline at end of file diff --git a/src/esd_cion/cion_ondemand_server.h b/src/esd_cion/cion_ondemand_server.h new file mode 100644 index 0000000..b3852d0 --- /dev/null +++ b/src/esd_cion/cion_ondemand_server.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 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 EVENTSYSTEM_DAEMON_CION_ONDEMAND_SERVER_H_ +#define EVENTSYSTEM_DAEMON_CION_ONDEMAND_SERVER_H_ + +#include + +#include +#include +#include + +#include "cion_peer_info.h" + +class CionOndemandServer : public cion::channel::ServerChannel { + public: + explicit CionOndemandServer(std::string service_name, + std::string display_name); + explicit CionOndemandServer(std::string service_name, + std::string display_name, cion::SecurityInfo security); + + void AddOndemandServiceList(std::string service_name, std::string appid, + std::string display_name); + void RemoveOndemandServiceList(std::string service_name, std::string appid); + + protected: + void OnConnectionResult(std::shared_ptr info, + const cion::ConnectionResult& result) override; + void OnDisconnected(std::shared_ptr peer) override; + std::vector OnDataReceived(const std::vector& data, + std::shared_ptr peer) override; + void OnPayloadReceived(std::shared_ptr data, + std::shared_ptr peer, + IPayloadReceiver::PayloadTransferStatus status) override; + void OnConnectionRequest(std::shared_ptr peer) override; + void OnOndemandListRequested(std::shared_ptr data, + std::shared_ptr peer) override; + int OnOndemandLaunchRequested(std::shared_ptr data, + std::shared_ptr peer) override; + + int OndemandLaunchApp(std::string appid); + void LoadOndemandServiceList(); + tizen_base::Parcel GetOndemandList(std::string service_name); + + private: + std::list> ondemand_peer_list_; +}; + +#endif /* EVENTSYSTEM_DAEMON_CION_ONDEMAND_SERVER_H_ */ \ No newline at end of file diff --git a/src/esd_cion/cion_peer_info.cc b/src/esd_cion/cion_peer_info.cc new file mode 100644 index 0000000..33705d8 --- /dev/null +++ b/src/esd_cion/cion_peer_info.cc @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 "cion_peer_info.h" + +CionPeerInfo::CionPeerInfo(std::string service_name) : cion::PeerInfo(), + service_name_(service_name) { +} + +CionPeerInfo::CionPeerInfo(std::string service_name, + const void* buf, uint32_t size) : cion::PeerInfo(buf, size), + service_name_(service_name){ + +} + +void CionPeerInfo::SetServiceName(std::string service_name) { + service_name_ = service_name; +} + +std::string CionPeerInfo::GetServiceName() const { + return service_name_; +} \ No newline at end of file diff --git a/src/esd_cion/cion_peer_info.h b/src/esd_cion/cion_peer_info.h new file mode 100644 index 0000000..acf14b0 --- /dev/null +++ b/src/esd_cion/cion_peer_info.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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 EVENTSYSTEM_DAEMON_CION_PEER_INFO_H_ +#define EVENTSYSTEM_DAEMON_CION_PEER_INFO_H_ + +#include + +#include + +class CionPeerInfo : public cion::PeerInfo { + public: + CionPeerInfo(std::string service_name); + CionPeerInfo(std::string service_name, const void* buf, uint32_t size); + + std::string GetServiceName() const; + void SetServiceName(std::string service_name); + + private: + std::string service_name_; +}; + +#endif /* EVENTSYSTEM_DAEMON_CION_PEER_INFO_H_ */ \ No newline at end of file diff --git a/src/esd_cion/esd_cion.c b/src/esd_cion/esd_cion.c deleted file mode 100644 index 48447e0..0000000 --- a/src/esd_cion/esd_cion.c +++ /dev/null @@ -1,316 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "eventsystem_daemon.h" - -#define CION_METADATA_KEY "http://tizen.org/metadata/cion" - -static uid_t cur_uid; -static pkgmgr_client *pkgmgr; -static GList *service_list; - -struct cion_service { - char *pkgid; - char *appid; - char *service_name; - char *uuid; - int port; -}; - -static void __free_cion_service(gpointer data) -{ - struct cion_service *service = (struct cion_service *)data; - - free(service->pkgid); - free(service->appid); - free(service->service_name); - free(service->uuid); - free(service); -} - -static int __esd_cion_set_cur_uid(void) -{ - /* TODO(jeremy.jang): get current user from gumd or systemd */ - cur_uid = 5001; - return 0; -} - -static int __esd_cion_foreach_metadata_callback(const char *key, - const char *val, void *user_data) -{ - struct cion_service *service; - GList **service_list = (GList **)user_data; - - if (strncmp(key, CION_METADATA_KEY, strlen(CION_METADATA_KEY)) != 0) - return 0; - - if (val == NULL || strlen(val) == 0) { - _E("Service name is mandatory"); - return 0; - } - - service = calloc(1, sizeof(struct cion_service)); - if (service == NULL) { - _E("Out of memory"); - return -1; - } - - service->service_name = strdup(val); - if (service->service_name == NULL) { - _E("Out of memory"); - return -1; - } - - *service_list = g_list_append(*service_list, (gpointer)service); - - return 0; -} - -static void __esd_cion_remove_cion_service_by_appid(const char *appid) -{ - GList *item; - GList *next; - struct cion_service *service; - - item = service_list; - while (item != NULL) { - next = item->next; - service = (struct cion_service *)item->data; - if (strcmp(service->appid, appid) == 0) { - _D("Remove a cion service [%s:%s:%s:%d]", - service->appid, service->service_name, - service->uuid, service->port); - __free_cion_service(service); - service_list = g_list_delete_link(service_list, item); - } - item = next; - } -} - -static void __esd_cion_remove_cion_service_by_pkgid(const char *pkgid) -{ - GList *item; - GList *next; - struct cion_service *service; - - item = service_list; - while (item != NULL) { - next = item->next; - service = (struct cion_service *)item->data; - if (strcmp(service->pkgid, pkgid) == 0) { - _D("Remove a cion service [%s:%s:%s:%d]", - service->appid, service->service_name, - service->uuid, service->port); - __free_cion_service(service); - service_list = g_list_delete_link(service_list, item); - } - item = next; - } -} - -static int __esd_cion_add_cion_service(struct cion_service *service, - const char *pkgid, const char *appid) -{ - /* service name already set by __esd_cion_foreach_metadata_callback() */ - service->pkgid = strdup(pkgid); - if (service->pkgid == NULL) { - _E("Out of memory"); - return -1; - } - - service->appid = strdup(appid); - if (service->appid == NULL) { - _E("Out of memory"); - return -1; - } - - /* how to get uuid? */ - - service_list = g_list_append(service_list, service); - _D("Add a cion service [%s:%s:%s:%d]", service->appid, - service->service_name, service->uuid, - service->port); - - return 0; -} - -static int __esd_cion_foreach_app_callback(const pkgmgrinfo_appinfo_h appinfo, - void *user_data) -{ - int ret; - char *pkgid; - char *appid; - struct cion_service *service; - GList *item; - GList *list = NULL; - - ret = pkgmgrinfo_appinfo_foreach_metadata(appinfo, - __esd_cion_foreach_metadata_callback, &list); - if (ret != PMINFO_R_OK) { - _E("Failed to get metadata: %d", ret); - return -1; - } - - ret = pkgmgrinfo_appinfo_get_pkgid(appinfo, &pkgid); - if (ret != PMINFO_R_OK) { - _E("Failed to get pkgid: %d", ret); - return -1; - } - - ret = pkgmgrinfo_appinfo_get_appid(appinfo, &appid); - if (ret != PMINFO_R_OK) { - _E("Failed to get appid: %d", ret); - return -1; - } - - /* remove first, the updated app may no longer provide cion service */ - __esd_cion_remove_cion_service_by_appid(appid); - for (item = list; item; item = item->next) { - service = (struct cion_service *)item->data; - if (__esd_cion_add_cion_service(service, pkgid, appid)) { - _E("Failed to add a cion service"); - __free_cion_service(service); - } - /* remove reference, the global 'service_list' takes reference - * of 'service'. - */ - item->data = NULL; - } - - g_list_free(list); - - return 0; -} - -static int __esd_cion_pkgmgr_event_callback(uid_t target_uid, int req_id, - const char *pkg_type, const char *pkgid, const char *key, - const char *val, const void *pmsg, void *data) -{ - int ret; - pkgmgrinfo_pkginfo_h pkginfo; - - if (strncmp(key, "end", strlen("end")) || - strncmp(val, "ok", strlen("ok"))) - return 0; - - ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &pkginfo); - if (ret == PMINFO_R_OK) { - /* install or update */ - ret = pkgmgrinfo_appinfo_get_usr_list(pkginfo, PMINFO_ALL_APP, - __esd_cion_foreach_app_callback, NULL, - target_uid); - if (ret != PMINFO_R_OK) { - _E("Failed to get appinfo of pkgid %s: %d", pkgid, ret); - pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); - return 0; - } - pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); - } else if (ret == PMINFO_R_ENOENT) { - /* uninstall */ - __esd_cion_remove_cion_service_by_pkgid(pkgid); - } else { - _E("Failed to get pkginfo of %s: %d", pkgid, ret); - } - - return 0; -} - -static int __esd_cion_set_pkgmgr_callback(void) -{ - int ret; - - pkgmgr = pkgmgr_client_new(PC_LISTENING); - if (pkgmgr == NULL) { - _E("Failed to create pkgmgr client"); - return -1; - } - - ret = pkgmgr_client_set_status_type(pkgmgr, - PKGMGR_CLIENT_STATUS_INSTALL | - PKGMGR_CLIENT_STATUS_UPGRADE | - PKGMGR_CLIENT_STATUS_UNINSTALL); - if (ret != PKGMGR_R_OK) { - _E("Failed to set pkgmgr event status type: %d", ret); - pkgmgr_client_free(pkgmgr); - pkgmgr = NULL; - return -1; - } - - ret = pkgmgr_client_listen_status(pkgmgr, - __esd_cion_pkgmgr_event_callback, NULL); - if (ret < 0) { - _E("Failed to set event callback: %d", ret); - pkgmgr_client_free(pkgmgr); - pkgmgr = NULL; - return -1; - } - - return 0; -} - -static int __esd_cion_load_services(uid_t uid) -{ - int ret; - pkgmgrinfo_appinfo_metadata_filter_h filter; - - ret = pkgmgrinfo_appinfo_metadata_filter_create(&filter); - if (ret != PMINFO_R_OK) { - _E("Failed to create metadata filter: %d", ret); - return -1; - } - - ret = pkgmgrinfo_appinfo_metadata_filter_add(filter, - CION_METADATA_KEY, ""); - if (ret != PMINFO_R_OK) { - _E("Failed to add keyval to metadata filter: %d", ret); - pkgmgrinfo_appinfo_metadata_filter_destroy(filter); - return -1; - } - - ret = pkgmgrinfo_appinfo_usr_metadata_filter_foreach(filter, - __esd_cion_foreach_app_callback, NULL, uid); - if (ret != PMINFO_R_OK) { - _E("Failed to metadata filter foreach: %d", ret); - pkgmgrinfo_appinfo_metadata_filter_destroy(filter); - return -1; - } - - pkgmgrinfo_appinfo_metadata_filter_destroy(filter); - - return 0; -} - -int __esd_cion_init(void) -{ - if (__esd_cion_set_cur_uid()) { - _E("Failed to set current uid"); - return -1; - } - - /* how to handle when user switched? */ - if (__esd_cion_load_services(cur_uid)) { - _E("Failed to load cion services"); - return -1; - } - - if (__esd_cion_set_pkgmgr_callback()) { - _E("Failed to set pkgmgr event callback"); - return -1; - } - - return 0; -} - -void __esd_cion_finalize(void) -{ - if (pkgmgr) { - pkgmgr_client_remove_listen_status(pkgmgr); - pkgmgr_client_free(pkgmgr); - } - - g_list_free_full(service_list, __free_cion_service); -} diff --git a/src/esd_cion/esd_cion.cc b/src/esd_cion/esd_cion.cc new file mode 100644 index 0000000..8ee6485 --- /dev/null +++ b/src/esd_cion/esd_cion.cc @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 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_daemon.h" +#include "cion_ondemand_server.h" + +namespace { + std::shared_ptr esd_cion_server; +} // namespace + +int _esd_cion_init() { + + try { + esd_cion_server = + std::make_shared("__CION_INTERNAL_DAEMON__", ""); + } catch (const cion::Exception& e) { + _D("cion_init failed : %s", e.what()); + return -1; + } + + esd_cion_server->Listen(); + + _D("cion_init done"); + + return 0; +} + +void _esd_cion_adds_enabled_app(const char *service_name, const char *app_id, + const char *display_name) { + if (esd_cion_server == nullptr) { + _E("Call init function at first"); + return; + } + + esd_cion_server->AddOndemandServiceList(std::string(service_name), + std::string(app_id), std::string(display_name)); +} + +void _esd_cion_removes_enabled_app(const char *service_name, const char *app_id) { + if (esd_cion_server == nullptr) { + _E("Call init function at first"); + return; + } + + esd_cion_server->RemoveOndemandServiceList(std::string(service_name), + std::string(app_id)); +} \ No newline at end of file diff --git a/src/esd_cion/esd_cion_db.c b/src/esd_cion/esd_cion_db.c index 2cf7fd9..1a99dc0 100644 --- a/src/esd_cion/esd_cion_db.c +++ b/src/esd_cion/esd_cion_db.c @@ -341,7 +341,9 @@ int esd_cion_set_enabled(const char *appid, const char *service_name, int ret = -1; sqlite3 *db; char *query = NULL; + const char *display_name = NULL; sqlite3_stmt *stmt = NULL; + sqlite3_stmt *select_stmt = NULL; db = esd_cion_db_open(); if (!db) { @@ -359,13 +361,34 @@ int esd_cion_set_enabled(const char *appid, const char *service_name, if (ret != SQLITE_OK) goto out; + query = sqlite3_mprintf("SELECT display_name FROM cion_display_name " + "WHERE appid = %Q AND service_name = %Q", appid, service_name); + if (query == NULL) + goto out; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &select_stmt, NULL); + if (ret != SQLITE_OK) + goto out; + ret = sqlite3_step(stmt); - if (ret == SQLITE_OK || ret == SQLITE_DONE) + if (ret != SQLITE_OK && ret != SQLITE_DONE) + goto out; + + ret = sqlite3_step(select_stmt); + if (ret == SQLITE_ROW) { ret = 0; + display_name = (const char*)sqlite3_column_text(select_stmt, 0); + } + + if (enabled) + _esd_cion_adds_enabled_app(service_name, appid, display_name); + else + _esd_cion_removes_enabled_app(service_name, appid); out: sqlite3_free(query); sqlite3_finalize(stmt); + sqlite3_finalize(select_stmt); esd_cion_db_close(&db); return ret; @@ -411,14 +434,12 @@ out: return ret; } -int esd_cion_get_enabled_service_list(const char *service_name, - const char *display_name, GList **list) +int esd_cion_get_enabled_service_list(GList **list) { int ret = -1; sqlite3 *db; char *query = NULL; sqlite3_stmt *stmt = NULL; - char *appid; db = esd_cion_db_open(); if (!db) { @@ -426,13 +447,8 @@ int esd_cion_get_enabled_service_list(const char *service_name, return -1; } - if (display_name) - query = sqlite3_mprintf("SELECT appid FROM cion_display_name " - "WHERE service_name = %Q AND display_name = %Q AND enabled = 1", - service_name, display_name); - else - query = sqlite3_mprintf("SELECT appid FROM cion_display_name " - "WHERE service_name = %Q AND enabled = 1", service_name); + query = sqlite3_mprintf("SELECT service_name, appid, display_name " + "FROM cion_display_name WHERE enabled = 1"); if (query == NULL) goto out; @@ -441,10 +457,17 @@ int esd_cion_get_enabled_service_list(const char *service_name, goto out; while(sqlite3_step(stmt) == SQLITE_ROW) { - appid = strdup((char*)sqlite3_column_text(stmt, 0)); - _E("get appid list : %s", appid); + cion_service_info_s *cion_info = malloc(sizeof(cion_service_info_s)); + cion_info->service_name = strdup((char*)sqlite3_column_text(stmt, 0)); + cion_info->appid = strdup((char*)sqlite3_column_text(stmt, 1)); + + char *display_name = (char*)sqlite3_column_text(stmt, 2); + if (display_name) + cion_info->display_name = strdup(display_name); + _D("get list : [%s:%s:%s]", + cion_info->service_name, cion_info->appid, cion_info->display_name); - *list = g_list_append(*list, appid); + *list = g_list_append(*list, cion_info); } out: diff --git a/src/esd_main.c b/src/esd_main.c index dabb5ce..69d5eb1 100644 --- a/src/esd_main.c +++ b/src/esd_main.c @@ -2619,7 +2619,7 @@ int main(int argc, char *argv[]) return ES_R_ERROR; } - if (__esd_cion_init() != 0) { + if (_esd_cion_init() != 0) { _E("ESD Cion Initialization failed!"); g_main_loop_unref(mainloop); return ES_R_ERROR; @@ -2639,7 +2639,6 @@ int main(int argc, char *argv[]) _E("shutdown"); - __esd_cion_finalize(); __esd_finalize(); g_main_loop_unref(mainloop); -- 2.7.4