PKG_CHECK_MODULES(DLOG_DEPS REQUIRED dlog)
PKG_CHECK_MODULES(GLIB_DEPS REQUIRED glib-2.0)
PKG_CHECK_MODULES(TIZEN_CORE_DEPS REQUIRED tizen-core)
+PKG_CHECK_MODULES(TIZEN_LIBOPENER_DEPS REQUIRED tizen-libopener)
PKG_CHECK_MODULES(INIPARSER_DEPS REQUIRED iniparser)
ADD_SUBDIRECTORY(src)
#define __SERVICE_H__
#include <bundle.h>
+#include <service_types.h>
#include <tizen_core.h>
#include <tizen_error.h>
#endif
/**
- * @breif Enumeration for the service result.
- * @since_tizen 10.0
- */
-typedef enum {
- SERVICE_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
- SERVICE_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
- SERVICE_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
- SERVICE_ERROR_INVALID_CONTEXT = TIZEN_ERROR_APPLICATION | 0x01, /**< Invalid context */
- SERVICE_ERROR_ALREADY_EXIST = TIZEN_ERROR_FILE_EXISTS, /**<Service already exists */
-} service_error_e;
-
-/**
- * @brief Enumeration for the service state.
+ * @brief The service handle.
* @since_tizen 10.0
+ * @see service_create()
+ * @see service_destroy()
+ * @see service_run()
+ * @see service_quit()
+ * @see service_send_message()
*/
-typedef enum {
- SERVICE_STATE_INITIALIZED, /**< The service is initialized */
- SERVICE_STATE_CREATED, /**< The service is created. */
- SERVICE_STATE_RUNNING, /**< The service is running. */
- SERVICE_STATE_DESTROYED, /**< The service is destroyed. */
-} service_state_e;
+typedef void *service_h;
/**
* @brief Called when the service starts.
* @details The callback function is called when the main loop of the service starts.
* @since_tizen 10.0
+ * @param[in] service The service handle.
* @param[in] user_data The user data passed from the registration function
* @pre @service_run() will invoke this callback function.
* @see service_run()
* @see #service_lifecycle_callback_s
*/
-typedef void (*service_create_cb)(void *user_data);
+typedef void (*service_create_cb)(service_h service, void *user_data);
/**
* @brief Called when the main loop of the service exits.
* @details You should release resources of the service in this function.
* @since_tizen 10.0
+ * @param[in] service The service handle.
* @param[in] user_data The user data passed from the registration function
* @see service_quit()
* @see #service_lifecycle_callback_s
*/
-typedef void (*service_destroy_cb)(void *user_data);
+typedef void (*service_destroy_cb)(service_h service, void *user_data);
/**
* @brief Called when a message is delivered.
* @since_tizen 10.0
+ * @param[in] service The service handle.
* @param[in] sender The name of the sender
* @param[in] envelope The message
* @param[in] user_data The user data passed from the registration function
* @see service_send_message()
* @see #service_lifecycle_callback_s
*/
-typedef void (*service_message_cb)(const char *sender, bundle *envelope,
- void *user_data);
+typedef void (*service_message_cb)(service_h service, const char *sender,
+ bundle *envelope, void *user_data);
/**
* @brief Thr structure type containing the set of callback functions for handling service lifecycle events.
- * @details It's one of the input parmaeters of the service_create() function.
+ * @details It's one of the input parmaeters of the service_register() function.
* @since_tizen 10.0
- * @see service_create()
+ * @see service_register()
* @see service_create_cb()
* @see service_destroy_cb()
* @see service_message_cb()
} service_lifecycle_callback_s;
/**
- * @brief The service handle.
- * @since_tizen 10.0
- * @see service_create()
- * @see service_destroy()
- * @see service_run()
- * @see service_quit()
- * @see service_send_message()
- */
-typedef void *service_h;
-
-/**
- * @brief Creates a new service instance.
+ * @brief Registers a structure containing the set of callback functions of the service.
* @since_tizen 10.0
- * @remarks @a service must be released using service_destroy().
* @param[in] name The name of the service
* @param[in] callback The set of callback functions for handling service lifecycle events
* @param[in] user_data The user data to be passed to the callback functions
- * @param[out] service The service handle
* @return @c 0 on success,
* otherwise a negative error value
* @retval #SERVICE_ERROR_NONE Successful
* @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory
* @retval #SERVICE_ERROR_ALREADY_EXIST Service already exists
- * @see service_destroy()
- * @see service_run()
+ * @see service_unregister()
* @see #service_lifecycle_callback_s
*
* @code
#undef EXPORT
#define EXPORT __attribute__((visibility("default")))
-static service_h __service;
-
-static void ServiceCreateCb(void* user_data) {
+static void ServiceCreateCb(service_h service, void* user_data) {
// ...
}
-static void ServiceDestroyCb(void* user_data) {
+static void ServiceDestroyCb(service_h service, void* user_data) {
// ...
}
-static void ServiceMessageCb(const char* sender, bundle* envelope, void* user_data) {
+static void ServiceMessageCb(service_h service, const char* sender, bundle* envelope, void* user_data) {
// ...
}
-extern "C" service_h UNITED_SERVICE_INIT(const char* name) {
+extern "C" int UNITED_SERVICE_INIT(const char* name) {
LOGD("UNITED_SERVICE_INIT. name=%s", name);
service_lifecycle_callback_s callback = {
.create = ServiceCreateCb,
.message = ServiceMessageCb,
};
- service_h service = nullptr;
- int ret = service_create(name, &callback, nullptr, &service);
+ int ret = service_register(name, &callback, nullptr);
if (ret != SERVICE_ERROR_NONE) {
LOGE("Failed to create service");
- return nullptr;
+ return -1;
}
- service_run(service);
- __service = service;
- return service;
+ return 0;
}
extern "C" void UNITED_SERVICE_SHUTDOWN(void) {
}
* @endcode
*/
-int service_create(const char *name, service_lifecycle_callback_s *callback,
- void *user_data, service_h *service);
+int service_register(const char *name, service_lifecycle_callback_s *callback,
+ void *user_data);
/**
- * @brief Runs the service instance.
+ * @brief Unregisters the registered the set of callback functions of the service.
* @since_tizen 10.0
- * @param[in] service The service handle
+ * @param[in] name The name of the service.
* @return @c 0 on success,
* otherwise a negative error value
* @retval #SERVICE_ERROR_NONE Successful
* @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #SERVICE_ERROR_INVALID_CONTEXT Invalid context
* @see service_create()
- * @see service_quit()
- * @see service_create_cb()
*
* @code
#include <service.h>
#undef EXPORT
#define EXPORT __attribute__((visibility("default")))
-static service_h __service;
-
-static void ServiceCreateCb(void* user_data) {
- LOGD("Alarm Service Created");
-}
+static char* __name;
extern "C" service_h UNITED_SERVICE_INIT(const char* name) {
LOGD("UNITED_SERVICE_INIT. name=%s", name);
+ __name = strdup(name);
// ...
-
- service_run(service);
- __service = service;
return service;
}
+
+extern "C" void UNITED_SERVICE_SHUTDOWN(void) {
+ LOGD("UNITED_SERVICE_SHUTDOWN");
+ service_unregister(__name);
+ free(__name);
+ __name = nullptr;
+}
* @endcode
*/
-int service_run(service_h service);
+int service_unregister(const char *name);
/**
* @brief Exits the service instance.
static service_h __service;
-static void ServiceDestroyCb(void* user_data) {
+static void ServiceDestroyCb(service_h service, void* user_data) {
// ...
}
LOGD("UNITED_SERVICE_SHUTDOWN");
if (__service) {
service_quit(__service);
- service_destroy(__service);
__service = nullptr;
}
}
static service_h __service;
-static void ServiceMessageCb(const char* sender, bundle* envelope, void* user_data) {
+static void ServiceMessageCb(service_h service, const char* sender, bundle* envelope, void* user_data) {
char* message = nullptr;
if (bundle_get_str(envelope, "MESSAGE", &message) == BUNDLE_ERROR_NONE) {
*/
int service_send_message(service_h service, bundle *envelope);
-/**
- * @brief Destroys the service instance.
- * @since_tizen 10.0
- * @param[in] service The service handle
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #SERVICE_ERROR_NONE Successful
- * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter
- * @see service_create()
- *
- * @code
-#include <service.h>
-#include <dlog.h>
-
-#undef LOG_TAG
-#define LOG_TAG "ALARM_SERVICE"
-
-#undef EXPORT
-#define EXPORT __attribute__((visibility("default")))
-
-static service_h __service;
-
-extern "C" service_h UNITED_SERVICE_INIT(const char* name) {
- LOGD("UNITED_SERVICE_INIT. name=%s", name);
- // ...
- return service;
-}
-
-extern "C" void UNITED_SERVICE_SHUTDOWN(void) {
- LOGD("UNITED_SERVICE_SHUTDOWN");
- if (__service) {
- service_destroy(__service);
- __service = nullptr;
- }
-}
- * @endcode
- */
-int service_destroy(service_h service);
-
/**
* @brief Gets the name of the service.
* @details The @a name must be released using free().
#define __SERVICE_LOADER_H__
#include <bundle.h>
+#include <service_types.h>
#include <tizen_error.h>
#ifdef __cplusplus
* @param[in] user_data The user data to be passed to the callback functions
* @return @c 0 on success,
* otherwise a negative error value
- * @retval #SERVICE_LOADER_ERROR_NONE Successful
- * @retval #SERVICE_LOADER_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #SERVICE_LOADER_ERROR_OUT_OF_MEMORY Out of memory
- * @retval #SERVICE_LOADER_ERROR_ALREADY_RUNNING The service loader is already running
+ * @retval #SERVICE_ERROR_NONE Successful
+ * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #SERVICE_ERROR_ALREADY_RUNNING The service loader is already running
* @see service_loader_create_cb()
* @see service_loader_destroy_cb()
* @see service_loader_message_cb()
* @param[in] envelope The envelope of the message
* @return @c 0 on success,
* otherwise a negative error value
- * @retval #SERVICE_LOADER_ERROR_NONE Successful
- * @retval #SERVICE_LOADER_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #SERVICE_LOADER_ERROR_INVALID_CONTEXT Invalid context
+ * @retval #SERVICE_ERROR_NONE Successful
+ * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SERVICE_ERROR_INVALID_CONTEXT Invalid context
* @see service_loader_message_cb()
*
* @code
*/
int service_loader_send_message(bundle *envelope);
+int service_loader_run_service(const char *name);
+
+int service_loader_run_all_services(void);
+
+int service_loader_quit_service(const char *name);
+
+int service_loader_quit_all_services(void);
+
+int service_loader_load_service(const char *name);
+
+int service_loader_unload_service(const char *name);
+
#ifdef __cplusplus
}
#endif
#define __SERVICE_MANAGER_H__
#include <service.h>
+#include <service_types.h>
#include <tizen.h>
#ifdef __cplusplus
extern "C" {
#endif
-/**
- * @brief Enumeration for the service manager result.
- * @since_tizen 10.0
- */
-typedef enum {
- SERVICE_MANAGER_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
- SERVICE_MANAGER_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
- SERVICE_MANAGER_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
-} service_manager_error_e;
-
/**
* @brief The handle for the service manager event handler.
* @since_tizen 10.0
* @param[out] event_handler The event handler
* @return @c 0 on success,
* otherwise a negative error value
- * @retval #SERVICE_MANAGER_ERROR_NONE Successful
- * @retval #SERVICE_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #SERVICE_MANAGER_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #SERVICE_ERROR_NONE Successful
+ * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory
* @see service_manager_remove_event_handler()
* @see service_state_changed_cb()
* @remarks The @a event_handler should be released using service_manager_remove_event_handler().
* @param[in] event_handler The event handler
* @return @c 0 on success,
* otherwise a negative error value
- * @retval #SERVICE_MANAGER_ERROR_NONE Successful
- * @retval #SERVICE_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SERVICE_ERROR_NONE Successful
+ * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter
* @see service_manager_add_event_handler()
*
* @code
* @param[out] service The service handle
* @return @c 0 on success,
* otherwise a negative error value
- * @retval #SERVICE_MANAGER_ERROR_NONE Successful
- * @retval #SERVICE_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SERVICE_ERROR_NONE Successful
+ * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter
* @remarks The @a service should not be released using service_destroy().
*
* @code
--- /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 __SERVICE_TYPES_H__
+#define __SERVICE_TYPES_H__
+
+#include <tizen_error.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @breif Enumeration for the service result.
+ * @since_tizen 10.0
+ */
+typedef enum {
+ SERVICE_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
+ SERVICE_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+ SERVICE_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
+ SERVICE_ERROR_INVALID_CONTEXT = TIZEN_ERROR_APPLICATION | 0x01, /**< Invalid context */
+ SERVICE_ERROR_ALREADY_EXIST = TIZEN_ERROR_FILE_EXISTS, /**< Already exists */
+ SERVICE_ERROR_ALREADY_RUNNING = TIZEN_ERROR_ALREADY_IN_PROGRESS, /**< Already running */
+ SERVICE_ERROR_NO_SUCH_SERVICE = TIZEN_ERROR_NO_SUCH_FILE, /**< No such service */
+ SERVICE_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< I/O error */
+} service_error_e;
+
+/**
+ * @brief Enumeration for the service state.
+ * @since_tizen 10.0
+ */
+typedef enum {
+ SERVICE_STATE_INITIALIZED, /**< The service is initialized */
+ SERVICE_STATE_CREATED, /**< The service is created. */
+ SERVICE_STATE_RUNNING, /**< The service is running. */
+ SERVICE_STATE_DESTROYED, /**< The service is destroyed. */
+} service_state_e;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SERVICE_TYPES_H__ */
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(bundle)
BuildRequires: pkgconfig(tizen-core)
+BuildRequires: pkgconfig(tizen-libopener)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(iniparser)
DLOG_DEPS
GLIB_DEPS
TIZEN_CORE_DEPS
+ TIZEN_LIBOPENER_DEPS
INIPARSER_DEPS
)
const char* Exception::what() const noexcept { return message_.c_str(); }
-int Exception::GetErrorCode() { return error_code_; }
+int Exception::GetErrorCode() const { return error_code_; }
std::string Exception::GetErrorMessage(int error_code, const std::string& file,
int line) {
#include <exception>
#include <string>
+#include "service_types.h"
#include "log_private.hh"
#define THROW(error_code) throw Exception(error_code, __FUNCTION__, __LINE__)
virtual ~Exception() = default;
virtual const char* what() const noexcept;
- int GetErrorCode();
+ int GetErrorCode() const;
private:
static std::string GetErrorMessage(int error_code, const std::string& file,
#include <errno.h>
+#include "service_types.h"
#include "exception.hh"
#include "log_private.hh"
dictionary* d = iniparser_load(path.c_str());
if (d == nullptr) {
_E("iniparser_load(%s) is failed", path.c_str());
- THROW(-errno);
+ THROW(SERVICE_ERROR_IO_ERROR);
}
auto d_ptr = std::unique_ptr<dictionary, decltype(iniparser_freedict)*>(
namespace tizen_base {
-Service::Service(std::string name) : name_(std::move(name)) {
+Service::Service(std::shared_ptr<ServiceInfo> info,
+ std::shared_ptr<IEvent> listener)
+ : info_(std::move(info)), listener_(std::move(listener)) {
if (!Init()) {
Shutdown();
throw new std::runtime_error("Failed to initialize service");
bool Service::Init() {
tizen_core_init();
- int ret = tizen_core_task_create(name_.c_str(), true, &task_);
+ int ret = tizen_core_task_create(GetName().c_str(), true, &task_);
if (ret != TIZEN_CORE_ERROR_NONE) {
- _E("tizen_core_task_create() is failed. name=%s", name_.c_str());
+ _E("tizen_core_task_create() is failed. name=%s", GetName().c_str());
return false;
}
}
}
-const std::string& Service::GetName() const { return name_; }
+const std::shared_ptr<ServiceInfo>& Service::GetServiceInfo() const {
+ return info_;
+}
+
+const std::string& Service::GetName() const { return info_->GetName(); }
Service::State Service::GetState() const { return state_; }
tizen_core_h Service::GetCore() const { return core_; }
-tizen_core_channel_sender_h Service::GetChannelSender() const { return sender_; }
+tizen_core_channel_sender_h Service::GetChannelSender() const {
+ return sender_;
+}
+
+bool Service::IsRunning() const { return running_; }
void Service::Run() {
- if (running_) {
+ if (IsRunning()) {
_E("Already running");
return;
}
}
void Service::Quit() {
- if (!running_) return;
+ if (!IsRunning()) return;
std::unique_lock<std::mutex> lock(mutex_);
tizen_core_source_h source = nullptr;
void Service::OnCreate() {
state_ = State::Created;
+ if (listener_.use_count() > 1) listener_->OnCreate(this);
ServiceManager::GetInst().NotifyServiceStateChanged(this);
}
void Service::OnDestroy() {
state_ = State::Destroyed;
+ if (listener_.use_count() > 1) listener_->OnDestroy(this);
ServiceManager::GetInst().NotifyServiceStateChanged(this);
}
void Service::OnMessageReceived(const std::string& sender,
- const tizen_base::Bundle& envelope) {}
+ const tizen_base::Bundle& envelope) {
+ if (listener_.use_count() > 1)
+ listener_->OnMessageReceived(this, sender, envelope);
+}
void Service::ChannelReceiveCb(tizen_core_channel_object_h object,
void* user_data) {
#include <tizen_core.h>
#include <tizen_core_channel.h>
+#include <atomic>
#include <condition_variable>
#include <memory>
#include <mutex>
#include <string>
+#include "service_info.hh"
+
namespace tizen_base {
class Service : public std::enable_shared_from_this<Service> {
Destroyed,
};
- Service(std::string name);
+ class IEvent {
+ public:
+ virtual ~IEvent() = default;
+ virtual void OnCreate(const Service* service) = 0;
+ virtual void OnDestroy(const Service* service) = 0;
+ virtual void OnMessageReceived(const Service* service,
+ const std::string& sender,
+ const Bundle& envelope) = 0;
+ };
+
+ Service(std::shared_ptr<ServiceInfo> info, std::shared_ptr<IEvent> listener);
virtual ~Service();
void Run();
void Quit();
+ bool IsRunning() const;
+ const std::shared_ptr<ServiceInfo>& GetServiceInfo() const;
const std::string& GetName() const;
State GetState() const;
tizen_core_h GetCore() const;
tizen_core_channel_sender_h GetChannelSender() const;
void SendMessage(const tizen_base::Bundle& envelope);
- virtual void OnCreate();
- virtual void OnDestroy();
- virtual void OnMessageReceived(const std::string& sender,
- const tizen_base::Bundle& envelope);
+ void OnCreate();
+ void OnDestroy();
+ void OnMessageReceived(const std::string& sender,
+ const tizen_base::Bundle& envelope);
private:
bool Init();
void* user_data);
private:
- std::string name_;
+ std::shared_ptr<ServiceInfo> info_;
+ std::shared_ptr<IEvent> listener_;
State state_ = State::Initialized;
tizen_core_task_h task_ = nullptr;
tizen_core_h core_ = nullptr;
tizen_core_channel_sender_h sender_ = nullptr;
tizen_core_channel_receiver_h receiver_ = nullptr;
tizen_core_source_h source_ = nullptr;
- bool running_ = false;
+ std::atomic<bool> running_{false};
std::mutex mutex_;
std::condition_variable cond_var_;
pid_t tid_ = -1;
--- /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_assembly.hh"
+
+#include <filesystem>
+#include <string>
+
+#include "exception.hh"
+#include "log_private.hh"
+
+namespace {
+
+constexpr const char kUnitedServiceInit[] = "UNITED_SERVICE_INIT";
+constexpr const char kUnitedServiceShutdown[] = "UNITED_SERVICE_SHUTDOWN";
+
+} // namespace
+
+namespace tizen_base {
+
+ServiceAssembly::ServiceAssembly(std::string assembly_path)
+ : assembly_path_(std::move(assembly_path)) {}
+
+ServiceAssembly::~ServiceAssembly() {}
+
+bool ServiceAssembly::IsLoaded() const { return lib_opener_.get(); }
+
+void ServiceAssembly::Load() {
+ try {
+ lib_opener_.reset(new tizen_base::LibOpener(assembly_path_));
+ } catch (const std::filesystem::filesystem_error& e) {
+ _E("Error=%s", e.what());
+ THROW(SERVICE_ERROR_IO_ERROR);
+ }
+}
+
+void ServiceAssembly::Unload() { lib_opener_.reset(); }
+
+void ServiceAssembly::ModuleInit(const std::string& name) {
+ try {
+ auto init_func =
+ lib_opener_->Bind<int (*)(const char*)>(kUnitedServiceInit);
+ int ret = init_func(name.c_str());
+ if (ret != 0) {
+ _E("Failed to initialize service. name=%s", name.c_str());
+ THROW(SERVICE_ERROR_INVALID_CONTEXT);
+ }
+ } catch (const std::exception& e) {
+ _E("Error=%s", e.what());
+ THROW(SERVICE_ERROR_NO_SUCH_SERVICE);
+ }
+}
+
+void ServiceAssembly::ModuleShutdown() {
+ try {
+ auto shutdown_func = lib_opener_->Bind<void (*)()>(kUnitedServiceShutdown);
+ shutdown_func();
+ } catch (const std::exception& e) {
+ _E("Error=%s", e.what());
+ THROW(SERVICE_ERROR_NO_SUCH_SERVICE);
+ }
+}
+
+} // 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 SERVICE_ASSEMBLY_HH_
+#define SERVICE_ASSEMBLY_HH_
+
+#include <memory>
+#include <string>
+
+#include <libopener.hpp>
+
+namespace tizen_base {
+
+class ServiceAssembly {
+ public:
+ ServiceAssembly(std::string assembly_path);
+ virtual ~ServiceAssembly();
+
+ bool IsLoaded() const;
+ void Load();
+ void Unload();
+
+ void ModuleInit(const std::string& name);
+ void ModuleShutdown();
+
+ private:
+ std::string assembly_path_;
+ std::unique_ptr<LibOpener> lib_opener_{nullptr};
+};
+
+} // namespace tizen_base
+
+#endif // SERVICE_ASSEMBLY_HH_
\ No newline at end of file
+++ /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();
-}
-
-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
-
+++ /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 SERVICE_CONTEXT_HH_
-#define SERVICE_CONTEXT_HH_
-
-#include <memory>
-#include <string>
-
-#include "service.hh"
-#include "service_info.hh"
-
-namespace tizen_base {
-
-class ServiceContext {
- public:
- ServiceContext(std::shared_ptr<ServiceInfo> info);
- ~ServiceContext();
-
- bool Init();
- void Shutdown();
- std::shared_ptr<Service> GetService() const;
- std::shared_ptr<ServiceInfo> GetServiceInfo() const;
- const std::string& GetName() const;
-
- private:
- bool Load();
- void Unload();
-
- private:
- std::shared_ptr<ServiceInfo> info_;
- std::shared_ptr<Service> service_;
- void* handle_ = nullptr;
-};
-
-} // namespace tizen_base
-
-#endif // SERVICE_CONTEXT_HH_
_D("Type=%s", type_.c_str());
path_ = dictionary->Get(kPath);
_D("Path=%s", path_.c_str());
+ assembly_ = std::make_shared<ServiceAssembly>(path_);
}
ServiceInfo::~ServiceInfo() {}
const std::string& ServiceInfo::GetPath() const { return path_; }
+std::shared_ptr<ServiceAssembly> ServiceInfo::GetAssembly() const {
+ return assembly_;
+}
+
} // namespace tizen_base
#include <string>
#include "dictionary.hh"
+#include "service_assembly.hh"
namespace tizen_base {
const std::string& GetMode() const;
const std::string& GetType() const;
const std::string& GetPath() const;
+ std::shared_ptr<ServiceAssembly> GetAssembly() const;
private:
std::string conf_name_;
std::string mode_;
std::string type_;
std::string path_;
+ std::shared_ptr<ServiceAssembly> assembly_;
};
} // namespace tizen_base
#include "exception.hh"
#include "iniparser.hh"
#include "log_private.hh"
+#include "service_manager.hh"
namespace {
auto dictionary = IniParser::Parse(file.string());
auto info =
std::make_shared<ServiceInfo>(file.string(), std::move(dictionary));
- auto context = std::make_shared<ServiceContext>(std::move(info));
- context->Init();
- contexts_.push_back(std::move(context));
+ infos_[info->GetName()] = std::move(info);
}
}
}
+
+ for (auto& [name, info] : infos_) {
+ try {
+ auto assembly = info->GetAssembly();
+ if (!assembly->IsLoaded()) {
+ assembly->Load();
+ assembly->ModuleInit(info->GetName());
+ }
+ } catch (const Exception& e) {
+ _E("Error=%s", e.what());
+ THROW(e.GetErrorCode());
+ }
+ }
}
int ServiceLoader::Run() {
tizen_core_channel_object_destroy(object);
if (ret != TIZEN_CORE_ERROR_NONE) {
_E("tizen_core_channel_send() is failed. error=%d", ret);
- throw new std::runtime_error("Failed to send message");
+ THROW(SERVICE_ERROR_IO_ERROR);
+ }
+}
+
+void ServiceLoader::RunService(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().GetServiceEventListener(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->Run();
+}
+
+void ServiceLoader::RunAllServices() {
+ for (auto& [name, _] : infos_) {
+ try {
+ RunService(name);
+ } catch (const Exception& e) {
+ _E("Error=%s", e.what());
+ }
+ }
+}
+
+void ServiceLoader::QuitService(const std::string& name) {
+ auto service = GetService(name);
+ if (service == nullptr || !service->IsRunning()) {
+ _E("Not running. name=%s", name.c_str());
+ THROW(SERVICE_ERROR_INVALID_CONTEXT);
+ }
+
+ service->Quit();
+}
+
+void ServiceLoader::QuitAllServices() {
+ for (auto& [name, service] : services_) {
+ if (service->IsRunning()) service->Quit();
+ }
+}
+
+void ServiceLoader::LoadService(const std::string& name) {
+ auto found = infos_.find(name);
+ 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);
+
+ try {
+ assembly->Load();
+ assembly->ModuleInit(info->GetName());
+ } catch (const Exception& e) {
+ _E("Error=%s", e.what());
+ THROW(e.GetErrorCode());
+ }
+}
+
+void ServiceLoader::UnloadService(const std::string& name) {
+ auto found = infos_.find(name);
+ 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);
+
+ try {
+ assembly->ModuleShutdown();
+ assembly->Unload();
+ } catch (const Exception& e) {
+ _E("Error=%s", e.what());
}
}
}
void ServiceLoader::OnDestroy() {
- for (auto& context : contexts_) {
- context->Shutdown();
+ for (auto& [name, service] : services_) {
+ if (service->IsRunning()) service->Quit();
}
}
tizen_base::Bundle(data, false, true));
}
+std::shared_ptr<ServiceInfo> ServiceLoader::GetServiceInfo(
+ const std::string& name) {
+ auto found = infos_.find(name);
+ 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;
+
+ return found->second;
+}
+
} // namespace tizen_base
* limitations under the License.
*/
+#ifndef SERVICE_LOADER_HH_
+#define SERVICE_LOADER_HH_
+
#include <bundle_cpp.h>
#include <tizen_core.h>
#include <memory>
#include <string>
+#include <unordered_map>
-#include "service_context.hh"
+#include "service.hh"
#include "service_info.hh"
namespace tizen_base {
void Quit();
void SendMessage(const tizen_base::Bundle& envelope);
+ void RunService(const std::string& name);
+ void RunAllServices();
+ void QuitService(const std::string& name);
+ void QuitAllServices();
+ void LoadService(const std::string& name);
+ void UnloadService(const std::string& name);
+
virtual void OnCreate();
virtual void OnDestroy();
virtual void OnMessageReceived(const std::string& sender,
const tizen_base::Bundle& envelope);
private:
+ std::shared_ptr<Service> GetService(const std::string& name);
+ std::shared_ptr<ServiceInfo> GetServiceInfo(const std::string& name);
+
bool Init();
void Shutdown();
void LoadServices();
tizen_core_channel_receiver_h receiver_ = nullptr;
tizen_core_source_h source_ = nullptr;
bool running_ = false;
- std::vector<std::shared_ptr<ServiceContext>> contexts_;
+ std::unordered_map<std::string, std::shared_ptr<ServiceInfo>> infos_;
+ std::unordered_map<std::string, std::shared_ptr<Service>> services_;
};
} // namespace tizen_base
+
+#endif // SERVICE_LOADER_HH_
}
}
+void ServiceManager::RegisterServiceEventListener(
+ std::string name, std::shared_ptr<Service::IEvent> listener) {
+ if (!Contains(name)) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ service_listeners_[std::move(name)] = std::move(listener);
+}
+
+void ServiceManager::UnregisterServiceEventListener(const std::string& name) {
+ auto found = service_listeners_.find(name);
+ if (found == service_listeners_.end()) return;
+
+ service_listeners_.erase(found);
+}
+
+std::shared_ptr<Service::IEvent> ServiceManager::GetServiceEventListener(
+ const std::string& name) {
+ auto found = service_listeners_.find(name);
+ if (found == service_listeners_.end()) return nullptr;
+
+ return found->second;
+}
+
std::shared_ptr<Service> ServiceManager::FindFromThisThread() {
tizen_core_h core = nullptr;
tizen_core_find_from_this_thread(&core);
void RemoveEventListener(const std::shared_ptr<Service>& service,
IEvent* listener);
void NotifyServiceStateChanged(Service* service);
+ void RegisterServiceEventListener(std::string name,
+ std::shared_ptr<Service::IEvent> listener);
+ void UnregisterServiceEventListener(const std::string& name);
+ std::shared_ptr<Service::IEvent> GetServiceEventListener(
+ const std::string& name);
std::shared_ptr<Service> FindFromThisThread();
~ServiceManager();
private:
+ std::unordered_map<std::string, std::shared_ptr<Service::IEvent>>
+ service_listeners_;
std::unordered_map<std::string, std::shared_ptr<Service>> services_;
std::unordered_map<std::shared_ptr<Service>, std::vector<IEvent*>> listeners_;
};
namespace {
-class ServiceExt : public tizen_base::Service {
+class ServiceEvent : public tizen_base::Service::IEvent {
public:
- ServiceExt(std::string name) : tizen_base::Service(std::move(name)) {}
+ ServiceEvent(service_lifecycle_callback_s* callback, void* user_data)
+ : callback_(*callback), user_data_(user_data) {}
- virtual ~ServiceExt() {}
-
- void SetCallback(service_lifecycle_callback_s* callback, void* user_data) {
- callback_ = *callback;
- user_data_ = user_data;
- }
+ virtual ~ServiceEvent() {}
private:
- void OnCreate() override {
- tizen_base::Service::OnCreate();
- if (callback_.create) callback_.create(user_data_);
+ void OnCreate(const tizen_base::Service* service) override {
+ if (callback_.create) {
+ auto* handle =
+ static_cast<service_h>(const_cast<tizen_base::Service*>(service));
+ callback_.create(handle, user_data_);
+ }
}
- void OnDestroy() override {
- tizen_base::Service::OnDestroy();
- if (callback_.destroy) callback_.destroy(user_data_);
+ void OnDestroy(const tizen_base::Service* service) override {
+ if (callback_.destroy) {
+ auto* handle =
+ static_cast<service_h>(const_cast<tizen_base::Service*>(service));
+ callback_.destroy(handle, user_data_);
+ }
}
- void OnMessageReceived(const std::string& sender,
+ void OnMessageReceived(const tizen_base::Service* service,
+ const std::string& sender,
const tizen_base::Bundle& envelope) override {
- tizen_base::Service::OnMessageReceived(sender, envelope);
if (callback_.message) {
- callback_.message(sender.c_str(), envelope.GetHandle(), user_data_);
+ auto* handle =
+ static_cast<service_h>(const_cast<tizen_base::Service*>(service));
+ callback_.message(handle, sender.c_str(), envelope.GetHandle(),
+ user_data_);
}
}
private:
- service_lifecycle_callback_s callback_ = { nullptr, };
+ service_lifecycle_callback_s callback_;
void* user_data_ = nullptr;
};
} // namespace
-API int service_create(const char* name, service_lifecycle_callback_s* callback,
- void* user_data, service_h* service) {
- if (!name || !callback || !service) {
+API int service_register(const char* name,
+ service_lifecycle_callback_s* callback,
+ void* user_data) {
+ if (!name || !callback || !callback->create) {
_E("Invalid parameter");
return SERVICE_ERROR_INVALID_PARAMETER;
}
auto& inst = tizen_base::ServiceManager::GetInst();
- if (inst.Contains(name)) return SERVICE_ERROR_ALREADY_EXIST;
+ auto listener = inst.GetServiceEventListener(name);
+ if (listener != nullptr) return SERVICE_ERROR_ALREADY_EXIST;
try {
- auto handle = std::make_shared<ServiceExt>(name);
- handle->SetCallback(callback, user_data);
- *service = reinterpret_cast<service_h>(handle.get());
- inst.Insert(name, std::move(handle));
+ auto handle = std::make_shared<ServiceEvent>(callback, user_data);
+ inst.RegisterServiceEventListener(name, std::move(handle));
} catch (const std::bad_alloc&) {
_E("Out of memory");
return SERVICE_ERROR_OUT_OF_MEMORY;
return SERVICE_ERROR_NONE;
}
-API int service_run(service_h service) {
- if (!service) {
+API int service_unregister(const char* name) {
+ if (!name) {
_E("Invalid parameter");
return SERVICE_ERROR_INVALID_PARAMETER;
}
- auto* handle = reinterpret_cast<ServiceExt*>(service);
- try {
- handle->Run();
- } catch (const std::runtime_error&) {
- _E("Failed to run service");
- return SERVICE_ERROR_INVALID_CONTEXT;
- }
-
+ tizen_base::ServiceManager::GetInst().UnregisterServiceEventListener(name);
return SERVICE_ERROR_NONE;
}
return SERVICE_ERROR_INVALID_PARAMETER;
}
- auto* handle = reinterpret_cast<ServiceExt*>(service);
+ auto* handle = reinterpret_cast<tizen_base::Service*>(service);
handle->Quit();
return SERVICE_ERROR_NONE;
}
return SERVICE_ERROR_INVALID_PARAMETER;
}
- auto* handle = reinterpret_cast<ServiceExt*>(service);
+ auto* handle = reinterpret_cast<tizen_base::Service*>(service);
try {
handle->SendMessage(tizen_base::Bundle(envelope));
} catch (const std::runtime_error&) {
return SERVICE_ERROR_NONE;
}
-API int service_destroy(service_h service) {
- if (!service) {
- _E("Invalid parameter");
- return SERVICE_ERROR_INVALID_PARAMETER;
- }
-
- auto* handle = reinterpret_cast<ServiceExt*>(service);
- tizen_base::ServiceManager::GetInst().Remove(handle->GetName());
- return SERVICE_ERROR_NONE;
-}
-
API int service_get_name(service_h service, char** name) {
if (!service || !name) {
_E("Invalid parameter");
return SERVICE_ERROR_INVALID_PARAMETER;
}
- auto* handle = reinterpret_cast<ServiceExt*>(service);
+ auto* handle = reinterpret_cast<tizen_base::Service*>(service);
*name = strdup(handle->GetName().c_str());
if (*name == nullptr) {
_E("Out of memory");
return SERVICE_ERROR_INVALID_PARAMETER;
}
- auto* handle = reinterpret_cast<ServiceExt*>(service);
+ auto* handle = reinterpret_cast<tizen_base::Service*>(service);
*state = static_cast<service_state_e>(handle->GetState());
return SERVICE_ERROR_NONE;
}
return SERVICE_ERROR_INVALID_PARAMETER;
}
- auto* handle = reinterpret_cast<ServiceExt*>(service);
+ auto* handle = reinterpret_cast<tizen_base::Service*>(service);
*core = handle->GetCore();
return SERVICE_ERROR_NONE;
}
return SERVICE_ERROR_INVALID_PARAMETER;
}
- auto* handle = reinterpret_cast<ServiceExt*>(service);
+ auto* handle = reinterpret_cast<tizen_base::Service*>(service);
*sender = handle->GetChannelSender();
return SERVICE_ERROR_NONE;
}
service_manager_event_h *event_handler) {
if (!callback || !event_handler) {
_E("Invalid parameter");
- return SERVICE_MANAGER_ERROR_INVALID_PARAMETER;
+ return SERVICE_ERROR_INVALID_PARAMETER;
}
auto* handle = new (std::nothrow) EventHandler(callback, user_data);
if (!handle) {
_E("Out of memory");
- return SERVICE_MANAGER_ERROR_OUT_OF_MEMORY;
+ return SERVICE_ERROR_OUT_OF_MEMORY;
}
auto& inst = tizen_base::ServiceManager::GetInst();
tizen_base::ServiceManager::GetInst().AddEventListener(service, handle);
*event_handler = reinterpret_cast<service_manager_event_h>(handle);
- return SERVICE_MANAGER_ERROR_NONE;
+ return SERVICE_ERROR_NONE;
}
API int service_manager_remove_event_handler(
service_manager_event_h event_handler) {
if (!event_handler) {
_E("Invalid parameter");
- return SERVICE_MANAGER_ERROR_INVALID_PARAMETER;
+ return SERVICE_ERROR_INVALID_PARAMETER;
}
auto* handle = reinterpret_cast<EventHandler*>(event_handler);
inst.RemoveEventListener(service, handle);
delete handle;
- return SERVICE_MANAGER_ERROR_NONE;
+ return SERVICE_ERROR_NONE;
}
API int service_manager_get_service(const char* name, service_h* service) {
if (!name || !service) {
_E("Invalid parameter");
- return SERVICE_MANAGER_ERROR_INVALID_PARAMETER;
+ return SERVICE_ERROR_INVALID_PARAMETER;
}
auto& inst = tizen_base::ServiceManager::GetInst();
- if (!inst.Contains(name)) return SERVICE_MANAGER_ERROR_INVALID_PARAMETER;
+ if (!inst.Contains(name)) return SERVICE_ERROR_INVALID_PARAMETER;
*service = reinterpret_cast<service_h>(inst.Get(name).get());
- return SERVICE_MANAGER_ERROR_NONE;
+ return SERVICE_ERROR_NONE;
}
* limitations under the License.
*/
- #include "service_loader.h"
-
- #include <new>
- #include <stdexcept>
- #include <utility>
-
- #include "log_private.hh"
- #include "service_loader.hh"
-
- #undef EXPORT
- #define EXPORT __attribute__((visibility("default")))
-
- #undef API
- #define API extern "C" EXPORT
+#include "service_loader.h"
+
+#include <new>
+#include <stdexcept>
+#include <utility>
+
+#include "exception.hh"
+#include "log_private.hh"
+#include "service_loader.hh"
+
+#undef EXPORT
+#define EXPORT __attribute__((visibility("default")))
+
+#undef API
+#define API extern "C" EXPORT
namespace {
void* user_data) {
if (argc < 1 || argv == nullptr || name == nullptr || callback == nullptr) {
_E("Invalid parameter");
- return SERVICE_LOADER_ERROR_INVALID_PARAMETER;
+ return SERVICE_ERROR_INVALID_PARAMETER;
}
if (::context != nullptr) {
_E("Already running");
- return SERVICE_LOADER_ERROR_ALREADY_RUNNING;
+ return SERVICE_ERROR_ALREADY_RUNNING;
}
try {
loader.Run();
} catch (const std::runtime_error& e) {
_E("Exception occurs. error: %s", e.what());
- return SERVICE_LOADER_ERROR_INVALID_CONTEXT;
+ return SERVICE_ERROR_INVALID_CONTEXT;
}
- return SERVICE_LOADER_ERROR_NONE;
+ return SERVICE_ERROR_NONE;
}
API void service_loader_quit(void) {
if (!::context) {
- set_last_result(SERVICE_LOADER_ERROR_INVALID_CONTEXT);
+ set_last_result(SERVICE_ERROR_INVALID_CONTEXT);
return;
}
::context->Quit();
- set_last_result(SERVICE_LOADER_ERROR_NONE);
+ set_last_result(SERVICE_ERROR_NONE);
}
API int service_loader_send_message(bundle* envelope) {
if (!envelope) {
_E("Invalid parameter");
- return SERVICE_LOADER_ERROR_INVALID_PARAMETER;
+ return SERVICE_ERROR_INVALID_PARAMETER;
}
- if (!::context) return SERVICE_LOADER_ERROR_INVALID_CONTEXT;
+ if (!::context) return SERVICE_ERROR_INVALID_CONTEXT;
::context->SendMessage(tizen_base::Bundle(envelope));
- return SERVICE_LOADER_ERROR_NONE;
+ return SERVICE_ERROR_NONE;
+}
+
+API int service_loader_run_service(const char *name) {
+ if (!name) {
+ _E("Invalid parameter");
+ return SERVICE_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!::context) {
+ _E("Invalid context");
+ return SERVICE_ERROR_INVALID_CONTEXT;
+ }
+
+ try {
+ ::context->RunService(name);
+ } catch (const tizen_base::Exception& e) {
+ _E("Exception occurs. error: %s", e.what());
+ return e.GetErrorCode();
+ }
+
+ return SERVICE_ERROR_NONE;
+}
+
+API int service_loader_run_all_services(void) {
+ if (!::context) {
+ _E("Invalid context");
+ return SERVICE_ERROR_INVALID_CONTEXT;
+ }
+
+ ::context->RunAllServices();
+ return SERVICE_ERROR_NONE;
+}
+
+API int service_loader_quit_service(const char *name) {
+ if (!name) {
+ _E("Invalid parameter");
+ return SERVICE_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!::context) {
+ _E("Invalid context");
+ return SERVICE_ERROR_INVALID_CONTEXT;
+ }
+
+ try {
+ ::context->QuitService(name);
+ } catch (const tizen_base::Exception& e) {
+ _E("Exception occurs. error: %s", e.what());
+ return e.GetErrorCode();
+ }
+
+ return SERVICE_ERROR_NONE;
+}
+
+API int service_loader_quit_all_services(void) {
+ if (!::context) {
+ _E("Invalid context");
+ return SERVICE_ERROR_INVALID_CONTEXT;
+ }
+
+ ::context->QuitAllServices();
+ return SERVICE_ERROR_NONE;
+}
+
+API int service_loader_load_service(const char *name) {
+ if (!name) {
+ _E("Invalid parameter");
+ return SERVICE_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!::context) {
+ _E("Invalid context");
+ return SERVICE_ERROR_INVALID_CONTEXT;
+ }
+
+ try {
+ ::context->LoadService(name);
+ } catch (const tizen_base::Exception& e) {
+ _E("Exception occurs. error: %s", e.what());
+ return e.GetErrorCode();
+ }
+ return SERVICE_ERROR_NONE;
+}
+
+API int service_loader_unload_service(const char* name) {
+ if (!name) {
+ _E("Invalid parameter");
+ return SERVICE_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!::context) {
+ _E("Invalid context");
+ return SERVICE_ERROR_INVALID_CONTEXT;
+ }
+
+ try {
+ ::context->UnloadService(name);
+ } catch (const tizen_base::Exception& e) {
+ _E("Exception occurs. error: %s", e.what());
+ return e.GetErrorCode();
+ }
+ return SERVICE_ERROR_NONE;
}