Extract some of existing logic into separate classes 50/226050/6 submit/tizen/20200408.110745
authorJi-hoon Lee <dalton.lee@samsung.com>
Fri, 21 Feb 2020 11:09:51 +0000 (20:09 +0900)
committerJi-hoon Lee <dalton.lee@samsung.com>
Tue, 7 Apr 2020 02:09:07 +0000 (11:09 +0900)
Change-Id: I125779f5ed85d2f4a7609b43fcb21f9d43c74404

16 files changed:
CMakeLists.txt
inc/application_manager.h [new file with mode: 0644]
inc/application_manager_aul.h [new file with mode: 0644]
inc/client_manager.h [new file with mode: 0644]
inc/service_ipc_dbus.h
inc/service_ipc_dbus_dispatcher.h
inc/service_main.h
src/application_manager_aul.cpp [new file with mode: 0644]
src/client_manager.cpp [new file with mode: 0644]
src/service_ipc_dbus.cpp
src/service_ipc_dbus_dispatcher.cpp
src/service_main.cpp
src/service_plugin.cpp
tests/utc/CMakeLists.txt
tests/utc/client-manager/CMakeLists.txt [new file with mode: 0644]
tests/utc/client-manager/test_client_manager.cpp [new file with mode: 0644]

index aca1239..be36924 100644 (file)
@@ -64,6 +64,8 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc)
 SET(SRCS
                src/main.cpp
                src/service_config.cpp
+               src/application_manager_aul.cpp
+               src/client_manager.cpp
                src/service_main.cpp
                src/service_plugin.cpp
                src/service_ipc_dbus.cpp
diff --git a/inc/application_manager.h b/inc/application_manager.h
new file mode 100644 (file)
index 0000000..f6733fc
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2018-2019 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 __APPLICATION_MANAGER_H__
+#define __APPLICATION_MANAGER_H__
+
+#include <string>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+class IApplicationManager {
+public:
+       virtual bool is_application_running(int pid) = 0;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APPLICATION_MANAGER_H__ */
diff --git a/inc/application_manager_aul.h b/inc/application_manager_aul.h
new file mode 100644 (file)
index 0000000..2c47dc2
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2018-2019 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 __APPLICATION_MANAGER_AUL_H__
+#define __APPLICATION_MANAGER_AUL_H__
+
+#include "application_manager.h"
+
+#include <string>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+class CApplicationManagerAul : public IApplicationManager {
+public:
+       virtual bool is_application_running(int pid) override;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APPLICATION_MANAGER_AUL_H__ */
diff --git a/inc/client_manager.h b/inc/client_manager.h
new file mode 100644 (file)
index 0000000..d2c51e2
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2018-2019 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 __CLIENT_MANAGER_H__
+#define __CLIENT_MANAGER_H__
+
+#include "application_manager.h"
+
+#include <string>
+#include <glib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+       int pid;
+       std::string appid;
+} ma_client_s;
+
+class CClientManager {
+public:
+       CClientManager() {}
+       virtual ~CClientManager() {}
+
+       int set_application_manager(IApplicationManager* manager);
+       int create_client(int pid, std::string appid);
+       int destroy_client_by_pid(int pid);
+       int destroy_client_by_appid(std::string appid);
+
+       int get_client_num();
+       int find_client_pid_by_index(unsigned int index);
+
+       int find_client_pid_by_appid(std::string appid);
+       std::string find_client_appid_by_pid(int pid);
+
+       bool check_client_validity_by_appid(std::string appid);
+private:
+       ma_client_s* find_client_by_appid(std::string appid);
+       ma_client_s* find_client_by_pid(int pid);
+       ma_client_s* get_client_by_index(unsigned int index);
+       int destroy_client(ma_client_s* client);
+
+private:
+       IApplicationManager* mApplicationManager{nullptr};
+       GSList* g_client_list{nullptr};
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CLIENT_MANAGER_H__ */
index 7242f12..8bd33de 100644 (file)
@@ -46,7 +46,7 @@ public:
        int service_state_change(int pid, int state);
        int voice_key_status_change(int pid, int status);
        int masc_ui_dbus_send_hello(void);
-       int masc_ui_dbus_send_asr_result(int pid, int event, char* asr_result);
+       int masc_ui_dbus_send_asr_result(int pid, int event, const char* asr_result);
        int masc_ui_dbus_send_result(int pid, const char* display_text, const char* utterance_text, const char* result_json);
        int masc_ui_dbus_change_assistant(const char* app_id);
        int masc_ui_dbus_send_error_message(int reason, const char* err_msg);
@@ -56,9 +56,11 @@ public:
        DBusConnection* get_connection_listener() { return g_conn_listener; }
        CServiceIpcDbusDispatcher* get_dispatcher() { return &mDispatcher; }
 
-       void set_service_main(CServiceMain* main) {
-               mServiceMain = main;
-               mDispatcher.set_service_main(main);
+       void set_client_manager(CClientManager* manager) {
+               mClientManager = manager;
+       }
+       void set_service_ipc_observer(IServiceIpcObserver* observer) {
+               mDispatcher.set_ipc_observer(observer);
        }
 private:
        int __dbus_check();
@@ -76,7 +78,7 @@ private:
 
        int g_streaming_data_serial{0};
 
-       CServiceMain* mServiceMain{nullptr};
+       CClientManager* mClientManager{nullptr};
 };
 
 #ifdef __cplusplus
index 45d06fe..70a5f5d 100644 (file)
@@ -17,6 +17,8 @@
 #ifndef __SERVICE_IPC_DBUS_DISPATCHER_H__
 #define __SERVICE_IPC_DBUS_DISPATCHER_H__
 
+#include <string>
+
 #include <dbus/dbus.h>
 
 #ifdef __cplusplus
@@ -25,6 +27,33 @@ extern "C" {
 
 class CServiceMain;
 
+class IServiceIpcObserver {
+public:
+       virtual int on_initialize(int pid) = 0;
+       virtual int on_deinitialize(int pid) = 0;
+       virtual int on_get_audio_format(int pid, int& rate, int& channel, int& audio_type) = 0;
+       virtual int on_get_audio_source_type(int pid, std::string& type) = 0;
+       virtual int on_send_asr_result(int pid, int event, std::string asr_result) = 0;
+       virtual int on_send_result(int pid,
+               std::string display_text, std::string utterance_text, std::string result_json) = 0;
+       virtual int on_send_recognition_result(int pid, int result) = 0;
+       virtual int on_start_streaming_audio_data(int pid, int type) = 0;
+       virtual int on_stop_streaming_audio_data(int pid, int type) = 0;
+       virtual int on_update_voice_feedback_state(int pid, int state) = 0;
+       virtual int on_send_assistant_specific_command(int pid, std::string command) = 0;
+       virtual int on_set_background_volume(int pid, double ratio) = 0;
+       virtual int on_set_preprocessing_allow_mode(int pid, int mode, std::string app_id) = 0;
+       virtual int on_send_preprocessing_result(int pid, int result) = 0;
+       virtual int on_set_wake_word_audio_require_flag(int pid, int require) = 0;
+       virtual int on_set_assistant_language(int pid, std::string language) = 0;
+       virtual int on_add_wake_word(int pid, std::string wake_word, std::string language) = 0;
+       virtual int on_remove_wake_word(int pid, std::string wake_word, std::string language) = 0;
+
+       virtual int on_ui_initialize(int pid) = 0;
+       virtual int on_ui_deinitialize(int pid) = 0;
+       virtual int on_ui_change_assistant(std::string app_id) = 0;
+};
+
 class CServiceIpcDbusDispatcher {
 public:
        CServiceIpcDbusDispatcher() {}
@@ -53,9 +82,9 @@ public:
        int on_ui_deinitialize(DBusConnection* conn, DBusMessage* msg);
        int on_ui_change_assistant(DBusConnection* conn, DBusMessage* msg);
 
-       void set_service_main(CServiceMain* main) { mServiceMain = main; }
+       void set_ipc_observer(IServiceIpcObserver* observer) { mIpcObserver = observer; }
 private:
-       CServiceMain* mServiceMain{nullptr};
+       IServiceIpcObserver *mIpcObserver{nullptr};
 };
 
 #ifdef __cplusplus
index 61e4853..5101be5 100644 (file)
 
 #include "service_common.h"
 #include "service_config.h"
+#include "client_manager.h"
 #include "service_plugin.h"
 #include "service_ipc_dbus.h"
+#include "application_manager_aul.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -66,27 +68,19 @@ typedef enum {
 
 #define MAX_MACLIENT_INFO_NUM 16
 
-typedef struct {
-       int pid;
-       char appid[MAX_APPID_LEN];
-} ma_client_s;
-
-class CServiceMain {
+class CServiceMain : public IServiceIpcObserver {
 public:
        CServiceMain() {}
        virtual ~CServiceMain() {}
 
-       int mas_client_initialize(int pid);
-       int mas_client_deinitialize(int pid);
        int mas_client_get_audio_format(int pid, int* rate, int* channel, int* audio_type);
        int mas_client_get_audio_source_type(int pid, char** type);
        int mas_client_send_preprocessing_information(int pid);
        int mas_client_send_voice_key_status_change(int pid, ma_voice_key_status_e status);
-       int mas_client_activate(int pid);
-       int mas_client_deactivate(int pid);
        int mas_client_request_speech_data(int pid);
-       int mas_client_send_asr_result(int pid, int event, char* asr_result);
-       int mas_client_send_result(int pid, char* display_text, char* utterance_text, char* result_json);
+       int mas_client_send_asr_result(int pid, int event, const char* asr_result);
+       int mas_client_send_result(int pid, const char* display_text,
+               const char* utterance_text, const char* result_json);
        int mas_client_send_recognition_result(int pid, int result);
        int mas_client_start_streaming_audio_data(int pid, int type);
        int mas_client_stop_streaming_audio_data(int pid, int type);
@@ -106,7 +100,7 @@ public:
        int mas_get_current_preprocessing_client_pid();
        int mas_get_client_pid_by_wakeup_word(const char *wakeup_word);
        int mas_get_client_pid_by_appid(const char *appid);
-       const char* mas_get_client_appid_by_pid(int pid);
+       std::string mas_get_client_appid_by_pid(int pid);
        bool mas_get_client_custom_ui_option_by_appid(const char *appid);
        const char* mas_get_client_appid_by_wakeup_word(const char *wakeup_word);
        int mas_set_current_client_by_wakeup_word(const char *wakeup_word);
@@ -120,6 +114,30 @@ public:
        int mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT event);
        int mas_update_voice_key_support_mode();
 
+       virtual int on_initialize(int pid) override;
+       virtual int on_deinitialize(int pid) override;
+       virtual int on_get_audio_format(int pid, int& rate, int& channel, int& audio_type) override;
+       virtual int on_get_audio_source_type(int pid, std::string& type) override;
+       virtual int on_send_asr_result(int pid, int event, std::string asr_result) override;
+       virtual int on_send_result(int pid, std::string display_text,
+               std::string utterance_text, std::string result_json) override;
+       virtual int on_send_recognition_result(int pid, int result) override;
+       virtual int on_start_streaming_audio_data(int pid, int type) override;
+       virtual int on_stop_streaming_audio_data(int pid, int type) override;
+       virtual int on_update_voice_feedback_state(int pid, int state) override;
+       virtual int on_send_assistant_specific_command(int pid, std::string command) override;
+       virtual int on_set_background_volume(int pid, double ratio) override;
+       virtual int on_set_preprocessing_allow_mode(int pid, int mode, std::string app_id) override;
+       virtual int on_send_preprocessing_result(int pid, int result) override;
+       virtual int on_set_wake_word_audio_require_flag(int pid, int require) override;
+       virtual int on_set_assistant_language(int pid, std::string language) override;
+       virtual int on_add_wake_word(int pid, std::string wake_word, std::string language) override;
+       virtual int on_remove_wake_word(int pid, std::string wake_word, std::string language) override;
+
+       virtual int on_ui_initialize(int pid) override;
+       virtual int on_ui_deinitialize(int pid) override;
+       virtual int on_ui_change_assistant(std::string app_id) override;
+
        bool app_create(void *data);
        void app_terminate(void *data);
 
@@ -133,11 +151,6 @@ public:
 
        CServicePlugin* get_service_plugin() { return &mServicePlugin; }
 private:
-       int ma_client_create(ma_client_s *info);
-       int ma_client_destroy(ma_client_s *client);
-       ma_client_s* ma_client_find_by_appid(const char *appid);
-       ma_client_s* ma_client_find_by_pid(int pid);
-
        bool check_preprocessing_assistant_exists();
        ma_preprocessing_allow_mode_e get_preprocessing_allow_mode(const char* appid);
        bool is_current_preprocessing_assistant(const char* appid);
@@ -170,14 +183,16 @@ private:
        PREPROCESSING_STATE g_current_preprocessing_state{PREPROCESSING_STATE_NONE};
        ma_service_state_e g_current_service_state{MA_SERVICE_STATE_INACTIVE};
 
-       /* client list */
-       GSList* g_client_list{nullptr};
-
        CServiceConfig mServiceConfig;
        CServicePlugin mServicePlugin;
        CServiceIpcDbus mServiceIpc;
 
        ma_voice_key_status_e mLastVoiceKeyStatus{MA_VOICE_KEY_STATUS_RELEASED_AFTER_PUSH};
+
+       CClientManager mClientManager;
+
+       CApplicationManagerAul mApplicationManager;
+
 };
 
 #ifdef __cplusplus
diff --git a/src/application_manager_aul.cpp b/src/application_manager_aul.cpp
new file mode 100644 (file)
index 0000000..2553c93
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2018-2019 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 "application_manager_aul.h"
+#include "service_common.h"
+
+#include <aul.h>
+
+bool CApplicationManagerAul::is_application_running(int pid)
+{
+       int status = aul_app_get_status_bypid(pid);
+       if (0 > status) {
+               MAS_LOGE("The process %d does not exist : %d", pid, status);
+               return false;
+       }
+       return true;
+}
\ No newline at end of file
diff --git a/src/client_manager.cpp b/src/client_manager.cpp
new file mode 100644 (file)
index 0000000..8175bb0
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2018-2019 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 "client_manager.h"
+#include "service_common.h"
+
+int CClientManager::set_application_manager(IApplicationManager* manager)
+{
+       mApplicationManager = manager;
+       return 0;
+}
+
+int CClientManager::create_client(int pid, std::string appid)
+{
+       ma_client_s* data = NULL;
+
+       try {
+               data = new ma_client_s;
+       } catch(const std::bad_alloc& e) {
+               MAS_LOGE("[ERROR] Fail to allocate memory : %s", e.what());
+               return -1;// MA_ERROR_OUT_OF_MEMORY;
+       }
+
+       if (data) {
+               data->pid = pid;
+               data->appid = appid;
+               g_client_list = g_slist_append(g_client_list, data);
+       } else {
+               MAS_LOGE("[ERROR] data is NULL");
+               return -1;// MA_ERROR_OUT_OF_MEMORY;
+       }
+
+       return 0;
+}
+
+int CClientManager::destroy_client(ma_client_s* client)
+{
+       if (nullptr == client) {
+               MAS_LOGE("Input parameter is NULL");
+               return -1;// MA_ERROR_OPERATION_FAILED;
+       }
+
+       g_client_list =  g_slist_remove(g_client_list, client);
+
+       delete client;
+
+       return 0;
+}
+
+int CClientManager::destroy_client_by_pid(int pid)
+{
+       ma_client_s* client = find_client_by_pid(pid);
+       return destroy_client(client);
+}
+
+int CClientManager::destroy_client_by_appid(std::string appid)
+{
+       ma_client_s* client = find_client_by_appid(appid);
+       return destroy_client(client);
+}
+
+ma_client_s* CClientManager::find_client_by_appid(std::string appid)
+{
+       ma_client_s *data = NULL;
+
+       int count = g_slist_length(g_client_list);
+       int i;
+
+       for (i = 0; i < count; i++) {
+               data = static_cast<ma_client_s*>(g_slist_nth_data(g_client_list, i));
+
+               if (NULL != data) {
+                       if (0 == appid.compare(data->appid)) {
+                               return data;
+                       }
+               }
+       }
+
+       MAS_LOGE("[ERROR] client Not found");
+
+       return NULL;
+}
+
+ma_client_s* CClientManager::find_client_by_pid(int pid)
+{
+       ma_client_s *data = NULL;
+
+       int count = g_slist_length(g_client_list);
+       int i;
+
+       for (i = 0; i < count; i++) {
+               data = static_cast<ma_client_s*>(g_slist_nth_data(g_client_list, i));
+
+               if (NULL != data) {
+                       if (data->pid == pid) {
+                               return data;
+                       }
+               }
+       }
+
+       MAS_LOGE("[ERROR] client Not found");
+
+       return NULL;
+}
+
+int CClientManager::get_client_num()
+{
+       return g_slist_length(g_client_list);
+}
+
+ma_client_s* CClientManager::get_client_by_index(unsigned int index)
+{
+       return static_cast<ma_client_s*>(g_slist_nth_data(g_client_list, index));
+}
+
+int CClientManager::find_client_pid_by_index(unsigned int index)
+{
+       int pid = -1;
+       ma_client_s* client = get_client_by_index(index);
+       if (client) {
+               pid = client->pid;
+       }
+       return pid;
+}
+
+int CClientManager::find_client_pid_by_appid(std::string appid)
+{
+       int pid = -1;
+
+       if (nullptr == mApplicationManager) {
+               MAS_LOGE("ApplicationManager is NULL, can't check if app is running or not");
+               return pid;
+       }
+
+       ma_client_s* client = find_client_by_appid(appid);
+       if (client) {
+               bool running = mApplicationManager->is_application_running(pid);
+               if (false == running) {
+                       MAS_LOGE("The PID for %s was %d, but it seems to be terminated",
+                               appid.c_str(), client->pid);
+               } else {
+                       pid = client->pid;
+               }
+       }
+       return pid;
+}
+
+std::string CClientManager::find_client_appid_by_pid(int pid)
+{
+       std::string appid;
+
+       if (nullptr == mApplicationManager) {
+               MAS_LOGE("ApplicationManager is NULL, can't check if app is running or not");
+               return appid;
+       }
+
+       ma_client_s* client = find_client_by_pid(pid);
+       if (client) {
+               bool running = mApplicationManager->is_application_running(pid);
+               if (false == running) {
+                       MAS_LOGE("The appid for %d was %s, but it seems to be terminated",
+                               pid, client->appid.c_str());
+               } else {
+                       appid = client->appid;
+               }
+       }
+       return appid;
+}
+
+bool CClientManager::check_client_validity_by_appid(std::string appid)
+{
+       int pid = find_client_pid_by_appid(appid);
+       if (0 < pid) return true;
+       return false;
+}
index 1a7558b..6888d0b 100644 (file)
@@ -208,8 +208,8 @@ static void masc_message_port_error(int error)
 
 int CServiceIpcDbus::send_streaming_audio_data(int pid, int event, void* data, unsigned int data_size)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mClientManager) {
+               MAS_LOGE("mClientManager variable is NULL");
                return -1;
        }
 
@@ -245,7 +245,7 @@ int CServiceIpcDbus::send_streaming_audio_data(int pid, int event, void* data, u
                if (b) {
                        bundle_add_byte(b, "content", pending_buffer, pending_buffer_size);
                        int ret = message_port_send_message(
-                               mServiceMain->mas_get_client_appid_by_pid(pid), message_port, b);
+                               mClientManager->find_client_appid_by_pid(pid).c_str(), message_port, b);
                        if (MESSAGE_PORT_ERROR_NONE != ret)
                                masc_message_port_error(ret);
 
@@ -266,7 +266,7 @@ int CServiceIpcDbus::send_streaming_audio_data(int pid, int event, void* data, u
                if (b) {
                        bundle_add_byte(b, "content", buffer, total_size);
                        int ret = message_port_send_message(
-                               mServiceMain->mas_get_client_appid_by_pid(pid), message_port, b);
+                               mClientManager->find_client_appid_by_pid(pid).c_str(), message_port, b);
                        if (MESSAGE_PORT_ERROR_NONE != ret)
                                masc_message_port_error(ret);
 
@@ -397,8 +397,8 @@ int CServiceIpcDbus::send_preprocessing_information(int pid, const char* app_id)
 
 int CServiceIpcDbus::send_streaming_section_changed(int pid, int section)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mClientManager) {
+               MAS_LOGE("mClientManager variable is NULL");
                return -1;
        }
 
@@ -420,7 +420,8 @@ int CServiceIpcDbus::send_streaming_section_changed(int pid, int section)
        total_size += sizeof(streaming_section_header);
 
        bundle_add_byte(b, "content", buffer, total_size);
-       int ret = message_port_send_message(mServiceMain->mas_get_client_appid_by_pid(pid), message_port, b);
+       int ret = message_port_send_message(
+               mClientManager->find_client_appid_by_pid(pid).c_str(), message_port, b);
        if (MESSAGE_PORT_ERROR_NONE != ret)
                masc_message_port_error(ret);
 
@@ -690,7 +691,7 @@ int CServiceIpcDbus::masc_ui_dbus_send_hello(void)
        return result;
 }
 
-int CServiceIpcDbus::masc_ui_dbus_send_asr_result(int pid, int event, char* asr_result)
+int CServiceIpcDbus::masc_ui_dbus_send_asr_result(int pid, int event, const char* asr_result)
 {
        if (0 != __dbus_check()) {
                return -1; //MAS_ERROR_OPERATION_FAILED;
index 76d40b0..df43612 100644 (file)
@@ -46,8 +46,8 @@ int CServiceIpcDbusDispatcher::on_hello(DBusConnection* conn, DBusMessage* msg)
 
 int CServiceIpcDbusDispatcher::on_initialize(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -69,7 +69,7 @@ int CServiceIpcDbusDispatcher::on_initialize(DBusConnection* conn, DBusMessage*
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGD("[IN] mas initialize : pid(%d)", pid);
-               ret =  mServiceMain->mas_client_initialize(pid);
+               ret = mIpcObserver->on_initialize(pid);
        }
 
        DBusMessage* reply;
@@ -102,8 +102,8 @@ int CServiceIpcDbusDispatcher::on_initialize(DBusConnection* conn, DBusMessage*
 
 int CServiceIpcDbusDispatcher::on_deinitialize(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -125,7 +125,7 @@ int CServiceIpcDbusDispatcher::on_deinitialize(DBusConnection* conn, DBusMessage
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGD("[IN] mas deinitialize : pid(%d)", pid);
-               ret =  mServiceMain->mas_client_deinitialize(pid);
+               ret = mIpcObserver->on_deinitialize(pid);
        }
 
        DBusMessage* reply;
@@ -158,8 +158,8 @@ int CServiceIpcDbusDispatcher::on_deinitialize(DBusConnection* conn, DBusMessage
 
 int CServiceIpcDbusDispatcher::on_get_audio_format(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -182,7 +182,7 @@ int CServiceIpcDbusDispatcher::on_get_audio_format(DBusConnection* conn, DBusMes
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGD("[IN] mas get audio format");
-               ret = mServiceMain->mas_client_get_audio_format(pid, &rate, &channel, &audio_type);
+               ret = mIpcObserver->on_get_audio_format(pid, rate, channel, audio_type);
        }
 
        DBusMessage* reply;
@@ -217,8 +217,8 @@ int CServiceIpcDbusDispatcher::on_get_audio_format(DBusConnection* conn, DBusMes
 
 int CServiceIpcDbusDispatcher::on_get_audio_source_type(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -226,7 +226,7 @@ int CServiceIpcDbusDispatcher::on_get_audio_source_type(DBusConnection* conn, DB
        dbus_error_init(&err);
 
        int pid = -1;
-       char *type = NULL;
+       std::string type;
        int ret;
 
        dbus_message_get_args(msg, &err,
@@ -241,7 +241,7 @@ int CServiceIpcDbusDispatcher::on_get_audio_source_type(DBusConnection* conn, DB
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGD("[IN] mas get audio source type");
-               ret = mServiceMain->mas_client_get_audio_source_type(pid, &type);
+               ret = mIpcObserver->on_get_audio_source_type(pid, type);
        }
 
        DBusMessage* reply;
@@ -249,10 +249,10 @@ int CServiceIpcDbusDispatcher::on_get_audio_source_type(DBusConnection* conn, DB
 
        char* temp_type = NULL;
 
-       if (type)
-               temp_type = strdup(type);
-       else
+       if (-1 == ret)
                temp_type = strdup("#NULL");
+       else
+               temp_type = strdup(type.c_str());
 
        if (NULL != reply) {
                /* Append result and voice */
@@ -284,8 +284,8 @@ int CServiceIpcDbusDispatcher::on_get_audio_source_type(DBusConnection* conn, DB
 
 int CServiceIpcDbusDispatcher::on_send_asr_result(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -310,7 +310,8 @@ int CServiceIpcDbusDispatcher::on_send_asr_result(DBusConnection* conn, DBusMess
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGI("[IN] mas send asr result : pid(%d), event(%d), asr_result(%s)", pid, event, asr_result);
-               ret = mServiceMain->mas_client_send_asr_result(pid, event, asr_result);
+               ret = mIpcObserver->on_send_asr_result(pid, event,
+                       asr_result ? std::string{asr_result} : std::string{});
        }
 
        DBusMessage* reply;
@@ -345,8 +346,8 @@ int CServiceIpcDbusDispatcher::on_send_asr_result(DBusConnection* conn, DBusMess
 
 int CServiceIpcDbusDispatcher::on_send_result(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -374,7 +375,10 @@ int CServiceIpcDbusDispatcher::on_send_result(DBusConnection* conn, DBusMessage*
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGI("[IN] mas send result : pid(%d), display_text(%s), utterance_text(%s), result_json(%s)", pid, display_text, utterance_text, result_json);
-               ret =  mServiceMain->mas_client_send_result(pid, display_text, utterance_text, result_json);
+               ret = mIpcObserver->on_send_result(pid,
+                       display_text ? std::string{display_text} : std::string{},
+                       utterance_text ? std::string{utterance_text} : std::string{},
+                       result_json ? std::string{result_json} : std::string{});
        }
 
        DBusMessage* reply;
@@ -409,8 +413,8 @@ int CServiceIpcDbusDispatcher::on_send_result(DBusConnection* conn, DBusMessage*
 
 int CServiceIpcDbusDispatcher::on_send_recognition_result(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -434,7 +438,7 @@ int CServiceIpcDbusDispatcher::on_send_recognition_result(DBusConnection* conn,
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGI("[IN] mas send recognition result : pid(%d), result(%d)", pid, result);
-               ret =  mServiceMain->mas_client_send_recognition_result(pid, result);
+               ret = mIpcObserver->on_send_recognition_result(pid, result);
        }
 
        MAS_LOGD("<<<<<");
@@ -445,8 +449,8 @@ int CServiceIpcDbusDispatcher::on_send_recognition_result(DBusConnection* conn,
 
 int CServiceIpcDbusDispatcher::on_start_streaming_audio_data(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -470,7 +474,7 @@ int CServiceIpcDbusDispatcher::on_start_streaming_audio_data(DBusConnection* con
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGI("[IN] mas send start streaming : pid(%d), type(%d)", pid, type);
-               ret =  mServiceMain->mas_client_start_streaming_audio_data(pid, type);
+               ret = mIpcObserver->on_start_streaming_audio_data(pid, type);
        }
 
        MAS_LOGD("<<<<<");
@@ -481,8 +485,8 @@ int CServiceIpcDbusDispatcher::on_start_streaming_audio_data(DBusConnection* con
 
 int CServiceIpcDbusDispatcher::on_stop_streaming_audio_data(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -506,7 +510,7 @@ int CServiceIpcDbusDispatcher::on_stop_streaming_audio_data(DBusConnection* conn
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGI("[IN] mas stop streaming : pid(%d), type(%d)", pid, type);
-               ret =  mServiceMain->mas_client_stop_streaming_audio_data(pid, type);
+               ret = mIpcObserver->on_stop_streaming_audio_data(pid, type);
        }
 
        MAS_LOGD("<<<<<");
@@ -517,8 +521,8 @@ int CServiceIpcDbusDispatcher::on_stop_streaming_audio_data(DBusConnection* conn
 
 int CServiceIpcDbusDispatcher::on_update_voice_feedback_state(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -542,7 +546,7 @@ int CServiceIpcDbusDispatcher::on_update_voice_feedback_state(DBusConnection* co
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGI("[IN] mas update voice feedback : pid(%d), state(%d)", pid, state);
-               ret =  mServiceMain->mas_client_update_voice_feedback_state(pid, state);
+               ret = mIpcObserver->on_update_voice_feedback_state(pid, state);
        }
 
        MAS_LOGD("<<<<<");
@@ -553,8 +557,8 @@ int CServiceIpcDbusDispatcher::on_update_voice_feedback_state(DBusConnection* co
 
 int CServiceIpcDbusDispatcher::on_send_assistant_specific_command(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -578,7 +582,8 @@ int CServiceIpcDbusDispatcher::on_send_assistant_specific_command(DBusConnection
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGI("[IN] mas send assistant specific command : pid(%d), command(%s)", pid, command);
-               ret =  mServiceMain->mas_client_set_assistant_specific_command(pid, command);
+               ret = mIpcObserver->on_send_assistant_specific_command(pid,
+                       command ? std::string{command} : std::string{});
        }
 
        MAS_LOGD("<<<<<");
@@ -589,8 +594,8 @@ int CServiceIpcDbusDispatcher::on_send_assistant_specific_command(DBusConnection
 
 int CServiceIpcDbusDispatcher::on_set_background_volume(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -614,7 +619,7 @@ int CServiceIpcDbusDispatcher::on_set_background_volume(DBusConnection* conn, DB
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGI("[IN] mas set background volume : pid(%d), ratio(%f)", pid, ratio);
-               ret =  mServiceMain->mas_client_set_background_volume(pid, ratio);
+               ret = mIpcObserver->on_set_background_volume(pid, ratio);
        }
 
        MAS_LOGD("<<<<<");
@@ -625,8 +630,8 @@ int CServiceIpcDbusDispatcher::on_set_background_volume(DBusConnection* conn, DB
 
 int CServiceIpcDbusDispatcher::on_set_preprocessing_allow_mode(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -651,15 +656,10 @@ int CServiceIpcDbusDispatcher::on_set_preprocessing_allow_mode(DBusConnection* c
                dbus_error_free(&err);
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
-               char* temp_app_id = NULL;
-               if (NULL != app_id && strcmp("#NULL", app_id)) {
-                       temp_app_id = strdup(app_id);
-               }
-               MAS_LOGI("[IN] mas set preprocessing allow mode : pid(%d), mode(%d), app_id(%s)", pid, mode, temp_app_id);
-               ret =  mServiceMain->mas_client_set_preprocessing_allow_mode(pid,
-                       static_cast<ma_preprocessing_allow_mode_e>(mode), temp_app_id);
-               if (NULL != temp_app_id)
-                       free(temp_app_id);
+               MAS_LOGI("[IN] mas set preprocessing allow mode : pid(%d), mode(%d), app_id(%s)", pid, mode, app_id);
+               ret = mIpcObserver->on_set_preprocessing_allow_mode(pid,
+                       static_cast<ma_preprocessing_allow_mode_e>(mode),
+                       app_id ? std::string{app_id} : std::string{});
        }
 
        MAS_LOGD("<<<<<");
@@ -670,8 +670,8 @@ int CServiceIpcDbusDispatcher::on_set_preprocessing_allow_mode(DBusConnection* c
 
 int CServiceIpcDbusDispatcher::on_send_preprocessing_result(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -695,7 +695,7 @@ int CServiceIpcDbusDispatcher::on_send_preprocessing_result(DBusConnection* conn
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGI("[IN] mas send preprocessing result : pid(%d), result(%d)", pid, result);
-               ret =  mServiceMain->mas_client_send_preprocessing_result(pid, (bool)result);
+               ret = mIpcObserver->on_send_preprocessing_result(pid, result);
        }
 
        MAS_LOGD("<<<<<");
@@ -706,8 +706,8 @@ int CServiceIpcDbusDispatcher::on_send_preprocessing_result(DBusConnection* conn
 
 int CServiceIpcDbusDispatcher::on_set_wake_word_audio_require_flag(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -731,7 +731,7 @@ int CServiceIpcDbusDispatcher::on_set_wake_word_audio_require_flag(DBusConnectio
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGI("[IN] mas set wake word audio require flag : pid(%d), require(%d)", pid, require);
-               ret =  mServiceMain->mas_client_set_wake_word_audio_require_flag(pid, (bool)require);
+               ret = mIpcObserver->on_set_wake_word_audio_require_flag(pid, require);
        }
 
        MAS_LOGD("<<<<<");
@@ -742,8 +742,8 @@ int CServiceIpcDbusDispatcher::on_set_wake_word_audio_require_flag(DBusConnectio
 
 int CServiceIpcDbusDispatcher::on_set_assistant_language(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -767,7 +767,8 @@ int CServiceIpcDbusDispatcher::on_set_assistant_language(DBusConnection* conn, D
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGI("[IN] mas set assistant language : pid(%d), language(%s)", pid, language);
-               ret =  mServiceMain->mas_client_set_assistant_language(pid, language);
+               ret = mIpcObserver->on_set_assistant_language(pid,
+                       language ? std::string{language} : std::string{});
        }
 
        MAS_LOGD("<<<<<");
@@ -778,8 +779,8 @@ int CServiceIpcDbusDispatcher::on_set_assistant_language(DBusConnection* conn, D
 
 int CServiceIpcDbusDispatcher::on_add_wake_word(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -805,7 +806,9 @@ int CServiceIpcDbusDispatcher::on_add_wake_word(DBusConnection* conn, DBusMessag
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGI("[IN] mas add wake word : pid(%d), wake_word(%s) language(%s)", pid, wake_word, language);
-               ret =  mServiceMain->mas_client_add_wake_word(pid, wake_word, language);
+               ret = mIpcObserver->on_add_wake_word(pid,
+                       wake_word ? std::string{wake_word} : std::string{},
+                       language ? std::string{language} : std::string{});
        }
 
        MAS_LOGD("<<<<<");
@@ -816,8 +819,8 @@ int CServiceIpcDbusDispatcher::on_add_wake_word(DBusConnection* conn, DBusMessag
 
 int CServiceIpcDbusDispatcher::on_remove_wake_word(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
        }
 
        DBusError err;
@@ -842,7 +845,9 @@ int CServiceIpcDbusDispatcher::on_remove_wake_word(DBusConnection* conn, DBusMes
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGI("[IN] mas remove wake word : pid(%d), wake_word(%s) language(%s)", pid, wake_word, language);
-               ret =  mServiceMain->mas_client_remove_wake_word(pid, wake_word, language);
+               ret = mIpcObserver->on_remove_wake_word(pid,
+                       wake_word ? std::string{wake_word} : std::string{},
+                       language ? std::string{language} : std::string{});
        }
 
        MAS_LOGD("<<<<<");
@@ -853,8 +858,8 @@ int CServiceIpcDbusDispatcher::on_remove_wake_word(DBusConnection* conn, DBusMes
 
 int CServiceIpcDbusDispatcher::on_ui_initialize(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -876,7 +881,7 @@ int CServiceIpcDbusDispatcher::on_ui_initialize(DBusConnection* conn, DBusMessag
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGD("[IN] mas ui initialize : pid(%d)", pid);
-               ret =  mServiceMain->mas_ui_client_initialize(pid);
+               ret = mIpcObserver->on_ui_initialize(pid);
        }
 
        DBusMessage* reply;
@@ -909,8 +914,8 @@ int CServiceIpcDbusDispatcher::on_ui_initialize(DBusConnection* conn, DBusMessag
 
 int CServiceIpcDbusDispatcher::on_ui_deinitialize(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -932,7 +937,7 @@ int CServiceIpcDbusDispatcher::on_ui_deinitialize(DBusConnection* conn, DBusMess
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGD("[IN] mas ui deinitialize : pid(%d)", pid);
-               ret =  mServiceMain->mas_ui_client_deinitialize(pid);
+               ret = mIpcObserver->on_ui_deinitialize(pid);
        }
 
        DBusMessage* reply;
@@ -965,8 +970,8 @@ int CServiceIpcDbusDispatcher::on_ui_deinitialize(DBusConnection* conn, DBusMess
 
 int CServiceIpcDbusDispatcher::on_ui_change_assistant(DBusConnection* conn, DBusMessage* msg)
 {
-       if (nullptr == mServiceMain) {
-               MAS_LOGE("mServiceMain variable is NULL");
+       if (nullptr == mIpcObserver) {
+               MAS_LOGE("mIpcObserver variable is NULL");
                return -1;
        }
 
@@ -988,7 +993,8 @@ int CServiceIpcDbusDispatcher::on_ui_change_assistant(DBusConnection* conn, DBus
                ret = -1; //MAS_ERROR_OPERATION_FAILED;
        } else {
                MAS_LOGD("[IN] mas ui change assisant : app_id(%s)", app_id);
-               ret =  mServiceMain->mas_ui_client_change_assistant(app_id);
+               ret = mIpcObserver->on_ui_change_assistant(
+                       app_id ? std::string{app_id} : std::string{});
        }
 
        DBusMessage* reply;
index 54c2368..6af73f6 100644 (file)
 
 static CServiceMain* g_service_main = nullptr;
 
-int CServiceMain::ma_client_create(ma_client_s *info)
-{
-       if (NULL == info) {
-               MAS_LOGE("Input parameter is NULL"); //LCOV_EXCL_LINE
-               return -1;
-       }
-
-       ma_client_s* data = NULL;
-
-       data = (ma_client_s*)calloc(1, sizeof(ma_client_s));
-       if (NULL == data) {
-               MAS_LOGE("[ERROR] Fail to allocate memory"); //LCOV_EXCL_LINE
-               return -1;// MA_ERROR_OUT_OF_MEMORY;
-       }
-
-       *data = *info;
-       g_client_list = g_slist_append(g_client_list, data);
-
-       return 0;
-}
-
-int CServiceMain::ma_client_destroy(ma_client_s *client)
-{
-       if (NULL == client) {
-               MAS_LOGE("Input parameter is NULL"); //LCOV_EXCL_LINE
-               return -1;// MA_ERROR_OPERATION_FAILED;
-       }
-
-       g_client_list =  g_slist_remove(g_client_list, client);
-
-       free(client);
-       client = NULL;
-
-       return 0;
-}
-
-ma_client_s* CServiceMain::ma_client_find_by_appid(const char *appid)
-{
-       if (NULL == appid) {
-               MAS_LOGE("Input parameter is NULL"); //LCOV_EXCL_LINE
-               return NULL;
-       }
-
-       ma_client_s *data = NULL;
-
-       int count = g_slist_length(g_client_list);
-       int i;
-
-       for (i = 0; i < count; i++) {
-               data = static_cast<ma_client_s*>(g_slist_nth_data(g_client_list, i));
-
-               if (NULL != data) {
-                       if (0 == strncmp(data->appid, appid, MAX_APPID_LEN)) {
-                               return data;
-                       }
-               }
-       }
-
-       MAS_LOGE("[ERROR] client Not found");
-
-       return NULL;
-}
-
-ma_client_s* CServiceMain::ma_client_find_by_pid(int pid)
-{
-       ma_client_s *data = NULL;
-
-       int count = g_slist_length(g_client_list);
-       int i;
-
-       for (i = 0; i < count; i++) {
-               data = static_cast<ma_client_s*>(g_slist_nth_data(g_client_list, i));
-
-               if (NULL != data) {
-                       if (data->pid == pid) {
-                               return data;
-                       }
-               }
-       }
-
-       MAS_LOGE("[ERROR] client Not found");
-
-       return NULL;
-}
-
 bool CServiceMain::check_preprocessing_assistant_exists()
 {
        bool ret = false;
@@ -130,12 +45,10 @@ bool CServiceMain::check_preprocessing_assistant_exists()
        char* vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
        if (vconf_str) {
                for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
-                       if (g_maclient_info[loop].used) {
-                               if (strncmp(vconf_str, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
-                                       ma_client_s* client = ma_client_find_by_appid(vconf_str);
-                                       if (client && client->pid > 0) {
-                                               ret = true;
-                                       }
+                       if (g_maclient_info[loop].used &&
+                               strncmp(vconf_str, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
+                               if (mClientManager.check_client_validity_by_appid(std::string{vconf_str})) {
+                                       ret = true;
                                }
                        }
                }
@@ -166,80 +79,6 @@ bool CServiceMain::is_current_preprocessing_assistant(const char* appid)
        return ret;
 }
 
-int CServiceMain::mas_client_initialize(int pid)
-{
-       MAS_LOGD("[Enter] pid(%d)", pid);
-
-       char appid[MAX_APPID_LEN] = {'\0', };
-       if (AUL_R_OK == aul_app_get_appid_bypid(pid, appid, sizeof(appid))) {
-               appid[MAX_APPID_LEN - 1] = '\0';
-
-               MAS_LOGD("appid for pid %d is : %s", pid, (appid ? appid : "Unknown"));
-
-               /* Remove existing client that has same appid, if there's any */
-               ma_client_s *old_client = NULL;
-               old_client = ma_client_find_by_appid(appid);
-               if (old_client) {
-                       ma_client_destroy(old_client);
-                       old_client = NULL;
-               }
-
-               /* And remove a client that has same pid also */
-               old_client = ma_client_find_by_pid(pid);
-               if (old_client) {
-                       ma_client_destroy(old_client);
-                       old_client = NULL;
-               }
-
-               ma_client_s new_client;
-               new_client.pid = pid;
-               strncpy(new_client.appid, appid, MAX_APPID_LEN);
-               new_client.appid[MAX_APPID_LEN - 1] = '\0';
-               ma_client_create(&new_client);
-
-               const char *current_maclient_appid = NULL;
-               if (g_current_maclient_info >= 0 && g_current_maclient_info < MAX_MACLIENT_INFO_NUM) {
-                       current_maclient_appid = g_maclient_info[g_current_maclient_info].appid;
-               }
-
-               mas_client_send_preprocessing_information(pid);
-               if (MA_VOICE_KEY_STATUS_PRESSED == mLastVoiceKeyStatus) {
-                       mas_client_send_voice_key_status_change(pid, mLastVoiceKeyStatus);
-               }
-               if (current_maclient_appid && 0 == strncmp(current_maclient_appid, appid, MAX_APPID_LEN)) {
-                       MAS_LOGD("MA client with current maclient appid connected!");
-
-                       if (0 == g_wakeup_maclient_appid.compare(appid)) {
-                               g_wakeup_maclient_appid.clear();
-                               mas_client_activate(pid);
-                               mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_ASSISTANT_ACTIVATED);
-                       } else {
-                               MAS_LOGE("[ERROR] g_wakeup_maclient_appid and appid differ : %s %s",
-                                       g_wakeup_maclient_appid.c_str(), appid);
-                       }
-               } else {
-                       MAS_LOGD("MA client connected, but its appid does not match with current maclient");
-               }
-
-               mServiceIpc.service_state_change(pid, mas_get_current_service_state());
-       } else {
-               MAS_LOGE("[ERROR] Fail to retrieve appid");
-       }
-
-       return 0;
-}
-
-int CServiceMain::mas_client_deinitialize(int pid)
-{
-       MAS_LOGD("[Enter] pid(%d)", pid);
-       ma_client_s *client = ma_client_find_by_pid(pid);
-       if (client) {
-               ma_client_destroy(client);
-               client = NULL;
-       }
-       return 0;
-}
-
 int CServiceMain::mas_client_get_audio_format(int pid, int* rate, int* channel, int* audio_type)
 {
        MAS_LOGD("[Enter] pid(%d)", pid);
@@ -302,27 +141,7 @@ int CServiceMain::mas_client_send_voice_key_status_change(int pid, ma_voice_key_
        return ret;
 }
 
-int CServiceMain::mas_client_activate(int pid)
-{
-       int ret = -1;
-       MAS_LOGD("[Enter] pid(%d)", pid);
-
-       ret = mServiceIpc.active_state_change(pid, MA_ACTIVE_STATE_ACTIVE);
-
-       return ret;
-}
-
-int CServiceMain::mas_client_deactivate(int pid)
-{
-       int ret = -1;
-       MAS_LOGD("[Enter] pid(%d)", pid);
-
-       ret = mServiceIpc.active_state_change(pid, MA_ACTIVE_STATE_INACTIVE);
-
-       return ret;
-}
-
-int CServiceMain::mas_client_send_asr_result(int pid, int event, char* asr_result)
+int CServiceMain::mas_client_send_asr_result(int pid, int event, const char* asr_result)
 {
        MAS_LOGD("[Enter] pid(%d), event(%d), asr_result(%s)", pid, event, asr_result);
        int ret = mServiceIpc.masc_ui_dbus_send_asr_result(pid, event, asr_result);
@@ -335,7 +154,8 @@ int CServiceMain::mas_client_send_asr_result(int pid, int event, char* asr_resul
        return ret;
 }
 
-int CServiceMain::mas_client_send_result(int pid, char* display_text, char* utterance_text, char* result_json)
+int CServiceMain::mas_client_send_result(int pid, const char* display_text,
+       const char* utterance_text, const char* result_json)
 {
        MAS_LOGD("[Enter] pid(%d), display_text(%s), utterance_text(%s), result_json(%s)", pid, display_text, utterance_text, result_json);
        int ret = mServiceIpc.masc_ui_dbus_send_result(pid, display_text, utterance_text, result_json);
@@ -497,9 +317,10 @@ int CServiceMain::mas_client_send_preprocessing_result(int pid, bool result)
                mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_PREPROCESSING_FAILED);
        }
 
-       ma_client_s* client = ma_client_find_by_appid(current_maclient_appid);
-       if (client) {
-               mServiceIpc.send_preprocessing_result(client->pid, result);
+       if (current_maclient_appid) {
+               int pid = mClientManager.find_client_pid_by_appid(
+                       std::string{current_maclient_appid});
+               mServiceIpc.send_preprocessing_result(pid, result);
        }
 
        return 0;
@@ -626,7 +447,7 @@ int CServiceMain::mas_ui_client_change_assistant(const char* appid)
                        mas_client_send_voice_key_status_change(pid, mLastVoiceKeyStatus);
                }
 
-               mas_client_activate(pid);
+               mServiceIpc.active_state_change(pid, MA_ACTIVE_STATE_ACTIVE);
                MAS_LOGD("MA Client with appid %s exists, requesting speech data", (appid ? appid : "NULL"));
                /*
                int ret = mServicePlugin.start_streaming_utterance_data();
@@ -870,9 +691,8 @@ int CServiceMain::mas_get_current_client_pid()
        int ret = -1;
        if (g_current_maclient_info >= 0 && g_current_maclient_info < MAX_MACLIENT_INFO_NUM) {
                const char *appid = g_maclient_info[g_current_maclient_info].appid;
-               ma_client_s* client = ma_client_find_by_appid(appid);
-               if (client) {
-                       ret = client->pid;
+               if (appid) {
+                       ret = mClientManager.find_client_pid_by_appid(std::string{appid});
                }
        }
        return ret;
@@ -883,9 +703,8 @@ int CServiceMain::mas_get_current_preprocessing_client_pid()
        int ret = -1;
        if (g_current_preprocessing_maclient_info >= 0 && g_current_preprocessing_maclient_info < MAX_MACLIENT_INFO_NUM) {
                const char *appid = g_maclient_info[g_current_preprocessing_maclient_info].appid;
-               ma_client_s* client = ma_client_find_by_appid(appid);
-               if (client) {
-                       ret = client->pid;
+               if (appid) {
+                       ret = mClientManager.find_client_pid_by_appid(std::string{appid});
                }
        }
        return ret;
@@ -896,45 +715,20 @@ int CServiceMain::mas_get_client_pid_by_appid(const char *appid)
        int ret = -1;
 
        if (appid) {
-               ma_client_s *client = NULL;
-               client = ma_client_find_by_appid(appid);
-               if (client) {
-                       ret = client->pid;
-               }
+               ret = mClientManager.find_client_pid_by_appid(std::string{appid});
        }
 
        int status = aul_app_get_status_bypid(ret);
        if (-1 != ret && 0 > status) {
                MAS_LOGE("The PID for %s was %d, but it seems to be terminated : %d",
                        (appid ? appid : "NULL"), ret, status);
-               mas_client_deinitialize(ret);
+               on_deinitialize(ret);
                ret = -1;
        }
 
        return ret;
 }
 
-const char* CServiceMain::mas_get_client_appid_by_pid(int pid)
-{
-       const char* ret = NULL;
-
-       ma_client_s *client = NULL;
-       client = ma_client_find_by_pid(pid);
-       if (client) {
-               ret = client->appid;
-       }
-
-       int status = aul_app_get_status_bypid(pid);
-       if (NULL != ret && 0 > status) {
-               MAS_LOGE("The appid for %d was %s, but it seems to be terminated : %d",
-                       pid, (ret ? ret : "NULL"), status);
-               mas_client_deinitialize(pid);
-               ret = NULL;
-       }
-
-       return ret;
-}
-
 bool CServiceMain::mas_get_client_custom_ui_option_by_appid(const char *appid)
 {
        bool ret = false;
@@ -1047,7 +841,8 @@ int CServiceMain::mas_set_current_client_by_wakeup_word(const char *wakeup_word)
 
        if (g_current_maclient_info != prev_selection) {
                if (prev_selection >= 0 && prev_selection < MAX_MACLIENT_INFO_NUM) {
-                       mas_client_deactivate(mas_get_client_pid_by_appid(g_maclient_info[prev_selection].appid));
+                       int pid = mas_get_client_pid_by_appid(g_maclient_info[prev_selection].appid);
+                       mServiceIpc.active_state_change(pid, MA_ACTIVE_STATE_INACTIVE);
                }
        }
 
@@ -1072,7 +867,8 @@ int CServiceMain::mas_set_current_client_by_appid(const char *appid)
 
        if (g_current_maclient_info != prev_selection) {
                if (prev_selection >= 0 && prev_selection < MAX_MACLIENT_INFO_NUM) {
-                       mas_client_deactivate(mas_get_client_pid_by_appid(g_maclient_info[prev_selection].appid));
+                       int pid = mas_get_client_pid_by_appid(g_maclient_info[prev_selection].appid);
+                       mServiceIpc.active_state_change(pid, MA_ACTIVE_STATE_INACTIVE);
                }
        }
 
@@ -1343,17 +1139,16 @@ int CServiceMain::mas_set_current_service_state(ma_service_state_e state)
 
        ma_client_s *data = NULL;
 
-       int count = g_slist_length(g_client_list);
+       int count = mClientManager.get_client_num();
        int i;
 
        for (i = 0; i < count; i++) {
-               data = static_cast<ma_client_s*>(g_slist_nth_data(g_client_list, i));
+               int pid = mClientManager.find_client_pid_by_index(i);
 
-               if (NULL != data && -1 != data->pid) {
-                       int ret = mServiceIpc.service_state_change(data->pid, state);
+               if (-1 != pid) {
+                       int ret = mServiceIpc.service_state_change(pid, state);
                        if (0 != ret) {
-                               MAS_LOGE("[ERROR] Fail to send wakeup service state change to %d, ret(%d)",
-                                       data->pid, ret);
+                               MAS_LOGE("[ERROR] Fail to set service state change to %d, ret(%d)", pid, ret);
                        }
                }
        }
@@ -1513,7 +1308,10 @@ bool CServiceMain::app_create(void *data)
 
        g_service_main = this;
 
-       mServiceIpc.set_service_main(this);
+       mClientManager.set_application_manager(&mApplicationManager);
+
+       mServiceIpc.set_client_manager(&mClientManager);
+       mServiceIpc.set_service_ipc_observer(this);
 
        mServicePlugin.set_service_ipc(&mServiceIpc);
        mServicePlugin.set_service_main(this);
@@ -1581,3 +1379,150 @@ void CServiceMain::app_terminate(void *data)
        return;
 }
 
+int CServiceMain::on_initialize(int pid) {
+       MAS_LOGD("[Enter] pid(%d)", pid);
+
+       char appid[MAX_APPID_LEN] = {'\0', };
+       if (AUL_R_OK == aul_app_get_appid_bypid(pid, appid, sizeof(appid))) {
+               appid[MAX_APPID_LEN - 1] = '\0';
+
+               MAS_LOGD("appid for pid %d is : %s", pid, (appid ? appid : "Unknown"));
+
+               /* Remove existing client that has same appid, if there's any */
+               mClientManager.destroy_client_by_appid(appid);
+
+               /* And remove a client that has same pid also */
+               mClientManager.destroy_client_by_pid(pid);
+
+               mClientManager.create_client(pid, appid);
+
+               const char *current_maclient_appid = NULL;
+               if (g_current_maclient_info >= 0 && g_current_maclient_info < MAX_MACLIENT_INFO_NUM) {
+                       current_maclient_appid = g_maclient_info[g_current_maclient_info].appid;
+               }
+
+               mas_client_send_preprocessing_information(pid);
+               if (MA_VOICE_KEY_STATUS_PRESSED == mLastVoiceKeyStatus) {
+                       mas_client_send_voice_key_status_change(pid, mLastVoiceKeyStatus);
+               }
+               if (current_maclient_appid && 0 == strncmp(current_maclient_appid, appid, MAX_APPID_LEN)) {
+                       MAS_LOGD("MA client with current maclient appid connected!");
+
+                       if (0 == g_wakeup_maclient_appid.compare(appid)) {
+                               g_wakeup_maclient_appid.clear();
+                               mServiceIpc.active_state_change(pid, MA_ACTIVE_STATE_ACTIVE);
+                               mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_ASSISTANT_ACTIVATED);
+                       } else {
+                               MAS_LOGE("[ERROR] g_wakeup_maclient_appid and appid differ : %s %s",
+                                       g_wakeup_maclient_appid.c_str(), appid);
+                       }
+               } else {
+                       MAS_LOGD("MA client connected, but its appid does not match with current maclient");
+               }
+
+               mServiceIpc.service_state_change(pid, mas_get_current_service_state());
+       } else {
+               MAS_LOGE("[ERROR] Fail to retrieve appid");
+       }
+
+       return 0;
+}
+
+int CServiceMain::on_deinitialize(int pid) {
+       MAS_LOGD("[Enter] pid(%d)", pid);
+       mClientManager.destroy_client_by_pid(pid);
+       return 0;
+}
+
+int CServiceMain::on_get_audio_format(int pid, int& rate, int& channel, int& audio_type) {
+       int main_rate, main_channel, main_audio_type;
+       int ret = mas_client_get_audio_format(pid,
+               &main_rate, &main_channel, &main_audio_type);
+       rate = main_rate;
+       channel = main_channel;
+       audio_type = main_audio_type;
+       return ret;
+}
+
+int CServiceMain::on_get_audio_source_type(int pid, std::string& type) {
+       char *main_type = nullptr;
+       int ret = mas_client_get_audio_source_type(pid, &main_type);
+       if (0 == ret && main_type) {
+               type = std::string{main_type};
+       }
+       return ret;
+}
+
+int CServiceMain::on_send_asr_result(int pid, int event, std::string asr_result) {
+       return mas_client_send_asr_result(pid, event, asr_result.c_str());
+}
+
+int CServiceMain::on_send_result(int pid, std::string display_text,
+       std::string utterance_text, std::string result_json) {
+       return mas_client_send_result(pid,
+               display_text.c_str(), utterance_text.c_str(), result_json.c_str());
+}
+
+int CServiceMain::on_send_recognition_result(int pid, int result) {
+       return mas_client_send_recognition_result(pid, result);
+}
+
+int CServiceMain::on_start_streaming_audio_data(int pid, int type) {
+       return mas_client_start_streaming_audio_data(pid, type);
+}
+
+int CServiceMain::on_stop_streaming_audio_data(int pid, int type) {
+       return mas_client_stop_streaming_audio_data(pid, type);
+}
+
+int CServiceMain::on_update_voice_feedback_state(int pid, int state) {
+       return mas_client_update_voice_feedback_state(pid, state);
+}
+
+int CServiceMain::on_send_assistant_specific_command(int pid, std::string command) {
+       return mas_client_set_assistant_specific_command(pid, command.c_str());
+}
+
+int CServiceMain::on_set_background_volume(int pid, double ratio) {
+       return mas_client_set_background_volume(pid, ratio);
+}
+
+int CServiceMain::on_set_preprocessing_allow_mode(int pid, int mode, std::string app_id) {
+       return mas_client_set_preprocessing_allow_mode(pid,
+               static_cast<ma_preprocessing_allow_mode_e>(mode), app_id.c_str());
+}
+
+int CServiceMain::on_send_preprocessing_result(int pid, int result) {
+       return mas_client_send_preprocessing_result(pid, result);
+}
+
+int CServiceMain::on_set_wake_word_audio_require_flag(int pid, int require) {
+       return mas_client_set_wake_word_audio_require_flag(pid, require);
+}
+
+int CServiceMain::on_set_assistant_language(int pid, std::string language) {
+       return mas_client_set_assistant_language(pid, language.c_str());
+}
+
+int CServiceMain::on_add_wake_word(int pid, std::string wake_word, std::string language) {
+       return mas_client_add_wake_word(pid, wake_word.c_str(), language.c_str());
+}
+
+int CServiceMain::on_remove_wake_word(int pid, std::string wake_word, std::string language) {
+       return mas_client_remove_wake_word(pid, wake_word.c_str(), language.c_str());
+}
+
+int CServiceMain::on_ui_initialize(int pid)
+{
+       return mas_ui_client_initialize(pid);
+}
+
+int CServiceMain::on_ui_deinitialize(int pid)
+{
+       return mas_ui_client_deinitialize(pid);
+}
+
+int CServiceMain::on_ui_change_assistant(std::string app_id)
+{
+       return mas_ui_client_change_assistant(app_id.c_str());
+}
index 7f1b4ef..b552823 100644 (file)
@@ -114,7 +114,7 @@ static Eina_Bool process_wakeup_event_by_appid_timer(void* data)
                service_main->mas_set_current_client_by_appid(appid);
                if ((pid = service_main->mas_get_client_pid_by_appid(appid)) != -1) {
                        service_main->mas_client_send_preprocessing_information(pid);
-                       service_main->mas_client_activate(pid);
+                       service_ipc->active_state_change(pid, MA_ACTIVE_STATE_ACTIVE);
                        service_main->mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_ASSISTANT_ACTIVATED);
                } else {
                        // Appropriate MA Client not available, trying to launch new one
index 145e97a..e968034 100644 (file)
@@ -1,3 +1,4 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
 
 ADD_SUBDIRECTORY(config)
+ADD_SUBDIRECTORY(client-manager)
diff --git a/tests/utc/client-manager/CMakeLists.txt b/tests/utc/client-manager/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ed114d9
--- /dev/null
@@ -0,0 +1,47 @@
+LINK_DIRECTORIES(${CMAKE_BINARY_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wno-unused-function -Wno-sign-compare")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIE")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -std=c++11")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}")
+
+ADD_DEFINITIONS("-DFULLVER=\"${FULLVER}\"")
+
+SET(TEST_SOURCES
+       test_client_manager.cpp
+       ${CMAKE_SOURCE_DIR}/src/client_manager.cpp
+)
+
+# Find Packages
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED
+       capi-appfw-application
+       capi-appfw-preference
+       multi-assistant
+       dlog
+       libxml-2.0
+)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FIND_PACKAGE(GTest REQUIRED)
+INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS})
+LINK_DIRECTORIES(${GTEST_LIBRARY_DIRS})
+
+SET(TEST_CLIENT_MANAGER test-client-manager)
+ADD_EXECUTABLE(${TEST_CLIENT_MANAGER}
+       ${TEST_SOURCES}
+       )
+
+TARGET_LINK_LIBRARIES(${TEST_CLIENT_MANAGER} -ldl ${GTEST_LIBRARIES} pthread
+       ${EXTRA_LDFLAGS} ${pkgs_LDFLAGS})
+
+INSTALL(TARGETS ${TEST_CLIENT_MANAGER} DESTINATION bin)
+
+ADD_TEST(NAME ${TEST_CLIENT_MANAGER} COMMAND ${TEST_CLIENT_MANAGER})
diff --git a/tests/utc/client-manager/test_client_manager.cpp b/tests/utc/client-manager/test_client_manager.cpp
new file mode 100644 (file)
index 0000000..e77ded9
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2018 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 <gtest/gtest.h>
+
+#include "client_manager.h"
+
+#include <string>
+
+class CDummyApplicationManager : public IApplicationManager
+{
+public:
+       CDummyApplicationManager() {};
+       virtual ~CDummyApplicationManager() {};
+
+       bool is_application_running(int pid) { return true; }
+};
+
+class StorageWithNoClient : public testing::Test
+{
+public:
+       StorageWithNoClient() {
+       }
+       virtual ~StorageWithNoClient() {
+       }
+       void SetUp() override {
+               client_manager.set_application_manager(&application_manager);
+       }
+       void TearDown() override {
+       }
+       CClientManager client_manager;
+       CDummyApplicationManager application_manager;
+};
+
+TEST_F(StorageWithNoClient, HasOneClientAfterCreate) {
+       const std::string arbitrary_client_appid{"Client1"};
+       const int arbitrary_client_pid{1};
+
+       client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+       int client_num = client_manager.get_client_num();
+
+       ASSERT_EQ(client_num, 1);
+}
+
+TEST_F(StorageWithNoClient, ValidityReturnsTrueForCreatedClient) {
+       const std::string arbitrary_client_appid{"Client1"};
+       const int arbitrary_client_pid{1};
+
+       client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+       bool validity = client_manager.check_client_validity_by_appid(arbitrary_client_appid);
+
+       ASSERT_TRUE(validity);
+}
+
+TEST_F(StorageWithNoClient, ValidityReturnsFalseForNotCreatedClient) {
+       const std::string arbitrary_client_appid{"Client1"};
+       const int arbitrary_client_pid{1};
+
+       const std::string noexist_client_appid{"Client987654321"};
+
+       client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+       bool validity = client_manager.check_client_validity_by_appid(noexist_client_appid);
+
+       ASSERT_FALSE(validity);
+}
+
+class StorageWithOneClient : public testing::Test {
+public:
+       StorageWithOneClient() {
+       }
+       virtual ~StorageWithOneClient() {
+       }
+       void SetUp() override {
+               client_manager.set_application_manager(&application_manager);
+               client_manager.create_client(preloaded_client_pid_1, preloaded_client_appid_1);
+       }
+       void TearDown() override {
+       }
+       const std::string preloaded_client_appid_1{"Client1"};
+       const int preloaded_client_pid_1{1};
+       CClientManager client_manager;
+       CDummyApplicationManager application_manager;
+};
+
+TEST_F(StorageWithOneClient, ReturnsExistingPIDByIndex) {
+       const std::string arbitrary_client_appid{"Client2"};
+       const int arbitrary_client_pid{2};
+
+       client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+       int pid = client_manager.find_client_pid_by_index(0);
+
+       ASSERT_EQ(pid, preloaded_client_pid_1);
+}
+
+TEST_F(StorageWithOneClient, ReturnsCreatedPIDByIndex) {
+       const std::string arbitrary_client_appid{"Client2"};
+       const int arbitrary_client_pid{2};
+
+       client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+       int pid = client_manager.find_client_pid_by_index(1);
+
+       ASSERT_EQ(pid, arbitrary_client_pid);
+}
+
+TEST_F(StorageWithOneClient, PreservesExistingItemNotRequestedForRemoval) {
+       const std::string arbitrary_client_appid{"Client2"};
+       const int arbitrary_client_pid{2};
+
+       client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+       client_manager.destroy_client_by_pid(arbitrary_client_pid);
+
+       int pid = client_manager.find_client_pid_by_index(0);
+
+       ASSERT_EQ(pid, preloaded_client_pid_1);
+}
+
+TEST_F(StorageWithOneClient, PreservesCreatedItemNotRequestedForRemoval) {
+       const std::string arbitrary_client_appid{"Client2"};
+       const int arbitrary_client_pid{2};
+
+       client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+       client_manager.destroy_client_by_pid(preloaded_client_pid_1);
+
+       int pid = client_manager.find_client_pid_by_index(0);
+
+       ASSERT_EQ(pid, arbitrary_client_pid);
+}
+
+TEST_F(StorageWithOneClient, ReturnsCorrectExistingPIDByAppID) {
+       const std::string arbitrary_client_appid{"Client2"};
+       const int arbitrary_client_pid{2};
+
+       client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+       int pid = client_manager.find_client_pid_by_appid(preloaded_client_appid_1);
+
+       ASSERT_EQ(pid, preloaded_client_pid_1);
+}
+
+TEST_F(StorageWithOneClient, ReturnsCorrectCreatedPIDByAppID) {
+       const std::string arbitrary_client_appid{"Client2"};
+       const int arbitrary_client_pid{2};
+
+       client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+       int pid = client_manager.find_client_pid_by_appid(arbitrary_client_appid);
+
+       ASSERT_EQ(pid, arbitrary_client_pid);
+}
+
+TEST_F(StorageWithOneClient, ReturnsCorrectExistingAppIDByPID) {
+       const std::string arbitrary_client_appid{"Client2"};
+       const int arbitrary_client_pid{2};
+
+       client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+       std::string appid = client_manager.find_client_appid_by_pid(preloaded_client_pid_1);
+
+       ASSERT_EQ(appid, preloaded_client_appid_1);
+}
+
+TEST_F(StorageWithOneClient, ReturnsCorrectCreatedPIDAppIDByPID) {
+       const std::string arbitrary_client_appid{"Client2"};
+       const int arbitrary_client_pid{2};
+
+       client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+       std::string appid = client_manager.find_client_appid_by_pid(arbitrary_client_pid);
+
+       ASSERT_EQ(appid, arbitrary_client_appid);
+}
+
+int main(int argc, char** argv) {
+       testing::InitGoogleTest(&argc, argv);
+       int ret = RUN_ALL_TESTS();
+       return ret;
+}