Impl runtime voice touch activation 94/149194/1 accepted/tizen/4.0/unified/20170922.064442 submit/tizen_4.0/20170921.073346 tizen_4.0.IoT.p1_release tizen_4.0.m2_release
authorSuyeon Hwang <stom.hwang@samsung.com>
Mon, 5 Jun 2017 05:00:56 +0000 (14:00 +0900)
committerSuyeon Hwang <stom.hwang@samsung.com>
Tue, 12 Sep 2017 01:35:25 +0000 (01:35 +0000)
Change-Id: I6047a4405b30cf48ab46ae46a52aee5e7f24a201
Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
(cherry picked from commit 921b5a33a98c67b2325308f4aa6db99d11277ad0)

include/vc-webview.pc.in
include/voice_control_webview.h
packaging/vc-webview.spec
src/CMakeLists.txt
src/voice_control_webview.cpp

index 35f958c..abc735c 100755 (executable)
@@ -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
index 0f5c949..bf5606d 100755 (executable)
@@ -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!
  */
 
 #ifndef VOICE_CONTROL_WEBVIEW_H_
 #define VOICE_CONTROL_WEBVIEW_H_
 
-#include <ctime>
-#include <unistd.h>
-#include <dlog.h>
 #include <EWebKit.h>
 #include <EWebKit_product.h>
-#include <string>
-#include <sstream>
 #include <tizen.h>
-#include <tzplatform_config.h>
+#include <vconf.h>
 #include <voice_control_widget.h>
 
-/**
-* 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
index e3edba7..a0f3373 100755 (executable)
@@ -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
 
index 69684e1..1934736 100755 (executable)
@@ -9,6 +9,7 @@ SET(VCWEBVIEW_PKGS
   evas
   voice-control-widget
   vconf
+  aul
   )
 
 PKG_CHECK_MODULES(VCWEBVIEW_DEPS ${VCWEBVIEW_PKGS} REQUIRED)
index e37e81d..fe249c7 100755 (executable)
  *   limitations under the License.
  */
 
+#include <ctime>
+#include <unistd.h>
+#include <string>
+#include <sstream>
+
+#include <aul.h>
+#include <aul_window.h>
+#include <dlog.h>
 #include <Ecore.h>
-#include <vconf.h>
+#include <tzplatform_config.h>
+
 #include <voice_control_webview.h>
 
+
 #ifdef LOG_TAG
 #undef LOG_TAG
 #endif
 #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, &current)) {
+               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