From 87cb2ec90082918a4b8eb8c57682cca27c65494e Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Tue, 20 Mar 2018 11:21:55 +0900 Subject: [PATCH 01/16] Change to BEGIN IMMEDIATE TRANSACTION for db lock issue Change-Id: I97b82c620eb055f69589f86e6cd29caedb979706 Signed-off-by: Wonnam Jang --- common/vc_cmd_db.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/vc_cmd_db.c b/common/vc_cmd_db.c index d55a171..7c74a97 100644 --- a/common/vc_cmd_db.c +++ b/common/vc_cmd_db.c @@ -85,7 +85,7 @@ static int __vc_db_transaction(sqlite3* db_handle, const char* transaction) static int __vc_db_begin_transaction(sqlite3* db_handle) { - int ret = __vc_db_transaction(db_handle, "BEGIN TRANSACTION"); + int ret = __vc_db_transaction(db_handle, "BEGIN IMMEDIATE TRANSACTION"); return ret; } -- 2.7.4 From 5a7f89ef648c51ab37dec07215f78bfdaccb2496 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Fri, 30 Jun 2017 17:54:41 +0900 Subject: [PATCH 02/16] Add text matching alogrithm function Change-Id: I6f590f79ddeb42263650f55f2069a93472d7756d Signed-off-by: Suyeon Hwang --- client/CMakeLists.txt | 3 + common/vc_command_util.c | 420 +++++++++++++++++++++++++++++++++ common/vc_command_util.h | 39 +++ include/voice_control_command_expand.h | 26 ++ server/CMakeLists.txt | 1 + 5 files changed, 489 insertions(+) create mode 100644 common/vc_command_util.c create mode 100644 common/vc_command_util.h diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 074d790..fcc4c43 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -4,6 +4,7 @@ SET(SRCS vc_dbus.c ../common/vc_cmd_db.c ../common/vc_command.c + ../common/vc_command_util.c ../common/vc_config_mgr.c ../common/vc_config_parser.c ../common/vc_info_parser.c @@ -23,6 +24,7 @@ SET(WIDGET_SRCS vc_widget_dbus.c ../common/vc_cmd_db.c ../common/vc_command.c + ../common/vc_command_util.c ../common/vc_config_mgr.c ../common/vc_config_parser.c ../common/vc_info_parser.c @@ -35,6 +37,7 @@ SET(MANAGER_SRCS vc_mgr_dbus.c ../common/vc_cmd_db.c ../common/vc_command.c + ../common/vc_command_util.c ../common/vc_config_mgr.c ../common/vc_config_parser.c ../common/vc_info_parser.c diff --git a/common/vc_command_util.c b/common/vc_command_util.c new file mode 100644 index 0000000..2386ef5 --- /dev/null +++ b/common/vc_command_util.c @@ -0,0 +1,420 @@ +/* +* Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the License); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an AS IS BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#include "ctype.h" + +#include "vc_main.h" +#include "vc_command_util.h" +#include "vc_command.h" + +#include + +vc_cmd_list_h ret_list = NULL; +GList *split_list = NULL; +int ret_cnt = -1; + +void __tolower(char *str) +{ + while (0 != *str) { + *str = tolower(*str); + ++str; + } +} + +int vc_cmd_get_partially_matched_cmd_list(const char *command, vc_cmd_list_h src_list, vc_cmd_list_h dst_list, int search_level) +{ + SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ vc_cmd_find_similar_commands"); + if (NULL == command || NULL == src_list || NULL == dst_list || VC_SEARCH_TEXT_LEVEL > search_level || VC_SEARCH_PRON_LEVEL < search_level) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter"); + return VC_ERROR_INVALID_PARAMETER; + } + + char *temp_cmd = NULL; + char *split = NULL; + char *tok_ptr = NULL; + + ret_list = dst_list; + split_list = NULL; + ret_cnt = 0; + + temp_cmd = strdup(command); + if (NULL == temp_cmd) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Out of memory"); + return VC_ERROR_OUT_OF_MEMORY; + } + + __tolower(temp_cmd); + split = strtok_r(temp_cmd, " ", &tok_ptr); + while (NULL != split) { + char *temp = strdup(split); + + if (NULL == temp) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Out of memory"); + free(temp_cmd); + temp_cmd = NULL; + + g_list_free_full(split_list, free); + split_list = NULL; + + return VC_ERROR_OUT_OF_MEMORY; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "(%s)", split); + split_list = g_list_append(split_list, temp); + + split = strtok_r(NULL, " ", &tok_ptr); + } + + free(temp_cmd); + temp_cmd = NULL; + + int ret = 0; + ret = vc_search_text(src_list, search_level); + + g_list_free_full(split_list, free); + split_list = NULL; + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to search similar commands (%d)", ret); + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "@@@"); + return ret; +} + +int vc_search_text(vc_cmd_list_h list, int search_level) +{ + SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Full Text level matching"); + vc_cmd_h vc_cmd = NULL; + int ret = VC_ERROR_NONE; + + ret = vc_cmd_list_first(list); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to make list first (%d)", ret); + return ret; + } + ret = vc_cmd_list_get_current(list, &vc_cmd); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get voice command handle (%d)", ret); + return ret; + } + + while (NULL != vc_cmd) { + GList *item = NULL; + char *cmd_text = NULL; + + if (0 != vc_cmd_get_command(vc_cmd, &cmd_text) || NULL == cmd_text) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get command"); + return VC_ERROR_OPERATION_FAILED; + } + + __tolower(cmd_text); + item = g_list_first(split_list); + while (NULL != item) { + char *word = (char*)item->data; + if (NULL != word && NULL == strstr(cmd_text, word)) { + break; + } + + item = item->next; + } + + free(cmd_text); + + if (NULL == item) { + if (0 == vc_cmd_list_add(ret_list, vc_cmd)) { + ret_cnt++; + } + } + + if (VC_ERROR_ITERATION_END == vc_cmd_list_next(list)) { + /* Move commands from list to ret_list */ + if (0 != vc_cmd_list_first(ret_list) || 0 != vc_cmd_list_get_current(ret_list, &vc_cmd)) { + break; + } + + while (NULL != vc_cmd) { + if (0 != vc_cmd_list_remove(list, vc_cmd)) { + break; + } + + if (0 != vc_cmd_list_next(ret_list)) { + break; + } + + if (0 != vc_cmd_list_get_current(ret_list, &vc_cmd)) { + break; + } + } + + break; + } + + vc_cmd_list_get_current(list, &vc_cmd); + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "Number of matched text : (%d)", ret_cnt); + + if (ret_cnt >= 1) { + return VC_ERROR_NONE; + } + + if (VC_SEARCH_WORD_LEVEL > search_level) { + SLOG(LOG_DEBUG, TAG_VCCMD, "Text matching ends by search level (%d)", search_level); + return VC_ERROR_NONE; + } + + return vc_search_word(list, search_level); +} + +int vc_search_word(vc_cmd_list_h list, int search_level) +{ + SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Partial Word level matching"); + vc_cmd_h vc_cmd = NULL; + vc_cmd_h ret_cmd = NULL; + int ret = VC_ERROR_NONE; + int max = -1; // This is also threshold value + + max = g_list_length(split_list) * VC_WORD_MATCHING_RATE; + + ret = vc_cmd_list_first(list); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to make list first (%d)", ret); + return ret; + } + ret = vc_cmd_list_get_current(list, &vc_cmd); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get voice command handle (%d)", ret); + return ret; + } + + while (NULL != vc_cmd) { + GList *item = NULL; + char *cmd_text = NULL; + int cnt = 0; + + if (0 != vc_cmd_get_command(vc_cmd, &cmd_text) || NULL == cmd_text) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get command"); + return VC_ERROR_OPERATION_FAILED; + } + + __tolower(cmd_text); + item = g_list_first(split_list); + while (NULL != item) { + char *word = (char*)item->data; + + if (NULL != word && NULL != strstr(cmd_text, word)) { + cnt++; + } + + item = item->next; + } + + free(cmd_text); + + SLOG(LOG_DEBUG, TAG_VCCMD, "The number of matched word in the text : (%d)", cnt); + if (cnt > max) { + ret_cmd = vc_cmd; + max = cnt; + } + + if (VC_ERROR_ITERATION_END == vc_cmd_list_next(list)) { + break; + } + + vc_cmd_list_get_current(list, &vc_cmd); + } + + if (NULL != ret_cmd) { + if (0 != vc_cmd_list_remove(list, ret_cmd)) { + return VC_ERROR_OPERATION_FAILED; + } + if (0 != vc_cmd_list_add(ret_list, ret_cmd)) { + return VC_ERROR_OPERATION_FAILED; + } + + ret_cnt++; + + return VC_ERROR_NONE; + } + + if (VC_SEARCH_CHAR_LEVEL > search_level) { + SLOG(LOG_DEBUG, TAG_VCCMD, "Text matching end by search level (%d)", search_level); + return VC_ERROR_NONE; + } + + return vc_search_char(list, search_level); +} + +/* check the behavior */ +int vc_search_char(vc_cmd_list_h list, int search_level) +{ + SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Partial Character level matching"); + vc_cmd_h vc_cmd = NULL; + vc_cmd_h ret_cmd = NULL; + int threshold = 0; + GList *item = NULL; + + int result_score = 2147483647; + + vc_cmd_list_first(list); + vc_cmd_list_get_current(list, &vc_cmd); + + while (NULL != vc_cmd) { + int score = 0; + char *split = NULL; + char *cmd_text = NULL; + char *tok_ptr = NULL; + + if (0 != vc_cmd_get_command(vc_cmd, &cmd_text) || NULL == cmd_text) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get command"); + return VC_ERROR_OPERATION_FAILED; + } + + __tolower(cmd_text); + item = g_list_first(split_list); + while (NULL != item) { + char *word = (char*)item->data; + int min_score = -1; + + if (NULL == word || 3 > strlen(word)) { + item = item->next; + continue; + } + + min_score = strlen(word) * VC_CHAR_MATCHING_RATE; // This is also threshold + + split = strtok_r(cmd_text, " ", &tok_ptr); + while (NULL != split) { + SLOG(LOG_DEBUG, TAG_VCCMD, "(%s)", split); + if (3 > strlen(split)) { + split = strtok_r(NULL, " ", &tok_ptr); + continue; + } + + char *long_str = NULL; + char *short_str = NULL; + + if (strlen(split) > strlen(word)) { + long_str = split; + short_str = word; + } else { + long_str = word; + short_str = split; + } + + int long_str_len = strlen(long_str); + int short_str_len = strlen(short_str); + + int *cost = (int*)calloc(long_str_len + 1, sizeof(int)); + int *ncost = (int*)calloc(long_str_len + 1, sizeof(int)); + + if (NULL == cost || NULL == ncost) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Out of memory"); + + free(cmd_text); + return VC_ERROR_OUT_OF_MEMORY; + } + + for (int l = 0; l <= long_str_len; l++) { + cost[l] = l; + } + + for (int s = 1; s <= short_str_len; s++) { + ncost[0] = s; + + for (int l = 1; l <= long_str_len; l++) { + int match = (short_str[s - 1] == long_str[l - 1] ? 0 : 1); + + int rep = cost[l - 1] + match; + int ins = cost[l] + 1; + int del = ncost[l - 1] + 1; + + int min = (rep < ins ? rep : ins); + ncost[l] = (min < del ? min : del); + } + + int *temp = cost; + cost = ncost; + ncost = temp; + } + + if (min_score > cost[long_str_len]) { + min_score = cost[long_str_len]; + } + + free(cost); + free(ncost); + + split = strtok_r(NULL, " ", &tok_ptr); + } + + if (min_score < strlen(word) * VC_CHAR_MATCHING_RATE) { + score = score + min_score; + } else { + score = score + strlen(word); + } + + item = item->next; + } + + free(cmd_text); + cmd_text = NULL; + + if (result_score > score) { + result_score = score; + ret_cmd = vc_cmd; + } + + if (VC_ERROR_ITERATION_END == vc_cmd_list_next(list)) { + break; + } + + vc_cmd_list_get_current(list, &vc_cmd); + } + + item = g_list_first(split_list); + while (NULL != item) { + char *word = (char*)item->data; + + if (NULL != word && 3 <= strlen(word)) { + threshold += strlen(word); + } + + item = item->next; + } + + if (threshold > result_score) { + vc_cmd_list_remove(list, ret_cmd); + vc_cmd_list_add(ret_list, ret_cmd); + ret_cnt++; + + return VC_ERROR_NONE; + } + + if (VC_SEARCH_PRON_LEVEL > search_level) { + SLOG(LOG_DEBUG, TAG_VCCMD, "Text matching ends by search level (%d)", search_level); + return VC_ERROR_NONE; + } + + return vc_search_pron(list, search_level); +} + +int vc_search_pron(vc_cmd_list_h list, int search_level) +{ + SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Partial Pronunciation level matching"); + return VC_ERROR_NONE; +} \ No newline at end of file diff --git a/common/vc_command_util.h b/common/vc_command_util.h new file mode 100644 index 0000000..a1a9e97 --- /dev/null +++ b/common/vc_command_util.h @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the License); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an AS IS BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __VOICE_CONTROL_COMMAND_UTIL_h_ +#define __VOICE_CONTROL_COMMAND_UTIL_h_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define VC_WORD_MATCHING_RATE 0.3 +#define VC_CHAR_MATCHING_RATE 0.25 + +int vc_search_text(vc_cmd_list_h list, int search_level); +int vc_search_word(vc_cmd_list_h list, int search_level); +int vc_search_char(vc_cmd_list_h list, int search_level); +int vc_search_pron(vc_cmd_list_h list, int search_level); + +#ifdef __cplusplus +} +#endif + +#endif /* __VOICE_CONTROL_COMMAND_UTIL_h_ */ diff --git a/include/voice_control_command_expand.h b/include/voice_control_command_expand.h index 62d83ad..a8627db 100755 --- a/include/voice_control_command_expand.h +++ b/include/voice_control_command_expand.h @@ -42,6 +42,11 @@ typedef enum { VC_CMD_FORMAT_PARTIAL /**< Partial matched command */ } vc_cmd_format_e; +#define VC_SEARCH_TEXT_LEVEL 1 +#define VC_SEARCH_WORD_LEVEL 2 +#define VC_SEARCH_CHAR_LEVEL 3 +#define VC_SEARCH_PRON_LEVEL 4 + /** * @brief Sets command domain * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif @@ -199,6 +204,27 @@ int vc_cmd_get_nlu_json(vc_cmd_h vc_cmd, char** json); */ int vc_cmd_get_datetime(const char *text, time_t *result, char **remain); +/** +* @brief Gets the commands list of commands similar to the text +* @since_tizen 4.0 +* +* @param[in] command The text to find the similar commands +* @param[in] src_list The command list handle of all registered foreground and widget type commands +* @param[out] dst_list The commands list handle to similar commands +* @param[in] search_level The search level selecting depth of algorithm +* +* @remark This function can modify @a src_list by the result, So if you want to keep the content of @a src_list, +* make a copy of @a src_list before running this function. And also, you need to create the list handle of +* @a dst_list before runnig this function, because this function does not create the handle internally. +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_OPERATION_FAILED operation failure +* @retval #VC_ERROR_OUT_OF_MEMORY Not enough memory +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +*/ +int vc_cmd_get_partially_matched_cmd_list(const char *command, vc_cmd_list_h src_list, vc_cmd_list_h dst_list, int search_level); + #ifdef __cplusplus } #endif diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index f9e8d48..0065863 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -1,5 +1,6 @@ SET(SRCS ../common/vc_cmd_db.c + ../common/vc_command_util.c ../common/vc_command.c ../common/vc_config_mgr.c ../common/vc_config_parser.c -- 2.7.4 From 5d5fb42816d67a08ec24473983ca6df2ce213256 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Tue, 4 Jul 2017 17:33:55 +0900 Subject: [PATCH 03/16] Apply text matching algorithm to daemon If there is only background type result or no result, daemon finds the similar commands list using text matchin alogrithm. The algorithm is only applied to foreground and widget type commands. Priority order of the command type on this patch : System and Exclusive > ASR result consumming > Foreground and Widget > Partial matched Commands(Foreground and Widget only) > System Background > Background Change-Id: I2eeb8c4cff06ce8b5de6f16a30a185d7ae71c11d Signed-off-by: Suyeon Hwang --- server/vcd_client_data.c | 62 ++++++++++++++ server/vcd_client_data.h | 2 + server/vcd_server.c | 214 +++++++++++++++++++++++++++++++---------------- 3 files changed, 206 insertions(+), 72 deletions(-) mode change 100755 => 100644 server/vcd_server.c diff --git a/server/vcd_client_data.c b/server/vcd_client_data.c index 505ab6f..4ae7bb3 100644 --- a/server/vcd_client_data.c +++ b/server/vcd_client_data.c @@ -22,6 +22,8 @@ #include "vcd_config.h" #include "vcd_main.h" +#include "voice_control_command_expand.h" + /* Client list */ static GSList* g_client_list = NULL; @@ -767,6 +769,66 @@ vcd_recognition_mode_e vcd_client_get_recognition_mode() return g_recognition_mode; } +int vcd_client_append_cmd_from_type(int type, vc_cmd_list_h list) +{ + GSList *item = NULL; + + if (NULL == list) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid list parameter"); + return VCD_ERROR_INVALID_PARAMETER; + } + + switch (type) { + case VC_COMMAND_TYPE_SYSTEM: + item = g_cur_cmd_list.system_cmds; + break; + case VC_COMMAND_TYPE_FOREGROUND: + item = g_cur_cmd_list.foreground_cmds; + break; + case VC_COMMAND_TYPE_WIDGET: + item = g_cur_cmd_list.widget_cmds; + break; + case VC_COMMAND_TYPE_SYSTEM_BACKGROUND: + item = g_cur_cmd_list.system_background_cmds; + break; + case VC_COMMAND_TYPE_BACKGROUND: + item = g_cur_cmd_list.background_cmds; + break; + case VC_COMMAND_TYPE_EXCLUSIVE: + item = g_cur_cmd_list.exclusive_system_cmds; + break; + default: + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid type parameter"); + return VCD_ERROR_INVALID_PARAMETER; + } + + while (NULL != item) { + vc_cmd_h temp_cmd = NULL; + vc_cmd_h target_cmd = (vc_cmd_h)item->data; + + temp_cmd = (vc_cmd_h)__command_copy((vc_cmd_s*)target_cmd); + + if (NULL == temp_cmd) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to copy the command"); + return VCD_ERROR_OUT_OF_MEMORY; + } + + if (0 != vc_cmd_list_add(list, temp_cmd)) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to add the command in the list"); + if (NULL != temp_cmd) { + vc_cmd_destroy(temp_cmd); + temp_cmd = NULL; + } + + return VCD_ERROR_OPERATION_FAILED; + } + + item = item->next; + } + + return 0; +} + int __show_client_list() { GSList *iter = NULL; diff --git a/server/vcd_client_data.h b/server/vcd_client_data.h index ae57883..3ee5f0d 100644 --- a/server/vcd_client_data.h +++ b/server/vcd_client_data.h @@ -96,6 +96,8 @@ int vcd_client_set_recognition_mode(vcd_recognition_mode_e mode); vcd_recognition_mode_e vcd_client_get_recognition_mode(); +int vcd_client_append_cmd_from_type(int type, vc_cmd_list_h list); + /* * Manager API */ diff --git a/server/vcd_server.c b/server/vcd_server.c old mode 100755 new mode 100644 index a525662..9c976a5 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -100,7 +100,8 @@ static Eina_Bool __restart_engine(void *data) SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Start engine"); - if (VCD_RECOGNITION_MODE_RESTART_AFTER_REJECT == vcd_client_get_recognition_mode()) { + vcd_recognition_mode_e mode = vcd_client_get_recognition_mode(); + if (VCD_RECOGNITION_MODE_RESTART_AFTER_REJECT == mode || VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY == mode) { vcd_config_set_service_state(VCD_STATE_RECORDING); vcdc_send_service_state(VCD_STATE_RECORDING); } @@ -466,9 +467,10 @@ static void* __recorder_stop(void *data) int vcd_send_result(vce_result_event_e event, int* result_id, int count, const char* all_result, const char* non_fixed_result, const char* nlu_result, const char* msg, int* user_info, void *user_data) { int ret = 0; + vcd_recognition_mode_e recognition_mode = vcd_client_get_recognition_mode(); if (VCD_STATE_PROCESSING != vcd_config_get_service_state()) { - if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY != vcd_client_get_recognition_mode()) { + if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY != recognition_mode) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not 'Processing' and mode is not 'Restart continuously'"); return VCD_ERROR_INVALID_STATE; } @@ -480,40 +482,8 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c SECURE_SLOG(LOG_INFO, TAG_VCD, "[Server] Event(%d), Text(%s) Nonfixed(%s) Msg(%s) Result count(%d)", event, all_result, non_fixed_result, msg, count); - SLOG(LOG_ERROR, TAG_VCD, "[Server] NLU result(%s)", nlu_result); + SECURE_SLOG(LOG_ERROR, TAG_VCD, "[Server] NLU result(%s)", nlu_result); - if (VCD_RECOGNITION_MODE_RESTART_AFTER_REJECT == vcd_client_get_recognition_mode()) { - if (VCE_RESULT_EVENT_REJECTED == event) { - SLOG(LOG_DEBUG, TAG_VCD, "[Server] Restart by no or rejected result"); - /* If no result and restart option is ON */ - /* Send reject message */ - bool temp = vcd_client_manager_get_exclusive(); - vc_info_parser_set_result(all_result, event, msg, NULL, temp); - ret = vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NOTIFICATION); - if (0 != ret) { - SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result"); - } - - g_restart_timer = ecore_timer_add(0, __restart_engine, NULL); - return ret; - } - SLOG(LOG_DEBUG, TAG_VCD, "[Server] Stop recorder due to success"); - //vcd_recorder_stop(); - ecore_main_loop_thread_safe_call_sync(__recorder_stop, NULL); - } else if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY == vcd_client_get_recognition_mode()) { - SLOG(LOG_DEBUG, TAG_VCD, "[Server] Restart continuously"); - /* Restart option is ON */ - g_restart_timer = ecore_timer_add(0, __restart_engine, NULL); - if (VCE_RESULT_EVENT_REJECTED == event) { - bool temp = vcd_client_manager_get_exclusive(); - vc_info_parser_set_result(all_result, event, msg, NULL, temp); - ret = vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NOTIFICATION); - if (0 != ret) { - SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result"); - } - return ret; - } - } #if 1 /* if nlu_result is exist, Add command handle(is_action) into result list */ /* Normal result */ @@ -523,7 +493,7 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c vc_cmd_list_h vc_cmd_list = NULL; if (0 != vc_cmd_list_create(&vc_cmd_list)) { - SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to create command list"); + SLOG(LOG_INFO, TAG_VCD, "[Server] Fail to create command list"); vcd_client_manager_set_exclusive(false); vcd_config_set_service_state(VCD_STATE_READY); vcdc_send_service_state(VCD_STATE_READY); @@ -536,6 +506,7 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c int* filtered_id = (int*)calloc(count, sizeof(int)); if (!filtered_id) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to allocate memory"); + vc_cmd_list_destroy(vc_cmd_list, true); return VCD_ERROR_OUT_OF_MEMORY; } int filtered_count = 0; @@ -597,6 +568,8 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c } } + // Set state manually, because the result is already handled in ASR result by client. + // So, the daemon does not need to send the result to client. vcd_client_manager_set_exclusive(false); vcd_config_set_service_state(VCD_STATE_READY); @@ -688,72 +661,170 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c int result_count = 0; vc_cmd_list_get_count(vc_cmd_list, &result_count); + /* Handle the result list */ if (0 == result_count) { /* No result */ if (NULL != all_result) { + vc_cmd_list_h fg_priority_cmd_list = NULL; SECURE_SLOG(LOG_DEBUG, TAG_VCD, "[Server] Engine result is no command : %s", all_result); + + if (0 != vc_cmd_list_create(&fg_priority_cmd_list)) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create command list handle"); + vc_cmd_list_destroy(vc_cmd_list, true); + return VCD_ERROR_OUT_OF_MEMORY; + } + + /* Get the list of foreground and widget type commands */ + vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_FOREGROUND, fg_priority_cmd_list); + vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_WIDGET, fg_priority_cmd_list); + + /* Matching algorithm */ + vc_cmd_get_partially_matched_cmd_list(all_result, fg_priority_cmd_list, vc_cmd_list, VC_SEARCH_CHAR_LEVEL); + + vc_cmd_list_destroy(fg_priority_cmd_list, true); } else { SLOG(LOG_DEBUG, TAG_VCD, "[Server] Engine result is NULL"); } - bool temp = vcd_client_manager_get_exclusive(); - vc_info_parser_set_result(all_result, event, msg, NULL, temp); - int pid = vcd_client_widget_get_foreground_pid(); - if (-1 != pid) { - SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide"); - /* Send to hide tooltip */ - vcdc_send_show_tooltip(pid, false); - } - - if (-1 != vcd_client_manager_get_pid()) { - /* Manager client is available */ - if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) { - SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result"); - } - } + vc_cmd_list_get_count(vc_cmd_list, &result_count); - vcd_client_manager_set_exclusive(false); + // After running partial matching algorithm, if there is no result. + if (0 == result_count) { + bool temp = vcd_client_manager_get_exclusive(); + vc_info_parser_set_result(all_result, event, msg, NULL, temp); - return VCD_ERROR_NONE; - } else { - if (false == vcd_client_manager_get_exclusive()) { int pid = vcd_client_widget_get_foreground_pid(); if (-1 != pid) { SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide"); + /* Send to hide tooltip */ vcdc_send_show_tooltip(pid, false); } - vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, false); - if (-1 != vcd_client_manager_get_pid()) { /* Manager client is available */ if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) { SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result"); } - } else { - SLOG(LOG_DEBUG, TAG_VCD, "[Server] Manager is NOT available. Send result to client directly"); - /* Send result to client */ - ecore_timer_add(0, __vcd_send_selected_result, NULL); } - } else { - /* exclusive command */ - vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, true); - if (-1 != vcd_client_manager_get_pid()) { - /* Manager client is available */ - if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) { - SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result"); + vcd_client_manager_set_exclusive(false); + vc_cmd_list_destroy(vc_cmd_list, true); + + return VCD_ERROR_NONE; + } + + // Partial matching algorithm find some commands + top_priority = VC_COMMAND_PRIORITY_FOREGROUND; + event = VC_RESULT_EVENT_RESULT_SUCCESS; + } + + // There are more than one result. + if (false == vcd_client_manager_get_exclusive()) { + /* Foreground, Widget, Background, System, System-Background */ + if (top_priority >= VC_COMMAND_PRIORITY_BACKGROUND) { + vc_cmd_list_h fg_priority_cmd_list = NULL; + vc_cmd_list_h temp_list = NULL; + + if (0 != vc_cmd_list_create(&fg_priority_cmd_list)) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create command list handle"); + vc_cmd_list_destroy(vc_cmd_list, true); + return VCD_ERROR_OUT_OF_MEMORY; + } + + if (0 != vc_cmd_list_create(&temp_list)) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create command list handle"); + vc_cmd_list_destroy(fg_priority_cmd_list, true); + vc_cmd_list_destroy(vc_cmd_list, true); + return VCD_ERROR_OUT_OF_MEMORY; + } + + /* Get the list of foreground and widget type commands */ + vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_FOREGROUND, fg_priority_cmd_list); + vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_WIDGET, fg_priority_cmd_list); + + /* Matching algorithm */ + vc_cmd_get_partially_matched_cmd_list(all_result, fg_priority_cmd_list, temp_list, VC_SEARCH_CHAR_LEVEL); + vc_cmd_list_destroy(fg_priority_cmd_list, true); + + vc_cmd_list_get_count(temp_list, &result_count); + + if (0 < result_count) { + if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) { + SLOG(LOG_WARN, TAG_VCD, "[WARNING] Fail to destroy list"); } - } else { - SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Manager is NOT available"); + vc_cmd_list = temp_list; + event = VC_RESULT_EVENT_RESULT_SUCCESS; } + } - vcd_client_manager_set_exclusive(false); + int pid = vcd_client_widget_get_foreground_pid(); + if (-1 != pid) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide"); + vcdc_send_show_tooltip(pid, false); + } + + vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, false); + + if (-1 != vcd_client_manager_get_pid()) { + /* Manager client is available */ + if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) { + SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result"); + } + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Manager is NOT available. Send result to client directly"); + ecore_timer_add(0, __vcd_send_selected_result, NULL); + } + } else { + /* exclusive command */ + vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, true); + + if (-1 != vcd_client_manager_get_pid()) { + /* Manager client is available */ + if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) { + SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result"); + } + } else { + SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Manager is NOT available"); } + + vcd_client_manager_set_exclusive(false); } vc_cmd_list_destroy(vc_cmd_list, true); + if (VCD_RECOGNITION_MODE_RESTART_AFTER_REJECT == recognition_mode) { + if (VCE_RESULT_EVENT_REJECTED == event) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Restart by no or rejected result"); + /* If no result and restart option is ON */ + /* Send reject message */ + bool temp = vcd_client_manager_get_exclusive(); + vc_info_parser_set_result(all_result, event, msg, NULL, temp); + ret = vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NOTIFICATION); + if (0 != ret) { + SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result"); + } + + g_restart_timer = ecore_timer_add(0, __restart_engine, NULL); + return ret; + } + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Stop recorder due to success"); + //vcd_recorder_stop(); + ecore_main_loop_thread_safe_call_sync(__recorder_stop, NULL); + } else if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY == recognition_mode) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Restart continuously"); + /* Restart option is ON */ + g_restart_timer = ecore_timer_add(0, __restart_engine, NULL); + if (VCE_RESULT_EVENT_REJECTED == event) { + bool temp = vcd_client_manager_get_exclusive(); + vc_info_parser_set_result(all_result, event, msg, NULL, temp); + ret = vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NOTIFICATION); + if (0 != ret) { + SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result"); + } + return ret; + } + } + return VCD_ERROR_NONE; #else @@ -2599,4 +2670,3 @@ int vcd_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_f return ret; } - -- 2.7.4 From dd410d47f6d7c835efe5b571e2333e92a4a231a4 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Thu, 22 Mar 2018 14:14:35 +0900 Subject: [PATCH 04/16] Delete dbus flush after dbus add match Change-Id: I47ce72a8c9ae5713b28ddf0992c1f134464640b0 Signed-off-by: sooyeon.kim --- client/vc_dbus.c | 2 -- client/vc_mgr_dbus.c | 2 -- client/vc_setting_dbus.c | 3 +-- client/vc_widget_dbus.c | 18 ++++++++---------- server/vcd_dbus.c | 1 - 5 files changed, 9 insertions(+), 17 deletions(-) diff --git a/client/vc_dbus.c b/client/vc_dbus.c index 7bc8cef..cab1bcb 100644 --- a/client/vc_dbus.c +++ b/client/vc_dbus.c @@ -277,7 +277,6 @@ int vc_dbus_open_connection() /* add a rule for which messages we want to see */ dbus_bus_add_match(g_conn_listener, rule, &err); - dbus_connection_flush(g_conn_listener); if (dbus_error_is_set(&err)) { SLOG(LOG_ERROR, TAG_VCC, "Match Error (%s)", err.message); @@ -289,7 +288,6 @@ int vc_dbus_open_connection() /* add a rule for daemon error */ snprintf(rule, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", VC_SERVER_SERVICE_INTERFACE); dbus_bus_add_match(g_conn_listener, rule, &err); - dbus_connection_flush(g_conn_listener); if (dbus_error_is_set(&err)) { SLOG(LOG_ERROR, TAG_VCC, "Match Error (%s)", err.message); diff --git a/client/vc_mgr_dbus.c b/client/vc_mgr_dbus.c index 4d182c3..2277fa9 100644 --- a/client/vc_mgr_dbus.c +++ b/client/vc_mgr_dbus.c @@ -675,7 +675,6 @@ int vc_mgr_dbus_open_connection() /* add a rule for which messages we want to see */ dbus_bus_add_match(g_m_conn_listener, rule, &err); - dbus_connection_flush(g_m_conn_listener); if (dbus_error_is_set(&err)) { SLOG(LOG_ERROR, TAG_VCM, "Match Error (%s)", err.message); @@ -913,7 +912,6 @@ int vc_mgr_dbus_request_initialize(int pid, int* service_state, int* foreground, char rule_err[256] = {0, }; snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", VC_SERVER_SERVICE_INTERFACE); dbus_bus_add_match(g_m_conn_listener, rule_err, &err); - dbus_connection_flush(g_m_conn_listener); if (dbus_error_is_set(&err)) { SLOG(LOG_ERROR, TAG_VCM, "Match Error (%s)", err.message); diff --git a/client/vc_setting_dbus.c b/client/vc_setting_dbus.c index 3da5868..1f88a64 100755 --- a/client/vc_setting_dbus.c +++ b/client/vc_setting_dbus.c @@ -183,7 +183,6 @@ int vc_setting_dbus_open_connection() /* add a rule for which messages we want to see */ dbus_bus_add_match(g_s_conn_listener, rule, &err); - dbus_connection_flush(g_s_conn_listener); if (dbus_error_is_set(&err)) { SLOG(LOG_ERROR, TAG_VCS, "Match Error (%s)", err.message); @@ -376,4 +375,4 @@ int vc_setting_dbus_request_set_language(int pid, const char* language) } return result; -} \ No newline at end of file +} diff --git a/client/vc_widget_dbus.c b/client/vc_widget_dbus.c index db68c92..6883ad0 100644 --- a/client/vc_widget_dbus.c +++ b/client/vc_widget_dbus.c @@ -270,7 +270,7 @@ static Eina_Bool widget_listener_event_callback(void* data, Ecore_Fd_Handler *fd return ECORE_CALLBACK_PASS_ON; } -static void __vc_mgr_dbus_connection_free() +static void __vc_widget_dbus_connection_free() { if (NULL != g_w_conn_listener) { dbus_connection_close(g_w_conn_listener); @@ -321,7 +321,7 @@ int vc_widget_dbus_open_connection() if (NULL == g_w_conn_listener) { SLOG(LOG_ERROR, TAG_VCW, "Fail to get dbus connection "); - __vc_mgr_dbus_connection_free(); + __vc_widget_dbus_connection_free(); return VC_ERROR_OPERATION_FAILED; } @@ -345,13 +345,13 @@ int vc_widget_dbus_open_connection() if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { SLOG(LOG_ERROR, TAG_VCW, "fail dbus_bus_request_name()"); - __vc_mgr_dbus_connection_free(); + __vc_widget_dbus_connection_free(); return -2; } if (NULL != g_w_fd_handler) { SLOG(LOG_WARN, TAG_VCW, "The handler already exists."); - __vc_mgr_dbus_connection_free(); + __vc_widget_dbus_connection_free(); return 0; } @@ -360,19 +360,18 @@ int vc_widget_dbus_open_connection() /* add a rule for which messages we want to see */ dbus_bus_add_match(g_w_conn_listener, rule, &err); - dbus_connection_flush(g_w_conn_listener); if (dbus_error_is_set(&err)) { SLOG(LOG_ERROR, TAG_VCW, "Match Error (%s)", err.message); dbus_error_free(&err); - __vc_mgr_dbus_connection_free(); + __vc_widget_dbus_connection_free(); return VC_ERROR_OPERATION_FAILED; } int fd = 0; if (1 != dbus_connection_get_unix_fd(g_w_conn_listener, &fd)) { SLOG(LOG_ERROR, TAG_VCW, "fail to get fd from dbus "); - __vc_mgr_dbus_connection_free(); + __vc_widget_dbus_connection_free(); return VC_ERROR_OPERATION_FAILED; } else { SLOG(LOG_DEBUG, TAG_VCW, "Get fd from dbus : %d", fd); @@ -382,7 +381,7 @@ int vc_widget_dbus_open_connection() if (NULL == g_w_fd_handler) { SLOG(LOG_ERROR, TAG_VCW, "fail to get fd handler from ecore "); - __vc_mgr_dbus_connection_free(); + __vc_widget_dbus_connection_free(); return VC_ERROR_OPERATION_FAILED; } @@ -414,7 +413,7 @@ int vc_widget_dbus_close_connection() } } - __vc_mgr_dbus_connection_free(); + __vc_widget_dbus_connection_free(); return 0; } @@ -571,7 +570,6 @@ int vc_widget_dbus_request_initialize(int pid, int* service_state, int* daemon_p char rule_err[256] = {0, }; snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", VC_SERVER_SERVICE_INTERFACE); dbus_bus_add_match(g_w_conn_listener, rule_err, &err); - dbus_connection_flush(g_w_conn_listener); if (dbus_error_is_set(&err)) { SLOG(LOG_ERROR, TAG_VCW, "Match Error (%s)", err.message); diff --git a/server/vcd_dbus.c b/server/vcd_dbus.c index fec9af1..5d37055 100755 --- a/server/vcd_dbus.c +++ b/server/vcd_dbus.c @@ -1107,7 +1107,6 @@ int vcd_dbus_open_connection() /* add a rule for which messages we want to see */ dbus_bus_add_match(g_conn_listener, rule, &err);/* see signals from the given interface */ - dbus_connection_flush(g_conn_listener); if (dbus_error_is_set(&err)) { SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] dbus_bus_add_match() : %s", err.message); -- 2.7.4 From 552942cc911bb6c952128abf5c6070be15b4b18e Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Mon, 26 Mar 2018 22:20:46 +0900 Subject: [PATCH 05/16] Add document and Fix get_command_count in VCE Change-Id: Iefbfa6591d09ee1dd3644355cc630b3bdc154a2b Signed-off-by: sooyeon.kim --- doc/uix_vc_engine_main_doc.h | 215 +++++++++++++++++++++++++++++++++++++++++++ include/vce.h | 210 ++++++++++++++++++++++++------------------ server/vce.c | 2 +- 3 files changed, 337 insertions(+), 90 deletions(-) create mode 100644 doc/uix_vc_engine_main_doc.h mode change 100755 => 100644 include/vce.h mode change 100755 => 100644 server/vce.c diff --git a/doc/uix_vc_engine_main_doc.h b/doc/uix_vc_engine_main_doc.h new file mode 100644 index 0000000..6c01165 --- /dev/null +++ b/doc/uix_vc_engine_main_doc.h @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2011-2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __TIZEN_UIX_VOICE_CONTROL_ENGINE_DOC_H__ +#define __TIZEN_UIX_VOICE_CONTROL_ENGINE_DOC_H__ + + +/** + * @ingroup CAPI_UIX_FRAMEWORK + * @defgroup CAPI_UIX_VOICE_CONTROL_ENGINE_MODULE Voice control engine + * @brief The @ref CAPI_UIX_VOICE_CONTROL_ENGINE_MODULE APIs provide functions to operate Voice-Control Engine. + * @section CAPI_UIX_VOICE_CONTROL_ENGINE_MODULE_HEADER Required Header + * \#include
+ * + * @section CAPI_UIX_VOICE_CONTROL_ENGINE_OVERVIEW Overview + * Voice-Control-Engine (below VCE) is an engine for recognize the sound data recorded by the user and send the result as a predefined command. + * Using the @ref CAPI_UIX_VOICE_CONTROL_ENGINE_MODULE APIs, VCE developers can provide VCE service users, who want to apply VCE, with functions necessary to operate the engine. + * According to the indispensability of VCE services, there are two ways to provide them to the users.
+ * + * A. Required VCE services
+ * These services are indispensable to operate VCE. Therefore, the VCE developers MUST implement callback functions corresponding to the required VCE services. + * The following is a list of the callback functions.
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
vce_get_info_cb()Called when the engine service user requests the basic information of VCE.
vce_get_recording_format_cb()Called when the engine service user requests the recording format of VCE.
vce_foreach_supported_languages_cb()Called when the engine service user retrieves all supported languages of VC engine.
vce_is_language_supported_cb()Called when the engine service user retrieves all supported languages of VCE.
vce_initialize_cb()Called when the engine service user initializes VCE.
vce_deinitialize_cb()Called when the engine service user deinitializes VCE.
vce_set_language_cb()Called when the engine service user sets language.
vce_set_commands_cb()Called when the engine service user sets command list before recognition.
vce_unset_commands_cb()Called when the engine service user unsets command list for reset.
vce_start_cb()Called when the engine service user starts recognition.
vce_set_recording_data_cb()Called when the engine service user sets recording data for speech recognition from recorder.
vce_stop_cb()Called when the engine service user stops to get the result of recognition.
vce_cancel_cb()Called when the engine service user cancels the recognition process.
vce_set_audio_type_cb()Called when the engine service user sets audio recording type.
vce_set_domain_cb()Called when the engine service user sets domain (agent or device type).
vce_process_text_cb()Called when the engine service user requests process text.
vce_process_list_event_cb()Called when the engine service user requests list event.
vce_process_haptic_event_cb()Called when the engine service user requests haptic event.
+ * + * The VCE developers can register the above callback functions at a time with using a structure 'vce_request_callback_s' and an API 'vce_main()'. + * To operate VCE, the following steps should be used:
+ * 1. Create a structure 'vce_request_callback_s' + * 2. Implement callback functions. (NOTE that the callback functions should return appropriate values in accordance with the instruction. + * If the callback function returns an unstated value, VCE framework will handle it as #VCE_ERROR_OPERATION_FAILED.)
+ * 3. Register callback functions using 'vce_main()'. (The registered callback functions will be invoked when the VCE service users request the VCE services.)
+ * 4. Use 'service_app_main()' for working VCE.
+ * + * B. Optional VCE services
+ * Unlike the required VCE services, these services are optional to operate VCE. The followings are optional VCE services.
+ * - receive/provide the private data
+ * + * If the VCE developers want to provide the above services, use the following APIs and implement the corresponding callback functions:
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
FUNCTIONDESCRIPTIONCORRESPONDING CALLBACK
vce_set_private_data_set_cb()Sets a callback function for setting the private data to the engine service.vce_private_data_set_cb()
vce_set_private_data_requested_cb()Sets a callback function for requesting the private data to the engine service.vce_private_data_requested_cb()
vce_set_nlu_base_info_requested_cb()Sets a callback function for requesting the NLU base information to the engine service.vce_nlu_base_info_requested_cb()
+ * + * Using the above APIs, the VCE developers can register the optional callback functions respectively. + * (For normal operation, put those APIs before 'service_app_main()' starts.) + * + * Unlike callback functions, the following APIs are functions for getting and sending data. The VCE developers can use these APIs when they implement VCE services:
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
FUNCTIONDESCRIPTION
vce_send_result()Sends the results to the engine service user.
vce_send_asr_result()Sends the ASR result to the engine service user.
vce_send_nlg_result()Sends the NLG (Natural Language Generation) result to the engine service user.
vce_send_error()Sends the error to the engine service user.
vce_get_foreach_command()Retrieves all commands using callback function.
vce_get_command_count()Gets command length.
vce_get_audio_type()Gets current audio type.
vce_set_private_data()Sets private data to a voice manager client.
vce_get_private_data()Gets private data from a voice manager client.
vce_start_recording()Starts recording voice.
vce_stop_recording()Stops recording voice.
+ * + * @section CAPI_UIX_VOICE_CONTROL_ENGINE_MODULE_FEATURES Related Features + * This API is related with the following features:
+ * - http://tizen.org/feature/microphone
+ * - http://tizen.org/feature/speech.control
+ * It is recommended to design feature related codes in your application for reliability.
+ * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.
+ * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.
+ * More details on featuring your application can be found from Feature Element. + */ + +#endif /* __TIZEN_UIX_VOICE_CONTROL_ENGINE_DOC_H__ */ + diff --git a/include/vce.h b/include/vce.h old mode 100755 new mode 100644 index 3d0946a..9c60993 --- a/include/vce.h +++ b/include/vce.h @@ -39,7 +39,8 @@ typedef enum { VCE_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< I/O error */ VCE_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER,/**< Invalid parameter */ VCE_ERROR_OUT_OF_NETWORK = TIZEN_ERROR_NETWORK_DOWN, /**< Out of network */ - VCE_ERROR_RECORDER_BUSY = TIZEN_ERROR_RESOURCE_BUSY,/**< Busy resource */ + VCE_ERROR_RECORDER_BUSY = TIZEN_ERROR_RESOURCE_BUSY,/**< Busy resource */ + VCE_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< VC Engine NOT supported */ VCE_ERROR_INVALID_STATE = TIZEN_ERROR_VOICE_CONTROL | 0x011, /**< Invalid state */ VCE_ERROR_INVALID_LANGUAGE = TIZEN_ERROR_VOICE_CONTROL | 0x012, /**< Invalid language */ VCE_ERROR_OPERATION_FAILED = TIZEN_ERROR_VOICE_CONTROL | 0x014, /**< Operation failed */ @@ -62,8 +63,8 @@ typedef enum { */ typedef enum { VCE_RESULT_EVENT_SUCCESS = 0, /**< Event when the recognition full result is ready */ - VCE_RESULT_EVENT_REJECTED, /**< Event when the recognition result is rejected */ - VCE_RESULT_EVENT_ERROR /**< Event when the recognition has failed */ + VCE_RESULT_EVENT_REJECTED, /**< Event when the recognition result is rejected */ + VCE_RESULT_EVENT_ERROR /**< Event when the recognition has failed */ } vce_result_event_e; /** @@ -171,10 +172,10 @@ typedef int vce_cmd_h; * @details This callback function is implemented by the engine service user. Therefore, the engine developer does NOT have to implement this callback function. * @since_tizen 5.0 * @remarks This callback function is called by vce_foreach_supported_languages_cb() to retrieve the whole supported language list. -* @a user_data must be transferred from vce_foreach_supported_languages_cb(). -* @param[in] language A language is specified as an ISO 3166 alpha-2 two letter country-code -* followed by ISO 639-1 for the two-letter language code \n -* For example, "ko_KR" for Korean, "en_US" for American English +* The @a user_data must be transferred from vce_foreach_supported_languages_cb(). +* The @a language can be used only in the callback. To use outside, make a copy. +* @param[in] language A language is specified as an ISO 3166 alpha-2 two letter country-code followed by ISO 639-1 for the two-letter language code \n +* For example, "ko_KR" for Korean, "en_US" for American English. * @param[in] user_data The user data passed from the foreach function * @return @c true to continue with the next iteration of the loop \n @c false to break out of the loop * @pre vce_foreach_supported_languages() will invoke this callback. @@ -183,7 +184,7 @@ typedef int vce_cmd_h; typedef bool (*vce_supported_language_cb)(const char* language, void* user_data); /** -* @brief Called when the engine service user initializes VC engine. +* @brief Called when the engine service user initializes Voice Control (VC) engine. * @since_tizen 5.0 * @remarks This callback function is mandatory and must be registered using vce_main(). * @return 0 on success, otherwise a negative error value @@ -210,7 +211,8 @@ typedef int (*vce_deinitialize_cb)(void); * @brief Called when the engine service user requests the recording format of VC engine. * @since_tizen 5.0 * @remarks This callback function is mandatory and must be registered using vce_main(). -* @param[out] audio_id The audio device id. (e.g. #VCE_AUDIO_ID_BLUETOOTH or VCE_AUDIO_ID_WIFI) +* The @a audio_id can be used only in the callback. To use outside, make a copy. +* @param[in] audio_id The audio device id. (e.g. #VCE_AUDIO_ID_BLUETOOTH or #VCE_AUDIO_ID_WIFI) * @param[out] types The format used by the recorder. * @param[out] rate The sample rate used by the recorder. * @param[out] channels The number of channels used by the recorder. @@ -218,7 +220,7 @@ typedef int (*vce_deinitialize_cb)(void); * @retval #VCE_ERROR_NONE Successful * @retval #VCE_ERROR_INVALID_PARAMETER Not initialized */ -typedef int (*vce_get_recording_format_cb)(const char* audio_id, const vce_audio_type_e* types, const int* rate, const int* channels); +typedef int (*vce_get_recording_format_cb)(const char* audio_id, vce_audio_type_e* types, int* rate, int* channels); /** * @brief Called when the engine service user retrieves all supported languages of VC engine. @@ -240,7 +242,8 @@ typedef int (*vce_foreach_supported_languages_cb)(vce_supported_language_cb call * @brief Called when the engine service user checks whether a language is supported or not. * @since_tizen 5.0 * @remarks This callback function is mandatory and must be registered using vce_main(). -* @param[out] language A language +* The @a language can be used only in the callback. To use outside, make a copy. +* @param[in] language A language * @return @c true = supported, \n @c false = not supported. */ typedef bool (*vce_is_language_supported_cb)(const char* language); @@ -248,11 +251,13 @@ typedef bool (*vce_is_language_supported_cb)(const char* language); /** * @brief Called when the engine service user sets language. * @since_tizen 5.0 +* @remarks The @a language can be used only in the callback. To use outside, make a copy. * @param[in] language A language. * @return 0 on success, otherwise a negative error value * @retval #VCE_ERROR_NONE Successful * @retval #VCE_ERROR_INVALID_LANGUAGE Invalid language * @retval #VCE_ERROR_INVALID_STATE Not initialized +* @retval #VCE_ERROR_NOT_SUPPORTED_FEATURE Not supported feature */ typedef int (*vce_set_language_cb)(const char* language); @@ -260,7 +265,7 @@ typedef int (*vce_set_language_cb)(const char* language); * @brief Called when the engine service user sets command list before recognition. * @since_tizen 5.0 * @remarks This function should set commands via vcd_foreach_command(). -* @param[in] vc_command command handle. +* @param[in] vc_command command handle. The @a vc_command can be used only in the callback. To use outside, make a copy. * @return 0 on success, otherwise a negative error value * @retval #VCE_ERROR_NONE Successful * @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter @@ -283,6 +288,7 @@ typedef int (*vce_set_commands_cb)(vce_cmd_h vc_command); * @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VCE_ERROR_INVALID_STATE Invalid state * @retval #VCE_ERROR_OPERATION_FAILED Operation failed +* @retval #VCE_ERROR_NOT_SUPPORTED_FEATURE Not supported feature * @see vce_set_commands_cb() */ typedef int (*vce_unset_commands_cb)(void); @@ -312,9 +318,10 @@ typedef int (*vce_start_cb)(bool stop_by_silence); * @brief Called when the engine service user sets recording data for speech recognition from recorder. * @since_tizen 5.0 * @remarks This function should be returned immediately after recording data copy. -* @param[out] data A recording data -* @param[out] length A length of recording data -* @param[in] speech_detected The status of speech (e.g. VCE_SPEECH_DETECT_BEGIN or VCE_SPEECH_DETECT_END) +* The @a data can be used only in the callback. To use outside, make a copy. +* @param[in] data A recording data +* @param[in] length A length of recording data +* @param[out] speech_detected The status of speech (e.g. #VCE_SPEECH_DETECT_BEGIN or #VCE_SPEECH_DETECT_END). The @a speech_detected can be used only in the callback. To use outside, make a copy. * @return 0 on success, otherwise a negative error value * @retval #VCE_ERROR_NONE Successful * @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter @@ -358,70 +365,91 @@ typedef int (*vce_cancel_cb)(void); /** * @brief Called when the engine service user sets audio recording type. * @since_tizen 5.0 -* @param[in] audio Available agent or device type +* @remarks The @a audio can be used only in the callback. To use outside, make a copy. +* @param[in] audio_type Current audio type (e.g. #VCE_AUDIO_ID_BLUETOOTH or #VCE_AUDIO_ID_WIFI) * @return 0 on success, otherwise a negative error value. * @retval #VCE_ERROR_NONE Successful. +* @retval #VCE_ERROR_NOT_SUPPORTED_FEATURE Not supported feature. */ -typedef int (*vce_set_audio_type_cb)(const char* audio); +typedef int (*vce_set_audio_type_cb)(const char* audio_type); /** -* @brief Called when the engine service user sets domain (Agent or device type). +* @brief Called when the engine service user sets domain (agent or device type). * @since_tizen 5.0 -* @param[in] domain Available agent or device type +* @remarks The @a domain can be used only in the callback. To use outside, make a copy. +* @param[in] domain Agent (e.g. "music", "news", etc) or device type (e.g. "tv", "mobile", etc) corresponding to the command * @return 0 on success, otherwise a negative error value. * @retval #VCE_ERROR_NONE Successful. +* @retval #VCE_ERROR_NOT_SUPPORTED_FEATURE Not supported feature */ typedef int (*vce_set_domain_cb)(const char* domain); /** -* @brief Called when the engine service user requests essential value from nlu result. +* @brief Called when the engine service user requests essential value from NLU result. * @since_tizen 5.0 -* @remarks This function is available inside vce_nlu_result_cb() -* @param[in] key NLU base info key -* @param[out] value NLU base info value +* @remarks The @a key can be used only in the callback. To use outside, make a copy. +* @param[in] key NLU base info key. +* @param[out] value NLU base info value. * @return 0 on success, otherwise a negative error value. +* @retval #VCE_ERROR_NONE Successful. +* @retval #VCE_ERROR_NOT_SUPPORTED_FEATURE Not supported feature. */ typedef int (*vce_nlu_base_info_requested_cb)(const char* key, char** value); /** * @brief Called when the engine service user sets private data between app and engine. * @since_tizen 5.0 -* @param[in] key Private key -* @param[in] data Private data +* @remarks The @a key, @a data can be used only in the callback. To use outside, make a copy. +* @param[in] key Private key. +* @param[in] data Private data. * @return 0 on success, otherwise a negative error value. +* @retval #VCE_ERROR_NONE Successful. +* @retval #VCE_ERROR_NOT_SUPPORTED_FEATURE Not supported feature. */ typedef int (*vce_private_data_set_cb)(const char* key, const char* data); /** * @brief Called when the engine service user requests private data between app and engine. * @since_tizen 5.0 -* @param[in] key Private key -* @param[out] data Private data +* @remarks The @a key can be used only in the callback. To use outside, make a copy. +* @param[in] key Private key. +* @param[out] data Private data. * @return 0 on success, otherwise a negative error value. +* @retval #VCE_ERROR_NONE Successful. +* @retval #VCE_ERROR_NOT_SUPPORTED_FEATURE Not supported feature. */ typedef int (*vce_private_data_requested_cb)(const char* key, char** data); /** * @brief Called when the engine service user requests process text. * @since_tizen 5.0 +* @remarks The @a text can be used only in the callback. To use outside, make a copy. * @param[in] text Requested text * @return 0 on success, otherwise a negative error value. +* @retval #VCE_ERROR_NONE Successful. +* @retval #VCE_ERROR_NOT_SUPPORTED_FEATURE Not supported feature. */ typedef int (*vce_process_text_cb)(const char* text); /** * @brief Called when the engine service user requests list event. * @since_tizen 5.0 +* @remarks The @a event can be used only in the callback. To use outside, make a copy. * @param[in] event Requested list event * @return 0 on success, otherwise a negative error value. +* @retval #VCE_ERROR_NONE Successful. +* @retval #VCE_ERROR_NOT_SUPPORTED_FEATURE Not supported feature. */ typedef int (*vce_process_list_event_cb)(const char* event); /** * @brief Called when the engine service user requests haptic event. * @since_tizen 5.0 +* @remarks The @a event can be used only in the callback. To use outside, make a copy. * @param[in] event Requested haptic event * @return 0 on success, otherwise a negative error value. +* @retval #VCE_ERROR_NONE Successful. +* @retval #VCE_ERROR_NOT_SUPPORTED_FEATURE Not supported feature. */ typedef int (*vce_process_haptic_event_cb)(const char* event); @@ -429,24 +457,25 @@ typedef int (*vce_process_haptic_event_cb)(const char* event); * @brief Called when the engine service user requests the base information of VC engine. * @since_tizen 5.0 * @remarks This callback function is mandatory and must be registered using vce_main(). -* The allocated @a engine_uuid, @a engine_name, and @a engine_setting will be released internally. -* In order to upload the engine at Tizen Appstore, both a service app and a ui app are necessary. -* Therefore, @a engine_setting must be transferred to the engine service user. +* The allocated @a engine_uuid, @a engine_name, and @a engine_settings_app_id will be released internally. +* In order to upload the engine to Tizen Appstore, both the service app and the UI app (engine settings) are necessary. +* Therefore, @a engine_settings_app_id should be set to the application ID of the UI application. +* If there is no UI application, then @a engine_settings_app_id should be set to NULL. * @param[out] engine_uuid The engine id * @param[out] engine_name The engine name -* @param[out] engine_setting The setting path name +* @param[out] engine_settings_app_id The ID of the engine settings application (the UI application) * @param[out] use_network @c true to need network @c false not to need network. -* @return @c 0 on success, -* otherwise a negative error code on failure +* @return @c 0 on success, otherwise a negative error code on failure * @retval #VCE_ERROR_NONE Successful * @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VCE_ERROR_OPERATION_FAILED Operation failure */ -typedef int (*vce_get_info_cb)(char** engine_uuid, char** engine_name, char** engine_setting, bool* use_network); +typedef int (*vce_get_info_cb)(char** engine_uuid, char** engine_name, char** engine_settings_app_id, bool* use_network); /** * @brief Called to retrieve the commands. * @since_tizen 5.0 +* @remarks The @a command, @a param can be used only in the callback. To use outside, make a copy. * @param[in] id command id * @param[in] type command type * @param[in] format command format @@ -471,31 +500,31 @@ typedef struct { int version; /**< Version */ /* Get engine information */ - vce_get_info_cb get_info; /**< Called when the engine service user requests the basic information of VC engine */ - vce_get_recording_format_cb get_recording_format; /**< Get recording format */ - vce_foreach_supported_languages_cb foreach_langs; /**< Foreach language list */ - vce_is_language_supported_cb is_lang_supported; /**< Check language */ + vce_get_info_cb get_info; /**< Called when the engine service user requests the basic information of VC engine */ + vce_get_recording_format_cb get_recording_format; /**< Get recording format */ + vce_foreach_supported_languages_cb foreach_langs; /**< Foreach language list */ + vce_is_language_supported_cb is_lang_supported; /**< Check language */ - vce_initialize_cb initialize; /**< Initialize engine */ - vce_deinitialize_cb deinitialize; /**< Shutdown engine */ + vce_initialize_cb initialize; /**< Initialize engine */ + vce_deinitialize_cb deinitialize; /**< Shutdown engine */ /* Set info */ - vce_set_language_cb set_language; /**< Set language */ - vce_set_commands_cb set_commands; /**< Request to set current commands */ - vce_unset_commands_cb unset_commands; /**< Request to unset current commands */ + vce_set_language_cb set_language; /**< Set language */ + vce_set_commands_cb set_commands; /**< Request to set current commands */ + vce_unset_commands_cb unset_commands; /**< Request to unset current commands */ /* Control recognition */ - vce_start_cb start; /**< Start recognition */ - vce_set_recording_data_cb set_recording; /**< Set recording data */ - vce_stop_cb stop; /**< Stop recording for getting result */ - vce_cancel_cb cancel; /**< Cancel recording and processing */ + vce_start_cb start; /**< Start recognition */ + vce_set_recording_data_cb set_recording; /**< Set recording data */ + vce_stop_cb stop; /**< Stop recording for getting result */ + vce_cancel_cb cancel; /**< Cancel recording and processing */ - vce_set_audio_type_cb set_audio_type; /**< Set audio type */ + vce_set_audio_type_cb set_audio_type; /**< Set audio type */ - vce_set_domain_cb set_domain; /**< Set domain */ - vce_process_text_cb process_text; /**< Request to process text */ - vce_process_list_event_cb process_list_event; /**< Request to process list event */ - vce_process_haptic_event_cb process_haptic_event; /**< Request to process haptic event */ + vce_set_domain_cb set_domain; /**< Set domain */ + vce_process_text_cb process_text; /**< Request to process text */ + vce_process_list_event_cb process_list_event; /**< Request to process list event */ + vce_process_haptic_event_cb process_haptic_event; /**< Request to process haptic event */ } vce_request_callback_s; /** @@ -508,8 +537,7 @@ typedef struct { * @param[in] argc The argument count(original) * @param[in] argv The argument(original) * @param[in] callback The structure of engine request callback function -* @return This function returns @c zero on success, -* or negative with error code on failure +* @return This function returns @c zero on success, or negative with error code on failure * @retval #VCE_ERROR_NONE Successful * @retval #VCE_ERROR_OUT_OF_MEMORY Out of Memory * @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter @@ -517,7 +545,6 @@ typedef struct { * @retval #VCE_ERROR_NOT_SUPPORTED Not supported * @retval #VCE_ERROR_OPERATION_FAILED Operation failed * @pre The vce_get_engine_info() should be successful. -* @post The daemon calls engine functions of vce_funcs_s. * @see vce_get_engine_info() * @see vce_unload_engine() * @see vce_request_callback_s @@ -623,8 +650,7 @@ int vce_main(int argc, char** argv, vce_request_callback_s* callback); * @param[in] msg Engine message (e.g. #VC_RESULT_MESSAGE_NONE, #VC_RESULT_MESSAGE_ERROR_TOO_LOUD) * @param[out] user_info A user info (e.g. If ASR result is consumed, the value is 0x01. If not, the value is 0x00.) * @param[in] user_data The user data passed from set callback function -* @return @c 0 on success, -* otherwise a negative error value +* @return @c 0 on success, otherwise a negative error value * @retval #VCE_ERROR_NONE Successful * @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VCE_ERROR_OUT_OF_MEMORY Out of Memory @@ -642,8 +668,7 @@ int vce_send_result(vce_result_event_e event, int* result_id, int count, const c * @param[in] event A asr result event * @param[in] asr_result A asr result text * @param[in] user_data The user data passed from the start -* @return @c 0 on success, -* otherwise a negative error value +* @return @c 0 on success, otherwise a negative error value * @retval #VCE_ERROR_NONE Successful * @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VCE_ERROR_OUT_OF_MEMORY Out of Memory @@ -654,12 +679,11 @@ int vce_send_result(vce_result_event_e event, int* result_id, int count, const c int vce_send_asr_result(vce_asr_result_event_e event, const char* asr_result, void* user_data); /** -* @brief Sends the nlg(natural language generation) result to the engine service user. +* @brief Sends the NLG (Natural Language Generation) result to the engine service user. * @since_tizen 5.0 * @param[in] nlg_result A nlg result * @param[in] user_data The user data passed from the start -* @return @c 0 on success, -* otherwise a negative error value +* @return @c 0 on success, otherwise a negative error value * @retval #VCE_ERROR_NONE Successful * @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VCE_ERROR_OUT_OF_MEMORY Out of Memory @@ -671,24 +695,24 @@ int vce_send_nlg_result(const char* nlg_result, void* user_data); /** * @brief Sends the error to the engine service user. -* @details The following error codes can be delivered. -* #VCE_ERROR_NONE, -* #VCE_ERROR_OUT_OF_MEMORY, -* #VCE_ERROR_IO_ERROR, -* #VCE_ERROR_INVALID_PARAMETER, -* #VCE_ERROR_OUT_OF_NETWORK, -* #VCE_ERROR_RECORDER_BUSY, -* #VCE_ERROR_INVALID_STATE, -* #VCE_ERROR_INVALID_LANGUAGE, -* #VCE_ERROR_OPERATION_FAILED, -* #VCE_ERROR_PERMISSION_DENIED, -* #VCE_ERROR_NOT_SUPPORTED_FEATURE. +* @details The following error codes can be delivered. \n +* #VCE_ERROR_NONE, \n +* #VCE_ERROR_OUT_OF_MEMORY, \n +* #VCE_ERROR_IO_ERROR, \n +* #VCE_ERROR_INVALID_PARAMETER, \n +* #VCE_ERROR_OUT_OF_NETWORK, \n +* #VCE_ERROR_RECORDER_BUSY, \n +* #VCE_ERROR_NOT_SUPPORTED, \n +* #VCE_ERROR_INVALID_STATE, \n +* #VCE_ERROR_INVALID_LANGUAGE, \n +* #VCE_ERROR_OPERATION_FAILED, \n +* #VCE_ERROR_PERMISSION_DENIED, \n +* #VCE_ERROR_NOT_SUPPORTED_FEATURE. * @since_tizen 5.0 * @param[in] error Error type * @param[in] msg Error message * @param[in] user_data The user data passed from set callback function -* @return @c 0 on success, -* otherwise a negative error value +* @return @c 0 on success, otherwise a negative error value * @retval #VCE_ERROR_NONE Successful * @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VCE_ERROR_OUT_OF_MEMORY Out of Memory @@ -704,13 +728,13 @@ int vce_send_error(vce_error_e error, const char* msg, void* user_data); * @privilege %http://tizen.org/privilege/recorder * @remarks The vce_private_data_set_cb() function is called when the engine service user sets the private data to the engine service. * @param[in] callback_func vce_private_data_set event callback function -* @return @c 0 on success, -* otherwise a negative error value +* @return @c 0 on success, otherwise a negative error value * @retval #VCE_ERROR_NONE Successful * @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VCE_ERROR_PERMISSION_DENIED Permission denied * @retval #VCE_ERROR_NOT_SUPPORTED Not supported * @retval #VCE_ERROR_OPERATION_FAILED Operation failure +* @retval #VCE_ERROR_NOT_SUPPORTED_FEATURE Not supported feature * @pre The vce_main() function should be invoked before this function is called. * @see vce_private_data_set_cb() */ @@ -723,8 +747,7 @@ int vce_set_private_data_set_cb(vce_private_data_set_cb callback_func); * @privilege %http://tizen.org/privilege/recorder * @remarks The vce_private_data_requested_cb() function is called when the engine service user requests the private data to the engine service. * @param[in] callback_func vce_private_data_requested event callback function -* @return @c 0 on success, -* otherwise a negative error value +* @return @c 0 on success, otherwise a negative error value * @retval #VCE_ERROR_NONE Successful * @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VCE_ERROR_PERMISSION_DENIED Permission denied @@ -739,11 +762,11 @@ int vce_set_private_data_requested_cb(vce_private_data_requested_cb callback_fun * @since_tizen 5.0 * @remarks The vce_nlu_base_info_requested_cb() function is called when the engine service user requests the NLU base information to the engine service. * @param[in] callback_func vce_nlu_base_info_requested event callback function -* @return @c 0 on success, -* otherwise a negative error value +* @return @c 0 on success, otherwise a negative error value * @retval #VCE_ERROR_NONE Successful * @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VCE_ERROR_OPERATION_FAILED Operation failure +* @retval #VCE_ERROR_NOT_SUPPORTED_FEATURE Not supported feature * @see vce_nlu_base_info_requested_cb() */ int vce_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func); @@ -769,24 +792,32 @@ int vce_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void * @brief Gets command length. * @since_tizen 5.0 * @param[in] vce_command The handle to be passed to the vce_set_commands() function -* @return the value greater than 0 on success +* @param[out] count The command count value +* @return 0 on success, otherwise a negative error value. +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VCE_ERROR_OPERATION_FAILED Operation failure * @see vce_set_commands() */ -int vce_get_command_count(vce_cmd_h vce_command); +int vce_get_command_count(vce_cmd_h vce_command, int* count); /** * @brief Gets current audio type. * @since_tizen 5.0 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder * @remarks audio_type must be released using free() when it is no longer required. -* @param[in] audio_type Current audio type (e.g. #VCE_AUDIO_ID_BLUETOOTH or VCE_AUDIO_ID_WIFI) +* @param[in] audio_type Current audio type (e.g. #VCE_AUDIO_ID_BLUETOOTH or #VCE_AUDIO_ID_WIFI) * @return the value greater than 0 on success, otherwise a negative error value * @retval #VCE_ERROR_NONE Successful * @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VCE_ERROR_PERMISSION_DENIED Permission denied +* @retval #VCE_ERROR_NOT_SUPPORTED Not supported */ int vce_get_audio_type(char** audio_type); /** -* @brief Sets private data to Manager client. +* @brief Sets private data to a voice manager client. * @since_tizen 5.0 * @privlevel public * @privilege %http://tizen.org/privilege/recorder @@ -804,10 +835,11 @@ int vce_get_audio_type(char** audio_type); int vce_set_private_data(const char* key, const char* data); /** -* @brief Gets private data from Manager client. +* @brief Gets private data from a voice manager client. * @since_tizen 5.0 * @privlevel public * @privilege %http://tizen.org/privilege/recorder +* @remarks The @a data should not be released. * @param[in] key Private key * @param[out] data Private data * @return 0 on success, otherwise a negative error value. @@ -822,7 +854,7 @@ int vce_set_private_data(const char* key, const char* data); int vce_get_private_data(const char* key, char** data); /** -* @brief Request start recording. +* @brief Starts recording voice. * @since_tizen 5.0 * @privlevel public * @privilege %http://tizen.org/privilege/recorder @@ -836,7 +868,7 @@ int vce_get_private_data(const char* key, char** data); int vce_start_recording(void); /** -* @brief Request stop recording. +* @brief Stops recording voice. * @since_tizen 5.0 * @privlevel public * @privilege %http://tizen.org/privilege/recorder diff --git a/server/vce.c b/server/vce.c old mode 100755 new mode 100644 index b7fb585..ea9fb76 --- a/server/vce.c +++ b/server/vce.c @@ -144,7 +144,7 @@ int vce_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void return ret; } -int vce_get_command_count(vce_cmd_h vce_command) +int vce_get_command_count(vce_cmd_h vce_command, int* count) { int ret = VCE_ERROR_NONE; -- 2.7.4 From be6a95fd225aa8b0421b1f3775010b74d6aef9e7 Mon Sep 17 00:00:00 2001 From: sungrae jo Date: Tue, 27 Mar 2018 10:48:23 +0900 Subject: [PATCH 06/16] Fixed vce_get_command_count Change-Id: I8f6c75a8bf2ec034e8790ecb19ca3cccd8f3128f Signed-off-by: sungrae jo --- server/vcd_engine_agent.c | 5 +++-- server/vcd_engine_agent.h | 2 +- server/vcd_server.c | 6 +++--- server/vcd_server.h | 2 +- server/vce.c | 6 +++++- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/server/vcd_engine_agent.c b/server/vcd_engine_agent.c index cd861bc..6c9dd57 100644 --- a/server/vcd_engine_agent.c +++ b/server/vcd_engine_agent.c @@ -725,11 +725,12 @@ int vcd_engine_agent_get_foreach_command(vce_cmd_h vce_command, vce_command_cb c return vcd_client_foreach_command((client_foreach_command_cb)callback, user_data); } -int vcd_engine_agent_get_command_count(vce_cmd_h vce_command) +int vcd_engine_agent_get_command_count(vce_cmd_h vce_command, int* count) { SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request command length from engine"); - return vcd_client_get_length(); + *count = vcd_client_get_length(); + return 0; } int vcd_engine_agent_get_audio_type(char** audio_type) diff --git a/server/vcd_engine_agent.h b/server/vcd_engine_agent.h index 4fa59d8..a327584 100644 --- a/server/vcd_engine_agent.h +++ b/server/vcd_engine_agent.h @@ -83,7 +83,7 @@ int vcd_engine_process_haptic_event(int pid, const char* event); /* for engine service */ int vcd_engine_agent_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void* user_data); -int vcd_engine_agent_get_command_count(vce_cmd_h vce_command); +int vcd_engine_agent_get_command_count(vce_cmd_h vce_command, int* count); int vcd_engine_agent_get_audio_type(char** audio_type); diff --git a/server/vcd_server.c b/server/vcd_server.c index 9c976a5..3157967 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -2542,13 +2542,13 @@ int vcd_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void return ret; } -int vcd_get_command_count(vce_cmd_h vce_command) +int vcd_get_command_count(vce_cmd_h vce_command, int* count) { SLOG(LOG_DEBUG, TAG_VCD, "[Server] Get command count"); int ret = 0; - ret = vcd_engine_agent_get_command_count(vce_command); - if (0 > ret) { + ret = vcd_engine_agent_get_command_count(vce_command, count); + if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get command count : ret(%d)", ret); } diff --git a/server/vcd_server.h b/server/vcd_server.h index 6df0154..70bc3d9 100644 --- a/server/vcd_server.h +++ b/server/vcd_server.h @@ -139,7 +139,7 @@ int vcd_send_error(vce_error_e error, const char* msg, void *user_data); int vcd_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void* user_data); -int vcd_get_command_count(vce_cmd_h vce_command); +int vcd_get_command_count(vce_cmd_h vce_command, int* count); int vcd_get_audio_type(char** audio_type); diff --git a/server/vce.c b/server/vce.c index ea9fb76..078b241 100644 --- a/server/vce.c +++ b/server/vce.c @@ -148,7 +148,11 @@ int vce_get_command_count(vce_cmd_h vce_command, int* count) { int ret = VCE_ERROR_NONE; - ret = vcd_get_command_count(vce_command); + if (NULL == count) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter"); + return VCE_ERROR_INVALID_PARAMETER; + } + ret = vcd_get_command_count(vce_command, count); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get command count"); } -- 2.7.4 From 5c7ef94d3350c8b3be41534904c867b6f44107e1 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Mon, 26 Mar 2018 18:34:31 +0900 Subject: [PATCH 07/16] Add partial matching algorithm when no result is Change-Id: I530abd69563212655ee63d3615113a86f6e467d9 Signed-off-by: Wonnam Jang --- server/vcd_server.c | 123 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 91 insertions(+), 32 deletions(-) diff --git a/server/vcd_server.c b/server/vcd_server.c index 9c976a5..94fec30 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -501,7 +501,7 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c } /* priority filter */ - /* system > exclusive > widget > foreground > system_background > background */ + /* system > exclusive > widget > foreground > system_background > widget partial > foreground paritial > background */ int i = 0; int* filtered_id = (int*)calloc(count, sizeof(int)); if (!filtered_id) { @@ -664,24 +664,52 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c /* Handle the result list */ if (0 == result_count) { /* No result */ + vc_cmd_list_h widget_cmd_list = NULL; + vc_cmd_list_h foreground_cmd_list = NULL; if (NULL != all_result) { - vc_cmd_list_h fg_priority_cmd_list = NULL; SECURE_SLOG(LOG_DEBUG, TAG_VCD, "[Server] Engine result is no command : %s", all_result); + int cnt = 0; - if (0 != vc_cmd_list_create(&fg_priority_cmd_list)) { - SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create command list handle"); + if (0 != vc_cmd_list_create(&widget_cmd_list)) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create widget command list handle"); vc_cmd_list_destroy(vc_cmd_list, true); return VCD_ERROR_OUT_OF_MEMORY; } - /* Get the list of foreground and widget type commands */ - vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_FOREGROUND, fg_priority_cmd_list); - vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_WIDGET, fg_priority_cmd_list); - - /* Matching algorithm */ - vc_cmd_get_partially_matched_cmd_list(all_result, fg_priority_cmd_list, vc_cmd_list, VC_SEARCH_CHAR_LEVEL); + /* Get the list of widget type commands */ + vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_WIDGET, widget_cmd_list); + vc_cmd_list_get_count(widget_cmd_list, &cnt); + if (0 < cnt) { + /* Matched with widget command partially */ + vc_cmd_get_partially_matched_cmd_list(all_result, widget_cmd_list, vc_cmd_list, VC_SEARCH_CHAR_LEVEL); + vc_cmd_list_get_count(vc_cmd_list, &cnt); + if (0 < cnt) { + top_priority = VC_COMMAND_PRIORITY_WIDGET; + SLOG(LOG_INFO, TAG_VCD, "[INFO] Partially matched widget command"); + } + } else { + if (0 != vc_cmd_list_create(&foreground_cmd_list)) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create foreground command list handle"); + vc_cmd_list_destroy(vc_cmd_list, true); + vc_cmd_list_destroy(widget_cmd_list, true); + return VCD_ERROR_OUT_OF_MEMORY; + } - vc_cmd_list_destroy(fg_priority_cmd_list, true); + /* Get the list of foreground type commands */ + vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_FOREGROUND, foreground_cmd_list); + vc_cmd_list_get_count(foreground_cmd_list, &cnt); + if (0 < cnt) { + /* Matched with foreground command partially */ + vc_cmd_get_partially_matched_cmd_list(all_result, foreground_cmd_list, vc_cmd_list, VC_SEARCH_CHAR_LEVEL); + vc_cmd_list_get_count(vc_cmd_list, &cnt); + if (0 < cnt) { + top_priority = VC_COMMAND_PRIORITY_FOREGROUND; + SLOG(LOG_INFO, TAG_VCD, "[INFO] Partially matched foreground command"); + } + } + vc_cmd_list_destroy(foreground_cmd_list, true); + } + vc_cmd_list_destroy(widget_cmd_list, true); } else { SLOG(LOG_DEBUG, TAG_VCD, "[Server] Engine result is NULL"); } @@ -690,6 +718,8 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c // After running partial matching algorithm, if there is no result. if (0 == result_count) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] No commands even after partial matching"); + bool temp = vcd_client_manager_get_exclusive(); vc_info_parser_set_result(all_result, event, msg, NULL, temp); @@ -714,7 +744,6 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c } // Partial matching algorithm find some commands - top_priority = VC_COMMAND_PRIORITY_FOREGROUND; event = VC_RESULT_EVENT_RESULT_SUCCESS; } @@ -722,39 +751,69 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c if (false == vcd_client_manager_get_exclusive()) { /* Foreground, Widget, Background, System, System-Background */ if (top_priority >= VC_COMMAND_PRIORITY_BACKGROUND) { - vc_cmd_list_h fg_priority_cmd_list = NULL; + vc_cmd_list_h widget_cmd_list = NULL; + vc_cmd_list_h foreground_cmd_list = NULL; vc_cmd_list_h temp_list = NULL; + int cnt = 0; - if (0 != vc_cmd_list_create(&fg_priority_cmd_list)) { - SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create command list handle"); + if (0 != vc_cmd_list_create(&temp_list)) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create widget command list handle"); vc_cmd_list_destroy(vc_cmd_list, true); return VCD_ERROR_OUT_OF_MEMORY; } - if (0 != vc_cmd_list_create(&temp_list)) { - SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create command list handle"); - vc_cmd_list_destroy(fg_priority_cmd_list, true); + if (0 != vc_cmd_list_create(&widget_cmd_list)) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create widget command list handle"); vc_cmd_list_destroy(vc_cmd_list, true); + vc_cmd_list_destroy(temp_list, true); return VCD_ERROR_OUT_OF_MEMORY; } - /* Get the list of foreground and widget type commands */ - vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_FOREGROUND, fg_priority_cmd_list); - vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_WIDGET, fg_priority_cmd_list); - - /* Matching algorithm */ - vc_cmd_get_partially_matched_cmd_list(all_result, fg_priority_cmd_list, temp_list, VC_SEARCH_CHAR_LEVEL); - vc_cmd_list_destroy(fg_priority_cmd_list, true); - - vc_cmd_list_get_count(temp_list, &result_count); + /* Get the list of widget type commands */ + vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_WIDGET, widget_cmd_list); + vc_cmd_list_get_count(widget_cmd_list, &cnt); + if (0 < cnt) { + /* Matched with widget command partially */ + vc_cmd_get_partially_matched_cmd_list(all_result, widget_cmd_list, temp_list, VC_SEARCH_CHAR_LEVEL); + vc_cmd_list_get_count(temp_list, &cnt); + if (0 < cnt) { + if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) { + SLOG(LOG_WARN, TAG_VCD, "[WARNING] Fail to destroy list"); + } + vc_cmd_list = temp_list; + top_priority = VC_COMMAND_PRIORITY_WIDGET; + event = VC_RESULT_EVENT_RESULT_SUCCESS; + SLOG(LOG_INFO, TAG_VCD, "[INFO] Partially matched widget command when background cmd exists"); + } + } else { + if (0 != vc_cmd_list_create(&foreground_cmd_list)) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create foreground command list handle"); + vc_cmd_list_destroy(vc_cmd_list, true); + vc_cmd_list_destroy(widget_cmd_list, true); + return VCD_ERROR_OUT_OF_MEMORY; + } - if (0 < result_count) { - if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) { - SLOG(LOG_WARN, TAG_VCD, "[WARNING] Fail to destroy list"); + /* Get the list of foreground type commands */ + vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_FOREGROUND, foreground_cmd_list); + vc_cmd_list_get_count(foreground_cmd_list, &cnt); + if (0 < cnt) { + /* Matched with foreground command partially */ + vc_cmd_get_partially_matched_cmd_list(all_result, foreground_cmd_list, temp_list, VC_SEARCH_CHAR_LEVEL); + vc_cmd_list_get_count(temp_list, &cnt); + if (0 < cnt) { + if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) { + SLOG(LOG_WARN, TAG_VCD, "[WARNING] Fail to destroy list"); + } + vc_cmd_list = temp_list; + top_priority = VC_COMMAND_PRIORITY_FOREGROUND; + event = VC_RESULT_EVENT_RESULT_SUCCESS; + SLOG(LOG_INFO, TAG_VCD, "[INFO] Partially matched foreground command when background cmd exists"); + } } - vc_cmd_list = temp_list; - event = VC_RESULT_EVENT_RESULT_SUCCESS; + vc_cmd_list_destroy(foreground_cmd_list, true); } + vc_cmd_list_destroy(widget_cmd_list, true); + vc_cmd_list_destroy(temp_list, true); } int pid = vcd_client_widget_get_foreground_pid(); -- 2.7.4 From 54b7bd8277e3da61e5bad02bfd8b8c1c69ce83db Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Tue, 27 Mar 2018 16:36:44 +0900 Subject: [PATCH 08/16] Remove duplicated group closure Change-Id: I59f632eb6d9ac6ba1e28dc1376e0a7352e00fc7c Signed-off-by: Wonnam Jang --- include/vce.h | 2 +- include/voice_control.h | 2 +- include/voice_control_authority.h | 2 +- include/voice_control_command.h | 2 +- include/voice_control_command_expand.h | 2 +- include/voice_control_common.h | 2 +- include/voice_control_internal.h | 2 +- include/voice_control_key_defines.h | 2 +- include/voice_control_manager.h | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/vce.h b/include/vce.h index 9c60993..f798a04 100644 --- a/include/vce.h +++ b/include/vce.h @@ -885,7 +885,7 @@ int vce_stop_recording(void); #endif /** -* @}@} +* @} */ #endif /* __VCE_H__ */ diff --git a/include/voice_control.h b/include/voice_control.h index 154dce9..9dfe6e0 100644 --- a/include/voice_control.h +++ b/include/voice_control.h @@ -569,7 +569,7 @@ int vc_unset_error_cb(void); #endif /** - * @}@} + * @} */ #endif /* __VOICE_CONTROL_H__ */ diff --git a/include/voice_control_authority.h b/include/voice_control_authority.h index a704c51..88a16d1 100644 --- a/include/voice_control_authority.h +++ b/include/voice_control_authority.h @@ -182,7 +182,7 @@ int vc_auth_cancel(); #endif /** - * @}@} + * @} */ #endif /* __VOICE_CONTROL_AUTHORITY_H__ */ diff --git a/include/voice_control_command.h b/include/voice_control_command.h index da7045e..06b899a 100644 --- a/include/voice_control_command.h +++ b/include/voice_control_command.h @@ -443,7 +443,7 @@ int vc_cmd_get_format(vc_cmd_h vc_command, int* format); /** - * @}@} + * @} */ diff --git a/include/voice_control_command_expand.h b/include/voice_control_command_expand.h index a8627db..7947fa5 100755 --- a/include/voice_control_command_expand.h +++ b/include/voice_control_command_expand.h @@ -230,7 +230,7 @@ int vc_cmd_get_partially_matched_cmd_list(const char *command, vc_cmd_list_h src #endif /** - * @}@} + * @} */ #endif /* __VOICE_CONTROL_COMMAND_EXPAND_H__ */ diff --git a/include/voice_control_common.h b/include/voice_control_common.h index 42e0ef0..b979562 100644 --- a/include/voice_control_common.h +++ b/include/voice_control_common.h @@ -177,7 +177,7 @@ typedef void (*vc_error_cb)(vc_error_e reason, void *user_data); /** - * @}@} + * @} */ #endif /* VOICE_CONTROL_COMMON */ diff --git a/include/voice_control_internal.h b/include/voice_control_internal.h index cc5b4ad..b653ca9 100644 --- a/include/voice_control_internal.h +++ b/include/voice_control_internal.h @@ -92,7 +92,7 @@ int vc_prepare_sync(void); #endif /** - * @}@} + * @} */ #endif /* __VOICE_CONTROL_INTERNAL_H__ */ diff --git a/include/voice_control_key_defines.h b/include/voice_control_key_defines.h index 8a0382a..520d77e 100644 --- a/include/voice_control_key_defines.h +++ b/include/voice_control_key_defines.h @@ -124,7 +124,7 @@ extern "C" #endif /** - * @}@} + * @} */ #endif /* __VOICE_CONTROL_KEY_DEFINES_H__ */ diff --git a/include/voice_control_manager.h b/include/voice_control_manager.h index eb0055b..3d6d294 100644 --- a/include/voice_control_manager.h +++ b/include/voice_control_manager.h @@ -1103,7 +1103,7 @@ int vc_mgr_unset_private_data_requested_cb(); #endif /** - * @}@} + * @} */ #endif /* __VOICE_CONTROL_MANAGER_H__ */ -- 2.7.4 From ea07f2969c15515f5f33152139236c7ccd067178 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Fri, 30 Mar 2018 15:41:18 +0900 Subject: [PATCH 09/16] Fix minor error Change-Id: I6c36ad79efd524038c313034c5de0dbfbf583f13 Signed-off-by: sooyeon.kim --- client/vc_client.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/vc_client.c b/client/vc_client.c index cb7be34..515c9c1 100644 --- a/client/vc_client.c +++ b/client/vc_client.c @@ -494,10 +494,10 @@ int vc_client_set_invocation_name(vc_h vc, const char* invocation_name) if (NULL == client) return VC_ERROR_INVALID_PARAMETER; - if (NULL != client->invocation_name) + if (NULL != client->invocation_name) { free(client->invocation_name); - - client->invocation_name = NULL; + client->invocation_name = NULL; + } if (NULL != invocation_name) { client->invocation_name = strdup(invocation_name); -- 2.7.4 From 83aa03e8b0da99bb20f5765254b6b257609f8ac4 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Wed, 4 Apr 2018 15:00:20 +0900 Subject: [PATCH 10/16] Check passed parameter if null is or not Change-Id: I3d442d7f230bb875d3a04af72080564375ae702c Signed-off-by: Wonnam Jang --- client/vc_mgr.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/client/vc_mgr.c b/client/vc_mgr.c index c092648..9610204 100644 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -599,6 +599,11 @@ int vc_mgr_is_command_format_supported(vc_cmd_format_e format, bool* support) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Is command type supported"); + if (NULL == support) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter, support is NULL ptr"); + return VC_ERROR_INVALID_PARAMETER; + } + vc_state_e state; if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available"); @@ -632,6 +637,11 @@ int vc_mgr_enable_command_type(int cmd_type) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Enable Command Type, cmd_type(%d)", cmd_type); + if (VC_COMMAND_TYPE_FOREGROUND > cmd_type || VC_COMMAND_TYPE_EXCLUSIVE < cmd_type) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] cmd type is not valid, (%d)", cmd_type); + return VC_ERROR_INVALID_PARAMETER; + } + vc_state_e state; if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available"); @@ -684,6 +694,11 @@ int vc_mgr_disable_command_type(int cmd_type) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Disable Command Type, cmd_type(%d)", cmd_type); + if (VC_COMMAND_TYPE_FOREGROUND > cmd_type || VC_COMMAND_TYPE_EXCLUSIVE < cmd_type) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] cmd type is not valid, (%d)", cmd_type); + return VC_ERROR_INVALID_PARAMETER; + } + vc_state_e state; if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available"); @@ -880,8 +895,8 @@ int vc_mgr_set_command_list_from_file(const char* file_path, int type) /* check type */ if (VC_COMMAND_TYPE_FOREGROUND > type || VC_COMMAND_TYPE_EXCLUSIVE < type) { - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid command type: input type is %d", type); - SLOG(LOG_DEBUG, TAG_VCC, "@@@"); + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid command type: input type is %d", type); + SLOG(LOG_DEBUG, TAG_VCM, "@@@"); return VC_ERROR_INVALID_PARAMETER; } @@ -942,6 +957,13 @@ int vc_mgr_set_preloaded_commands_from_file(const char* file_path) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Set preloaded command list"); + if (NULL == file_path) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter, file_path is NULL ptr"); + return VC_ERROR_INVALID_PARAMETER; + } else { + SLOG(LOG_ERROR, TAG_VCM, "@@@ File path: %s", file_path); + } + vc_state_e state; if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available"); @@ -1334,6 +1356,11 @@ int vc_mgr_get_recognition_mode(vc_recognition_mode_e* mode) { int ret = -1; + if (NULL == mode) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter, mode is NULL ptr"); + return VC_ERROR_INVALID_PARAMETER; + } + ret = vc_mgr_client_get_recognition_mode(g_vc_m, mode); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get recognition mode"); -- 2.7.4 From 07a0a11c7f5ff60ec7e43696bbf5448df6476886 Mon Sep 17 00:00:00 2001 From: sungrae jo Date: Tue, 10 Apr 2018 19:50:44 +0900 Subject: [PATCH 11/16] Add invaild parameter check logic Change-Id: I371e84d349d1f8e186ec4aefc709c1bd1deca35a Signed-off-by: sungrae jo --- server/vce.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/server/vce.c b/server/vce.c index 078b241..593a471 100644 --- a/server/vce.c +++ b/server/vce.c @@ -62,6 +62,11 @@ int vce_send_result(vce_result_event_e event, int* result_id, int count, const c { int ret = VCE_ERROR_NONE; + if (event < VCE_RESULT_EVENT_SUCCESS || event > VCE_RESULT_EVENT_ERROR) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter"); + return VCE_ERROR_INVALID_PARAMETER; + } + if (NULL == all_result || NULL == non_fixed_result || NULL == nlu_result) { SLOG(LOG_ERROR, TAG_VCD, "[INFO] Input parameter is NULL. (no result)"); } @@ -81,6 +86,11 @@ int vce_send_asr_result(vce_asr_result_event_e event, const char* asr_result, vo { int ret = VCE_ERROR_NONE; + if (event < VCE_ASR_RESULT_EVENT_FINAL_RESULT || event > VCE_ASR_RESULT_EVENT_ERROR) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter"); + return VCE_ERROR_INVALID_PARAMETER; + } + if (NULL == asr_result) { SLOG(LOG_ERROR, TAG_VCD, "[INFO] Input parameter is NULL. (no result)"); } @@ -176,6 +186,11 @@ int vce_set_private_data(const char* key, const char* data) { int ret = VCE_ERROR_NONE; + if (NULL == key || NULL == data) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter"); + return VCE_ERROR_INVALID_PARAMETER; + } + ret = vcd_set_private_data(key, data); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set private data to vc manager"); @@ -188,6 +203,11 @@ int vce_get_private_data(const char* key, char** data) { int ret = VCE_ERROR_NONE; + if (NULL == key || NULL == data) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter"); + return VCE_ERROR_INVALID_PARAMETER; + } + ret = vcd_get_private_data(key, data); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get private data from vc manager"); -- 2.7.4 From 16dab0bd55b7d4fe74ef58a0f62ba0264e14039b Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Thu, 12 Apr 2018 20:27:49 +0900 Subject: [PATCH 12/16] Correct to check return of fread Change-Id: I2be0a615a5a5052f56c1c4958f9575033c952b38 Signed-off-by: Wonnam Jang --- client/vc.c | 2 +- common/vc_command.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/vc.c b/client/vc.c index 9cfc04b..b3c9b24 100644 --- a/client/vc.c +++ b/client/vc.c @@ -110,7 +110,7 @@ static int __check_privilege(const char* uid, const char * privilege) fp = fopen(label_path, "r"); if (fp != NULL) { - if (strlen(smack_label) != fread(smack_label, 1, sizeof(smack_label), fp)) + if (0 >= fread(smack_label, 1, sizeof(smack_label), fp)) SLOG(LOG_ERROR, TAG_VCC, "[ERROR] fail to fread"); fclose(fp); diff --git a/common/vc_command.c b/common/vc_command.c index 77e363b..282f9a4 100644 --- a/common/vc_command.c +++ b/common/vc_command.c @@ -102,7 +102,7 @@ static int __check_privilege(const char* uid, const char * privilege) fp = fopen(label_path, "r"); if (fp != NULL) { - if (sizeof(smack_label) != fread(smack_label, 1, sizeof(smack_label), fp)) + if (0 >= fread(smack_label, 1, sizeof(smack_label), fp)) SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] fail to fread"); fclose(fp); -- 2.7.4 From f97d96877af0661419996011aa2bd16d7824252c Mon Sep 17 00:00:00 2001 From: sungrae jo Date: Thu, 12 Apr 2018 19:52:20 +0900 Subject: [PATCH 13/16] Add privilege and feature check of vce Change-Id: I29726e6ed771b8541c433c2ecd98115cff746ffd Signed-off-by: sungrae jo --- server/vce.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) diff --git a/server/vce.c b/server/vce.c index 593a471..cbb21fa 100644 --- a/server/vce.c +++ b/server/vce.c @@ -15,15 +15,131 @@ */ +#include +#include +#include +#include #include "vcd_dbus.h" #include "vcd_main.h" #include "vcd_server.h" #include "vce.h" +static int g_feature_enabled = -1; +static int g_privilege_allowed = -1; +static cynara *p_cynara = NULL; + +static int __vce_get_feature_enabled() +{ + if (0 == g_feature_enabled) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Voice control feature NOT supported"); + return VCE_ERROR_NOT_SUPPORTED; + } else if (-1 == g_feature_enabled) { + bool vc_supported = false; + bool mic_supported = false; + if (0 == system_info_get_platform_bool(VC_FEATURE_PATH, &vc_supported)) { + if (0 == system_info_get_platform_bool(VC_MIC_FEATURE_PATH, &mic_supported)) { + if (false == vc_supported || false == mic_supported) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Voice control feature NOT supported"); + g_feature_enabled = 0; + return VCE_ERROR_NOT_SUPPORTED; + } + + g_feature_enabled = 1; + } else { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get feature value"); + return VCE_ERROR_NOT_SUPPORTED; + } + } else { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get feature value"); + return VCE_ERROR_NOT_SUPPORTED; + } + } + + return 0; +} + +static int __check_privilege_initialize() +{ + int ret = cynara_initialize(&p_cynara, NULL); + if (CYNARA_API_SUCCESS != ret) + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] fail to initialize"); + + return ret == CYNARA_API_SUCCESS; +} + +static int __check_privilege(const char* uid, const char * privilege) +{ + FILE *fp = NULL; + char label_path[1024] = "/proc/self/attr/current"; + char smack_label[1024] = {'\0',}; + + if (!p_cynara) { + return false; + } + + fp = fopen(label_path, "r"); + if (fp != NULL) { + if (0 >= fread(smack_label, 1, sizeof(smack_label), fp)) + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] fail to fread"); + + fclose(fp); + } + + pid_t pid = getpid(); + char *session = cynara_session_from_pid(pid); + int ret = cynara_check(p_cynara, smack_label, session, uid, privilege); + SLOG(LOG_DEBUG, TAG_VCD, "[Client]cynara_check returned %d(%s)", ret, (CYNARA_API_ACCESS_ALLOWED == ret) ? "Allowed" : "Denied"); + if (session) + free(session); + + if (ret != CYNARA_API_ACCESS_ALLOWED) + return false; + return true; +} + +static void __check_privilege_deinitialize() +{ + if (p_cynara) + cynara_finish(p_cynara); + p_cynara = NULL; +} + +static int __vce_check_privilege() +{ + char uid[16]; + + if (0 == g_privilege_allowed) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Permission is denied"); + return VCE_ERROR_PERMISSION_DENIED; + } else if (-1 == g_privilege_allowed) { + if (false == __check_privilege_initialize()) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] privilege initialize is failed"); + return VCE_ERROR_PERMISSION_DENIED; + } + snprintf(uid, 16, "%d", getuid()); + if (false == __check_privilege(uid, VC_PRIVILEGE)) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Permission is denied"); + g_privilege_allowed = 0; + __check_privilege_deinitialize(); + return VCE_ERROR_PERMISSION_DENIED; + } + __check_privilege_deinitialize(); + } + + g_privilege_allowed = 1; + return VCE_ERROR_NONE; +} int vce_main(int argc, char** argv, vce_request_callback_s *callback) { + if (0 != __vce_get_feature_enabled()) { + return VCE_ERROR_NOT_SUPPORTED; + } + if (0 != __vce_check_privilege()) { + return VCE_ERROR_PERMISSION_DENIED; + } + SLOG(LOG_DEBUG, TAG_VCD, " "); SLOG(LOG_DEBUG, TAG_VCD, " "); SLOG(LOG_DEBUG, TAG_VCD, "===== VC Engine Service Initialize"); @@ -172,6 +288,13 @@ int vce_get_command_count(vce_cmd_h vce_command, int* count) int vce_get_audio_type(char** audio_type) { + if (0 != __vce_get_feature_enabled()) { + return VCE_ERROR_NOT_SUPPORTED; + } + if (0 != __vce_check_privilege()) { + return VCE_ERROR_PERMISSION_DENIED; + } + int ret = VCE_ERROR_NONE; ret = vcd_get_audio_type(audio_type); @@ -184,6 +307,13 @@ int vce_get_audio_type(char** audio_type) int vce_set_private_data(const char* key, const char* data) { + if (0 != __vce_get_feature_enabled()) { + return VCE_ERROR_NOT_SUPPORTED; + } + if (0 != __vce_check_privilege()) { + return VCE_ERROR_PERMISSION_DENIED; + } + int ret = VCE_ERROR_NONE; if (NULL == key || NULL == data) { @@ -201,6 +331,13 @@ int vce_set_private_data(const char* key, const char* data) int vce_get_private_data(const char* key, char** data) { + if (0 != __vce_get_feature_enabled()) { + return VCE_ERROR_NOT_SUPPORTED; + } + if (0 != __vce_check_privilege()) { + return VCE_ERROR_PERMISSION_DENIED; + } + int ret = VCE_ERROR_NONE; if (NULL == key || NULL == data) { @@ -218,6 +355,13 @@ int vce_get_private_data(const char* key, char** data) int vce_start_recording() { + if (0 != __vce_get_feature_enabled()) { + return VCE_ERROR_NOT_SUPPORTED; + } + if (0 != __vce_check_privilege()) { + return VCE_ERROR_PERMISSION_DENIED; + } + int ret = VCE_ERROR_NONE; ret = vcd_start_recording(); @@ -230,6 +374,13 @@ int vce_start_recording() int vce_stop_recording() { + if (0 != __vce_get_feature_enabled()) { + return VCE_ERROR_NOT_SUPPORTED; + } + if (0 != __vce_check_privilege()) { + return VCE_ERROR_PERMISSION_DENIED; + } + int ret = VCE_ERROR_NONE; ret = vcd_stop_recording(); @@ -242,6 +393,13 @@ int vce_stop_recording() int vce_set_private_data_set_cb(vce_private_data_set_cb callback_func) { + if (0 != __vce_get_feature_enabled()) { + return VCE_ERROR_NOT_SUPPORTED; + } + if (0 != __vce_check_privilege()) { + return VCE_ERROR_PERMISSION_DENIED; + } + if (NULL == callback_func) { SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter"); return VCE_ERROR_INVALID_PARAMETER; @@ -257,6 +415,13 @@ int vce_set_private_data_set_cb(vce_private_data_set_cb callback_func) int vce_set_private_data_requested_cb(vce_private_data_requested_cb callback_func) { + if (0 != __vce_get_feature_enabled()) { + return VCE_ERROR_NOT_SUPPORTED; + } + if (0 != __vce_check_privilege()) { + return VCE_ERROR_PERMISSION_DENIED; + } + if (NULL == callback_func) { SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter"); return VCE_ERROR_INVALID_PARAMETER; -- 2.7.4 From b2c632f3fbe71d160430e71a686875cd9a8224d6 Mon Sep 17 00:00:00 2001 From: sungrae jo Date: Fri, 13 Apr 2018 17:11:15 +0900 Subject: [PATCH 14/16] Add released code of engine_agent_release Change-Id: Icd95526178f9c3c79128e1b8882d8311bc540de1 Signed-off-by: sungrae jo --- server/vcd_engine_agent.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/server/vcd_engine_agent.c b/server/vcd_engine_agent.c index 6c9dd57..bd3ecea 100644 --- a/server/vcd_engine_agent.c +++ b/server/vcd_engine_agent.c @@ -86,6 +86,7 @@ int vcd_engine_agent_init() /* init dynamic engine */ g_dynamic_engine.engine_uuid = NULL; g_dynamic_engine.engine_name = NULL; + g_dynamic_engine.engine_setting_path = NULL; g_dynamic_engine.engine_path = NULL; g_dynamic_engine.is_set = false; @@ -134,6 +135,18 @@ int vcd_engine_agent_release() free(g_dynamic_engine.callbacks); g_dynamic_engine.callbacks = NULL; } + if (NULL != g_dynamic_engine.engine_uuid) { + free(g_dynamic_engine.engine_uuid); + g_dynamic_engine.engine_uuid = NULL; + } + if (NULL != g_dynamic_engine.engine_name) { + free(g_dynamic_engine.engine_name); + g_dynamic_engine.engine_name = NULL; + } + if (NULL != g_dynamic_engine.engine_setting_path) { + free(g_dynamic_engine.engine_setting_path); + g_dynamic_engine.engine_setting_path = NULL; + } g_agent_init = false; @@ -206,6 +219,7 @@ int __internal_get_engine_info(vce_request_callback_s* callback) SLOG(LOG_DEBUG, TAG_VCD, "@@@ Valid Engine"); SLOG(LOG_DEBUG, TAG_VCD, "Engine uuid : %s", g_dynamic_engine.engine_uuid); SLOG(LOG_DEBUG, TAG_VCD, "Engine name : %s", g_dynamic_engine.engine_name); + SLOG(LOG_DEBUG, TAG_VCD, "Engine setting : %s", g_dynamic_engine.engine_setting_path); SLOG(LOG_DEBUG, TAG_VCD, "@@@"); return 0; -- 2.7.4 From 282a40e46ed048e768f7ab46c415f6430844b2b1 Mon Sep 17 00:00:00 2001 From: sungrae jo Date: Thu, 19 Apr 2018 11:15:50 +0900 Subject: [PATCH 15/16] Fixed resource leak for vc_command_util Change-Id: I36a3551e75c25bb66c6151f4367414c9e941728e Signed-off-by: sungrae jo --- common/vc_command_util.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/common/vc_command_util.c b/common/vc_command_util.c index 2386ef5..7fcda43 100644 --- a/common/vc_command_util.c +++ b/common/vc_command_util.c @@ -324,8 +324,12 @@ int vc_search_char(vc_cmd_list_h list, int search_level) if (NULL == cost || NULL == ncost) { SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Out of memory"); - - free(cmd_text); + if (NULL != cost) + free(cost); + if (NULL != ncost) + free(ncost); + if (NULL != cmd_text) + free(cmd_text); return VC_ERROR_OUT_OF_MEMORY; } -- 2.7.4 From d4a3f9895922d3653df664e6702222269e32e038 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Thu, 19 Apr 2018 18:53:26 +0900 Subject: [PATCH 16/16] Change build macro for tv profile Change-Id: I60a81733cba7959fd5acd7db023443754599f3d2 Signed-off-by: Wonnam Jang --- packaging/voice-control.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/voice-control.spec b/packaging/voice-control.spec index 3b585bc..9bc04cd 100644 --- a/packaging/voice-control.spec +++ b/packaging/voice-control.spec @@ -29,7 +29,7 @@ BuildRequires: pkgconfig(json-glib-1.0) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(libxml-2.0) BuildRequires: pkgconfig(sqlite3) -%if "%{PRODUCT_TYPE}" == "TV" +%if "%{tizen_profile_name}" == "tv" BuildRequires: pkgconfig(capi-network-bluetooth) BuildRequires: pkgconfig(capi-network-bluetooth-tv) BuildRequires: pkgconfig(msfapi) @@ -91,7 +91,7 @@ cp %{SOURCE1001} %{SOURCE1002} . %build -%if "%{PRODUCT_TYPE}" == "TV" +%if "%{tizen_profile_name}" == "tv" export CFLAGS="$CFLAGS -DTV_PRODUCT" cmake . -DCMAKE_INSTALL_PREFIX=/usr -DLIBDIR=%{_libdir} -DINCLUDEDIR=%{_includedir} \ -DTZ_SYS_RO_SHARE=%TZ_SYS_RO_SHARE -D_TV_PRODUCT=TRUE -- 2.7.4