PKG_CHECK_MODULES(TIZEN_LIBOPENER_DEPS REQUIRED tizen-libopener)
PKG_CHECK_MODULES(INIPARSER_DEPS REQUIRED iniparser)
PKG_CHECK_MODULES(AUL_DEPS REQUIRED aul)
+PKG_CHECK_MODULES(LIBSYSTEMD_DEPS REQUIRED libsystemd)
ADD_SUBDIRECTORY(src)
* @retval #SERVICE_ERROR_ALREADY_EXIST Service already exists
* @see service_unregister()
* @see #service_lifecycle_callback_s
- *
+ *
* @code
#include <service.h>
#include <dlog.h>
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(iniparser)
BuildRequires: pkgconfig(aul)
+BuildRequires: pkgconfig(libsystemd)
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SRCS)
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/watchdog WATCHDOG_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/activation_method ACTIVATION_METHOD_SRCS)
-ADD_LIBRARY(${TARGET_UNITED_SERVICE} SHARED ${SRCS} ${WATCHDOG_SRCS})
+ADD_LIBRARY(${TARGET_UNITED_SERVICE} SHARED ${SRCS} ${WATCHDOG_SRCS} ${ACTIVATION_METHOD_SRCS})
SET_TARGET_PROPERTIES(${TARGET_UNITED_SERVICE} PROPERTIES SOVERSION ${MAJORVER})
SET_TARGET_PROPERTIES(${TARGET_UNITED_SERVICE} PROPERTIES VERSION ${FULLVER})
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_SOURCE_DIR}/../include/
+ ${CMAKE_CURRENT_SOURCE_DIR}/activation_method/
)
APPLY_PKG_CONFIG(${TARGET_UNITED_SERVICE} PUBLIC
TIZEN_LIBOPENER_DEPS
INIPARSER_DEPS
AUL_DEPS
+ LIBSYSTEMD_DEPS
)
TARGET_LINK_LIBRARIES(${TARGET_UNITED_SERVICE} PUBLIC "-lpthread -ldl")
--- /dev/null
+#include "dbus_info.hh"
+
+#include <utility>
+
+namespace tizen_base {
+
+tizen_base::DBusInfo::DBusInfo(std::string bus_name)
+ : bus_name_(std::move(bus_name)) {}
+
+const std::string& DBusInfo::GetBusName() const {
+ return bus_name_;
+}
+
+} // namespace tizen_base
--- /dev/null
+/*
+ * Copyright (c) 2025 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 ACTIVATION_METHOD_DBUS_INFO_HH_
+#define ACTIVATION_METHOD_DBUS_INFO_HH_
+
+#include <string>
+
+namespace tizen_base {
+
+class DBusInfo {
+ public:
+ explicit DBusInfo(std::string bus_name);
+
+ const std::string& GetBusName() const;
+ private:
+ std::string bus_name_;
+};
+
+} // namespace tizen_base
+
+#endif // ACTIVATION_METHOD_DBUS_INFO_HH_
--- /dev/null
+#include "dbus_monitor.hh"
+
+#include <stdexcept>
+#include <utility>
+
+#include "log_private.hh"
+
+namespace tizen_base {
+
+DBusMonitor::DBusMonitor(std::string name,
+ std::string bus_name,
+ IEventListener* listener)
+ : name_(std::move(name)),
+ bus_name_(std::move(bus_name)),
+ listener_(listener) {
+ static GDBusConnection* conn = nullptr;
+ GError* error = nullptr;
+ if (!conn)
+ conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
+
+ if (conn == nullptr) {
+ if (error != nullptr) {
+ _E("Failed to get dbus [%s]", error->message);
+ g_error_free(error);
+ }
+
+ throw std::runtime_error("Failed to get dbus connection");
+ }
+
+ own_id_ = g_bus_own_name(G_BUS_TYPE_SYSTEM, bus_name_.c_str(),
+ G_BUS_NAME_OWNER_FLAGS_NONE, BusAcquiredCb,
+ NameAppearedCb, NameVanishedCb, this, nullptr);
+ if (own_id_ == 0)
+ throw std::runtime_error("Fail to watch name " + bus_name_);
+}
+
+DBusMonitor::~DBusMonitor() {
+ if (own_id_) {
+ g_bus_unown_name(own_id_);
+ }
+}
+
+void DBusMonitor::BusAcquiredCb(GDBusConnection* connection,
+ const gchar* name,
+ gpointer user_data) {
+ _I("bus acquired : %s", name);
+}
+
+void DBusMonitor::NameAppearedCb(GDBusConnection* connection,
+ const gchar* name,
+ gpointer user_data) {
+ _I("name appeared : %s", name);
+ auto* self = static_cast<DBusMonitor*>(user_data);
+ if (self->bus_name_ == name) {
+ self->listener_->OnEvent(self->name_);
+ }
+}
+
+void DBusMonitor::NameVanishedCb(GDBusConnection* connection,
+ const gchar* name,
+ gpointer user_data) {
+ _E("name vanished : %s", name);
+}
+
+} // namespace tizen_base
--- /dev/null
+/*
+ * Copyright (c) 2025 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 ACTIVATION_METHOD_DBUS_MONITOR_HH_
+#define ACTIVATION_METHOD_DBUS_MONITOR_HH_
+
+#include <gio/gio.h>
+#include <glib.h>
+
+#include <string>
+
+#include "event_listener.hh"
+
+namespace tizen_base {
+
+class DBusMonitor {
+ public:
+ DBusMonitor(std::string name, std::string bus_name, IEventListener* listener);
+ ~DBusMonitor();
+
+ static void BusAcquiredCb(GDBusConnection* connection,
+ const gchar* name,
+ gpointer user_data);
+
+ static void NameAppearedCb(GDBusConnection* connection,
+ const gchar* name,
+ gpointer user_data);
+ static void NameVanishedCb(GDBusConnection* connection,
+ const gchar* name,
+ gpointer user_data);
+
+ private:
+ std::string name_;
+ std::string bus_name_;
+ gint own_id_ = 0;
+ IEventListener* listener_;
+};
+
+}; // namespace tizen_base
+
+#endif // ACTIVATION_METHOD_DBUS_MONITOR_HH_
--- /dev/null
+#include "fd_monitor.hh"
+
+tizen_base::FdMonitor::FdMonitor(std::string,
+ int fd,
+ IEventListener* listener) {}
+
+tizen_base::FdMonitor::FdMonitor(std::string name,
+ std::string path,
+ IEventListener* listener) {}
+
+gboolean tizen_base::FdMonitor::UnixFdSourceFunc(gint fd,
+ GIOCondition cond,
+ gpointer data) {
+ // TODO
+ return FALSE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2025 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 ACTIVATION_METHOD_FD_MONITOR_HH_
+#define ACTIVATION_METHOD_FD_MONITOR_HH_
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <string>
+
+#include "event_listener.hh"
+
+namespace tizen_base {
+
+class FdMonitor {
+ public:
+ FdMonitor(std::string, int fd, IEventListener* listener);
+ FdMonitor(std::string name, std::string path, IEventListener* listener);
+
+ static gboolean UnixFdSourceFunc(gint fd, GIOCondition cond, gpointer data);
+};
+
+};
+
+ #endif // ACTIVATION_METHOD_FD_MONITOR_HH_
--- /dev/null
+#include "file_info.hh"
+
+#include <utility>
+
+namespace tizen_base {
+
+FileInfo::FileInfo(std::string path, FileMode mode)
+ : path_(std::move(path)), mode_(mode) {}
+
+const std::string& FileInfo::GetPath() const {
+ return path_;
+}
+
+FileMode FileInfo::GetMode() const {
+ return mode_;
+}
+
+} // namespace tizen_base
--- /dev/null
+/*
+ * Copyright (c) 2025 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 ACTIVATION_METHOD_FILE_INFO_HH_
+#define ACTIVATION_METHOD_FILE_INFO_HH_
+
+#include <string>
+
+namespace tizen_base {
+
+enum FileMode {
+// TODO
+};
+
+class FileInfo {
+ public:
+ FileInfo(std::string path, FileMode mode);
+ const std::string& GetPath() const;
+ FileMode GetMode() const;
+
+ private:
+ std::string path_;
+ FileMode mode_;
+};
+
+} // namespace tizen_base
+
+#endif // ACTIVATION_METHOD_FILE_INFO_HH_
--- /dev/null
+#include "file_monitor.hh"
+
+tizen_base::FileMonitor::FileMonitor(std::string name,
+ std::string path,
+ IEventListener* listener) {}
+
+gboolean tizen_base::FileMonitor::UnixFdSourceFunc(gint fd,
+ GIOCondition cond,
+ gpointer data) {
+ // TODO
+ return FALSE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2025 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 ACTIVATION_METHOD_FILE_MONITOR_HH_
+#define ACTIVATION_METHOD_FILE_MONITOR_HH_
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <string>
+
+#include "event_listener.hh"
+
+namespace tizen_base {
+
+class FileMonitor {
+ public:
+ FileMonitor(std::string name, std::string path, IEventListener* listener);
+
+ static gboolean UnixFdSourceFunc(gint fd, GIOCondition cond, gpointer data);
+};
+
+};
+
+#endif // ACTIVATION_METHOD_FILE_MONITOR_HH_
--- /dev/null
+#include "socket_info.hh"
+
+#include <utility>
+
+namespace tizen_base {
+
+SocketInfo::SocketInfo(std::string path, int mode)
+ : path_(std::move(path)), mode_(mode) {}
+
+const std::string& SocketInfo::GetPath() const {
+ return path_;
+}
+
+int SocketInfo::GetMode() const {
+ return mode_;
+}
+
+} // namespace tizen_base
--- /dev/null
+/*
+ * Copyright (c) 2025 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 ACTIVATION_METHOD_SOCKET_INFO_HH_
+#define ACTIVATION_METHOD_SOCKET_INFO_HH_
+
+#include <string>
+
+namespace tizen_base {
+
+class SocketInfo {
+ public:
+ SocketInfo(std::string path, int mode);
+ const std::string& GetPath() const;
+ int GetMode() const;
+
+ private:
+ std::string path_;
+ int mode_;
+};
+
+} // namespace tizen_base
+
+#endif // ACTIVATION_METHOD_SOCKET_INFO_HH_
--- /dev/null
+/*
+ * Copyright (c) 2025 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 ACTIVATION_METHOD_VCONF_INFO_HH_
+#define ACTIVATION_METHOD_VCONF_INFO_HH_
+
+#include <string>
+
+namespace tizen_base {
+
+template<typename T>
+class VconfInfo {
+ public:
+ VconfInfo(std::string key, T value);
+ const std::string& GetKey() const;
+ const T& GetValue() const;
+
+ private:
+ std::string key_;
+ T value_;
+};
+
+};
+
+#endif // ACTIVATION_METHOD_VCONF_INFO_HH_
--- /dev/null
+/*
+ * Copyright (c) 2025 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 EVENT_LISTENER_HH_
+#define EVENT_LISTENER_HH_
+
+#include <string>
+
+namespace tizen_base {
+
+class IEventListener {
+ public:
+ virtual void OnEvent(const std::string& name) = 0;
+};
+
+} // namespace tizen_base
+
+#endif // EVENT_LISTENER_HH_
state_changed_cb_ = std::move(cb);
}
+void Service::Listen(IEventListener* listener) {
+ auto type = info_->GetType();
+ if (type == "socket") {
+ const auto& socket_info = info_->GetSocketInfo();
+ fd_monitor_.reset(new FdMonitor(info_->GetName(), socket_info->GetPath(), listener));
+ } else if (type == "file") {
+ const auto& file_info = info_->GetFileInfo();
+ file_monitor_.reset(new FileMonitor(info_->GetName(), file_info->GetPath(), listener));
+ } else if (type == "dbus") {
+ const auto& dbus_info = info_->GetDbusInfo();
+ dbus_monitor_.reset(new DBusMonitor(info_->GetName(), dbus_info->GetBusName(), listener));
+ }
+}
+
void Service::NotifyStateChanged() {
auto* args = new ServiceStateChangedEventArgs(this, state_);
g_idle_add(
#include <functional>
#include <string>
+#include "event_listener.hh"
#include "service_info.hh"
+#include "activation_method/dbus_monitor.hh"
+#include "activation_method/fd_monitor.hh"
+#include "activation_method/file_monitor.hh"
+
namespace tizen_base {
class Service : public std::enable_shared_from_this<Service> {
tizen_core_channel_sender_h GetChannelSender() const;
void SendMessage(const tizen_base::Bundle& envelope);
void SetStateChangedCb(StateChangedCb cb);
+ void Listen(IEventListener* listener);
private:
void OnBaseCreate();
std::atomic<bool> running_{false};
pid_t tid_ = -1;
StateChangedCb state_changed_cb_ = nullptr;
+
+ std::unique_ptr<FdMonitor> fd_monitor_;
+ std::unique_ptr<FileMonitor> file_monitor_;
+ std::unique_ptr<DBusMonitor> dbus_monitor_;
};
} // namespace tizen_base
#include <libopener.hpp>
+#include "activation_method/dbus_monitor.hh"
+#include "activation_method/fd_monitor.hh"
+#include "activation_method/file_monitor.hh"
+
namespace tizen_base {
class ServiceAssembly {
--- /dev/null
+/*
+ * Copyright (c) 2025 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 "service_context.hh"
+
+#include <dlfcn.h>
+
+#include <string>
+#include <utility>
+
+#include "log_private.hh"
+
+namespace {
+
+constexpr const char kUnitedServiceInit[] = "UNITED_SERVICE_INIT";
+constexpr const char kUnitedServiceShutdown[] = "UNITED_SERVICE_SHUTDOWN";
+
+} // namespace
+
+namespace tizen_base {
+
+ServiceContext::ServiceContext(std::shared_ptr<ServiceInfo> info)
+ : info_(std::move(info)) {}
+
+ServiceContext::~ServiceContext() { Shutdown(); }
+
+bool ServiceContext::Init() {
+ if (!Load()) return false;
+
+ auto* init_func = reinterpret_cast<void* (*)(const char*)>(
+ dlsym(handle_, kUnitedServiceInit));
+ if (init_func == nullptr) {
+ _E("dlsym() is failed. error=%s", dlerror());
+ Unload();
+ return false;
+ }
+
+ auto* handle = init_func(info_->GetName().c_str());
+ if (handle == nullptr) {
+ _E("Failed to initialize united service");
+ Unload();
+ return false;
+ }
+
+ auto* service = static_cast<Service*>(handle);
+ service_ = service->shared_from_this();
+ return true;
+}
+
+void ServiceContext::Shutdown() {
+ if (!handle_) return;
+
+ if (service_) service_->Quit();
+
+ auto* shutdown_func =
+ reinterpret_cast<void (*)(void)>(dlsym(handle_, kUnitedServiceShutdown));
+ if (shutdown_func == nullptr) {
+ _E("dlsym() is failed. error=%s", dlerror());
+ } else {
+ shutdown_func();
+ }
+
+ Unload();
+}
+
+void ServiceContext::Listen(IEventListener* listener) {
+ auto type = info_->GetType();
+ if (type == "socket") {
+ const auto& socket_info = info_->GetSocketInfo();
+ fd_monitor_.reset(new FdMonitor(info_->GetName(), socket_info->GetPath(), listener));
+ } else if (type == "file") {
+ const auto& file_info = info_->GetFileInfo();
+ file_monitor_.reset(new FileMonitor(info_->GetName(), file_info->GetPath(), listener));
+ } else if (type == "dbus") {
+ const auto& dbus_info = info_->GetDbusInfo();
+ dbus_monitor_.reset(new DBusMonitor(info_->GetName(), dbus_info->GetBusName(), listener));
+ }
+}
+
+std::shared_ptr<Service> ServiceContext::GetService() const { return service_; }
+
+std::shared_ptr<ServiceInfo> ServiceContext::GetServiceInfo() const {
+ return info_;
+}
+
+const std::string& ServiceContext::GetName() const { return info_->GetName(); }
+
+bool ServiceContext::Load() {
+ if (handle_) return true;
+
+ _D("Load(): %s", info_->GetPath().c_str());
+ handle_ = dlopen(info_->GetPath().c_str(), RTLD_LAZY | RTLD_GLOBAL);
+ if (handle_ == nullptr) {
+ _E("dlopen() is failed. path=%s, error=%s", info_->GetPath().c_str(),
+ dlerror());
+ return false;
+ }
+
+ return true;
+}
+
+void ServiceContext::Unload() {
+ if (!handle_) return;
+
+ _D("Unload(): %s", info_->GetPath().c_str());
+ dlclose(handle_);
+ handle_ = nullptr;
+}
+
+} // namespace tizen_base
+
static const std::string kType = kTagUnitedService + ":type";
static const std::string kPath = kTagUnitedService + ":path";
static const std::string kPriority = kTagUnitedService + ":priority";
+static const std::string kActivationMethod = "activation-method";
+static const std::string kSocketActivation = kActivationMethod + ":socket";
+static const std::string kFileActivation = kActivationMethod + ":file";
+static const std::string kDBusActivation = kActivationMethod + ":busname";
+static const std::string kVconfActivation = kActivationMethod + ":vconf";
static const int kMinPriority = 1;
static const int kMaxPriority = 99;
_E("Failed to get priority : %s", e.what());
priority_ = 0;
}
+
+ if (mode_ != "on-demand")
+ return;
+
+ if (type_ == "socket") {
+ std::string socket = dictionary->Get(kSocketActivation);
+ if (socket.empty())
+ throw std::runtime_error("No socket activation method defined in configuration file: " + conf_name_);
+
+ socket_info_ = std::make_shared<SocketInfo>(std::move(socket), 0);
+ }
+ else if (type_ == "file") {
+ std::string file = dictionary->Get(kFileActivation);
+ if (file.empty())
+ throw std::runtime_error("No file activation method defined in configuration file: " + conf_name_);
+
+ file_info_ = std::make_shared<FileInfo>(std::move(file), FileMode());
+ }
+ else if (type_ == "dbus") {
+ std::string bus_name = dictionary->Get(kDBusActivation);
+ if (bus_name.empty())
+ throw std::runtime_error("No DBus activation method defined in configuration file: " + conf_name_);
+
+ dbus_info_ = std::make_shared<DBusInfo>(std::move(bus_name));
+ }
+ // std::string vconf = dictionary->Get(kVconfActivation);
+ // if (!vconf.empty())
+ // vconf_info_ = std::make_shared<VconfInfo<std::string>>(std::move(vconf), std::string(""));
}
ServiceInfo::~ServiceInfo() {}
return assembly_;
}
+std::shared_ptr<DBusInfo> ServiceInfo::GetDbusInfo() const {
+ return dbus_info_;
+}
+
+std::shared_ptr<FileInfo> ServiceInfo::GetFileInfo() const {
+ return file_info_;
+}
+
+std::shared_ptr<SocketInfo> ServiceInfo::GetSocketInfo() const {
+ return socket_info_;
+}
+
} // namespace tizen_base
#include "dictionary.hh"
#include "service_assembly.hh"
+#include "activation_method/dbus_info.hh"
+#include "activation_method/file_info.hh"
+#include "activation_method/socket_info.hh"
+#include "activation_method/vconf_info.hh"
+
namespace tizen_base {
class ServiceInfo {
const unsigned int GetPriority() const;
std::shared_ptr<ServiceAssembly> GetAssembly() const;
+ std::shared_ptr<DBusInfo> GetDbusInfo() const;
+ std::shared_ptr<FileInfo> GetFileInfo() const;
+ std::shared_ptr<SocketInfo> GetSocketInfo() const;
+ // std::shared_ptr<VconfInfo> GetVconfInfo() const;
+
private:
std::string conf_name_;
std::string name_;
std::string path_;
unsigned int priority_;
std::shared_ptr<ServiceAssembly> assembly_;
+
+ std::shared_ptr<DBusInfo> dbus_info_;
+ std::shared_ptr<FileInfo> file_info_;
+ std::shared_ptr<SocketInfo> socket_info_;
+ // std::shared_ptr<VconfInfo> vconf_info_;
};
} // namespace tizen_base
#include <tizen_core.h>
#include <tizen_core_channel.h>
+#include <algorithm>
#include <filesystem>
#include <utility>
assembly->Load();
assembly->ModuleInit(info->GetName());
}
+
+ if (info->GetMode() == "on-demand") {
+
+ }
} catch (const Exception& e) {
_E("Error=%s", e.what());
THROW(e.GetErrorCode());
}
void ServiceLoader::Quit() {
- if (!running_) return;
+ if (!running_)
+ return;
tizen_core_task_quit(task_);
}
void ServiceLoader::QuitAllServices() {
for (auto& [name, service] : services_) {
- if (service->IsRunning()) service->Quit();
+ if (service->IsRunning())
+ service->Quit();
+ }
+}
+
+void ServiceLoader::ListenService(const std::string & name) {
+ auto service = GetService(name);
+ if (service != nullptr && service->IsRunning()) {
+ _E("Already running. name=%s", name.c_str());
+ THROW(SERVICE_ERROR_ALREADY_RUNNING);
+ }
+
+ auto info = GetServiceInfo(name);
+ if (info == nullptr) {
+ _E("No such service. name=%s", name.c_str());
+ THROW(SERVICE_ERROR_NO_SUCH_SERVICE);
+ }
+
+ auto listener = ServiceManager::GetInst().Get(name);
+ if (listener == nullptr) {
+ _E("No such event listener. name=%s", name.c_str());
+ THROW(SERVICE_ERROR_INVALID_CONTEXT);
+ }
+
+ service = std::make_shared<Service>(std::move(info), std::move(listener));
+ if (service == nullptr) {
+ _E("Out of memory. name=%s", name.c_str());
+ THROW(SERVICE_ERROR_OUT_OF_MEMORY);
}
+
+ service->SetStateChangedCb(std::bind(&ServiceLoader::ServiceStateChangedCb,
+ this, std::placeholders::_1,
+ std::placeholders::_2));
+ services_[name] = service;
+ service->Listen();
}
void ServiceLoader::LoadService(const std::string& name) {
auto found = infos_.find(name);
- if (found == infos_.end()) THROW(SERVICE_ERROR_INVALID_PARAMETER);
+ if (found == infos_.end())
+ THROW(SERVICE_ERROR_INVALID_PARAMETER);
auto& info = found->second;
auto assembly = info->GetAssembly();
- if (assembly->IsLoaded()) THROW(SERVICE_ERROR_INVALID_CONTEXT);
+ if (assembly->IsLoaded())
+ THROW(SERVICE_ERROR_INVALID_CONTEXT);
try {
assembly->Load();
void ServiceLoader::UnloadService(const std::string& name) {
auto found = infos_.find(name);
- if (found == infos_.end()) THROW(SERVICE_ERROR_NO_SUCH_SERVICE);
+ if (found == infos_.end())
+ THROW(SERVICE_ERROR_NO_SUCH_SERVICE);
auto& info = found->second;
auto assembly = info->GetAssembly();
- if (!assembly->IsLoaded()) THROW(SERVICE_ERROR_INVALID_CONTEXT);
+ if (!assembly->IsLoaded())
+ THROW(SERVICE_ERROR_INVALID_CONTEXT);
try {
assembly->ModuleShutdown(name.c_str());
void ServiceLoader::OnDestroy() {
for (auto& [name, service] : services_) {
- if (service->IsRunning()) service->Quit();
+ if (service->IsRunning())
+ service->Quit();
}
}
void ServiceLoader::OnServiceStateChanged(const Service* service,
Service::State state) {}
+void ServiceLoader::OnEvent(const std::string& name) {
+ auto it = std::find_if(services_.begin(), services_.end(),
+ [&](const std::shared_ptr<Service>& service) {
+ return service->GetName() == name;
+ });
+
+ if (it != services_.end()) {
+ _I("%s on-demand launch", name.c_str());
+ auto& service = *it;
+ service->Run();
+ }
+}
+
void ServiceLoader::ChannelReceiveCb(tizen_core_channel_object_h object,
void* user_data) {
bundle* data = nullptr;
std::shared_ptr<ServiceInfo> ServiceLoader::GetServiceInfo(
const std::string& name) {
auto found = infos_.find(name);
- if (found == infos_.end()) return nullptr;
+ if (found == infos_.end())
+ return nullptr;
return found->second;
}
std::shared_ptr<Service> ServiceLoader::GetService(const std::string& name) {
auto found = services_.find(name);
- if (found == services_.end()) return nullptr;
+ if (found == services_.end())
+ return nullptr;
return found->second;
}
}
}
-} // namespace tizen_base
+} // namespace tizen_base
#include <queue>
#include "service.hh"
+#include <vector>
+
+#include "event_listener.hh"
#include "service_info.hh"
#include "watchdog/watchdog_manager.hh"
namespace tizen_base {
-class ServiceLoader {
+class ServiceLoader : IEventListener {
public:
ServiceLoader(int argc, char** argv, std::string name);
~ServiceLoader();
void RunAllServices();
void QuitService(const std::string& name);
void QuitAllServices();
+ void ListenService(const std::string& name);
void LoadService(const std::string& name);
void UnloadService(const std::string& name);
virtual void OnServiceStateChanged(const Service* service,
Service::State state);
+ void OnEvent(const std::string& name) override;
+
private:
std::shared_ptr<Service> GetService(const std::string& name);
std::shared_ptr<ServiceInfo> GetServiceInfo(const std::string& name);