a6a8c0aff8efdf3361adf428e86f04ba92f81a40
[platform/core/uifw/multi-assistant-service.git] / src / multi_assistant_service.c
1 /*
2  * Copyright 2018  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <tizen.h>
18 #include <service_app.h>
19 #include <app_manager.h>
20 #include <app.h>
21 #include <aul.h>
22 #include <malloc.h>
23 #include <Ecore.h>
24 #include <vconf.h>
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <glib.h>
30
31 #include "multi_assistant_main.h"
32 #include "multi_assistant_service.h"
33 #include "multi_assistant_service_plugin.h"
34 #include "multi_assistant_dbus.h"
35 #include "multi_assistant_config.h"
36 #include "multi_assistant_common.h"
37
38 static const char *g_current_lang = "en_US";
39
40 #define MULTI_ASSISTANT_SETTINGS_ACTIVATED "db/multi-assistant/activated"
41 #define WAKEUP_SETTINGS_KEY_DEFAULT_ASSISTANT_APPID "db/multi-assistant/default_assistant_appid"
42 #define WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID "db/multi-assistant/preprocessing_assistant_appid"
43 #define WAKEUP_SETTINGS_KEY_PRELAUNCH_MODE "db/multi-assistant/prelaunch_mode"
44
45 #define MAX_MACLIENT_INFO_NUM 16
46 #define MAX_WAKEUP_WORDS_NUM 255
47 #define MAX_WAKEUP_WORD_LEN 32
48 #define MAX_SUPPORTED_LANGUAGES_NUM 255
49 #define MAX_SUPPORTED_LANGUAGE_LEN 16
50 typedef struct {
51         bool used;
52         char appid[MAX_APPID_LEN];
53         char wakeup_word[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN];
54         char wakeup_language[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN];
55         char wakeup_engine[MAX_APPID_LEN];
56         char supported_language[MAX_SUPPORTED_LANGUAGES_NUM][MAX_SUPPORTED_LANGUAGE_LEN];
57         bool custom_ui_option;
58
59         ma_preprocessing_allow_mode_e preprocessing_allow_mode;
60         char preprocessing_allow_appid[MAX_APPID_LEN];
61 } ma_client_info;
62
63 static ma_client_info g_maclient_info[MAX_MACLIENT_INFO_NUM];
64
65 typedef struct {
66         int pid;
67         char appid[MAX_APPID_LEN];
68 } ma_client_s;
69
70 static int g_current_maclient_info = 0;
71 static int g_current_preprocessing_maclient_info = -1;
72 static const char *g_wakeup_maclient_appid = NULL;
73
74 static PREPROCESSING_STATE g_current_preprocessing_state = PREPROCESSING_STATE_NONE;
75
76 /* client list */
77 static GSList* g_client_list = NULL;
78
79 int ma_client_create(ma_client_s *info)
80 {
81         if (NULL == info) {
82                 MAS_LOGE("Input parameter is NULL"); //LCOV_EXCL_LINE
83                 return -1;
84         }
85
86         ma_client_s* data = NULL;
87
88         data = (ma_client_s*)calloc(1, sizeof(ma_client_s));
89         if (NULL == data) {
90                 MAS_LOGE("[ERROR] Fail to allocate memory"); //LCOV_EXCL_LINE
91                 return -1;// MA_ERROR_OUT_OF_MEMORY;
92         }
93
94         *data = *info;
95
96         g_client_list = g_slist_append(g_client_list, data);
97
98         return 0;
99 }
100
101 int ma_client_destroy(ma_client_s *client)
102 {
103         if (NULL == client) {
104                 MAS_LOGE("Input parameter is NULL"); //LCOV_EXCL_LINE
105                 return -1;// MA_ERROR_OPERATION_FAILED;
106         }
107
108         g_client_list =  g_slist_remove(g_client_list, client);
109
110         free(client);
111         client = NULL;
112
113         return 0;
114 }
115
116 ma_client_s* ma_client_find_by_appid(const char *appid)
117 {
118         if (NULL == appid) {
119                 MAS_LOGE("Input parameter is NULL"); //LCOV_EXCL_LINE
120                 return NULL;
121         }
122
123         ma_client_s *data = NULL;
124
125         int count = g_slist_length(g_client_list);
126         int i;
127
128         for (i = 0; i < count; i++) {
129                 data = g_slist_nth_data(g_client_list, i);
130
131                 if (NULL != data) {
132                         if (0 == strncmp(data->appid, appid, MAX_APPID_LEN)) {
133                                 return data;
134                         }
135                 }
136         }
137
138         MAS_LOGE("[ERROR] client Not found");
139
140         return NULL;
141 }
142
143 ma_client_s* ma_client_find_by_pid(int pid)
144 {
145         ma_client_s *data = NULL;
146
147         int count = g_slist_length(g_client_list);
148         int i;
149
150         for (i = 0; i < count; i++) {
151                 data = g_slist_nth_data(g_client_list, i);
152
153                 if (NULL != data) {
154                         if (data->pid == pid) {
155                                 return data;
156                         }
157                 }
158         }
159
160         MAS_LOGE("[ERROR] client Not found");
161
162         return NULL;
163 }
164
165 bool check_preprocessing_assistant_exists()
166 {
167         bool ret = false;
168
169         char* vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
170         if (vconf_str) {
171                 for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
172                         if (g_maclient_info[loop].used) {
173                                 if (strncmp(vconf_str, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
174                                         ma_client_s* client = ma_client_find_by_appid(vconf_str);
175                                         if (client && client->pid > 0) {
176                                                 ret = true;
177                                         }
178                                 }
179                         }
180                 }
181                 free(vconf_str);
182                 vconf_str = NULL;
183         }
184
185         MAS_LOGD("result : %d", ret);
186
187         return ret;
188 }
189
190 bool is_current_preprocessing_assistant(const char* appid)
191 {
192         if (NULL == appid) return false;
193
194         bool ret = false;
195
196         char* vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
197         if (vconf_str) {
198                 if (strncmp(vconf_str, appid, MAX_APPID_LEN) == 0) {
199                         ret = true;
200                 }
201                 free(vconf_str);
202                 vconf_str = NULL;
203         }
204
205         return ret;
206 }
207
208 int mas_client_initialize(int pid)
209 {
210         MAS_LOGD("[Enter] pid(%d)", pid);
211
212         char appid[MAX_APPID_LEN] = {'\0',};
213         if (AUL_R_OK == aul_app_get_appid_bypid(pid, appid, sizeof(appid))) {
214                 appid[MAX_APPID_LEN - 1] = '\0';
215
216                 MAS_LOGD("appid for pid %d is : %s", pid, (appid ? appid : "Unknown"));
217
218                 /* Remove existing client that has same appid, if there's any */
219                 ma_client_s *old_client = NULL;
220                 old_client = ma_client_find_by_appid(appid);
221                 if (old_client) {
222                         ma_client_destroy(old_client);
223                         old_client = NULL;
224                 }
225
226                 /* And remove a client that has same pid also */
227                 old_client = ma_client_find_by_pid(pid);
228                 if (old_client) {
229                         ma_client_destroy(old_client);
230                         old_client = NULL;
231                 }
232
233                 ma_client_s new_client;
234                 new_client.pid = pid;
235                 strncpy(new_client.appid, appid, MAX_APPID_LEN);
236                 new_client.appid[MAX_APPID_LEN - 1] = '\0';
237                 ma_client_create(&new_client);
238
239                 const char *current_maclient_appid = NULL;
240                 if (g_current_maclient_info >= 0 && g_current_maclient_info < MAX_MACLIENT_INFO_NUM) {
241                         current_maclient_appid = g_maclient_info[g_current_maclient_info].appid;
242                 }
243
244                 mas_client_send_preprocessing_information(pid);
245                 if (current_maclient_appid && 0 == strncmp(current_maclient_appid, appid, MAX_APPID_LEN)) {
246                         MAS_LOGD("MA client with current maclient appid connected!");
247
248                         if (g_wakeup_maclient_appid && strncmp(g_wakeup_maclient_appid, appid, MAX_APPID_LEN) == 0) {
249                                 g_wakeup_maclient_appid = NULL;
250                                 mas_client_activate(pid);
251                                 mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_ACTIVE_ASSISTANT_LAUNCHED);
252                         } else {
253                                 MAS_LOGE("[ERROR] g_wakeup_maclient_appid and appid differ : %s %s",
254                                         (g_wakeup_maclient_appid ? g_wakeup_maclient_appid : "NULL"), appid);
255                         }
256                 } else {
257                         MAS_LOGD("MA client connected, but its appid does not match with current maclient");
258                 }
259         } else {
260                 MAS_LOGE("[ERROR] Fail to retrieve appid");
261         }
262
263         return 0;
264 }
265
266 int mas_client_deinitialize(int pid)
267 {
268         MAS_LOGD("[Enter] pid(%d)", pid);
269         ma_client_s *client = ma_client_find_by_pid(pid);
270         if (client) {
271                 ma_client_destroy(client);
272                 client = NULL;
273         }
274         return 0;
275 }
276
277 int mas_client_get_audio_format(int pid, int* rate, int* channel, int* audio_type)
278 {
279         MAS_LOGD("[Enter] pid(%d)", pid);
280
281         int ret = multi_assistant_service_plugin_get_recording_audio_format(rate, channel, audio_type);
282         if (0 != ret){
283                 MAS_LOGE("[ERROR] Fail to get recording audio format, ret(%d)", ret);
284         }
285
286         return ret;
287 }
288
289 int mas_client_get_audio_source_type(int pid, char** type)
290 {
291         MAS_LOGD("[Enter] pid(%d)", pid);
292
293         int ret = multi_assistant_service_plugin_get_recording_audio_source_type(type);
294         if (0 != ret){
295                 MAS_LOGE("[ERROR] Fail to get recording audio source type, ret(%d)", ret);
296         }
297
298         return ret;
299 }
300
301 int mas_client_send_preprocessing_information(int pid)
302 {
303         int ret = -1;
304         MAS_LOGD("[Enter] pid(%d)", pid);
305
306         char* vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
307         MAS_LOGD("preprocessing_assistant_appid : %s", vconf_str);
308         ret = masc_dbus_send_preprocessing_information(pid, vconf_str);
309         free(vconf_str);
310         vconf_str = NULL;
311
312         return ret;
313 }
314
315 int mas_client_activate(int pid)
316 {
317         int ret = -1;
318         MAS_LOGD("[Enter] pid(%d)", pid);
319
320         ret = masc_dbus_active_state_change(pid, MA_ACTIVE_STATE_ACTIVE);
321
322         return ret;
323 }
324
325 int mas_client_deactivate(int pid)
326 {
327         int ret = -1;
328         MAS_LOGD("[Enter] pid(%d)", pid);
329
330         ret = masc_dbus_active_state_change(pid, MA_ACTIVE_STATE_INACTIVE);
331
332         return ret;
333 }
334
335 int mas_client_send_asr_result(int pid, int event, char* asr_result)
336 {
337         MAS_LOGD("[Enter] pid(%d), event(%d), asr_result(%s)", pid, event, asr_result);
338         int ret = masc_ui_dbus_send_asr_result(pid, event, asr_result);
339         if (0 != ret){
340                 MAS_LOGE("[ERROR] Fail to send asr result, ret(%d)", ret);
341         }
342
343         // if final event is , launch assistant app which is invoked with wakeup word.
344         /* TO_DO */
345         return ret;
346 }
347
348 int mas_client_send_result(int pid, char* display_text, char* utterance_text, char* result_json)
349 {
350         MAS_LOGD("[Enter] pid(%d), display_text(%s), utterance_text(%s), result_json(%s)", pid, display_text, utterance_text, result_json);
351         int ret = masc_ui_dbus_send_result(pid, display_text, utterance_text, result_json);
352         if (0 != ret){
353                 MAS_LOGE("[ERROR] Fail to send result, ret(%d)", ret);
354         }
355
356         const char* pid_appid = NULL;
357         char buf[MAX_APPID_LEN] = {'\0',};
358         if (AUL_R_OK == aul_app_get_appid_bypid(pid, buf, sizeof(buf))) {
359                 buf[MAX_APPID_LEN - 1] = '\0';
360                 pid_appid = buf;
361         }
362         multi_assistant_service_plugin_update_recognition_result(pid_appid, MA_RECOGNITION_RESULT_EVENT_SUCCESS);
363
364         return ret;
365 }
366
367 int mas_client_send_recognition_result(int pid, int result)
368 {
369         MAS_LOGD("[Enter] pid(%d), result(%d)", pid, result);
370         int ret = masc_ui_dbus_send_recognition_result(pid, result);
371         if (0 != ret){
372                 MAS_LOGE("[ERROR] Fail to send recognition result, ret(%d)", ret);
373         }
374
375         const char* pid_appid = NULL;
376         char buf[MAX_APPID_LEN] = {'\0',};
377         if (AUL_R_OK == aul_app_get_appid_bypid(pid, buf, sizeof(buf))) {
378                 buf[MAX_APPID_LEN - 1] = '\0';
379                 pid_appid = buf;
380         }
381         multi_assistant_service_plugin_update_recognition_result(pid_appid, result);
382
383         return ret;
384 }
385
386 int mas_client_start_streaming_audio_data(int pid, int type)
387 {
388         int ret = -1;
389         switch(type) {
390                 case MA_AUDIO_STREAMING_DATA_TYPE_CURRENT_UTTERANCE:
391                         ret = multi_assistant_service_plugin_start_streaming_utterance_data();
392                         mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_UTTERANCE_STREAMING_STARTED);
393                         break;
394                 case MA_AUDIO_STREAMING_DATA_TYPE_PREVIOUS_UTTERANCE:
395                         ret = multi_assistant_service_plugin_start_streaming_previous_utterance_data();
396                         /* Preprocessing is not required for previous utterance streaming */
397                         break;
398                 case MA_AUDIO_STREAMING_DATA_TYPE_FOLLOW_UP_SPEECH:
399                         ret = multi_assistant_service_plugin_start_streaming_follow_up_data();
400                         mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_FOLLOW_UP_STREAMING_STARTED);
401                         break;
402         }
403         return ret;
404 }
405
406 int mas_client_stop_streaming_audio_data(int pid, int type)
407 {
408         int ret = -1;
409         switch(type) {
410                 case MA_AUDIO_STREAMING_DATA_TYPE_CURRENT_UTTERANCE:
411                         ret = multi_assistant_service_plugin_stop_streaming_utterance_data();
412                         break;
413                 case MA_AUDIO_STREAMING_DATA_TYPE_PREVIOUS_UTTERANCE:
414                         ret = multi_assistant_service_plugin_stop_streaming_previous_utterance_data();
415                         break;
416                 case MA_AUDIO_STREAMING_DATA_TYPE_FOLLOW_UP_SPEECH:
417                         ret = multi_assistant_service_plugin_stop_streaming_follow_up_data();
418                         break;
419         }
420         return ret;
421 }
422
423 int mas_client_update_voice_feedback_state(int pid, int state)
424 {
425         const char* pid_appid = NULL;
426         char buf[MAX_APPID_LEN] = {'\0',};
427         if (AUL_R_OK == aul_app_get_appid_bypid(pid, buf, sizeof(buf))) {
428                 buf[MAX_APPID_LEN - 1] = '\0';
429                 pid_appid = buf;
430         }
431         multi_assistant_service_plugin_update_voice_feedback_state(pid_appid, state);
432         return 0;
433 }
434
435 int mas_client_send_assistant_specific_command(int pid, const char *command)
436 {
437         const char* pid_appid = NULL;
438         char buf[MAX_APPID_LEN] = {'\0',};
439         if (AUL_R_OK == aul_app_get_appid_bypid(pid, buf, sizeof(buf))) {
440                 buf[MAX_APPID_LEN - 1] = '\0';
441                 pid_appid = buf;
442         }
443         multi_assistant_service_plugin_send_assistant_specific_command(pid_appid, command);
444         return 0;
445 }
446
447 int mas_client_set_background_volume(int pid, double ratio)
448 {
449         const char* pid_appid = NULL;
450         char buf[MAX_APPID_LEN] = {'\0',};
451         if (AUL_R_OK == aul_app_get_appid_bypid(pid, buf, sizeof(buf))) {
452                 buf[MAX_APPID_LEN - 1] = '\0';
453                 pid_appid = buf;
454         }
455         multi_assistant_service_plugin_set_background_volume(pid_appid, ratio);
456         return 0;
457 }
458
459 int mas_client_set_preprocessing_allow_mode(int pid, int mode, const char* appid)
460 {
461         const char* pid_appid = NULL;
462         char buf[MAX_APPID_LEN] = {'\0',};
463         if (AUL_R_OK == aul_app_get_appid_bypid(pid, buf, sizeof(buf))) {
464                 buf[MAX_APPID_LEN - 1] = '\0';
465                 pid_appid = buf;
466         }
467
468         for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
469                 if (g_maclient_info[loop].used) {
470                         if (pid_appid && strncmp(pid_appid, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
471                                 g_maclient_info[loop].preprocessing_allow_mode = mode;
472                                 if (appid) {
473                                         strncpy(g_maclient_info[loop].preprocessing_allow_appid, appid, MAX_APPID_LEN);
474                                         g_maclient_info[loop].preprocessing_allow_appid[MAX_APPID_LEN - 1] = '\0';
475                                 } else {
476                                         g_maclient_info[loop].preprocessing_allow_appid[0] = '\0';
477                                 }
478                         }
479                 }
480         }
481
482         mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_PREPROCESSING_ALLOW_MODE_CHANGED);
483
484         return 0;
485 }
486
487 int mas_client_send_preprocessing_result(int pid, bool result)
488 {
489         const char* pid_appid = NULL;
490         char buf[MAX_APPID_LEN] = {'\0',};
491         if (AUL_R_OK == aul_app_get_appid_bypid(pid, buf, sizeof(buf))) {
492                 buf[MAX_APPID_LEN - 1] = '\0';
493                 pid_appid = buf;
494         }
495         if (!is_current_preprocessing_assistant(pid_appid)) return -1;
496
497         const char *current_maclient_appid = NULL;
498         if (g_current_maclient_info >= 0 && g_current_maclient_info < MAX_MACLIENT_INFO_NUM) {
499                 current_maclient_appid = g_maclient_info[g_current_maclient_info].appid;
500         }
501
502         if (result) {
503                 MAS_LOGD("Preprocessing succeeded, bring (%s) to foreground", pid_appid);
504                 mas_bring_client_to_foreground(pid_appid);
505                 mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_PREPROCESSING_SUCCEEDED);
506         } else {
507                 MAS_LOGD("Preprocessing failed, bring (%s) to foreground", current_maclient_appid);
508                 mas_bring_client_to_foreground(current_maclient_appid);
509                 mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_PREPROCESSING_FAILED);
510         }
511
512         ma_client_s* client = ma_client_find_by_appid(current_maclient_appid);
513         if (client) {
514                 masc_dbus_send_preprocessing_result(client->pid, result);
515         }
516
517         return 0;
518 }
519
520 int mas_client_set_wake_word_audio_require_flag(int pid, bool require)
521 {
522         const char* pid_appid = NULL;
523         char buf[MAX_APPID_LEN] = {'\0',};
524         if (AUL_R_OK == aul_app_get_appid_bypid(pid, buf, sizeof(buf))) {
525                 buf[MAX_APPID_LEN - 1] = '\0';
526                 pid_appid = buf;
527         }
528
529         multi_assistant_service_plugin_set_wake_word_audio_require_flag(pid_appid, require);
530         return 0;
531 }
532
533 int mas_ui_client_initialize(int pid)
534 {
535         MAS_LOGD("[Enter] pid(%d)", pid);
536
537         return 0;
538 }
539
540 int mas_ui_client_deinitialize(int pid)
541 {
542         MAS_LOGD("[Enter] pid(%d)", pid);
543
544         return 0;
545 }
546
547 int mas_ui_client_change_assistant(const char* appid)
548 {
549         MAS_LOGD("[Enter]");
550
551         if (NULL == appid) {
552                 MAS_LOGE("NULL parameter");
553                 return -1;
554         }
555
556         bool use_custom_ui = mas_get_client_custom_ui_option_by_appid(appid);
557         masc_ui_dbus_enable_common_ui(!use_custom_ui);
558
559         mas_set_current_client_by_appid(appid);
560         int pid = mas_get_client_pid_by_appid(appid);
561         if (pid != -1) {
562                 mas_bring_client_to_foreground(appid);
563                 mas_client_send_preprocessing_information(pid);
564                 mas_client_activate(pid);
565                 MAS_LOGD("MA Client with appid %s exists, requesting speech data", (appid ? appid : "NULL"));
566                 /*
567                 int ret = multi_assistant_service_plugin_start_streaming_utterance_data();
568                 if (0 != ret) {
569                         MAS_LOGE("[ERROR] Fail to start streaming utterance data(%d)", ret);
570                 }
571                 */
572         } else {
573                 // Appropriate MA Client not available, trying to launch new one
574                 MAS_LOGD("MA Client with appid %s does not exist, launching client", (appid ? appid : "NULL"));
575
576                 /* The appid parameter might not exist after this function call, so we use appid string in our g_maclient_info */
577                 for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
578                         if (g_maclient_info[loop].used &&
579                                 0 < strlen(g_maclient_info[loop].appid) &&
580                                 0 < strlen(g_maclient_info[loop].wakeup_word[0])) {
581                                 if (strncmp(appid, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
582                                         mas_launch_client_by_appid(g_maclient_info[loop].appid, CLIENT_LAUNCH_MODE_ACTIVATION);
583                                 }
584                         }
585                 }
586         }
587
588         return 0;
589 }
590
591 int __mas_assistant_info_cb(const char* appid, const char* name, const char* icon_path,
592                 const char* wakeup_list[], const char* wakeup_language[], int cnt_wakeup,
593                 const char* supported_lang[], int cnt_lang, const char* wakeup_engine,
594                 bool custom_ui_option, void* user_data) {
595         MAS_LOGD("__mas_assistant_info_cb called");
596
597         if (NULL == appid) {
598                 MAS_LOGD("app_id NULL, returning");
599                 return -1;
600         }
601
602         int index = -1;
603         int loop = 0;
604         while(-1 == index && loop < MAX_MACLIENT_INFO_NUM) {
605                 if (false == g_maclient_info[loop].used) {
606                         index = loop;
607                 }
608                 loop++;
609         }
610         if (-1 != index) {
611                 g_maclient_info[index].used = true;
612                 g_maclient_info[index].preprocessing_allow_mode = MA_PREPROCESSING_ALLOW_NONE;
613                 g_maclient_info[index].preprocessing_allow_appid[0] = '\0';
614                 MAS_LOGD("app_id(%s)", appid);
615                 strncpy(g_maclient_info[index].appid, appid, MAX_APPID_LEN);
616                 g_maclient_info[index].appid[MAX_APPID_LEN - 1] = '\0';
617
618                 if (is_current_preprocessing_assistant(g_maclient_info[index].appid)) {
619                         g_current_preprocessing_maclient_info = index;
620                 }
621
622                 for (loop = 0;loop < MAX_WAKEUP_WORDS_NUM;loop++) {
623                         if (loop < cnt_wakeup && wakeup_list[loop]) {
624                                 MAS_LOGD("wakeup_list(%d)(%s)(%s)", loop, wakeup_list[loop], wakeup_language[loop]);
625                                 strncpy(g_maclient_info[index].wakeup_word[loop], wakeup_list[loop], MAX_WAKEUP_WORD_LEN);
626                                 g_maclient_info[index].wakeup_word[loop][MAX_WAKEUP_WORD_LEN - 1] = '\0';
627                                 if (wakeup_language[loop]) {
628                                         strncpy(g_maclient_info[index].wakeup_language[loop], wakeup_language[loop], MAX_SUPPORTED_LANGUAGE_LEN);
629                                         g_maclient_info[index].wakeup_language[loop][MAX_SUPPORTED_LANGUAGE_LEN - 1] = '\0';
630                                 } else {
631                                         strncpy(g_maclient_info[index].wakeup_language[loop], "", MAX_SUPPORTED_LANGUAGE_LEN);
632                                 }
633                         } else {
634                                 strncpy(g_maclient_info[index].wakeup_word[loop], "", MAX_WAKEUP_WORD_LEN);
635                         }
636                 }
637
638                 for (loop = 0;loop < MAX_SUPPORTED_LANGUAGES_NUM;loop++) {
639                         if (loop < cnt_lang && supported_lang[loop]) {
640                                 MAS_LOGD("supported_lang(%d)(%s)", loop, supported_lang[loop]);
641                                 strncpy(g_maclient_info[index].supported_language[loop], supported_lang[loop], MAX_SUPPORTED_LANGUAGE_LEN);
642                                 g_maclient_info[index].supported_language[loop][MAX_SUPPORTED_LANGUAGE_LEN - 1] = '\0';
643                         } else {
644                                 strncpy(g_maclient_info[index].supported_language[loop], "", MAX_SUPPORTED_LANGUAGE_LEN);
645                         }
646                 }
647
648                 MAS_LOGD("wakeup_engine(%s)", wakeup_engine);
649                 if (wakeup_engine) {
650                         strncpy(g_maclient_info[index].wakeup_engine, wakeup_engine, MAX_APPID_LEN);
651                         g_maclient_info[index].wakeup_engine[MAX_APPID_LEN - 1] = '\0';
652                 } else {
653                         g_maclient_info[index].wakeup_engine[0] = '\0';
654                         MAS_LOGW("Wakeup engine information not provided for : %s", appid);
655                 }
656                 g_maclient_info[index].custom_ui_option = custom_ui_option;
657         } else {
658                 MAS_LOGD("Couldn't find an empty slot for storing assistant info");
659         }
660
661         MAS_LOGD("__mas_assistant_info_cb end");
662
663         return 0;
664 }
665
666 static void mas_active_state_changed_cb(keynode_t* key, void* data)
667 {
668         int vconf_value = 0;
669         if (vconf_get_bool(MULTI_ASSISTANT_SETTINGS_ACTIVATED, &vconf_value) == 0) {
670                 MAS_LOGD("multi-assistant active state : %d\n", vconf_value);
671
672                 if (vconf_value) {
673                         multi_assistant_service_plugin_activate();
674                 } else {
675                         multi_assistant_service_plugin_deactivate();
676                 }
677         }
678 }
679
680 static int init_wakeup(void)
681 {
682         MAS_LOGD("[Enter] init_wakeup");
683
684         int ret = mas_dbus_open_connection();
685         if (0 != ret) {
686                 MAS_LOGE("[ERROR] Fail to open connection");
687         }
688
689         if (0 != multi_assistant_service_plugin_initialize()) {
690                 MAS_LOGE("Fail to ws intialize");
691                 return -1;
692         }
693
694         if (0 != multi_assistant_service_plugin_set_language(g_current_lang)) {
695                 MAS_LOGE("Fail to ws set language");
696                 return -1;
697         }
698
699         if (0 == mas_config_get_assistant_info(__mas_assistant_info_cb, NULL)) {
700                 for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
701                         int inner_loop;
702                         if (g_maclient_info[loop].used &&
703                                 0 < strlen(g_maclient_info[loop].appid)) {
704                                 if (0 < strlen(g_maclient_info[loop].wakeup_engine)) {
705                                         multi_assistant_service_plugin_set_assistant_wakeup_engine(
706                                                 g_maclient_info[loop].appid,
707                                                 g_maclient_info[loop].wakeup_engine);
708                                 }
709                                 for (inner_loop = 0; inner_loop < MAX_WAKEUP_WORDS_NUM; inner_loop++) {
710                                         if (0 < strlen(g_maclient_info[loop].wakeup_word[inner_loop])) {
711                                                 MAS_LOGD("Registering wakeup word %s for app %s",
712                                                         g_maclient_info[loop].wakeup_word[inner_loop], g_maclient_info[loop].appid);
713                                                 if (0 != multi_assistant_service_plugin_add_assistant_wakeup_word(
714                                                         g_maclient_info[loop].appid,
715                                                         g_maclient_info[loop].wakeup_word[inner_loop],
716                                                         g_maclient_info[loop].wakeup_language[inner_loop])) {
717                                                         MAS_LOGE("Fail to add assistant's wakeup word");
718                                                 }
719                                         }
720                                 }
721                                 for (inner_loop = 0; inner_loop < MAX_SUPPORTED_LANGUAGE_NUM; inner_loop++) {
722                                         if (0 < strlen(g_maclient_info[loop].supported_language[inner_loop])) {
723                                                 MAS_LOGD("Adding language %s for app %s",
724                                                         g_maclient_info[loop].supported_language[inner_loop], g_maclient_info[loop].appid);
725                                                 if (0 != multi_assistant_service_plugin_add_assistant_language(
726                                                         g_maclient_info[loop].appid,
727                                                         g_maclient_info[loop].supported_language[inner_loop])) {
728                                                         MAS_LOGE("Fail to add assistant's language");
729                                                 }
730                                         }
731                                 }
732                         }
733                 }
734         } else {
735                 MAS_LOGE("Fail to load assistant info");
736         }
737
738         if (0 != multi_assistant_service_plugin_set_callbacks()) {
739                 MAS_LOGE("Fail to set callbacks");
740                 return -1;
741         }
742
743         if (0 == vconf_notify_key_changed(MULTI_ASSISTANT_SETTINGS_ACTIVATED, mas_active_state_changed_cb, NULL)) {
744                 /* Activate / deactivate according to the vconf key setting */
745                 mas_active_state_changed_cb(NULL, NULL);
746         } else {
747                 /* Multi-assistant needs to be enabled by default, unless disabled explicitly */
748                 multi_assistant_service_plugin_activate();
749                 vconf_set_bool(MULTI_ASSISTANT_SETTINGS_ACTIVATED, 1);
750                 vconf_notify_key_changed(MULTI_ASSISTANT_SETTINGS_ACTIVATED, mas_active_state_changed_cb, NULL);
751         }
752
753         /* CHECK NEEDED : should the code segment below and activation logic above be moved to wakeup manger? */
754         int prelaunch_mode;
755         int res = vconf_get_bool(WAKEUP_SETTINGS_KEY_PRELAUNCH_MODE, &prelaunch_mode);
756         if (0 == res && 0 != prelaunch_mode) {
757                 char *vconf_str;
758                 vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_DEFAULT_ASSISTANT_APPID);
759                 if (vconf_str) {
760                         MAS_LOGD("prelaunching default_assistant_appid : %s", vconf_str);
761                         mas_launch_client_by_appid(vconf_str, CLIENT_LAUNCH_MODE_PRELAUNCH);
762                         free(vconf_str);
763                         vconf_str = NULL;
764                 }
765         }
766
767         /* For the case of preprocessing assistant, it always have to be launched beforehand */
768         char *vconf_str;
769         vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
770         if (vconf_str) {
771                 MAS_LOGD("prelaunching preprocessing_assistant_appid : %s", vconf_str);
772                 mas_launch_client_by_appid(vconf_str, CLIENT_LAUNCH_MODE_PRELAUNCH);
773                 free(vconf_str);
774                 vconf_str = NULL;
775         }
776
777         return 0;
778 }
779
780 static void deinit_wakeup(void)
781 {
782         MAS_LOGD("[Enter] deinit_wakeup ");
783
784 /*      if (NULL != g_current_lang) {
785                 free(g_current_lang);
786                 g_current_lang = NULL;
787         }
788 */
789
790         vconf_ignore_key_changed(MULTI_ASSISTANT_SETTINGS_ACTIVATED, mas_active_state_changed_cb);
791
792         int ret = mas_dbus_close_connection();
793         if (0 != ret) {
794                 MAS_LOGE("[ERROR] Fail to close connection");
795         }
796
797         if (0 != multi_assistant_service_plugin_deinitialize()) {
798                 MAS_LOGE("Fail to ws deinitialize");
799         }
800 }
801
802 int mas_get_current_client_pid()
803 {
804         int ret = -1;
805         if (g_current_maclient_info >= 0 && g_current_maclient_info < MAX_MACLIENT_INFO_NUM) {
806                 const char *appid = g_maclient_info[g_current_maclient_info].appid;
807                 ma_client_s* client = ma_client_find_by_appid(appid);
808                 if (client) {
809                         ret = client->pid;
810                 }
811         }
812         return ret;
813 }
814
815 int mas_get_current_preprocessing_client_pid()
816 {
817         int ret = -1;
818         if (g_current_preprocessing_maclient_info >= 0 && g_current_preprocessing_maclient_info < MAX_MACLIENT_INFO_NUM) {
819                 const char *appid = g_maclient_info[g_current_preprocessing_maclient_info].appid;
820                 ma_client_s* client = ma_client_find_by_appid(appid);
821                 if (client) {
822                         ret = client->pid;
823                 }
824         }
825         return ret;
826 }
827
828 int mas_get_client_pid_by_appid(const char *appid)
829 {
830         int ret = -1;
831
832         if (appid) {
833                 ma_client_s *client = NULL;
834                 client = ma_client_find_by_appid(appid);
835                 if (client) {
836                         ret = client->pid;
837                 }
838         }
839
840         int status = aul_app_get_status_bypid(ret);
841         if (-1 != ret && 0 > status) {
842                 MAS_LOGE("The PID for %s was %d, but it seems to be terminated : %d",
843                         (appid ? appid : "NULL"), ret, status);
844                 mas_client_deinitialize(ret);
845                 ret = -1;
846         }
847
848         return ret;
849 }
850
851 bool mas_get_client_custom_ui_option_by_appid(const char *appid)
852 {
853         bool ret = false;
854         for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
855                 if (g_maclient_info[loop].used &&
856                         0 < strlen(g_maclient_info[loop].appid) &&
857                         0 < strlen(g_maclient_info[loop].wakeup_word[0])) {
858                         if (strncmp(appid, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
859                                 ret = g_maclient_info[loop].custom_ui_option;
860                         }
861                 }
862         }
863         return ret;
864 }
865
866 int mas_get_client_pid_by_wakeup_word(const char *wakeup_word)
867 {
868         const char *appid = mas_get_client_appid_by_wakeup_word(wakeup_word);
869         return mas_get_client_pid_by_appid(appid);
870 }
871
872 const char* mas_get_client_appid_by_wakeup_word(const char *wakeup_word)
873 {
874         int loop;
875         const char *appid = NULL;
876
877         if (NULL == wakeup_word) return NULL;
878
879         for (loop = 0; loop < MAX_MACLIENT_INFO_NUM && NULL == appid; loop++) {
880                 if (g_maclient_info[loop].used &&
881                         0 < strlen(g_maclient_info[loop].appid)) {
882                         for (int inner_loop = 0; inner_loop < MAX_WAKEUP_WORDS_NUM; inner_loop++) {
883                                 if (0 < strlen(g_maclient_info[loop].wakeup_word[inner_loop])) {
884                                         if (0 == strncmp(wakeup_word, g_maclient_info[loop].wakeup_word[inner_loop], MAX_WAKEUP_WORD_LEN)) {
885                                                 appid = g_maclient_info[loop].appid;
886                                         }
887                                 }
888                         }
889                 }
890         }
891
892         /* Perform extended search, by eliminating blank characters */
893         if (NULL == appid) {
894                 for (loop = 0; loop < MAX_MACLIENT_INFO_NUM && NULL == appid; loop++) {
895                         if (g_maclient_info[loop].used &&
896                                 0 < strlen(g_maclient_info[loop].appid)) {
897                                 for (int inner_loop = 0; inner_loop < MAX_WAKEUP_WORDS_NUM; inner_loop++) {
898                                         if (0 < strlen(g_maclient_info[loop].wakeup_word[inner_loop])) {
899                                                 char comparand[MAX_WAKEUP_WORD_LEN];
900                                                 int comparand_index = 0;
901                                                 for (int index = 0; index < MAX_WAKEUP_WORD_LEN; index++) {
902                                                         if (' ' != g_maclient_info[loop].wakeup_word[inner_loop][index]) {
903                                                                 comparand[comparand_index++] = g_maclient_info[loop].wakeup_word[inner_loop][index];
904                                                         }
905                                                 }
906                                                 if (0 == strncmp(wakeup_word, comparand, MAX_WAKEUP_WORD_LEN)) {
907                                                         appid = g_maclient_info[loop].appid;
908                                                 }
909                                         }
910                                 }
911                         }
912                 }
913         }
914
915         return appid;
916 }
917
918 int mas_set_current_client_by_wakeup_word(const char *wakeup_word)
919 {
920         int loop;
921         int ret = -1;
922         int prev_selection = g_current_maclient_info;
923
924         for (loop = 0; loop < MAX_MACLIENT_INFO_NUM && -1 == ret; loop++) {
925                 if (g_maclient_info[loop].used &&
926                         0 < strlen(g_maclient_info[loop].appid)) {
927                         for (int inner_loop = 0; inner_loop < MAX_WAKEUP_WORDS_NUM; inner_loop++) {
928                                 if (0 < strlen(g_maclient_info[loop].wakeup_word[inner_loop])) {
929                                         if (0 == strncmp(wakeup_word, g_maclient_info[loop].wakeup_word[inner_loop], MAX_WAKEUP_WORD_LEN)) {
930                                                 g_current_maclient_info = loop;
931                                                 ret = 0;
932                                         }
933                                 }
934                         }
935                 }
936         }
937         /* Perform extended search, by eliminating blank characters */
938         if (ret == -1) {
939                 for (loop = 0; loop < MAX_MACLIENT_INFO_NUM && -1 == ret; loop++) {
940                         if (g_maclient_info[loop].used &&
941                                 0 < strlen(g_maclient_info[loop].appid)) {
942                                 for (int inner_loop = 0; inner_loop < MAX_WAKEUP_WORDS_NUM; inner_loop++) {
943                                         if (0 < strlen(g_maclient_info[loop].wakeup_word[inner_loop])) {
944                                                 char comparand[MAX_WAKEUP_WORD_LEN];
945                                                 int comparand_index = 0;
946                                                 for (int index = 0; index < MAX_WAKEUP_WORD_LEN; index++) {
947                                                         if (' ' != g_maclient_info[loop].wakeup_word[inner_loop][index]) {
948                                                                 comparand[comparand_index++] = g_maclient_info[loop].wakeup_word[inner_loop][index];
949                                                         }
950                                                 }
951                                                 if (0 == strncmp(wakeup_word, comparand, MAX_WAKEUP_WORD_LEN)) {
952                                                         g_current_maclient_info = loop;
953                                                         ret = 0;
954                                                 }
955                                         }
956                                 }
957                         }
958                 }
959         }
960
961         if (g_current_maclient_info != prev_selection) {
962                 if (prev_selection >= 0 && prev_selection < MAX_MACLIENT_INFO_NUM) {
963                         mas_client_deactivate(mas_get_client_pid_by_appid(g_maclient_info[prev_selection].appid));
964                 }
965         }
966
967         return ret;
968 }
969
970 int mas_set_current_client_by_appid(const char *appid)
971 {
972         int ret = -1;
973         int prev_selection = g_current_maclient_info;
974
975         for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
976                 if (g_maclient_info[loop].used &&
977                         0 < strlen(g_maclient_info[loop].appid) &&
978                         0 < strlen(g_maclient_info[loop].wakeup_word[0])) {
979                         if (strncmp(appid, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
980                                 g_current_maclient_info = loop;
981                                 ret = 0;
982                         }
983                 }
984         }
985
986         if (g_current_maclient_info != prev_selection) {
987                 if (prev_selection >= 0 && prev_selection < MAX_MACLIENT_INFO_NUM) {
988                         mas_client_deactivate(mas_get_client_pid_by_appid(g_maclient_info[prev_selection].appid));
989                 }
990         }
991
992         return ret;
993 }
994
995 int mas_launch_client_by_appid(const char *appid, CLIENT_LAUNCH_MODE launch_mode)
996 {
997         if (NULL == appid || 0 == strlen(appid)) {
998                 MAS_LOGE("appid invalid, failed launching MA Client");
999                 return -1;
1000         }
1001
1002         bundle *b = NULL;
1003         b = bundle_create();
1004         if (NULL == b) {
1005                 MAS_LOGE("Failed creating bundle for aul operation");
1006                 return -1;
1007         }
1008
1009         int result = aul_svc_set_background_launch(b, TRUE);
1010         if (result < AUL_R_OK) {
1011                 MAS_LOGE("ERROR : aul_svc_set_background_launch failed. app_id [%s] bundle[%p] result[%d : %s]",
1012                         appid, b, result, get_error_message(result));
1013         }
1014
1015         result = aul_launch_app(appid, b);
1016         if (result < AUL_R_OK) {
1017                 MAS_LOGE("ERROR : aul_launch_app failed. app_id [%s] bundle[%p] result[%d : %s]",
1018                         appid, b, result, get_error_message(result));
1019         }
1020
1021         if (CLIENT_LAUNCH_MODE_ACTIVATION == launch_mode) {
1022                 bool found = false;
1023                 for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
1024                         if (g_maclient_info[loop].used &&
1025                                 0 < strlen(g_maclient_info[loop].appid)) {
1026                                 if (strncmp(appid, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
1027                                         g_wakeup_maclient_appid = g_maclient_info[loop].appid;
1028                                         found = true;
1029                                 }
1030                         }
1031                 }
1032                 MAS_LOGD("g_wakeup_maclient_appid : %s, %d", g_wakeup_maclient_appid, found);
1033         }
1034
1035         if (b) bundle_free(b);
1036         b = NULL;
1037
1038         return result;
1039 }
1040
1041 int mas_bring_client_to_foreground(const char* appid)
1042 {
1043         /* Bring MA client to foreground - is there a better way other than launching? */
1044         if (NULL == appid || 0 == strlen(appid)) {
1045                 MAS_LOGE("appid invalid, failed launching MA Client");
1046                 return -1;
1047         }
1048
1049         bundle *b = NULL;
1050         b = bundle_create();
1051         if (NULL == b) {
1052                 MAS_LOGE("Failed creating bundle for aul operation");
1053                 return -1;
1054         }
1055
1056         int result = aul_launch_app(appid, b);
1057         if (result < AUL_R_OK) {
1058                 MAS_LOGE("ERROR : aul_launch_app failed. app_id [%s] bundle[%p] result[%d : %s]",
1059                         appid, b, result, get_error_message(result));
1060         }
1061
1062         if (b) bundle_free(b);
1063         b = NULL;
1064
1065         return result;
1066 }
1067
1068 int mas_launch_client_by_wakeup_word(const char *wakeup_word)
1069 {
1070         const char *appid = mas_get_client_appid_by_wakeup_word(wakeup_word);
1071         return mas_launch_client_by_appid(appid, CLIENT_LAUNCH_MODE_ACTIVATION);
1072 }
1073
1074
1075 int mas_process_voice_key_event(bool pressed)
1076 {
1077         if (pressed) {
1078                 multi_assistant_service_plugin_process_event(MA_PLUGIN_EVENT_VOICE_KEY_PRESSED, NULL, 0);
1079         } else {
1080                 multi_assistant_service_plugin_process_event(MA_PLUGIN_EVENT_VOICE_KEY_RELEASED, NULL, 0);
1081         }
1082         return 0;
1083 }
1084
1085 ma_preprocessing_allow_mode_e get_preprocessing_allow_mode(const char* appid)
1086 {
1087         for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
1088                 if (appid && g_maclient_info[loop].used) {
1089                         if (strncmp(appid, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
1090                                 return g_maclient_info[loop].preprocessing_allow_mode;
1091                         }
1092                 }
1093         }
1094         return MA_PREPROCESSING_ALLOW_NONE;
1095 }
1096
1097 int mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT event)
1098 {
1099         const char* current_maclient_appid = NULL;
1100         const char* preprocessing_allow_appid = NULL;
1101         if (g_current_maclient_info >= 0 && g_current_maclient_info < MAX_MACLIENT_INFO_NUM) {
1102                 current_maclient_appid = g_maclient_info[g_current_maclient_info].appid;
1103                 preprocessing_allow_appid = g_maclient_info[g_current_maclient_info].preprocessing_allow_appid;
1104         }
1105         ma_preprocessing_allow_mode_e mode = get_preprocessing_allow_mode(current_maclient_appid);
1106
1107         switch (event) {
1108                 case PREPROCESSING_STATE_EVENT_WAKEUP:
1109                 case PREPROCESSING_STATE_EVENT_ACTIVE_ASSISTANT_LAUNCHED:
1110                 {
1111                         if (!check_preprocessing_assistant_exists()) {
1112                                 mas_bring_client_to_foreground(current_maclient_appid);
1113                         }
1114                         g_current_preprocessing_state = PREPROCESSING_STATE_WAKEUP_PREPROCESS_DISABLED;
1115                         if (MA_PREPROCESSING_ALLOW_UTTERANCE == mode ||
1116                                 MA_PREPROCESSING_ALLOW_ALL == mode) {
1117                                 if (is_current_preprocessing_assistant(preprocessing_allow_appid)) {
1118                                         g_current_preprocessing_state = PREPROCESSING_STATE_WAKEUP_PREPROCESS_ENABLED;
1119                                 }
1120                         }
1121                 }
1122                 break;
1123                 case PREPROCESSING_STATE_EVENT_PREPROCESSING_ALLOW_MODE_CHANGED:
1124                 {
1125                         g_current_preprocessing_state = PREPROCESSING_STATE_WAKEUP_PREPROCESS_DISABLED;
1126                         if (MA_PREPROCESSING_ALLOW_UTTERANCE == mode ||
1127                                 MA_PREPROCESSING_ALLOW_ALL == mode) {
1128                                 if (is_current_preprocessing_assistant(preprocessing_allow_appid)) {
1129                                         g_current_preprocessing_state = PREPROCESSING_STATE_WAKEUP_PREPROCESS_ENABLED;
1130                                 }
1131                         }
1132                 }
1133                 break;
1134                 case PREPROCESSING_STATE_EVENT_UTTERANCE_STREAMING_STARTED:
1135                 {
1136                         if (PREPROCESSING_STATE_WAKEUP_PREPROCESS_ENABLED == g_current_preprocessing_state) {
1137                                 g_current_preprocessing_state = PREPROCESSING_STATE_PREPROCESSING_UTTERANCE;
1138                         } else if (PREPROCESSING_STATE_WAKEUP_PREPROCESS_DISABLED == g_current_preprocessing_state) {
1139                                 mas_bring_client_to_foreground(current_maclient_appid);
1140                                 g_current_preprocessing_state = PREPROCESSING_STATE_NONE;
1141                         }
1142                 }
1143                 break;
1144                 case PREPROCESSING_STATE_EVENT_FOLLOW_UP_STREAMING_STARTED:
1145                 {
1146                         if (MA_PREPROCESSING_ALLOW_FOLLOW_UP == mode ||
1147                                 MA_PREPROCESSING_ALLOW_ALL == mode) {
1148                                 g_current_preprocessing_state = PREPROCESSING_STATE_PREPROCESSING_FOLLOW_UP;
1149                         }
1150                 }
1151                 break;
1152                 case PREPROCESSING_STATE_EVENT_PREPROCESSING_SUCCEEDED:
1153                 {
1154                         g_current_preprocessing_state = PREPROCESSING_STATE_NONE;
1155                 }
1156                 break;
1157                 case PREPROCESSING_STATE_EVENT_PREPROCESSING_FAILED:
1158                 {
1159                         mas_bring_client_to_foreground(current_maclient_appid);
1160                         g_current_preprocessing_state = PREPROCESSING_STATE_NONE;
1161                 }
1162                 break;
1163         }
1164         return 0;
1165 }
1166
1167 bool service_app_create(void *data)
1168 {
1169         // Todo: add your code here.
1170
1171         MAS_LOGD("[Enter] Service app create");
1172
1173         if (0 != init_wakeup()) {
1174                 MAS_LOGE("Fail to init wakeup service");
1175                 return false;
1176         }
1177
1178         return true;
1179 }
1180
1181 void service_app_terminate(void *data)
1182 {
1183         // Todo: add your code here.
1184         deinit_wakeup();
1185         return;
1186 }
1187
1188 void service_app_control(app_control_h app_control, void *data)
1189 {
1190         // Todo: add your code here.
1191         return;
1192 }
1193
1194 static void
1195 service_app_lang_changed(app_event_info_h event_info, void *user_data)
1196 {
1197         /*APP_EVENT_LANGUAGE_CHANGED*/
1198         return;
1199 }
1200
1201 static void
1202 service_app_region_changed(app_event_info_h event_info, void *user_data)
1203 {
1204         /*APP_EVENT_REGION_FORMAT_CHANGED*/
1205 }
1206
1207 static void
1208 service_app_low_battery(app_event_info_h event_info, void *user_data)
1209 {
1210         /*APP_EVENT_LOW_BATTERY*/
1211 }
1212
1213 static void
1214 service_app_low_memory(app_event_info_h event_info, void *user_data)
1215 {
1216         /*APP_EVENT_LOW_MEMORY*/
1217 }
1218
1219 int main(int argc, char* argv[])
1220 {
1221         char ad[50] = {0,};
1222         service_app_lifecycle_callback_s event_callback;
1223         app_event_handler_h handlers[5] = {NULL, };
1224
1225         event_callback.create = service_app_create;
1226         event_callback.terminate = service_app_terminate;
1227         event_callback.app_control = service_app_control;
1228
1229         service_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, service_app_low_battery, &ad);
1230         service_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, service_app_low_memory, &ad);
1231         service_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, service_app_lang_changed, &ad);
1232         service_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, service_app_region_changed, &ad);
1233
1234         return service_app_main(argc, argv, &event_callback, ad);
1235 }