Extract vconf dependency from service_main.cpp 12/229412/6
authorJi-hoon Lee <dalton.lee@samsung.com>
Wed, 1 Apr 2020 02:42:18 +0000 (11:42 +0900)
committerJi-hoon Lee <dalton.lee@samsung.com>
Wed, 8 Apr 2020 05:04:53 +0000 (14:04 +0900)
Change-Id: I1ef3458ccbd2a298319068d27fca8bcced170512

CMakeLists.txt
inc/preference_manager.h [new file with mode: 0644]
inc/preference_manager_vconf.h [new file with mode: 0644]
inc/service_main.h
packaging/org.tizen.multi-assistant-service.spec
src/main.cpp
src/preference_manager_vconf.cpp [new file with mode: 0644]
src/service_main.cpp

index 529f152..61c3363 100644 (file)
@@ -70,6 +70,7 @@ SET(SRCS
                src/main.cpp
                src/service_config.cpp
                src/application_manager_aul.cpp
+               src/preference_manager_vconf.cpp
                src/client_manager.cpp
                src/service_main.cpp
                src/service_plugin.cpp
diff --git a/inc/preference_manager.h b/inc/preference_manager.h
new file mode 100644 (file)
index 0000000..fa33d7f
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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 __PREFERENCE_MANAGER_H__
+#define __PREFERENCE_MANAGER_H__
+
+#include <string>
+#include <boost/optional.hpp>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*preference_changed_cb)(std::string key, void* user_data);
+
+class IPreferenceManager {
+public:
+       virtual boost::optional<std::string> get_string(const std::string& key) = 0;
+       virtual boost::optional<int> get_int(const std::string& key) = 0;
+       virtual boost::optional<bool> get_bool(const std::string& key) = 0;
+
+       virtual bool register_changed_callback(
+                       const std::string& key, preference_changed_cb calback, void* user_data) = 0;
+       virtual bool unregister_changed_callback(
+                       const std::string& key, preference_changed_cb callback) = 0;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PREFERENCE_MANAGER_H__ */
diff --git a/inc/preference_manager_vconf.h b/inc/preference_manager_vconf.h
new file mode 100644 (file)
index 0000000..bae3670
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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 __PREFERENCE_MANAGER_VCONF_H__
+#define __PREFERENCE_MANAGER_VCONF_H__
+
+#include "preference_manager.h"
+
+#include <map>
+#include <list>
+#include <tuple>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef std::tuple<preference_changed_cb, void*> CallbackEntry;
+
+class CPreferenceManagerVconf : public IPreferenceManager {
+public:
+       CPreferenceManagerVconf();
+       ~CPreferenceManagerVconf();
+
+       boost::optional<std::string> get_string(const std::string& key) override;
+       boost::optional<int> get_int(const std::string& key) override;
+       boost::optional<bool> get_bool(const std::string& key) override;
+
+       bool register_changed_callback(
+                       const std::string& key, preference_changed_cb calback, void* user_data) override;
+       bool unregister_changed_callback(
+                       const std::string& key, preference_changed_cb callback) override;
+
+       const std::map<std::string, std::list<CallbackEntry>>& get_callbacks() {
+               return mCallbackEntries;
+       }
+
+private:
+       std::map<std::string, std::list<CallbackEntry>> mCallbackEntries;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PREFERENCE_MANAGER_VCONF_H__ */
index d97e68a..4bfaddd 100644 (file)
@@ -30,7 +30,8 @@
 #include "client_manager.h"
 #include "service_plugin.h"
 #include "service_ipc_dbus.h"
-#include "application_manager_aul.h"
+#include "application_manager.h"
+#include "preference_manager.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -70,7 +71,10 @@ typedef enum {
 
 class CServiceMain : public IServiceIpcObserver {
 public:
-       CServiceMain() {}
+       CServiceMain(IApplicationManager& applicationManager, IPreferenceManager& preferenceManager) :
+               mApplicationManager{applicationManager},
+               mPreferenceManager{preferenceManager}
+               {}
        virtual ~CServiceMain() {}
 
        int mas_client_get_audio_format(int pid, int* rate, int* channel, int* audio_type);
@@ -191,8 +195,8 @@ private:
 
        CClientManager mClientManager;
 
-       CApplicationManagerAul mApplicationManager;
-
+       IApplicationManager& mApplicationManager;
+       IPreferenceManager& mPreferenceManager;
 };
 
 #ifdef __cplusplus
index bb4d60b..ee68c66 100644 (file)
@@ -26,6 +26,7 @@ BuildRequires: pkgconfig(libxml-2.0)
 BuildRequires: pkgconfig(multi-assistant)
 BuildRequires: pkgconfig(vconf)
 BuildRequires: pkgconfig(pkgmgr-info)
+BuildRequires: boost-devel
 %if %{defined _test_type}
 BuildRequires:  gtest-devel
 %endif
index 951d933..c7e4dae 100644 (file)
 #include <service_app.h>
 
 #include "service_main.h"
+#include "application_manager_aul.h"
+#include "preference_manager_vconf.h"
 
-CServiceMain g_service_main;
+CApplicationManagerAul g_application_manager_aul;
+CPreferenceManagerVconf g_preference_manager_vconf;
+CServiceMain g_service_main{g_application_manager_aul, g_preference_manager_vconf};
 
 static bool service_app_create(void *data)
 {
diff --git a/src/preference_manager_vconf.cpp b/src/preference_manager_vconf.cpp
new file mode 100644 (file)
index 0000000..823cbad
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * 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 "preference_manager_vconf.h"
+
+#include <vconf.h>
+
+CPreferenceManagerVconf::CPreferenceManagerVconf()
+{
+}
+
+CPreferenceManagerVconf::~CPreferenceManagerVconf()
+{
+}
+
+boost::optional<std::string> CPreferenceManagerVconf::get_string(const std::string& key)
+{
+       boost::optional<std::string> ret;
+
+       char* vconf_str = vconf_get_str(key.c_str());
+       if (vconf_str) {
+               ret = std::string{vconf_str};
+               free(vconf_str);
+               vconf_str = NULL;
+       }
+
+       return ret;
+}
+
+boost::optional<int> CPreferenceManagerVconf::get_int(const std::string& key)
+{
+       boost::optional<int> ret;
+
+       int vconf_value = 0;
+       int succeeded = vconf_get_int(key.c_str(), &vconf_value);
+       if (0 == succeeded) {
+               ret = vconf_value;
+       }
+
+       return ret;
+}
+
+boost::optional<bool> CPreferenceManagerVconf::get_bool(const std::string& key)
+{
+       boost::optional<bool> ret;
+
+       int vconf_value = 0;
+       int succeeded = vconf_get_bool(key.c_str(), &vconf_value);
+       if (0 == succeeded) {
+               /* Non-zero means true */
+               ret = (vconf_value != 0);
+       }
+
+       return ret;
+}
+
+static void vconf_key_changed(keynode_t* key, void* data)
+{
+       if (nullptr == key) return;
+
+       const char* name = vconf_keynode_get_name(key);
+       if (nullptr == name) return;
+
+       CPreferenceManagerVconf* preference_manager =
+               static_cast<CPreferenceManagerVconf*>(data);
+       if (nullptr == preference_manager) return;
+
+       const std::map<std::string, std::list<CallbackEntry>>& entries_map =
+               preference_manager->get_callbacks();
+
+       std::map<std::string, std::list<CallbackEntry>>::const_iterator iter =
+               entries_map.find(name);
+
+       if (iter != entries_map.end()) {
+               std::list<CallbackEntry> entries = iter->second;
+               /* Iterate through list */
+               for (const auto& entry : entries) {
+                       preference_changed_cb callback = std::get<0>(entry);
+                       void* user_data = std::get<1>(entry);
+                       callback(std::string{name}, user_data);
+               }
+       }
+}
+
+bool CPreferenceManagerVconf::register_changed_callback(
+       const std::string& key, preference_changed_cb callback, void* user_data)
+{
+       bool ret = false;
+
+       std::list<CallbackEntry> entries;
+       CallbackEntry entry = std::make_tuple(callback, user_data);
+       std::map<std::string, std::list<CallbackEntry>>::iterator iter =
+               mCallbackEntries.find(key);
+
+       bool registered = false;
+       if (iter != mCallbackEntries.end()) {
+               entries = iter->second;
+               registered = true;
+       }
+
+       /* Avoid registering vconf_key_changed() for the same key */
+       if (!registered) {
+               if (0 == vconf_notify_key_changed(key.c_str(), vconf_key_changed, this)) {
+                       registered = true;
+               }
+       }
+       if (registered) {
+               entries.push_back(entry);
+               mCallbackEntries[key] = entries;
+               ret = true;
+       }
+       return ret;
+}
+
+bool CPreferenceManagerVconf::unregister_changed_callback(const std::string& key, preference_changed_cb callback)
+{
+       std::map<std::string, std::list<CallbackEntry>>::iterator map_iter =
+               mCallbackEntries.find(key);
+
+       if (map_iter != mCallbackEntries.end()) {
+               bool found = false;
+               for (const auto& entry : map_iter->second) {
+                       if (callback == std::get<0>(entry)) {
+                               if (!found) {
+                                       map_iter->second.remove(entry);
+                                       found = true;
+                               }
+                       }
+               }
+               if (map_iter->second.empty()) {
+                       vconf_ignore_key_changed(key.c_str(), vconf_key_changed);
+               }
+       }
+       return true;
+}
index 0abb443..cad2c4a 100644 (file)
@@ -42,18 +42,17 @@ bool CServiceMain::check_preprocessing_assistant_exists()
 {
        bool ret = false;
 
-       char* vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
-       if (vconf_str) {
+       boost::optional<std::string> preprocessing_appid =
+               mPreferenceManager.get_string(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
+       if (preprocessing_appid) {
                for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
                        if (mClientInfo[loop].used &&
-                               strncmp(vconf_str, mClientInfo[loop].appid, MAX_APPID_LEN) == 0) {
-                               if (mClientManager.check_client_validity_by_appid(std::string{vconf_str})) {
+                               strncmp((*preprocessing_appid).c_str(), mClientInfo[loop].appid, MAX_APPID_LEN) == 0) {
+                               if (mClientManager.check_client_validity_by_appid(*preprocessing_appid)) {
                                        ret = true;
                                }
                        }
                }
-               free(vconf_str);
-               vconf_str = NULL;
        }
 
        MAS_LOGD("result : %d", ret);
@@ -67,13 +66,12 @@ bool CServiceMain::is_current_preprocessing_assistant(const char* appid)
 
        bool ret = false;
 
-       char* vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
-       if (vconf_str) {
-               if (strncmp(vconf_str, appid, MAX_APPID_LEN) == 0) {
+       boost::optional<std::string> preprocessing_appid =
+               mPreferenceManager.get_string(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
+       if (preprocessing_appid) {
+               if (strncmp((*preprocessing_appid).c_str(), appid, MAX_APPID_LEN) == 0) {
                        ret = true;
                }
-               free(vconf_str);
-               vconf_str = NULL;
        }
 
        return ret;
@@ -116,12 +114,11 @@ int CServiceMain::mas_client_send_preprocessing_information(int pid)
        int ret = -1;
        MAS_LOGD("[Enter] pid(%d)", pid);
 
-       char* vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
-       MAS_LOGD("preprocessing_assistant_appid : %s", vconf_str);
-       if (vconf_str) {
-               ret = mServiceIpc.send_preprocessing_information(pid, vconf_str);
-               free(vconf_str);
-               vconf_str = NULL;
+       boost::optional<std::string> preprocessing_appid =
+               mPreferenceManager.get_string(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
+       if (preprocessing_appid) {
+               MAS_LOGD("preprocessing_assistant_appid : %s", (*preprocessing_appid).c_str());
+               ret = mServiceIpc.send_preprocessing_information(pid, (*preprocessing_appid).c_str());
        }
 
        return ret;
@@ -564,18 +561,22 @@ int CServiceMain::add_assistant_info(ma_assistant_info_s* info) {
        return 0;
 }
 
-static void active_state_changed_cb(keynode_t* key, void* data)
+static void active_state_changed_cb(std::string key, void* user_data)
 {
-       int vconf_value = 0;
-       if (vconf_get_bool(MULTI_ASSISTANT_SETTINGS_ACTIVATED, &vconf_value) == 0) {
-               MAS_LOGD("multi-assistant active state : %d\n", vconf_value);
+       IPreferenceManager* manager = static_cast<IPreferenceManager*>(user_data);
+       if (nullptr == manager) return;
+
+       boost::optional<bool> activated =
+               manager->get_bool(MULTI_ASSISTANT_SETTINGS_ACTIVATED);
+       if (activated) {
+               MAS_LOGD("multi-assistant active state : %d\n", *activated);
 
                CServicePlugin *plugin = nullptr;
                if (g_service_main) {
                        plugin = g_service_main->get_service_plugin();
                }
                if (plugin) {
-                       if (vconf_value) {
+                       if (*activated) {
                                plugin->activate();
                        } else {
                                plugin->deactivate();
@@ -662,9 +663,10 @@ int CServiceMain::deinitialize_service_plugin(void)
 
 int CServiceMain::process_activated_setting()
 {
-       if (0 == vconf_notify_key_changed(MULTI_ASSISTANT_SETTINGS_ACTIVATED, active_state_changed_cb, NULL)) {
+       if (mPreferenceManager.register_changed_callback(
+               MULTI_ASSISTANT_SETTINGS_ACTIVATED, active_state_changed_cb, &mPreferenceManager)) {
                /* Activate / deactivate according to the vconf key setting */
-               active_state_changed_cb(NULL, NULL);
+               active_state_changed_cb(std::string{}, &mPreferenceManager);
        } else {
 #ifdef ENABLE_MULTI_ASSISTANT_BY_DEFAULT
                /* Multi-assistant needs to be enabled by default, unless disabled explicitly */
@@ -965,9 +967,9 @@ int CServiceMain::mas_launch_client_by_wakeup_word(const char *wakeup_word)
 int CServiceMain::mas_prelaunch_default_assistant()
 {
        /* CHECK NEEDED : should the code segment below and activation logic above be moved to wakeup manger? */
-       int prelaunch_mode;
-       int res = vconf_get_bool(WAKEUP_SETTINGS_KEY_PRELAUNCH_MODE, &prelaunch_mode);
-       if (0 == res && 0 != prelaunch_mode) {
+       boost::optional<bool> prelaunch_mode =
+               mPreferenceManager.get_bool(WAKEUP_SETTINGS_KEY_PRELAUNCH_MODE);
+       if (prelaunch_mode && *prelaunch_mode) {
                const char *default_assistant = NULL;
                if (0 == mServicePlugin.get_default_assistant(&default_assistant)) {
                        if (0 == aul_app_is_running(default_assistant)) {
@@ -1106,12 +1108,11 @@ int CServiceMain::mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVEN
 #ifdef BRING_PREPROCESSING_ASSISTANT_TO_FRONT
                        if (PREPROCESSING_STATE_EVENT_UTTERANCE_STREAMING_STARTED == mCurrentPreprocessingState ||
                                PREPROCESSING_STATE_EVENT_FOLLOW_UP_STREAMING_STARTED == mCurrentPreprocessingState) {
-                               char* vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
-                               MAS_LOGD("preprocessing_assistant_appid : %s", vconf_str);
-                               if (vconf_str) {
-                                       mas_bring_client_to_foreground(vconf_str);
-                                       free(vconf_str);
-                                       vconf_str = NULL;
+                               boost::optional<std::string> preprocessing_assistant =
+                                       mPreferenceManager.get_bool(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
+                               if (preprocessing_assistant) {
+                                       MAS_LOGD("preprocessing_assistant_appid : %s", (*preprocessing_assistant).c_str());
+                                       mas_bring_client_to_foreground((*preprocessing_assistant).c_str());
                                }
                        }
 #endif
@@ -1329,13 +1330,11 @@ bool CServiceMain::app_create(void *data)
        mas_update_voice_key_support_mode();
 
        /* For the case of preprocessing assistant, it always have to be launched beforehand */
-       char *vconf_str;
-       vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
-       if (vconf_str) {
-               MAS_LOGD("prelaunching preprocessing_assistant_appid : %s", vconf_str);
-               mas_launch_client_by_appid(vconf_str, CLIENT_LAUNCH_MODE_PRELAUNCH);
-               free(vconf_str);
-               vconf_str = NULL;
+       boost::optional<std::string> preprocessing_assistant =
+               mPreferenceManager.get_string(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
+       if (preprocessing_assistant) {
+               MAS_LOGD("prelaunching preprocessing_assistant_appid : %s", (*preprocessing_assistant).c_str());
+               mas_launch_client_by_appid((*preprocessing_assistant).c_str(), CLIENT_LAUNCH_MODE_PRELAUNCH);
        }
 
        if (!mPackageManagerHandle) {
@@ -1366,7 +1365,8 @@ void CServiceMain::app_terminate(void *data)
 
        deinitialize_service_plugin();
 
-       vconf_ignore_key_changed(MULTI_ASSISTANT_SETTINGS_ACTIVATED, active_state_changed_cb);
+       mPreferenceManager.unregister_changed_callback(
+               MULTI_ASSISTANT_SETTINGS_ACTIVATED, active_state_changed_cb);
 
        int ret = mServiceIpc.close_connection();
        if (0 != ret) {