From: Suyeon Hwang Date: Mon, 5 Jun 2017 05:00:56 +0000 (+0900) Subject: Impl runtime voice touch activation X-Git-Tag: submit/tizen_4.0/20170921.073346^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a695ad6d3d3e580448a188078d60b32f3689b67d;p=platform%2Fcore%2Fuifw%2Fvc-webview.git Impl runtime voice touch activation Change-Id: I6047a4405b30cf48ab46ae46a52aee5e7f24a201 Signed-off-by: Suyeon Hwang (cherry picked from commit 921b5a33a98c67b2325308f4aa6db99d11277ad0) --- diff --git a/include/vc-webview.pc.in b/include/vc-webview.pc.in index 35f958c..abc735c 100755 --- a/include/vc-webview.pc.in +++ b/include/vc-webview.pc.in @@ -6,6 +6,6 @@ includedir=@INCLUDEDIR@ Name: libvc-webview Description: Voice control webview plugin Version: @VERSION@ -Requires: chromium-efl voice-control-widget +Requires: chromium-efl voice-control-widget vconf Libs: -L${libdir} -lvc-webview Cflags: -I${includedir} \ No newline at end of file diff --git a/include/voice_control_webview.h b/include/voice_control_webview.h index 0f5c949..bf5606d 100755 --- a/include/voice_control_webview.h +++ b/include/voice_control_webview.h @@ -25,7 +25,7 @@ * To enable VCWebPage plugin, one have to add pointer to plugin into * browser_data structure (in main.cpp) or WRT and initialize this object * on app_create passing as argument pointer to web view evas object. - * IMPORTANT! Before initializing VCWebPage plugin, web view evas object + * IMPORTANT! Before initializing VCWebView plugin, web view evas object * has to be already created and initialized! */ @@ -37,23 +37,12 @@ #ifndef VOICE_CONTROL_WEBVIEW_H_ #define VOICE_CONTROL_WEBVIEW_H_ -#include -#include -#include #include #include -#include -#include #include -#include +#include #include -/** -* Path to JavaScript code -*/ -#define VC_WEBVIEW_JS_PATH tzplatform_mkpath(TZ_SYS_RO_SHARE, "voice/vc-webview/res/js") -#define VC_WEBVIEW_CUSTOM_PATH tzplatform_mkpath(TZ_SYS_RO_SHARE, "voice/vc-webview/res/js_custom") - typedef void (*vc_webview_result_cb)(const char *, const char *); @@ -128,6 +117,22 @@ public: */ void vc_language_changed_cb(const char* previous, const char* current, void *user_data); + /** + * @brief This method is called by vconf when the target vconf key changes. + * + * @param[in] key keynode pointer of target vconf key + * @param[in] data user callback data + */ + void vc_vt_changed_cb(keynode_t *key, void *data); + + /** + * @brief This method is called by aul when the status of the app is changed. + * + * @param[in] status current status of the app + * @param[in] data user callback data + */ + int vc_app_status_changed_cb(int status, void *data); + #if 0 bool vc_request_action_cb(const char* action, const char* data); @@ -205,13 +210,15 @@ public: private: VCWebView(); + static void __vc_webview_init(); + static void __vc_webview_deinit(); + static char* vc_webview_load_script(const char*); static vc_webview_result_cb m_result_cb; static Evas_Object *m_ewk_view; static int m_enable_navigation; void vc_register_commands(); - int vc_add_command(const char*, const char*, vc_cmd_list_h &list); - char* vc_webview_load_script(const char*); + int vc_add_command(const char*, const char*, vc_cmd_list_h &); }; #endif /* VOICE_CONTROL_WEBVIEW_H_ */ \ No newline at end of file diff --git a/packaging/vc-webview.spec b/packaging/vc-webview.spec index e3edba7..a0f3373 100755 --- a/packaging/vc-webview.spec +++ b/packaging/vc-webview.spec @@ -14,6 +14,7 @@ BuildRequires: pkgconfig(evas) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(voice-control-widget) BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(aul) BuildRequires: cmake BuildRequires: gettext-tools diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 69684e1..1934736 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,6 +9,7 @@ SET(VCWEBVIEW_PKGS evas voice-control-widget vconf + aul ) PKG_CHECK_MODULES(VCWEBVIEW_DEPS ${VCWEBVIEW_PKGS} REQUIRED) diff --git a/src/voice_control_webview.cpp b/src/voice_control_webview.cpp index e37e81d..fe249c7 100755 --- a/src/voice_control_webview.cpp +++ b/src/voice_control_webview.cpp @@ -14,10 +14,20 @@ * limitations under the License. */ +#include +#include +#include +#include + +#include +#include +#include #include -#include +#include + #include + #ifdef LOG_TAG #undef LOG_TAG #endif @@ -25,6 +35,12 @@ #define LOG_TAG "vc-webview" #define VC_VOICE_TOUCH_AUTOMODE "db/voice/vc/voice_touch/automode" +/** +* Path to JavaScript code +*/ +#define VC_WEBVIEW_JS_PATH tzplatform_mkpath(TZ_SYS_RO_SHARE, "voice/vc-webview/res/js") +#define VC_WEBVIEW_CUSTOM_PATH tzplatform_mkpath(TZ_SYS_RO_SHARE, "voice/vc-webview/res/js_custom") + char *m_main_script = NULL; char *m_lang_script = NULL; char *m_custom_script = NULL; @@ -43,6 +59,8 @@ static clock_t end_clock; static bool g_wait = false; static bool g_consumed = false; +static bool g_vc_init = false; +static bool g_vt_support = false; static void __vc_widget_result_cb(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char* result, void *user_data) { @@ -87,6 +105,16 @@ static void __vc_language_changed_cb(const char* previous, const char* current, (VCWebView::getInstance())->vc_language_changed_cb(previous, current, data); } +static void __vc_vt_changed_cb(keynode_t *key, void *data) +{ + (VCWebView::getInstance())->vc_vt_changed_cb(key, data); +} + +static int __vc_app_status_changed_cb(int status, void *data) +{ + return (VCWebView::getInstance())->vc_app_status_changed_cb(status, data); +} + #if 0 static bool __vc_request_action_cb(const char* action, const char* data) { @@ -117,10 +145,8 @@ static void __vc_widget_send_current_command_list_cb(vc_cmd_list_h* vc_cmd_list, double time_taken = double(end_clock - start_clock) / CLOCKS_PER_SEC; LOGD("**********************************************"); LOGD("* *"); - LOGD("* *"); LOGD("* %lf *", time_taken);; LOGD("* *"); - LOGD("* *"); LOGD("**********************************************"); } @@ -141,7 +167,7 @@ char* VCWebView::vc_webview_load_script(const char* filename) } fseek(f, 0, SEEK_END); long int fsize = ftell(f); - if (fsize < 0) { + if (fsize < 0 || fsize == 2147483647) { LOGE("Wrong file size"); fclose(f); return NULL; @@ -162,8 +188,7 @@ char* VCWebView::vc_webview_load_script(const char* filename) return script; } -VCWebView::VCWebView() -{ +void VCWebView::__vc_webview_init() { LOGI("===== Init VC Webview ====="); LOGI("%d ", vc_widget_initialize(&g_vc_w)); @@ -182,16 +207,76 @@ VCWebView::VCWebView() #endif LOGI("%d ", vc_widget_prepare(g_vc_w)); - m_main_script = vc_webview_load_script("vc-webview.js"); + g_vc_init = true; + + // Load base script if (NULL == m_main_script) { + m_main_script = vc_webview_load_script("vc-webview.js"); + if (NULL == m_main_script) { + LOGE("[ERROR] Fail to load base script"); + return; + } + } + + // Load language script + + char filename[64] = {'\0',}; + char *current = NULL; + if (0 != vc_widget_get_current_language(g_vc_w, ¤t)) { + LOGE("[ERROR] fail to get current langauge"); return; } - LOGI("[INFO] All listeners unset!"); + if (NULL != current) { + snprintf(filename, 64, "vc-webview-%s.js", current); + m_lang_script = vc_webview_load_script(filename); + + free(current); + current = NULL; + } + + if (NULL == m_lang_script) { + m_lang_script = vc_webview_load_script("vc-webview-en_US.js"); + } + + LOGI("====="); } -VCWebView::~VCWebView() +VCWebView::VCWebView() { + LOGI("===== Constructor ====="); + + int value = 0; + if (0 != vconf_get_bool(VC_VOICE_TOUCH_AUTOMODE, &value)) { + LOGE("[ERROR] Fail to get vconfkey"); + return; + } + + if (1 == value) { + g_vt_support = true; + } else { + g_vt_support = false; + } + + /* Register callback to detect changing option in runtime */ + if (0 != vconf_notify_key_changed(VC_VOICE_TOUCH_AUTOMODE, __vc_vt_changed_cb, NULL)) { + LOGE("[ERROR] Fail to set callback"); + return; + } + + if (0 != aul_add_status_local_cb(__vc_app_status_changed_cb, NULL)) { + LOGE("[ERROR] Fail to set callback"); + return; + } + + if (g_vt_support && false == g_vc_init) { + __vc_webview_init(); + } + + LOGI("====="); +} + +void VCWebView::__vc_webview_deinit() { LOGI("===== Deinit VC Webview ====="); vc_widget_unprepare(g_vc_w); @@ -210,6 +295,8 @@ VCWebView::~VCWebView() #endif vc_widget_deinitialize(g_vc_w); + g_vc_init = false; + if (NULL != m_list) { vc_cmd_list_destroy(m_list, true); m_list = NULL; @@ -217,6 +304,42 @@ VCWebView::~VCWebView() if (NULL != m_main_script) { delete [] m_main_script; + m_main_script = NULL; + } + + if (NULL != m_lang_script) { + delete [] m_lang_script; + m_lang_script = NULL; + } + + if (NULL != m_custom_script) { + delete [] m_custom_script; + m_custom_script = NULL; + } + + LOGI("====="); +} + +VCWebView::~VCWebView() +{ + LOGI("===== Destructor ====="); + m_enable_navigation = 0; + m_ewk_view = NULL; + m_result_cb = NULL; + + /* Remove callback to detect changing option in runtime */ + if (0 != vconf_ignore_key_changed(VC_VOICE_TOUCH_AUTOMODE, __vc_vt_changed_cb)) { + LOGE("[ERROR] Fail to remove callback"); + return; + } + + if (0 != aul_remove_status_local_cb(__vc_app_status_changed_cb, NULL)) { + LOGE("[ERROR] Fail to remove callback"); + return; + } + + if (g_vc_init) { + __vc_webview_deinit(); } LOGI("====="); @@ -519,6 +642,46 @@ void VCWebView::vc_show_tooltip_cb(bool show, void *user_data) } } +void VCWebView::vc_vt_changed_cb(keynode_t *key, void *data) +{ + if (NULL == key) { + LOGE("[ERROR] parameter key is not valid"); + return; + } + + LOGI("===== vconf key change callback (%s)(%d)", key->keyname, key->value.b); + /* Refresh vconf value of voice touch */ + if (1 == key->value.b) { + g_vt_support = true; + } else { + g_vt_support = false; + } + + int pid = -1; + if (0 != aul_window_get_focused_pid(&pid)) { + LOGE("[ERROR] fail to get pid of focused app"); + } + + if ((int)getpid() == pid) { + vc_webview_set_view(m_ewk_view); + } +} + +int VCWebView::vc_app_status_changed_cb(int status, void *data) +{ + static int prev = -1; + + LOGI("===== app status change callback (%d)(%d)", prev, status); + if (-1 != prev && STATUS_VISIBLE == status) { + LOGD("App is in focused status"); + vc_webview_set_view(m_ewk_view); + } + + prev = status; + + return 0; +} + void VCWebView::vc_register_commands() { vc_add_command("****", "", m_list); @@ -538,9 +701,9 @@ void VCWebView::vc_register_commands() // } } -int VCWebView::vc_add_command(const char* cmd, const char* param1, vc_cmd_list_h &list) +int VCWebView::vc_add_command(const char* cmd, const char* param, vc_cmd_list_h &list) { - LOGI("vc_add_command: %s %s", cmd, param1); + LOGI("vc_add_command: %s %s", cmd, param); int ret = 0; if (!list) { ret = vc_cmd_list_create(&list); @@ -556,7 +719,7 @@ int VCWebView::vc_add_command(const char* cmd, const char* param1, vc_cmd_list_h return ret; } - if (0 == strcmp(param1, "input")) { + if (0 == strcmp(param, "input")) { ret = vc_cmd_set_command(cmdh, cmd); ret = vc_cmd_set_type(cmdh, VC_COMMAND_TYPE_WIDGET); ret = vc_cmd_set_format(cmdh, VC_CMD_FORMAT_FIXED_AND_NONFIXED); @@ -606,14 +769,14 @@ void VCWebView::get_visible_commands(Evas_Object *ewk_view) } #endif -static void __js_script_loading_result_cb(Evas_Object *obj, const char *javascript_result, void *data) +static void __js_script_execute_result_cb(Evas_Object *obj, const char *javascript_result, void *data) { LOGI("javascript [%s] -> result [%s]", data, javascript_result); } -static void __js_script_loading_custom_cb(Evas_Object *obj, const char *javascript_result, void *data) +static void __js_get_script_name_cb(Evas_Object *obj, const char *javascript_result, void *data) { - LOGI("javascript pathname [%s]", javascript_result); + LOGI("javascript [Path name] -> [%s]", javascript_result); if (NULL == javascript_result) { LOGE("[ERROR] vc_get_url_path() failed"); @@ -660,7 +823,7 @@ static void __js_script_loading_custom_cb(Evas_Object *obj, const char *javascri if (m_custom_name.compare(file_name) != 0) { fseek(f, 0, SEEK_END); long int fsize = ftell(f); - if (fsize < 0) { + if (fsize < 0 || fsize == 2147483647) { LOGE("Wrong file size"); fclose(f); return; @@ -682,7 +845,7 @@ static void __js_script_loading_custom_cb(Evas_Object *obj, const char *javascri m_custom_name = file_name; } - ewk_view_script_execute((Evas_Object*)data, m_custom_script, __js_script_loading_result_cb, (void*)"custom"); + ewk_view_script_execute((Evas_Object*)data, m_custom_script, __js_script_execute_result_cb, (void*)"custom"); fclose(f); } @@ -691,16 +854,26 @@ void VCWebView::vc_webview_set_view(Evas_Object *ewk_view) { m_ewk_view = ewk_view; - /** Load js file that is already read into script variable */ - LOGI("Main script loading"); - ewk_view_script_execute(m_ewk_view, m_main_script, __js_script_loading_result_cb, (void*)"main"); + if (false == g_vt_support) { + if (true == g_vc_init) { + __vc_webview_deinit(); + } + } else { + if (false == g_vc_init) { + __vc_webview_init(); + } + + /* Load js file that is already read into script variable */ + LOGI("Main script loading"); + ewk_view_script_execute(m_ewk_view, m_main_script, __js_script_execute_result_cb, (void*)"main"); - if (NULL != m_lang_script) { - LOGI("Lang script loading"); - ewk_view_script_execute(m_ewk_view, m_lang_script, __js_script_loading_result_cb, (void*)"lang"); - } + if (NULL != m_lang_script) { + LOGI("Lang script loading"); + ewk_view_script_execute(m_ewk_view, m_lang_script, __js_script_execute_result_cb, (void*)"lang"); + } - ewk_view_script_execute(m_ewk_view, "vc_get_url_path();", __js_script_loading_custom_cb, m_ewk_view); + ewk_view_script_execute(m_ewk_view, "vc_get_url_path();", __js_get_script_name_cb, m_ewk_view); + } } void VCWebView::vc_webview_set_result_cb(vc_webview_result_cb cb) @@ -713,8 +886,7 @@ void VCWebView::vc_webview_enable_navigation(int enable) m_enable_navigation = enable; } -#if 1 -static void __js_script_conflict_result_cb(Evas_Object *obj, const char *javascript_result, void *data) +static void __js_get_conflict_status_cb(Evas_Object *obj, const char *javascript_result, void *data) { LOGI("javascript [Conflict] -> result [%s]", javascript_result); @@ -729,8 +901,12 @@ int VCWebView::vc_get_conflict_status() Eina_Bool ret; int conflict = -1; + if (false == g_vt_support) { + return -1; + } + g_wait = true; - ret = ewk_view_script_execute(m_ewk_view, "vc_get_conflict_status();", __js_script_conflict_result_cb, (void*)&conflict); + ret = ewk_view_script_execute(m_ewk_view, "vc_get_conflict_status();", __js_get_conflict_status_cb, (void*)&conflict); while (true == g_wait) { ecore_main_loop_iterate(); @@ -747,9 +923,7 @@ int VCWebView::vc_get_conflict_status() void VCWebView::vc_remove_tooltip() { LOGI("===== Remove tooltips on web view"); - std::string ready("REMOVE_TOOLTIP"); - std::string execute = "vc_request_action(\"" + ready + "\",\"\");"; - ewk_view_script_execute(m_ewk_view, execute.c_str(), __js_script_loading_result_cb, (void*)"REMOVE_TOOLTIP"); -} - -#endif + std::string action("REMOVE_TOOLTIP"); + std::string execute = "vc_request_action(\"" + action + "\",\"\");"; + ewk_view_script_execute(m_ewk_view, execute.c_str(), __js_script_execute_result_cb, (void*)"REMOVE_TOOLTIP"); +} \ No newline at end of file