Add Cion Server 45/258545/17 devel/cion
authorInkyun Kil <inkyun.kil@samsung.com>
Thu, 19 Aug 2021 05:07:08 +0000 (14:07 +0900)
committerInkyun Kil <inkyun.kil@samsung.com>
Fri, 20 Aug 2021 06:56:26 +0000 (15:56 +0900)
- 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 <inkyun.kil@samsung.com>
CMakeLists.txt
include/eventsystem_daemon.h
packaging/esd.spec
src/esd_cion/cion_ondemand_server.cc [new file with mode: 0644]
src/esd_cion/cion_ondemand_server.h [new file with mode: 0644]
src/esd_cion/cion_peer_info.cc [new file with mode: 0644]
src/esd_cion/cion_peer_info.h [new file with mode: 0644]
src/esd_cion/esd_cion.c [deleted file]
src/esd_cion/esd_cion.cc [new file with mode: 0644]
src/esd_cion/esd_cion_db.c
src/esd_main.c

index cbdc5cb..d207d7c 100644 (file)
@@ -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
index 879a62e..706a89b 100644 (file)
@@ -25,6 +25,9 @@
 extern "C" {
 #endif
 
+#include <stdbool.h>
+#include <glib.h>
+
 #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
 }
index 6d7c3c5..4bcc907 100644 (file)
@@ -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 (file)
index 0000000..0d5965e
--- /dev/null
@@ -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 <dlog.h>
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <aul.h>
+#include <aul_svc.h>
+#include <bundle_cpp.h>
+#include <parcel.hh>
+#include <pkgmgr-info.h>
+#include <vconf.h>
+#include <system_info.h>
+#include <cion/common/data_payload.hh>
+
+#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<cion::PeerInfo> info,
+    const cion::ConnectionResult& result) {
+}
+
+void CionOndemandServer::OnDisconnected(std::shared_ptr<cion::PeerInfo> peer) {
+}
+
+std::vector<char> CionOndemandServer::OnDataReceived(
+    const std::vector<char>& data, std::shared_ptr<cion::PeerInfo> peer) {
+  std::string return_data("returned");
+
+  std::vector<char> v(return_data.begin(), return_data.end());
+  return v;
+}
+
+void CionOndemandServer::OnPayloadReceived(std::shared_ptr<cion::IPayload> data,
+    std::shared_ptr<cion::PeerInfo> peer,
+    IPayloadReceiver::PayloadTransferStatus status) {
+}
+
+void CionOndemandServer::OnConnectionRequest(
+    std::shared_ptr<cion::PeerInfo> peer) {
+}
+
+void CionOndemandServer::OnOndemandListRequested(
+    std::shared_ptr<cion::IPayload> data,
+    std::shared_ptr<cion::PeerInfo> peer) {
+  std::vector<uint8_t> raw;
+
+  _D("[Request Ondemand List]");
+
+  if (data->GetType() == cion::IPayload::PayloadType::File)
+    return;
+
+  std::shared_ptr<cion::DataPayload> data_payload =
+      std::dynamic_pointer_cast<cion::DataPayload>(data);
+  std::vector<char> 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<cion::DataPayload>();
+  std::vector<char> listdata_vector(raw.begin(), raw.end());
+  dpl->SetData(listdata_vector);
+
+  SendPayloadAsync(dpl.get(), peer, [] (
+      std::shared_ptr<cion::PayloadAsyncResult> result) {
+    _I("result received !!! %s", result->GetPayloadID().c_str());
+  });
+}
+
+int CionOndemandServer::OnOndemandLaunchRequested(
+    std::shared_ptr<cion::IPayload> data,
+    std::shared_ptr<cion::PeerInfo> 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<cion::DataPayload> data_payload =
+      std::dynamic_pointer_cast<cion::DataPayload>(data);
+
+  std::vector<char> 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<CionPeerInfo> 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<CionPeerInfo> pi =
+          std::make_shared<CionPeerInfo>(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<CionPeerInfo> pi =
+      std::make_shared<CionPeerInfo>(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<uint8_t> 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 (file)
index 0000000..b3852d0
--- /dev/null
@@ -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 <list>
+
+#include <cion/channel/server_channel.hh>
+#include <cion/common/ipayload.hh>
+#include <cion/common/exception.hh>
+
+#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<cion::PeerInfo> info,
+      const cion::ConnectionResult& result) override;
+  void OnDisconnected(std::shared_ptr<cion::PeerInfo> peer) override;
+  std::vector<char> OnDataReceived(const std::vector<char>& data,
+      std::shared_ptr<cion::PeerInfo> peer) override;
+  void OnPayloadReceived(std::shared_ptr<cion::IPayload> data,
+      std::shared_ptr<cion::PeerInfo> peer,
+      IPayloadReceiver::PayloadTransferStatus status) override;
+  void OnConnectionRequest(std::shared_ptr<cion::PeerInfo> peer) override;
+  void OnOndemandListRequested(std::shared_ptr<cion::IPayload> data,
+      std::shared_ptr<cion::PeerInfo> peer) override;
+  int OnOndemandLaunchRequested(std::shared_ptr<cion::IPayload> data,
+      std::shared_ptr<cion::PeerInfo> peer) override;
+
+  int OndemandLaunchApp(std::string appid);
+  void LoadOndemandServiceList();
+  tizen_base::Parcel GetOndemandList(std::string service_name);
+
+ private:
+  std::list<std::shared_ptr<CionPeerInfo>> 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 (file)
index 0000000..33705d8
--- /dev/null
@@ -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 (file)
index 0000000..acf14b0
--- /dev/null
@@ -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 <string>
+
+#include <cion/common/peer_info.hh>
+
+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 (file)
index 48447e0..0000000
+++ /dev/null
@@ -1,316 +0,0 @@
-#include <dlog.h>
-#include <glib.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pkgmgr-info.h>
-#include <package-manager.h>
-
-#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 (file)
index 0000000..8ee6485
--- /dev/null
@@ -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 <dlog.h>
+
+#include "eventsystem_daemon.h"
+#include "cion_ondemand_server.h"
+
+namespace {
+  std::shared_ptr<CionOndemandServer> esd_cion_server;
+} // namespace
+
+int _esd_cion_init() {
+
+  try {
+    esd_cion_server =
+        std::make_shared<CionOndemandServer>("__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
index 2cf7fd9..1a99dc0 100644 (file)
@@ -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:
index dabb5ce..69d5eb1 100644 (file)
@@ -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);