From: Wonnam Jang Date: Tue, 14 Feb 2017 23:54:13 +0000 (+0900) Subject: Init version X-Git-Tag: submit/tizen/20170428.060545^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3eef2fe528d369ea76dbc6c6933ee3a259ca12ab;p=platform%2Fcore%2Fuifw%2Fvc-webview.git Init version Change-Id: Ib5063b3bf99e64d25d5e5e0b281bcc9d271451de Signed-off-by: Wonnam Jang --- diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..b5fa653 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,4 @@ +Wonnam Jang +Kwangyoun Kim +Sooyeon Kim +Suyeon Hwang \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..651e8b0 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,94 @@ +# +# Copyright 2017 Samsung Electronics Co., Ltd. +# +# Licensed under the Flora License, Version 1.1 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://floralicense.org/license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Suyeon Hwang (stom.hwang@samsung.com) +# @version 1.0 +# @brief +# + +# Check minimum CMake version +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +# Project name +PROJECT(vc-webview) + +# pkg config tool +INCLUDE(FindPkgConfig) + +# Build type +SET(CMAKE_BUILD_TYPE "Release") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -fprofile-arcs -ftest-coverage -D_GNU_SOURCE") + +# CMake settings +MESSAGE(STATUS "========================================") +MESSAGE(STATUS "CMAKE_BINARY_DIR: " ${CMAKE_BINARY_DIR}) +MESSAGE(STATUS "CMAKE_CURRENT_BINARY_DIR: " ${CMAKE_CURRENT_BINARY_DIR}) +MESSAGE(STATUS "CMAKE_SOURCE_DIR: " ${CMAKE_SOURCE_DIR}) +MESSAGE(STATUS "CMAKE_CURRENT_SOURCE_DIR: " ${CMAKE_CURRENT_SOURCE_DIR}) +MESSAGE(STATUS "PROJECT_BINARY_DIR: " ${PROJECT_BINARY_DIR}) +MESSAGE(STATUS "PROJECT_SOURCE_DIR: " ${PROJECT_SOURCE_DIR}) +MESSAGE(STATUS "EXECUTABLE_OUTPUT_PATH: " ${EXECUTABLE_OUTPUT_PATH}) +MESSAGE(STATUS "LIBRARY_OUTPUT_PATH: " ${LIBRARY_OUTPUT_PATH}) +MESSAGE(STATUS "CMAKE_MODULE_PATH: " ${CMAKE_MODULE_PATH}) +MESSAGE(STATUS "CMAKE_COMMAND: " ${CMAKE_COMMAND}) +MESSAGE(STATUS "CMAKE_ROOT: " ${CMAKE_ROOT}) +MESSAGE(STATUS "CMAKE_CURRENT_LIST_FILE: " ${CMAKE_CURRENT_LIST_FILE}) +MESSAGE(STATUS "CMAKE_CURRENT_LIST_LINE: " ${CMAKE_CURRENT_LIST_LINE}) +MESSAGE(STATUS "CMAKE_INCLUDE_PATH: " ${CMAKE_INCLUDE_PATH}) +MESSAGE(STATUS "CMAKE_LIBRARY_PATH: " ${CMAKE_LIBRARY_PATH}) +MESSAGE(STATUS "CMAKE_SYSTEM: " ${CMAKE_SYSTEM}) +MESSAGE(STATUS "CMAKE_SYSTEM_NAME: " ${CMAKE_SYSTEM_NAME}) +MESSAGE(STATUS "CMAKE_SYSTEM_VERSION: " ${CMAKE_SYSTEM_VERSION}) +MESSAGE(STATUS "CMAKE_SYSTEM_PROCESSOR: " ${CMAKE_SYSTEM_PROCESSOR}) +MESSAGE(STATUS "UNIX: " ${UNIX}) +MESSAGE(STATUS "WIN32: " ${WIN32}) +MESSAGE(STATUS "APPLE: " ${APPLE}) +MESSAGE(STATUS "MINGW: " ${MINGW}) +MESSAGE(STATUS "CYGWIN: " ${CYGWIN}) +MESSAGE(STATUS "BORLAND: " ${BORLAND}) +MESSAGE(STATUS "MSVC: " ${MSVC}) +MESSAGE(STATUS "MSVC_IDE: " ${MSVC_IDE}) +MESSAGE(STATUS "MSVC60: " ${MSVC60}) +MESSAGE(STATUS "MSVC70: " ${MSVC70}) +MESSAGE(STATUS "MSVC71: " ${MSVC71}) +MESSAGE(STATUS "MSVC80: " ${MSVC80}) +MESSAGE(STATUS "CMAKE_COMPILER_2005: " ${CMAKE_COMPILER_2005}) +MESSAGE(STATUS "CMAKE_SKIP_RULE_DEPENDENCY: " ${CMAKE_SKIP_RULE_DEPENDENCY}) +MESSAGE(STATUS "CMAKE_SKIP_INSTALL_ALL_DEPENDENCY: " ${CMAKE_SKIP_INSTALL_ALL_DEPENDENCY}) +MESSAGE(STATUS "CMAKE_SKIP_RPATH: " ${CMAKE_SKIP_RPATH}) +MESSAGE(STATUS "CMAKE_VERBOSE_MAKEFILE: " ${CMAKE_VERBOSE_MAKEFILE}) +MESSAGE(STATUS "CMAKE_SUPPRESS_REGENERATION: " ${CMAKE_SUPPRESS_REGENERATION}) +MESSAGE(STATUS "CMAKE_C_FLAGS: " ${CMAKE_C_FLAGS}) +MESSAGE(STATUS "CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS}) +MESSAGE(STATUS "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE}) +MESSAGE(STATUS "BUILD_SHARED_LIBS: " ${BUILD_SHARED_LIBS}) +MESSAGE(STATUS "CMAKE_C_COMPILER: " ${CMAKE_C_COMPILER}) +MESSAGE(STATUS "CMAKE_CXX_COMPILER: " ${CMAKE_CXX_COMPILER}) +MESSAGE(STATUS "CMAKE_COMPILER_IS_GNUCC: " ${CMAKE_COMPILER_IS_GNUCC}) +MESSAGE(STATUS "CMAKE_COMPILER_IS_GNUCXX : " ${CMAKE_COMPILER_IS_GNUCXX}) +MESSAGE(STATUS "CMAKE_AR: " ${CMAKE_AR}) +MESSAGE(STATUS "CMAKE_RANLIB: " ${CMAKE_RANLIB}) +MESSAGE(STATUS "========================================") + +# Warning flags + +SET(TARGET_EVC_LIBRARY "${PROJECT_NAME}") + +SET(VC_WEBVIEW_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include) + +ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(include) +#ADD_SUBDIRECTORY(src/po) \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..571fe79 --- /dev/null +++ b/LICENSE @@ -0,0 +1,206 @@ +Flora License + +Version 1.1, April, 2013 + +http://floralicense.org/license/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, +and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by +the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and +all other entities that control, are controlled by, or are +under common control with that entity. For the purposes of +this definition, "control" means (i) the power, direct or indirect, +to cause the direction or management of such entity, +whether by contract or otherwise, or (ii) ownership of fifty percent (50%) +or more of the outstanding shares, or (iii) beneficial ownership of +such entity. + +"You" (or "Your") shall mean an individual or Legal Entity +exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, +including but not limited to software source code, documentation source, +and configuration files. + +"Object" form shall mean any form resulting from mechanical +transformation or translation of a Source form, including but +not limited to compiled object code, generated documentation, +and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, +made available under the License, as indicated by a copyright notice +that is included in or attached to the work (an example is provided +in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, +that is based on (or derived from) the Work and for which the editorial +revisions, annotations, elaborations, or other modifications represent, +as a whole, an original work of authorship. For the purposes of this License, +Derivative Works shall not include works that remain separable from, +or merely link (or bind by name) to the interfaces of, the Work and +Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original +version of the Work and any modifications or additions to that Work or +Derivative Works thereof, that is intentionally submitted to Licensor +for inclusion in the Work by the copyright owner or by an individual or +Legal Entity authorized to submit on behalf of the copyright owner. +For the purposes of this definition, "submitted" means any form of +electronic, verbal, or written communication sent to the Licensor or +its representatives, including but not limited to communication on +electronic mailing lists, source code control systems, and issue +tracking systems that are managed by, or on behalf of, the Licensor +for the purpose of discussing and improving the Work, but excluding +communication that is conspicuously marked or otherwise designated +in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity +on behalf of whom a Contribution has been received by Licensor and +subsequently incorporated within the Work. + +"Tizen Certified Platform" shall mean a software platform that complies +with the standards set forth in the Tizen Compliance Specification +and passes the Tizen Compliance Tests as defined from time to time +by the Tizen Technical Steering Group and certified by the Tizen +Association or its designated agent. + +2. Grant of Copyright License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the +Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +(except as stated in this section) patent license to make, have made, +use, offer to sell, sell, import, and otherwise transfer the Work +solely as incorporated into a Tizen Certified Platform, where such +license applies only to those patent claims licensable by such +Contributor that are necessarily infringed by their Contribution(s) +alone or by combination of their Contribution(s) with the Work solely +as incorporated into a Tizen Certified Platform to which such +Contribution(s) was submitted. If You institute patent litigation +against any entity (including a cross-claim or counterclaim +in a lawsuit) alleging that the Work or a Contribution incorporated +within the Work constitutes direct or contributory patent infringement, +then any patent licenses granted to You under this License for that +Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the +Work or Derivative Works thereof pursuant to the copyright license +above, in any medium, with or without modifications, and in Source or +Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works + a copy of this License; and + 2. You must cause any modified files to carry prominent notices stating + that You changed the files; and + 3. You must retain, in the Source form of any Derivative Works that + You distribute, all copyright, patent, trademark, and attribution + notices from the Source form of the Work, excluding those notices + that do not pertain to any part of the Derivative Works; and + 4. If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable + copy of the attribution notices contained within such NOTICE file, + excluding those notices that do not pertain to any part of + the Derivative Works, in at least one of the following places: + within a NOTICE text file distributed as part of the Derivative Works; + within the Source form or documentation, if provided along with the + Derivative Works; or, within a display generated by the Derivative Works, + if and wherever such third-party notices normally appear. + The contents of the NOTICE file are for informational purposes only + and do not modify the License. You may add Your own attribution notices + within Derivative Works that You distribute, alongside or as an addendum + to the NOTICE text from the Work, provided that such additional attribution + notices cannot be construed as modifying the License. You may add Your own + copyright statement to Your modifications and may provide additional or + different license terms and conditions for use, reproduction, or + distribution of Your modifications, or for any such Derivative Works + as a whole, provided Your use, reproduction, and distribution of + the Work otherwise complies with the conditions stated in this License + and your own copyright statement or terms and conditions do not conflict + the conditions stated in the License including section 3. + +5. Submission of Contributions. Unless You explicitly state otherwise, +any Contribution intentionally submitted for inclusion in the Work +by You to the Licensor shall be under the terms and conditions of +this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify +the terms of any separate license agreement you may have executed +with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade +names, trademarks, service marks, or product names of the Licensor, +except as required for reasonable and customary use in describing the +origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or +agreed to in writing, Licensor provides the Work (and each +Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied, including, without limitation, any warranties or conditions +of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +PARTICULAR PURPOSE. You are solely responsible for determining the +appropriateness of using or redistributing the Work and assume any +risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, +whether in tort (including negligence), contract, or otherwise, +unless required by applicable law (such as deliberate and grossly +negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, +incidental, or consequential damages of any character arising as a +result of this License or out of the use or inability to use the +Work (including but not limited to damages for loss of goodwill, +work stoppage, computer failure or malfunction, or any and all +other commercial damages or losses), even if such Contributor +has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing +the Work or Derivative Works thereof, You may choose to offer, +and charge a fee for, acceptance of support, warranty, indemnity, +or other liability obligations and/or rights consistent with this +License. However, in accepting such obligations, You may act only +on Your own behalf and on Your sole responsibility, not on behalf +of any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason +of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Flora License to your work + +To apply the Flora License to your work, attach the following +boilerplate notice, with the fields enclosed by brackets "[]" +replaced with your own identifying information. (Don't include +the brackets!) The text should be enclosed in the appropriate +comment syntax for the file format. We also recommend that a +file or class name and description of purpose be included on the +same "printed page" as the copyright notice for easier +identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Flora License, Version 1.1 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://floralicense.org/license/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..205e4cf --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Flora License, Version 1.1 +Please, see the LICENSE.Flora file for Flora License, Version 1.1 terms and conditions. \ No newline at end of file diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt new file mode 100755 index 0000000..ebbc243 --- /dev/null +++ b/include/CMakeLists.txt @@ -0,0 +1,4 @@ +CONFIGURE_FILE(vc-webview.pc.in vc-webview.pc @ONLY) + +INSTALL(FILES ${CMAKE_BINARY_DIR}/include/vc-webview.pc DESTINATION ${LIBDIR}/pkgconfig/) +INSTALL(FILES voice_control_webview.h DESTINATION ${INCLUDEDIR}) \ No newline at end of file diff --git a/include/vc-webview.pc.in b/include/vc-webview.pc.in new file mode 100755 index 0000000..35f958c --- /dev/null +++ b/include/vc-webview.pc.in @@ -0,0 +1,11 @@ +prefix= +exec_prefix= +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: libvc-webview +Description: Voice control webview plugin +Version: @VERSION@ +Requires: chromium-efl voice-control-widget +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 new file mode 100755 index 0000000..4c2fd00 --- /dev/null +++ b/include/voice_control_webview.h @@ -0,0 +1,222 @@ +/** + * Copyright 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * voice_control_webview.h + * + * Any command sent to web page which would not match any of these listed above, + * will be treated as attempt to click in a link, with specified words. + * Current page will be searched for link, which description contains given words. + * If the link is found and is visible on a screen, page will be changed. + * + * 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 + * has to be already created and initialized! + */ + +/** +* @file voice_control_webview.h +* @brief This file contains the VCWebView class and related definitions +*/ + +#ifndef VOICE_CONTROL_WEBVIEW_H_ +#define VOICE_CONTROL_WEBVIEW_H_ + +#include +#include +#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 *); + + +/** +* @brief This class is responsible for communication between webview and voice-control. +* VCWebView is a singleton. +*/ +class VCWebView +{ + +public: + /** + * @brief Destructor of VCWebView class object + */ + ~VCWebView(); + + /** + * @brief This method returns VCWebView singleton object + */ + static VCWebView* getInstance(); + + /** + * @brief This method is called by voice-control with voice control recognition result as argument + * + * @param[in] event voice-control event + * @param[in] vc_cmd_list command list object recognized by voice-control + * @param[in] result result of the STT engine recognition + * @param[in] user_data user callback data + */ + void vc_widget_result_cb(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char* result, void *user_data); + + /** + * @brief This method is called by voice-control if engine changes state. + * + * @param[in] previous previous state + * @param[in] current current state + * @param[in] user_data user callback data + */ + void vc_state_changed_cb(vc_state_e previous, vc_state_e current, void *user_data); + + /** + * @brief This method is called by voice-control if service changes state. + * + * @param[in] prevoius previous state + * @param[in] current current state + * @param[in] user_data user callback data + */ + void vc_service_state_changed_cb(vc_service_state_e previous, vc_service_state_e current, void* user_data); + + /** + * @brief This method is called by voice-control if error occurs. + * + * @param[in] reason the cause of error + * @param[in] user_data user callback data + */ + void vc_error_cb(vc_error_e reason, void *user_data); + + /** + * @brief This method is called by voice-control when hints should be displayed or hidden. + * + * @param[in] show determines if hints should be displayed or hidden + * @param[in] user_data user callback data + */ + void vc_show_tooltip_cb(bool show, void *user_data); + + /** + * @brief This method is called by voice-control when language changes. + * + * @param[in] previous previous language + * @param[in] current current language + * @param[in] user_data user callback data + */ + void vc_language_changed_cb(const char* previous, const char* current, void *user_data); + +#if 0 + bool vc_request_action_cb(const char* action, const char* data); + + bool vc_get_client_data_cb(const char* key, char** value); + + bool vc_set_client_data_cb(const char* key, const char* value); +#endif + + /** + * @brief This method is called when click specified element on web view + * + * @param[in] x x coordinate of specified element + * @param[in] y y coordinate of specified element + */ + void vc_feed_touch_event(double x, double y); + + /** + * @brief This method is used to call vc_get_visible_commands using ewk. + * + * @param[in] ewk_view EWK object from browser_view + * + * @see register_image_commands + */ + static void get_visible_commands(Evas_Object *ewk_view); + + /** + * This method is used to enable voice navigation command. + * + * @param[in] enable 0 : disable / 1 : enable + */ + static void vc_webview_enable_navigation(int enable); + + /** + * @brief This method is called when something (ex. height) of a webview changes. + * + * @param[in] ewk_view EWK object of web view + */ + static void vc_webview_set_view(Evas_Object *ewk_view); + + /** + * @brief This method is used to set callback function in webview application. + * + * @param[in] cb pointer to callback function + */ + static void vc_webview_set_result_cb(vc_webview_result_cb cb); + + /** + * @brief This method is used to call JavaScript's vc_show_popup. + * + * @param[in] timeout timeout in ms after which the popup will disappear. If 0ms it will be shown until new popup is created + * @parma[in] message message to be displayed inside popup + */ + static void vc_webview_show_popup(int timeout, const std::string message); + + /** + * @brief This method is used to get conflict state of web view + * + * @return 1 when web view in conflict state, otherwise 0. + */ + static int vc_get_conflict_status(); + + /** + * @brief This method is used to remove tooltips on web view + */ + static void vc_remove_tooltip(); + + /** + * @brief This method is used to get vconfkey of voice touch auto mode setting + * + * @param[out] vt_automode boolean of vconfkey. if voice touch auto mode is enabled, it is true. Otherwise, false + * + * @return 0 when the function is normally worked, otherwise a negative value. + */ + static int vc_is_supported_web_vt(bool *vt_automode); + +private: + VCWebView(); + + static vc_webview_result_cb m_result_cb; + static Evas_Object *m_ewk_view; + static int m_enable_navigation; + static int vc_conf_status; + static efl_util_inputgen_h touch; + void vc_register_commands(); + int vc_add_command(const char*, const char*, vc_cmd_list_h &list); + char* vc_webview_load_script(const char*); +}; + +#endif /* VOICE_CONTROL_WEBVIEW_H_ */ \ No newline at end of file diff --git a/packaging/vc-webview-devel.manifest b/packaging/vc-webview-devel.manifest new file mode 100755 index 0000000..a76fdba --- /dev/null +++ b/packaging/vc-webview-devel.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/vc-webview.manifest b/packaging/vc-webview.manifest new file mode 100755 index 0000000..a76fdba --- /dev/null +++ b/packaging/vc-webview.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/vc-webview.spec b/packaging/vc-webview.spec new file mode 100755 index 0000000..7c0fa61 --- /dev/null +++ b/packaging/vc-webview.spec @@ -0,0 +1,70 @@ +Name: vc-webview +Summary: Web voice touch internal library +Version: 0.0.1 +Release: 1 +Group: Graphics & UI Framework/Voice Framework +License: Flora-1.1 +Source0: %{name}-%{version}.tar.gz +Source1001: %{name}.manifest +Source1002: %{name}-devel.manifest +BuildRequires: pkgconfig(chromium-efl) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(ecore) +BuildRequires: pkgconfig(evas) +BuildRequires: pkgconfig(libtzplatform-config) +BuildRequires: pkgconfig(voice-control-widget) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(capi-ui-efl-util) +BuildRequires: cmake +BuildRequires: gettext-tools + +%description +Internal library to enable web voice touch function on web application runtime + +%package devel +Summary: Voice control webview header files for web voice control +Group: libdevel +Requires: %{name} = %{version}-%{release} + +%description devel +Voice control webview header files for web voice control + +%prep +%setup -q +cp %{SOURCE1001} %{SOURCE1002} . + +%build +export LDFLAGS+="-Wl,--rpath=%{_libdir} -Wl,--hash-style=both -Wl,--as-needed,-lgcov" +rm -rf objdir +mkdir objdir + +cd objdir && cmake .. -DVERSION=%{version} \ + -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + -DCMAKE_BUILD_TYPE=Debug \ + -DLIBDIR=%{_libdir} \ + -DINCLUDEDIR=%{_includedir} \ + -DTZ_SYS_RO_SHARE=%TZ_SYS_RO_SHARE + +cd objdir && make %{?jobs:-j%jobs} + +%install +(cd objdir && +%make_install) + +%clean +rm -rf %{buildroot} + +%post + +%files +%license LICENSE +%manifest %{name}.manifest +%defattr(-,root,root,-) +%{_libdir}/libvc-webview.so +#/opt/apps/vc-webpage/res/locale/* + +%files devel +%manifest %{name}-devel.manifest +%defattr(-,root,root,-) +%{_includedir}/voice_control_webview.h +%{_libdir}/pkgconfig/vc-webview.pc \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100755 index 0000000..86619b7 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,31 @@ +FILE(GLOB VCWEBVIEW_SOURCES *.cpp) + +SET(TARGET_VCWEBVIEW "vc-webview") + +SET(VCWEBVIEW_PKGS + chromium-efl + dlog + ecore + evas + voice-control-widget + vconf + capi-ui-efl-util + ) + +PKG_CHECK_MODULES(VCWEBVIEW_DEPS ${VCWEBVIEW_PKGS} REQUIRED) + +ADD_DEFINITIONS(${VCWEBVIEW_DEPS_CFLAGS}) +ADD_DEFINITIONS(${VCWEBVIEW_DEPS_CFLAGS_OTHER} "-lpthread") +INCLUDE_DIRECTORIES( + ${VCWEBVIEW_DEPS_INCLUDE_DIRS} + ${VC_WEBVIEW_INCLUDE_DIR} + ) + +ADD_LIBRARY(${TARGET_VCWEBVIEW} SHARED ${VCWEBVIEW_SOURCES}) + +TARGET_LINK_LIBRARIES(${TARGET_VCWEBVIEW} + ${VCWEBVIEW_DEPS_LIBRARIES} + ) + +INSTALL(TARGETS ${TARGET_VCWEBVIEW} DESTINATION ${LIBDIR}) + diff --git a/src/po/CMakeLists.txt b/src/po/CMakeLists.txt new file mode 100755 index 0000000..eaa2b42 --- /dev/null +++ b/src/po/CMakeLists.txt @@ -0,0 +1,26 @@ +# for i18n + +SET(POFILES en_US.po en.po ) + +SET(MSGFMT "/usr/bin/msgfmt") + +FOREACH(pofile ${POFILES}) + SET(pofile ${CMAKE_CURRENT_SOURCE_DIR}/${pofile}) + MESSAGE("PO: ${pofile}") + GET_FILENAME_COMPONENT(absPofile ${pofile} ABSOLUTE) + GET_FILENAME_COMPONENT(lang ${absPofile} NAME_WE) + SET(moFile ${CMAKE_CURRENT_BINARY_DIR}/${lang}.mo) + ADD_CUSTOM_COMMAND( + OUTPUT ${moFile} + COMMAND ${MSGFMT} -o ${moFile} ${absPofile} + DEPENDS ${absPofile} + ) + +INSTALL(FILES ${moFile} DESTINATION /opt/apps/vc-webpage/res/locale/${lang}/LC_MESSAGES RENAME ${PROJECT_NAME}.mo) + + + SET(moFiles ${moFiles} ${moFile}) +ENDFOREACH(pofile) + +MESSAGE(".mo files: ${moFiles}") +ADD_CUSTOM_TARGET(po ALL DEPENDS ${moFiles}) diff --git a/src/po/en.po b/src/po/en.po new file mode 100755 index 0000000..77cb71c --- /dev/null +++ b/src/po/en.po @@ -0,0 +1,121 @@ +msgid "IDS_ALPHA" +msgstr "alpha" + +msgid "IDS_BRAVO" +msgstr "bravo" + +msgid "IDS_CHARLIE" +msgstr "charlie" + +msgid "IDS_DELTA" +msgstr "delta" + +msgid "IDS_ECHO" +msgstr "echo" + +msgid "IDS_FOXTROT" +msgstr "foxtrot" + +msgid "IDS_GOLF" +msgstr "golf" + +msgid "IDS_HOTEL" +msgstr "hotel" + +msgid "IDS_INDIA" +msgstr "india" + +msgid "IDS_JULIET" +msgstr "juliet" + +msgid "IDS_KILO" +msgstr "kilo" + +msgid "IDS_LIMA" +msgstr "lima" + +msgid "IDS_MIKE" +msgstr "mike" + +msgid "IDS_NOVEMBER" +msgstr "november" + +msgid "IDS_OSCAR" +msgstr "oscar" + +msgid "IDS_PAPA" +msgstr "papa" + +msgid "IDS_QUEBEC" +msgstr "quebec" + +msgid "IDS_ROMEO" +msgstr "romeo" + +msgid "IDS_SIERRO" +msgstr "sierro" + +msgid "IDS_TANGO" +msgstr "tango" + +msgid "IDS_UNIFORM" +msgstr "uniform" + +msgid "IDS_VICTOR" +msgstr "victor" + +msgid "IDS_WHISKEY" +msgstr "whiskey" + +msgid "IDS_XRAY" +msgstr "xray" + +msgid "IDS_YANKEE" +msgstr "yankee" + +msgid "IDS_ZULU" +msgstr "zulu" + +msgid "IDS_ZORRO" +msgstr "zorro" + +msgid "IDS_CASTLE" +msgstr "castle" + +msgid "IDS_ONE" +msgstr "one" + +msgid "IDS_TWO" +msgstr "two" + +msgid "IDS_THREE" +msgstr "three" + +msgid "IDS_FOUR" +msgstr "four" + +msgid "IDS_FIVE" +msgstr "five" + +msgid "IDS_SIX" +msgstr "six" + +msgid "IDS_SEVEN" +msgstr "seven" + +msgid "IDS_EIGHT" +msgstr "eight" + +msgid "IDS_NINE" +msgstr "nine" + +msgid "IDS_TEN" +msgstr "ten" + +msgid "IDS_ELEVEN" +msgstr "eleven" + +msgid "IDS_TWELVE" +msgstr "twelve" + + diff --git a/src/po/en_US.po b/src/po/en_US.po new file mode 100755 index 0000000..77cb71c --- /dev/null +++ b/src/po/en_US.po @@ -0,0 +1,121 @@ +msgid "IDS_ALPHA" +msgstr "alpha" + +msgid "IDS_BRAVO" +msgstr "bravo" + +msgid "IDS_CHARLIE" +msgstr "charlie" + +msgid "IDS_DELTA" +msgstr "delta" + +msgid "IDS_ECHO" +msgstr "echo" + +msgid "IDS_FOXTROT" +msgstr "foxtrot" + +msgid "IDS_GOLF" +msgstr "golf" + +msgid "IDS_HOTEL" +msgstr "hotel" + +msgid "IDS_INDIA" +msgstr "india" + +msgid "IDS_JULIET" +msgstr "juliet" + +msgid "IDS_KILO" +msgstr "kilo" + +msgid "IDS_LIMA" +msgstr "lima" + +msgid "IDS_MIKE" +msgstr "mike" + +msgid "IDS_NOVEMBER" +msgstr "november" + +msgid "IDS_OSCAR" +msgstr "oscar" + +msgid "IDS_PAPA" +msgstr "papa" + +msgid "IDS_QUEBEC" +msgstr "quebec" + +msgid "IDS_ROMEO" +msgstr "romeo" + +msgid "IDS_SIERRO" +msgstr "sierro" + +msgid "IDS_TANGO" +msgstr "tango" + +msgid "IDS_UNIFORM" +msgstr "uniform" + +msgid "IDS_VICTOR" +msgstr "victor" + +msgid "IDS_WHISKEY" +msgstr "whiskey" + +msgid "IDS_XRAY" +msgstr "xray" + +msgid "IDS_YANKEE" +msgstr "yankee" + +msgid "IDS_ZULU" +msgstr "zulu" + +msgid "IDS_ZORRO" +msgstr "zorro" + +msgid "IDS_CASTLE" +msgstr "castle" + +msgid "IDS_ONE" +msgstr "one" + +msgid "IDS_TWO" +msgstr "two" + +msgid "IDS_THREE" +msgstr "three" + +msgid "IDS_FOUR" +msgstr "four" + +msgid "IDS_FIVE" +msgstr "five" + +msgid "IDS_SIX" +msgstr "six" + +msgid "IDS_SEVEN" +msgstr "seven" + +msgid "IDS_EIGHT" +msgstr "eight" + +msgid "IDS_NINE" +msgstr "nine" + +msgid "IDS_TEN" +msgstr "ten" + +msgid "IDS_ELEVEN" +msgstr "eleven" + +msgid "IDS_TWELVE" +msgstr "twelve" + + diff --git a/src/po/ko_KR.po b/src/po/ko_KR.po new file mode 100755 index 0000000..e69de29 diff --git a/src/po/pl.po b/src/po/pl.po new file mode 100755 index 0000000..e69de29 diff --git a/src/voice_control_webview.cpp b/src/voice_control_webview.cpp new file mode 100755 index 0000000..eaa38fe --- /dev/null +++ b/src/voice_control_webview.cpp @@ -0,0 +1,747 @@ +/** + * Copyright 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "vc-webview" +#define VC_VOICE_TOUCH_AUTOMODE "db/voice/vc/voice_touch/automode" + +char *m_main_script = NULL; +char *m_lang_script = NULL; +char *m_custom_script = NULL; +std::string m_custom_name; + +Evas_Object *VCWebView::m_ewk_view = NULL; +vc_webview_result_cb VCWebView::m_result_cb = NULL; +int VCWebView::m_enable_navigation = 0; +int VCWebView::vc_conf_status = 0; +efl_util_inputgen_h VCWebView::touch; + +static vc_cmd_list_h m_list = NULL; +static vc_cmd_h cmdh; +static vc_h g_vc_w; + +static clock_t start_clock; +static clock_t end_clock; + +static bool g_wait = false; +static bool g_consumed = 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) +{ + //(VCWebView::getInstance())->vc_widget_result_cb(event, vc_cmd_list, result, user_data); +} + +static bool __vc_widget_asr_result_cb(vc_result_event_e event, const char* result, void *user_data) +{ + (VCWebView::getInstance())->vc_widget_result_cb(event, NULL, result, user_data); + + while (true == g_wait) { + ecore_main_loop_iterate(); + } + + return g_consumed; +} + +static void __vc_state_changed_cb(vc_state_e previous, vc_state_e current, void *user_data) +{ + (VCWebView::getInstance())->vc_state_changed_cb(previous, current, user_data); + // vc_widget_enable_asr_result(g_vc_w, true); +} + +static void __vc_error_cb(vc_error_e reason, void *user_data) +{ + (VCWebView::getInstance())->vc_error_cb(reason, user_data); +} + +static void __vc_show_tooltip_cb(bool show, void *user_data) +{ + (VCWebView::getInstance())->vc_show_tooltip_cb(show, user_data); +} + +static void __vc_service_state_changed_cb(vc_service_state_e previous, vc_service_state_e current, void* user_data) +{ + (VCWebView::getInstance())->vc_service_state_changed_cb(previous, current, user_data); + // vc_widget_enable_asr_result(g_vc_w, true); +} + +static void __vc_language_changed_cb(const char* previous, const char* current, void* data) +{ + (VCWebView::getInstance())->vc_language_changed_cb(previous, current, data); +} + +#if 0 +static bool __vc_request_action_cb(const char* action, const char* data) +{ + return (VCWebView::getInstance())->vc_request_action_cb(action, data); +} + +static bool __vc_get_client_data_cb(const char* key, char** value) +{ + return (VCWebView::getInstance())->vc_get_client_data_cb(key, value); +} + +static bool __vc_set_client_data_cb(const char* key, const char* value) +{ + return (VCWebView::getInstance())->vc_set_client_data_cb(key, value); +} +#endif + +static void __vc_widget_send_current_command_list_cb(vc_cmd_list_h* vc_cmd_list, void* user_data) +{ + *vc_cmd_list = m_list; + LOGI("SEND CURRENT COMMAND GROUP CB CALLED"); + + int cnt = 0; + vc_cmd_list_get_count(*vc_cmd_list, &cnt); + LOGI("Current command is (%d)", cnt); + + end_clock = clock(); + double time_taken = double(end_clock - start_clock) / CLOCKS_PER_SEC; + LOGD("**********************************************"); + LOGD("* *"); + LOGD("* *"); + LOGD("* %lf *", time_taken);; + LOGD("* *"); + LOGD("* *"); + LOGD("**********************************************"); +} + +char* VCWebView::vc_webview_load_script(const char* filename) +{ + LOGI("==== Load Script ===="); + + FILE *f = NULL; + char js_path[1024] = {'\0',}; + snprintf(js_path, 1024, "%s/%s", VC_WEBVIEW_JS_PATH, filename); + LOGD("===path (%s)", js_path); + f = fopen(js_path, "r"); + if (NULL == f) { + LOGE("Couldn't open %s - %s", filename, strerror(errno)); + return NULL; + } + fseek(f, 0, SEEK_END); + long int fsize = ftell(f); + fseek(f, 0, SEEK_SET); + + char *script = new char [fsize + 1]; + long int ret = fread(script, 1, fsize, f); + if (ret != fsize) { + LOGE("Couldn't read vc-webview.js file %d, %d", fsize, ret); + fclose(f); + delete [] script; + return NULL; + } + fclose(f); + script[fsize] = '\0'; + + return script; +} + +VCWebView::VCWebView() +{ + LOGI("===== Init VC Webview ====="); + + LOGI("%d ", vc_widget_initialize(&g_vc_w)); + LOGI("%d ", vc_widget_set_error_cb(g_vc_w, __vc_error_cb, NULL)); + LOGI("%d ", vc_widget_set_show_tooltip_cb(g_vc_w, __vc_show_tooltip_cb, NULL)); + LOGI("%d ", vc_widget_set_result_cb(g_vc_w, __vc_widget_result_cb, NULL)); + LOGI("%d ", vc_widget_set_asr_result_cb(g_vc_w, __vc_widget_asr_result_cb, NULL)); + LOGI("%d ", vc_widget_set_state_changed_cb(g_vc_w, __vc_state_changed_cb, NULL)); + LOGI("%d ", vc_widget_set_service_state_changed_cb(g_vc_w, __vc_service_state_changed_cb, NULL)); + LOGI("%d ", vc_widget_set_send_current_command_list_cb(g_vc_w, __vc_widget_send_current_command_list_cb, (void*)m_list)); + LOGI("%d ", vc_widget_set_current_language_changed_cb(g_vc_w, __vc_language_changed_cb, NULL)); + #if 0 + LOGI("%d ",vc_widget_set_request_action_cb(g_vc_w, __vc_request_action_cb, NULL)); + LOGI("%d ",vc_widget_set_getdata_cb(g_vc_w, __vc_get_client_data_cb, NULL)); + LOGI("%d ",vc_widget_set_setdata_cb(g_vc_w, __vc_set_client_data_cb, NULL)); + #endif + LOGI("%d ", vc_widget_prepare(g_vc_w)); + + // initialize virtual touch device + touch = efl_util_input_initialize_generator(EFL_UTIL_INPUT_DEVTYPE_TOUCHSCREEN); + + if (NULL == touch) { + LOGE("[ERROR] initialize efl util failed"); + } + + m_main_script = vc_webview_load_script("vc-webview.js"); + if (NULL == m_main_script) { + return; + } + + LOGI("[INFO] All listeners unset!"); +} + +VCWebView::~VCWebView() +{ + LOGI("===== Deinit VC Webview ====="); + + vc_widget_unprepare(g_vc_w); + vc_widget_unset_error_cb(g_vc_w); + vc_widget_unset_show_tooltip_cb(g_vc_w); + vc_widget_unset_result_cb(g_vc_w); + vc_widget_unset_asr_result_cb(g_vc_w); + vc_widget_unset_state_changed_cb(g_vc_w); + vc_widget_unset_service_state_changed_cb(g_vc_w); + vc_widget_unset_send_current_command_list_cb(g_vc_w); + vc_widget_unset_current_language_changed_cb(g_vc_w); + #if 0 + vc_widget_unset_request_action_cb(g_vc_w); + vc_widget_unset_getdata_cb(g_vc_w); + vc_widget_unset_setdata_cb(g_vc_w); + #endif + vc_widget_deinitialize(g_vc_w); + + if (NULL != m_list) { + vc_cmd_list_destroy(m_list, true); + m_list = NULL; + } + + if (NULL != m_main_script) + delete [] m_main_script; + + if (0 != efl_util_input_deinitialize_generator(touch)) { + LOGE("[ERROR] Fail to deinitialize"); + } + + LOGI("====="); +} + +int VCWebView::vc_is_supported_web_vt(bool *vt_automode) { + int ret = -1; + ret = vconf_get_bool(VC_VOICE_TOUCH_AUTOMODE, (int*)vt_automode); + + if (0 != ret) { + LOGE("[ERROR] Fail to get vconfkey"); + return VC_ERROR_OPERATION_FAILED; + } + + return ret; +} + +VCWebView* VCWebView::getInstance() +{ + static VCWebView plugin; + return &plugin; +} + +void VCWebView::vc_feed_touch_event(double x, double y) +{ + LOGI("===== Feed touch event (%lf) (%lf) =====", x, y); + + int ret = -1; + int ewk_x, ewk_y, ewk_w, ewk_h; + evas_object_geometry_get(m_ewk_view, &ewk_x, &ewk_y, &ewk_w, &ewk_h); + LOGD("x : (%d), y : (%d), w : (%d), h : (%d)", ewk_x, ewk_y, ewk_w, ewk_h); + + usleep(1500000); + + int coord_x, coord_y; + coord_x = (int)(x * ewk_w) + ewk_x; + coord_y = (int)(y * ewk_h) + ewk_y; + + ret = efl_util_input_generate_touch(touch, 0, EFL_UTIL_INPUT_TOUCH_BEGIN, coord_x, coord_y); + if (0 != ret) { + LOGW("[WARNING] event generation failed"); + } + + ret = efl_util_input_generate_touch(touch, 0, EFL_UTIL_INPUT_TOUCH_END, coord_x, coord_y); + if (0 != ret) { + LOGW("[WARNING] event generation failed"); + } + + LOGI("==="); +} + +void __js_script_result_action_cb(Evas_Object *obj, const char *javascript_result, void *data) +{ + LOGI("===== javascript_result_action[%s] = [%s]", data, javascript_result); + + if (NULL != data) { + if (!strcmp((char*)data, "RESULT")) { + if (NULL != javascript_result) { + std::string js_result(javascript_result); + js_result.erase(0, 1); + js_result.erase(js_result.length() - 1, 1); + LOGD("After modify (%s)", js_result.c_str()); + const std::string delimiters = ","; + + int cnt = 0; + double x = 0; + double y = 0; + std::string::size_type lastPos = js_result.find_first_not_of(delimiters, 0); + std::string::size_type pos = js_result.find_first_of(delimiters, lastPos); + + std::string sub = js_result.substr(lastPos, pos - lastPos); + if (sub != "undefined") { + cnt = atoi(sub.c_str()); + LOGD("Result count = %d", cnt); + } + + lastPos = js_result.find_first_not_of(delimiters, pos); + pos = js_result.find_first_of(delimiters, lastPos); + + sub = js_result.substr(lastPos, pos - lastPos); + if (sub != "undefined") { + x = strtod(sub.c_str(), NULL); + LOGD("Point x(%lf)", x); + } + + lastPos = js_result.find_first_not_of(delimiters, pos); + pos = js_result.find_first_of(delimiters, lastPos); + + sub = js_result.substr(lastPos, pos - lastPos); + if (sub != "undefined") { + y = strtod(sub.c_str(), NULL); + LOGD("Point y(%lf)", y); + } + + if (-1 == cnt) { + LOGI("There is Nothing to match"); + g_wait = false; + return; + } + + g_consumed = true; + if (cnt > 1) { + LOGI("Conflict"); + } else if (cnt == 1) { + LOGI("[INFO] Touch specified element"); + VCWebView::getInstance()->vc_feed_touch_event(x, y); + } + } + } + } + + g_wait = false; +} + +#if 0 +void __js_script_client_data_cb(Evas_Object *obj, const char *javascript_result, void *data) +{ + LOGI("===== javascript_result_action[%s] = [%s]", data, javascript_result); + + if (NULL != data) { + g_wait = false; + if (!strcmp((char*)data, "SET")) { + } else if (!strcmp((char*)data, "GET")) { + if (NULL != javascript_result) { + std::string js_result(javascript_result); + js_result.erase(0, 1); + js_result.erase(js_result.length() - 1, 1); + LOGI("After modify (%s)", js_result.c_str()); + + g_return = strdup(js_result.c_str()); + } + } + } +} + +void __js_script_request_action_cb(Evas_Object *obj, const char *javascript_result, void *data) +{ +} + +bool VCWebView::vc_set_client_data_cb(const char* key, const char* value) +{ + LOGI("=== Set client data cb ==="); + std::string key_temp(key); + std::string value_temp(value); + std::string execute = "vc_widget_get_client_data(\"" + key_temp + "\",\"" + value_temp + "\");"; + + g_wait = true; + ewk_view_script_execute(m_ewk_view, execute.c_str(), __js_script_client_data_cb, (void*)"SET"); + while (true == g_wait) { + ecore_main_loop_iterate(); + } + + return true; +} + +bool VCWebView::vc_get_client_data_cb(const char* key, char** value) +{ + LOGI("=== Get client data cb ==="); + std::string key_temp(key); + std::string execute = "vc_widget_request_action(\"" + key_temp + "\");"; + + g_wait = true; + + ewk_view_script_execute(m_ewk_view, execute.c_str(), __js_script_client_data_cb, (void*)"GET"); + while (true == g_wait) { + ecore_main_loop_iterate(); + } + + if (NULL != g_return) { + *value = strdup(g_return); + free(g_return); + g_return = NULL; + } + + return true; +} + +bool VCWebView::vc_request_action_cb(const char* action, const char* data) +{ + LOGI("=== Request action cb ==="); + std::string data_temp(data); + std::string action_temp(action); + std::string execute = "vc_widget_request_action(\"" + action_temp + "\",\"" + data_temp + "\");"; + + ewk_view_script_execute(m_ewk_view, execute.c_str(), __js_script_request_action_cb, NULL); + + return true; +} +#endif + +void VCWebView::vc_widget_result_cb(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char* result, void *user_data) +{ + LOGI("=== Widget result cb ==="); + + std::string result_temp(result); + std::string action("RESULT"); + std::string execute = "vc_request_action(\"" + action + "\",\"" + result_temp + "\");"; + + g_wait = true; + g_consumed = false; + ewk_view_script_execute(m_ewk_view, execute.c_str(), __js_script_result_action_cb, (void*)"RESULT"); + + LOGI("Execute command: %s", execute.c_str()); +} + +void VCWebView::vc_webview_show_popup(int timeout, const std::string message) +{ + std::stringstream ss; + std::string exec; + ss << timeout; + exec = "vc_show_popup(\"" + message + "\"," + ss.str() + ");"; + + ewk_view_script_execute(m_ewk_view, exec.c_str(), NULL, NULL); + + LOGI("Showing popup: %s", message.c_str()); +} + +void VCWebView::vc_language_changed_cb(const char* previous, const char* current, void *user_data) +{ + if (NULL != m_lang_script) + delete [] m_lang_script; + + char filename[64] = {'\0',}; + snprintf(filename, 64, "vc-webview-%s.js", current); + m_lang_script = vc_webview_load_script(filename); + if (NULL == m_lang_script) { + m_lang_script = vc_webview_load_script("vc-webview-ko_KR.js"); + } + + LOGI("===== Previous lang(%s), Current lang(%s)", previous, current); +} + +void VCWebView::vc_state_changed_cb(vc_state_e previous, vc_state_e current, void *data) +{ + if (VC_STATE_READY == current) { + if (VC_STATE_INITIALIZED == previous) { + LOGI("%d ", vc_widget_enable_asr_result(g_vc_w, true)); + } + + char* lang = NULL; + vc_widget_get_current_language(g_vc_w, &lang); + if (NULL != lang) { + char filename[64] = {'\0',}; + snprintf(filename, 64, "vc-webview-%s.js", lang); + if (NULL != m_lang_script) + delete [] m_lang_script; + + m_lang_script = vc_webview_load_script(filename); + if (NULL == m_lang_script) { + m_lang_script = vc_webview_load_script("vc-webview-ko_KR.js"); + } + free(lang); + } + } + + LOGI("===== Previous state(%d), Current state(%d)", previous, current); +} + +void VCWebView::vc_service_state_changed_cb(vc_service_state_e previous, vc_service_state_e current, void* user_data) +{ + LOGI("service_state_changed_cb"); + if ((VC_SERVICE_STATE_PROCESSING == previous && VC_SERVICE_STATE_READY == current) + ||(VC_SERVICE_STATE_RECORDING == previous && VC_SERVICE_STATE_READY == current)) { + if (NULL != m_list) { + vc_cmd_list_destroy(m_list, true); + m_list = NULL; + } + } +} + +void VCWebView::vc_error_cb(vc_error_e reason, void *data) +{ + LOGE("Error callback : reason(%d)", reason); +} + +void VCWebView::vc_show_tooltip_cb(bool show, void *user_data) +{ + LOGI("===== Show tooltips callback: %d", show); + + if (show == true) { + start_clock = clock(); + std::string start("SHOW_TOOLTIP"); + std::string execute = "vc_request_action(\"" + start + "\",\"\");"; + ewk_view_script_execute(m_ewk_view, execute.c_str(), __js_script_result_action_cb, (void*)"SHOW_TOOLTIP"); + vc_register_commands(); + } else { + std::string ready("HIDE_TOOLTIP"); + std::string execute = "vc_request_action(\"" + ready + "\",\"\");"; + ewk_view_script_execute(m_ewk_view, execute.c_str(), __js_script_result_action_cb, (void*)"HIDE_TOOLTIP"); + } +} + +void VCWebView::vc_register_commands() +{ + vc_add_command("****", "", m_list); + + // if (1 == m_enable_navigation) { + // LOGI("Navigation is ENABLED"); + // vc_add_command(commands[0].c_str(), "", m_list); + // vc_add_command(commands[1].c_str(), "", m_list); + // vc_add_command(commands[2].c_str(), "", m_list); + // vc_add_command(commands[3].c_str(), "", m_list); + // vc_add_command(commands[4].c_str(), "", m_list); + // vc_add_command(commands[5].c_str(), "", m_list); + // vc_add_command(commands[6].c_str(), "", m_list); + // vc_add_command(commands[7].c_str(), "", m_list); + // } else { + // LOGI("Navigation is DISABLED"); + // } +} + +int VCWebView::vc_add_command(const char* cmd, const char* param1, vc_cmd_list_h &list) +{ + LOGI("vc_add_command: %s %s", cmd, param1); + int ret = 0; + if (!list) { + ret = vc_cmd_list_create(&list); + if (ret != 0) { + LOGE("vc_command_group_create error "); + return ret; + } + } + + ret = vc_cmd_create(&cmdh); + if (ret != 0) { + LOGI("vc_create_command != 0"); + return ret; + } + + if (0 == strcmp(param1, "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); + } else { + 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); + } + + if (ret != 0) { + LOGI("vc_command_set_command != 0"); + return ret; + } + + vc_cmd_list_add(list, cmdh); + + return 0; +} + +#if 0 +void __js_script_get_visible_result_cb(Evas_Object *obj, const char *javascript_result, void *data) +{ + LOGI("javascript_result_show=[%s]", javascript_result); +} + +void VCWebView::get_visible_commands(Evas_Object *ewk_view) +{ + std::string str = "vc_get_visible_commands();"; + + LOGI("get_visible_commands"); + + vc_service_state_e state; + int ret; + ret = vc_widget_get_service_state(g_vc_w, &state); + if (0 != ret) { + LOGE("Fail to get service state"); + } else { + if (VC_SERVICE_STATE_RECORDING == state || VC_SERVICE_STATE_PROCESSING == state) { + ret = vc_widget_cancel(g_vc_w); + if ( 0 != ret) { + LOGE("Fail to cancel"); + } + } + } + + ewk_view_script_execute(ewk_view, str.c_str(), __js_script_get_visible_result_cb, NULL); +} +#endif + +static void __js_script_loading_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) +{ + LOGI("javascript pathname [%s]", javascript_result); + + if (NULL == javascript_result) { + LOGE("[ERROR] vc_get_url_path() failed"); + return; + } + + std::string host_name; + std::string path_name; + std::string file_name; + + std::string js_result(javascript_result); + std::string::size_type pos = js_result.find_first_of("/", 0); + + host_name = js_result.substr(0, pos); + path_name = js_result.substr(pos + 1, js_result.length() - pos); + + LOGI("==== Load Custom Script ===="); + + FILE *f = NULL; + file_name = host_name + path_name + ".js"; + char js_path[1024] = {'\0',}; + snprintf(js_path, 1024, "%s/%s", VC_WEBVIEW_CUSTOM_PATH, file_name.c_str()); + LOGD("=== path (%s)", js_path); + + f = fopen(js_path, "r"); + + if (NULL == f) { + LOGE("Couldn't open %s - %s", file_name.c_str(), strerror(errno)); + + file_name = host_name + ".js"; + snprintf(js_path, 1024, "%s/%s", VC_WEBVIEW_CUSTOM_PATH, file_name.c_str()); + LOGD("=== path (%s)", js_path); + + f = fopen(js_path, "r"); + + if (NULL == f) { + LOGE("Couldn't open %s - %s", file_name.c_str(), strerror(errno)); + return; + } + } + + if (m_custom_name.compare(file_name) != 0) { + fseek(f, 0, SEEK_END); + long int fsize = ftell(f); + fseek(f, 0, SEEK_SET); + + char *script = new char [fsize + 1]; + long int ret = fread(script, 1, fsize, f); + if (ret != fsize) { + LOGE("Couldn't read vc-webview.js file %d, %d", fsize, ret); + fclose(f); + delete [] script; + return; + } + fclose(f); + script[fsize] = '\0'; + + delete [] m_custom_script; + m_custom_script = script; + m_custom_name = file_name; + } + + ewk_view_script_execute((Evas_Object*)data, m_custom_script, __js_script_loading_result_cb, (void*)"custom"); +} + +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 (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"); + } + + ewk_view_script_execute(m_ewk_view, "vc_get_url_path();", __js_script_loading_custom_cb, m_ewk_view); +} + +void VCWebView::vc_webview_set_result_cb(vc_webview_result_cb cb) +{ + m_result_cb = cb; +} + +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) +{ + LOGI("javascript [Conflict] -> result [%s]", javascript_result); + + int *conflict = (int*)data; + + *conflict = atoi(javascript_result); + g_wait = false; +} + +int VCWebView::vc_get_conflict_status() +{ + Eina_Bool ret; + int conflict = -1; + + if (!vc_conf_status) { + LOGI("[INFO] Configuration does not set"); + return -1; + } + + g_wait = true; + ret = ewk_view_script_execute(m_ewk_view, "vc_get_conflict_status();", __js_script_conflict_result_cb, (void*)&conflict); + + while (true == g_wait) { + ecore_main_loop_iterate(); + } + + if (!ret) { + LOGE("[ERROR] script execute fail"); + return -1; + } + + return conflict; +} + +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 \ No newline at end of file