summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xCMakeLists.txt91
-rwxr-xr-xLICENSE.Flora206
-rwxr-xr-xPo/CMakeLists.txt46
-rwxr-xr-xPo/ar.po21
-rwxr-xr-xPo/az.po21
-rwxr-xr-xPo/bg.po21
-rwxr-xr-xPo/ca.po21
-rwxr-xr-xPo/cs.po21
-rwxr-xr-xPo/da.po21
-rwxr-xr-xPo/de_DE.po21
-rwxr-xr-xPo/el_GR.po21
-rwxr-xr-xPo/en.po21
-rwxr-xr-xPo/en_PH.po21
-rwxr-xr-xPo/en_US.po21
-rwxr-xr-xPo/es_ES.po21
-rwxr-xr-xPo/es_MX.po21
-rwxr-xr-xPo/et.po21
-rwxr-xr-xPo/eu.po21
-rwxr-xr-xPo/fi.po21
-rwxr-xr-xPo/fr_CA.po21
-rwxr-xr-xPo/fr_FR.po21
-rwxr-xr-xPo/ga.po21
-rwxr-xr-xPo/gl.po21
-rwxr-xr-xPo/hi.po21
-rwxr-xr-xPo/hr.po21
-rwxr-xr-xPo/hu.po21
-rwxr-xr-xPo/hy.po21
-rwxr-xr-xPo/is.po21
-rwxr-xr-xPo/it_IT.po21
-rwxr-xr-xPo/ja_JP.po21
-rwxr-xr-xPo/ka.po21
-rwxr-xr-xPo/kk.po21
-rwxr-xr-xPo/ko_KR.po21
-rwxr-xr-xPo/lt.po21
-rwxr-xr-xPo/lv.po21
-rwxr-xr-xPo/mk.po21
-rwxr-xr-xPo/nb.po21
-rwxr-xr-xPo/nl_NL.po21
-rwxr-xr-xPo/pl.po21
-rwxr-xr-xPo/pt_BR.po21
-rwxr-xr-xPo/pt_PT.po21
-rwxr-xr-xPo/ro.po21
-rwxr-xr-xPo/ru_RU.po21
-rwxr-xr-xPo/sk.po21
-rwxr-xr-xPo/sl.po21
-rwxr-xr-xPo/sr.po21
-rwxr-xr-xPo/sv.po21
-rwxr-xr-xPo/tr_TR.po21
-rwxr-xr-xPo/uk.po21
-rwxr-xr-xPo/uz.po21
-rwxr-xr-xPo/zh_CN.po21
-rwxr-xr-xPo/zh_HK.po21
-rwxr-xr-xPo/zh_SG.po21
-rwxr-xr-xPo/zh_TW.po21
-rw-r--r--cmake/OptionsTizen.cmake3
-rw-r--r--data/200.livebox.web-provider.patch.sh3
-rw-r--r--data/web_provider_db.sql11
-rw-r--r--data/web_provider_reset_db.sh36
-rwxr-xr-xlivebox.web-provider.manifest16
-rwxr-xr-xlivebox.web-provider.mobile.rule89
-rwxr-xr-xlivebox.web-provider.rule40
-rw-r--r--livebox.web-provider.xml18
-rw-r--r--packaging/livebox.web-provider.spec121
-rw-r--r--pkgconfig/web-provider-svc.pc.in11
-rw-r--r--pkgconfig/web-provider.pc.in11
-rw-r--r--src_mobile/API/CMakeLists.txt68
-rw-r--r--src_mobile/API/SqliteDB.cpp138
-rw-r--r--src_mobile/API/SqliteDB.h44
-rw-r--r--src_mobile/API/WebProviderDB.h34
-rw-r--r--src_mobile/API/web-provider-info.h25
-rw-r--r--src_mobile/API/web_provider_livebox_info.cpp316
-rw-r--r--src_mobile/API/web_provider_livebox_info.h55
-rwxr-xr-xsrc_mobile/API/web_provider_plugin_info.cpp350
-rwxr-xr-xsrc_mobile/API/web_provider_plugin_info.h51
-rw-r--r--src_mobile/CMakeLists.txt31
-rw-r--r--src_mobile/Core/Box.cpp387
-rw-r--r--src_mobile/Core/Box.h104
-rw-r--r--src_mobile/Core/BoxData.h80
-rw-r--r--src_mobile/Core/BoxManager.cpp327
-rw-r--r--src_mobile/Core/BoxManager.h81
-rwxr-xr-xsrc_mobile/Core/BoxSchemeHandler.cpp308
-rwxr-xr-xsrc_mobile/Core/BoxSchemeHandler.h68
-rw-r--r--src_mobile/Core/BoxState.cpp109
-rw-r--r--src_mobile/Core/BoxState.h158
-rw-r--r--src_mobile/Core/BoxUpdateTimer.cpp91
-rw-r--r--src_mobile/Core/BoxUpdateTimer.h48
-rw-r--r--src_mobile/Core/Buffer/BoxRenderBuffer.cpp135
-rw-r--r--src_mobile/Core/Buffer/BoxRenderBuffer.h83
-rw-r--r--src_mobile/Core/Buffer/CMakeLists.txt67
-rw-r--r--src_mobile/Core/Buffer/IRenderBuffer.h41
-rw-r--r--src_mobile/Core/Buffer/PdRenderBuffer.cpp132
-rw-r--r--src_mobile/Core/Buffer/PdRenderBuffer.h79
-rwxr-xr-xsrc_mobile/Core/Buffer/RenderBuffer.cpp326
-rw-r--r--src_mobile/Core/Buffer/RenderBuffer.h78
-rw-r--r--src_mobile/Core/Buffer/RenderBufferFactory.cpp49
-rw-r--r--src_mobile/Core/Buffer/RenderBufferFactory.h45
-rw-r--r--src_mobile/Core/CMakeLists.txt86
-rw-r--r--src_mobile/Core/IBox.h56
-rw-r--r--src_mobile/Core/IBoxContext.h33
-rw-r--r--src_mobile/Core/IBoxManager.h36
-rw-r--r--src_mobile/Core/IBoxState.h41
-rw-r--r--src_mobile/Core/Service/AppControl.cpp124
-rw-r--r--src_mobile/Core/Service/AppControl.h30
-rwxr-xr-xsrc_mobile/Core/Service/CMakeLists.txt72
-rwxr-xr-xsrc_mobile/Core/Service/MessageManager.cpp92
-rw-r--r--src_mobile/Core/Service/MessageManager.h53
-rwxr-xr-xsrc_mobile/Core/Service/PeriodChanger.cpp287
-rwxr-xr-xsrc_mobile/Core/Service/PeriodChanger.h79
-rw-r--r--src_mobile/Core/Service/ScrollHolder.cpp42
-rw-r--r--src_mobile/Core/Service/ScrollHolder.h29
-rw-r--r--src_mobile/Core/Util/CMakeLists.txt60
-rw-r--r--src_mobile/Core/Util/ITimer.h39
-rw-r--r--src_mobile/Core/Util/Log.cpp19
-rw-r--r--src_mobile/Core/Util/Log.h35
-rw-r--r--src_mobile/Core/Util/Noncopyable.h33
-rw-r--r--src_mobile/Core/Util/Util.h25
-rw-r--r--src_mobile/Core/View/CMakeLists.txt66
-rw-r--r--src_mobile/Core/View/IPdHelper.h41
-rw-r--r--src_mobile/Core/View/IRenderView.h53
-rw-r--r--src_mobile/Core/View/IWebView.h44
-rw-r--r--src_mobile/Core/View/PdHelper.cpp147
-rw-r--r--src_mobile/Core/View/PdHelper.h69
-rwxr-xr-xsrc_mobile/Core/View/WebView.cpp847
-rw-r--r--src_mobile/Core/View/WebView.h175
-rw-r--r--src_mobile/Core/View/injection.js129
-rw-r--r--src_mobile/Daemon/BoxDaemon.cpp47
-rw-r--r--src_mobile/Daemon/BoxDaemon.h43
-rwxr-xr-xsrc_mobile/Daemon/BoxDaemonImpl.cpp754
-rw-r--r--src_mobile/Daemon/BoxDaemonImpl.h119
-rw-r--r--src_mobile/Daemon/BoxDaemonUtil.cpp70
-rw-r--r--src_mobile/Daemon/BoxDaemonUtil.h35
-rw-r--r--src_mobile/Daemon/CMakeLists.txt66
-rwxr-xr-xsrc_mobile/Daemon/main.cpp159
-rwxr-xr-xsrc_mobile/Plugin/AppBoxPlugin/AppBoxManager.cpp153
-rw-r--r--src_mobile/Plugin/AppBoxPlugin/AppBoxManager.h55
-rw-r--r--src_mobile/Plugin/AppBoxPlugin/AppBoxObserver.cpp156
-rw-r--r--src_mobile/Plugin/AppBoxPlugin/AppBoxObserver.h59
-rw-r--r--src_mobile/Plugin/AppBoxPlugin/AppBoxPdHelper.cpp89
-rw-r--r--src_mobile/Plugin/AppBoxPlugin/AppBoxPdHelper.h55
-rw-r--r--src_mobile/Plugin/AppBoxPlugin/AppBoxPluginFactory.cpp41
-rw-r--r--src_mobile/Plugin/AppBoxPlugin/AppBoxPluginFactory.h45
-rw-r--r--src_mobile/Plugin/AppBoxPlugin/AppBoxRenderBuffer.cpp119
-rw-r--r--src_mobile/Plugin/AppBoxPlugin/AppBoxRenderBuffer.h60
-rwxr-xr-xsrc_mobile/Plugin/AppBoxPlugin/AppBoxRenderView.cpp683
-rw-r--r--src_mobile/Plugin/AppBoxPlugin/AppBoxRenderView.h136
-rw-r--r--src_mobile/Plugin/AppBoxPlugin/CMakeLists.txt75
-rw-r--r--src_mobile/Plugin/AppBoxPlugin/app.json5
-rw-r--r--src_mobile/Plugin/AppBoxPlugin/box_plugin_interface.cpp55
-rw-r--r--src_mobile/Plugin/BoxPluginConnector.cpp186
-rw-r--r--src_mobile/Plugin/BoxPluginConnector.h51
-rw-r--r--src_mobile/Plugin/CMakeLists.txt67
-rw-r--r--src_mobile/Plugin/IBoxPluginConnector.h40
-rw-r--r--src_mobile/Plugin/IBoxPluginFactory.h47
-rw-r--r--src_mobile/Plugin/box_plugin_interface.h77
-rw-r--r--src_wearable/API/CMakeLists.txt72
-rw-r--r--src_wearable/API/SqliteDB.cpp137
-rw-r--r--src_wearable/API/SqliteDB.h44
-rw-r--r--src_wearable/API/WebProviderDB.h34
-rw-r--r--src_wearable/API/web-provider-info.h25
-rw-r--r--src_wearable/API/web_provider_livebox_info.cpp400
-rw-r--r--src_wearable/API/web_provider_livebox_info.h59
-rwxr-xr-xsrc_wearable/API/web_provider_plugin_info.cpp349
-rwxr-xr-xsrc_wearable/API/web_provider_plugin_info.h51
-rw-r--r--src_wearable/API/web_provider_service.cpp175
-rw-r--r--src_wearable/API/web_provider_service.h48
-rw-r--r--src_wearable/CMakeLists.txt31
-rw-r--r--src_wearable/Core/Box.cpp311
-rw-r--r--src_wearable/Core/Box.h94
-rw-r--r--src_wearable/Core/BoxData.h85
-rwxr-xr-xsrc_wearable/Core/BoxLoadBalancer.cpp185
-rwxr-xr-xsrc_wearable/Core/BoxLoadBalancer.h80
-rwxr-xr-xsrc_wearable/Core/BoxManager.cpp471
-rwxr-xr-xsrc_wearable/Core/BoxManager.h91
-rw-r--r--src_wearable/Core/BoxState.cpp109
-rw-r--r--src_wearable/Core/BoxState.h158
-rw-r--r--src_wearable/Core/BoxUpdateTimer.cpp112
-rw-r--r--src_wearable/Core/BoxUpdateTimer.h56
-rwxr-xr-xsrc_wearable/Core/Buffer/BoxRenderBuffer.cpp151
-rw-r--r--src_wearable/Core/Buffer/BoxRenderBuffer.h80
-rw-r--r--src_wearable/Core/Buffer/CMakeLists.txt65
-rw-r--r--src_wearable/Core/Buffer/IRenderBuffer.h45
-rw-r--r--src_wearable/Core/Buffer/PdRenderBuffer.cpp247
-rw-r--r--src_wearable/Core/Buffer/PdRenderBuffer.h80
-rwxr-xr-xsrc_wearable/Core/Buffer/RenderBuffer.cpp428
-rw-r--r--src_wearable/Core/Buffer/RenderBuffer.h90
-rw-r--r--src_wearable/Core/CMakeLists.txt88
-rw-r--r--src_wearable/Core/IBox.h59
-rw-r--r--src_wearable/Core/IBoxContext.h33
-rw-r--r--src_wearable/Core/IBoxManager.h36
-rw-r--r--src_wearable/Core/IBoxState.h41
-rw-r--r--src_wearable/Core/Platform.h48
-rw-r--r--src_wearable/Core/Util/CMakeLists.txt61
-rw-r--r--src_wearable/Core/Util/ITimer.h43
-rw-r--r--src_wearable/Core/Util/Log.cpp19
-rw-r--r--src_wearable/Core/Util/Log.h35
-rw-r--r--src_wearable/Core/Util/Noncopyable.h33
-rw-r--r--src_wearable/Core/Util/Util.h25
-rw-r--r--src_wearable/Core/View/CMakeLists.txt75
-rw-r--r--src_wearable/Core/View/IJsInterface.h34
-rw-r--r--src_wearable/Core/View/IPdHelper.h41
-rw-r--r--src_wearable/Core/View/IRenderView.h48
-rw-r--r--src_wearable/Core/View/IWebView.h44
-rwxr-xr-xsrc_wearable/Core/View/JsInterface.cpp243
-rwxr-xr-xsrc_wearable/Core/View/JsInterface.h64
-rw-r--r--src_wearable/Core/View/PdHelper.cpp147
-rw-r--r--src_wearable/Core/View/PdHelper.h69
-rw-r--r--src_wearable/Core/View/RenderView.cpp321
-rw-r--r--src_wearable/Core/View/RenderView.h99
-rw-r--r--src_wearable/Core/View/Service/AppControl.cpp124
-rw-r--r--src_wearable/Core/View/Service/AppControl.h30
-rwxr-xr-xsrc_wearable/Core/View/Service/CMakeLists.txt72
-rwxr-xr-xsrc_wearable/Core/View/Service/MessageManager.cpp92
-rw-r--r--src_wearable/Core/View/Service/MessageManager.h53
-rwxr-xr-xsrc_wearable/Core/View/Service/PeriodChanger.cpp276
-rwxr-xr-xsrc_wearable/Core/View/Service/PeriodChanger.h79
-rw-r--r--src_wearable/Core/View/Service/ScrollHolder.cpp42
-rw-r--r--src_wearable/Core/View/Service/ScrollHolder.h29
-rwxr-xr-xsrc_wearable/Core/View/WebView.cpp904
-rw-r--r--src_wearable/Core/View/WebView.h177
-rw-r--r--src_wearable/Core/View/injection.js151
-rw-r--r--src_wearable/Core/config.h25
-rw-r--r--src_wearable/Daemon/BoxDaemon.cpp47
-rw-r--r--src_wearable/Daemon/BoxDaemon.h43
-rwxr-xr-xsrc_wearable/Daemon/BoxDaemonImpl.cpp790
-rwxr-xr-xsrc_wearable/Daemon/BoxDaemonImpl.h124
-rw-r--r--src_wearable/Daemon/BoxDaemonUtil.cpp89
-rw-r--r--src_wearable/Daemon/BoxDaemonUtil.h36
-rw-r--r--src_wearable/Daemon/CMakeLists.txt66
-rwxr-xr-xsrc_wearable/Daemon/main.cpp161
-rwxr-xr-xsrc_wearable/Plugin/AppBoxPlugin/AppBoxManager.cpp161
-rw-r--r--src_wearable/Plugin/AppBoxPlugin/AppBoxManager.h55
-rw-r--r--src_wearable/Plugin/AppBoxPlugin/AppBoxPdHelper.cpp89
-rw-r--r--src_wearable/Plugin/AppBoxPlugin/AppBoxPdHelper.h55
-rw-r--r--src_wearable/Plugin/AppBoxPlugin/AppBoxPluginFactory.cpp32
-rw-r--r--src_wearable/Plugin/AppBoxPlugin/AppBoxPluginFactory.h44
-rwxr-xr-xsrc_wearable/Plugin/AppBoxPlugin/AppBoxRenderView.cpp950
-rwxr-xr-xsrc_wearable/Plugin/AppBoxPlugin/AppBoxRenderView.h143
-rw-r--r--src_wearable/Plugin/AppBoxPlugin/CMakeLists.txt73
-rw-r--r--src_wearable/Plugin/AppBoxPlugin/app.json5
-rw-r--r--src_wearable/Plugin/AppBoxPlugin/box_plugin_interface.cpp55
-rwxr-xr-xsrc_wearable/Plugin/BoxPluginConnector.cpp187
-rw-r--r--src_wearable/Plugin/BoxPluginConnector.h51
-rw-r--r--src_wearable/Plugin/CMakeLists.txt67
-rw-r--r--src_wearable/Plugin/IBoxPluginConnector.h40
-rw-r--r--src_wearable/Plugin/IBoxPluginFactory.h42
-rwxr-xr-xsrc_wearable/Plugin/box_plugin_interface.h78
-rw-r--r--uncrustify.cfg170
-rwxr-xr-xuncrustify.sh1
248 files changed, 23847 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755
index 0000000..f99cd6c
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,91 @@
+# Copyright (c) 2012-13 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(web-provider CXX)
+
+STRING(REGEX MATCH "([^.]*)" CMAKE_PROJECT_API_VERSION "${CMAKE_PROJECT_VERSION}")
+INCLUDE(FindPkgConfig)
+
+# Build type
+IF(NOT CMAKE_BUILD_TYPE)
+ SET(CMAKE_BUILD_TYPE "Release")
+ENDIF(NOT CMAKE_BUILD_TYPE)
+
+SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+INCLUDE(OptionsTizen)
+
+# Compiler flags
+SET(CMAKE_C_FLAGS_PROFILING "-O0 -g -pg")
+SET(CMAKE_CXX_FLAGS_PROFILING "-O0 -std=c++0x -g -pg")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -std=c++0x -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2 -g")
+SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -std=c++0x -g -fvisibility-inlines-hidden")
+
+SET(GC_SECTIONS_FLAGS "-fdata-sections -ffunction-sections -Wl,--gc-sections")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GC_SECTIONS_FLAGS}")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GC_SECTIONS_FLAGS}")
+
+# Set compiler options
+ADD_DEFINITIONS("-Wall")
+ADD_DEFINITIONS("-Wextra")
+ADD_DEFINITIONS("-fPIC")
+ADD_DEFINITIONS("-Wno-deprecated")
+ADD_DEFINITIONS("-fvisibility=hidden")
+ADD_DEFINITIONS("-shared")
+
+# Set Tag Name
+ADD_DEFINITIONS("-DLOG_TAG=\"${PROJECT_NAME}\"")
+
+SET(PKGCONFIG_DIR pkgconfig)
+SET(DATA_DIR data)
+
+# Macro for easy usage
+MACRO(INSTALL_FILE FILE DEST_DIR)
+ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}
+ DESTINATION ${DEST_DIR})
+ENDMACRO()
+MACRO(INSTALL_FILE_RENAMED FILE DEST_DIR NEW_NAME)
+ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}
+ DESTINATION ${DEST_DIR} RENAME ${NEW_NAME})
+ENDMACRO()
+MACRO(CONFIG_FILE SRC_FILE DEST_FILE)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FILE}
+ ${CMAKE_CURRENT_SOURCE_DIR}/${DEST_FILE} @ONLY)
+ENDMACRO()
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src)
+ADD_SUBDIRECTORY(src)
+ADD_SUBDIRECTORY(Po)
+
+CONFIG_FILE(${PKGCONFIG_DIR}/web-provider-svc.pc.in ${PKGCONFIG_DIR}/web-provider-svc.pc) # DEPRECATED
+INSTALL_FILE(${PKGCONFIG_DIR}/web-provider-svc.pc lib/pkgconfig) # DEPRECATED
+
+CONFIG_FILE(${PKGCONFIG_DIR}/web-provider.pc.in ${PKGCONFIG_DIR}/web-provider.pc)
+INSTALL_FILE(${PKGCONFIG_DIR}/web-provider.pc lib/pkgconfig)
+INSTALL_FILE(livebox.web-provider.xml /usr/share/packages)
+INSTALL_FILE(${DATA_DIR}/web_provider_reset_db.sh bin)
+INSTALL_FILE(${DATA_DIR}/web_provider_db.sql /usr/share/${PROJECT_NAME})
+INSTALL_FILE(${DATA_DIR}/200.livebox.web-provider.patch.sh /etc/opt/upgrade)
+
+IF(DEVICE_PROFILE STREQUAL "wearable")
+ INSTALL_FILE(livebox.web-provider.rule /etc/smack/accesses2.d)
+ELSE(DEVICE_PROFILE STREQUAL "wearable")
+ INSTALL_FILE(livebox.web-provider.rule /etc/smack/accesses.d)
+ENDIF(DEVICE_PROFILE STREQUAL "wearable")
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "web-provider-svc.pc")
diff --git a/LICENSE.Flora b/LICENSE.Flora
new file mode 100755
index 0000000..571fe79
--- /dev/null
+++ b/LICENSE.Flora
@@ -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/Po/CMakeLists.txt b/Po/CMakeLists.txt
new file mode 100755
index 0000000..462c6b3
--- /dev/null
+++ b/Po/CMakeLists.txt
@@ -0,0 +1,46 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Leerang Song (leerang.song@samsung.com)
+
+SET(POFILES
+hy.po az.po eu.po bg.po ca.po cs.po da.po nl_NL.po en.po en_US.po
+et.po fi.po fr_FR.po gl.po hr.po ka.po de_DE.po el_GR.po hu.po is.po
+it_IT.po kk.po ko_KR.po lv.po lt.po nb.po pl.po pt_PT.po pt_BR.po ro.po
+ru_RU.po sr.po sk.po sl.po es_ES.po es_MX.po sv.po tr_TR.po uk.po uz.po
+fr_CA.po ja_JP.po)
+
+SET(LOCALE_DIR "/usr/share/res/locale/")
+ADD_DEFINITIONS("-DLOCALEDIR=\"${LOCALE_DIR}\"")
+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 ${LOCALE_DIR}/${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/Po/ar.po b/Po/ar.po
new file mode 100755
index 0000000..dc63866
--- /dev/null
+++ b/Po/ar.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 ساعة"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "إلغاء"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "مطلقا"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 ساعات"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "ساعة واحدة"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 ساعات"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "تحديث تلقائي"
+
diff --git a/Po/az.po b/Po/az.po
new file mode 100755
index 0000000..4e47d4e
--- /dev/null
+++ b/Po/az.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 saat"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Ləğv et"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Heç vaxt"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 saat"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 saat"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 saat"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Avtomatik yeniləmə"
+
diff --git a/Po/bg.po b/Po/bg.po
new file mode 100755
index 0000000..e79dad0
--- /dev/null
+++ b/Po/bg.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 часа"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Отказ"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Никога"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 часа"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 час"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 часа"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Автоматично опресняване"
+
diff --git a/Po/ca.po b/Po/ca.po
new file mode 100755
index 0000000..aac7114
--- /dev/null
+++ b/Po/ca.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 hores"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Cancelar"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Mai"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 hores"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 hora"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 hores"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Actualitzar automàticament"
+
diff --git a/Po/cs.po b/Po/cs.po
new file mode 100755
index 0000000..571ba99
--- /dev/null
+++ b/Po/cs.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 hodin"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Zrušit"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Nikdy"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 hodin"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 hodina"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 hodiny"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Automatická aktualizace"
+
diff --git a/Po/da.po b/Po/da.po
new file mode 100755
index 0000000..2de61d2
--- /dev/null
+++ b/Po/da.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 timer"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Annullér"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Aldrig"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 timer"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 time"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 timer"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Automatisk opdatering"
+
diff --git a/Po/de_DE.po b/Po/de_DE.po
new file mode 100755
index 0000000..1391bcd
--- /dev/null
+++ b/Po/de_DE.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 Stunden"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Abbruch"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Nie"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 Stunden"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 Stunde"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 Stunden"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Autom. Aktualisierung"
+
diff --git a/Po/el_GR.po b/Po/el_GR.po
new file mode 100755
index 0000000..2ae63db
--- /dev/null
+++ b/Po/el_GR.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 ώρες"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Ακύρωση"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Ποτέ"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 ώρες"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 ώρα"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 ώρες"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Αυτόματη ανανέωση"
+
diff --git a/Po/en.po b/Po/en.po
new file mode 100755
index 0000000..d5defb1
--- /dev/null
+++ b/Po/en.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 hours"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Cancel"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Never"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 hours"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 hour"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 hours"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Auto refresh"
+
diff --git a/Po/en_PH.po b/Po/en_PH.po
new file mode 100755
index 0000000..d5defb1
--- /dev/null
+++ b/Po/en_PH.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 hours"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Cancel"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Never"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 hours"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 hour"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 hours"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Auto refresh"
+
diff --git a/Po/en_US.po b/Po/en_US.po
new file mode 100755
index 0000000..d5defb1
--- /dev/null
+++ b/Po/en_US.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 hours"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Cancel"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Never"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 hours"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 hour"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 hours"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Auto refresh"
+
diff --git a/Po/es_ES.po b/Po/es_ES.po
new file mode 100755
index 0000000..85f5dc5
--- /dev/null
+++ b/Po/es_ES.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 horas"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Cancelar"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Nunca"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 horas"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 hora"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 horas"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Actualizar automáticamente"
+
diff --git a/Po/es_MX.po b/Po/es_MX.po
new file mode 100755
index 0000000..85f5dc5
--- /dev/null
+++ b/Po/es_MX.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 horas"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Cancelar"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Nunca"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 horas"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 hora"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 horas"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Actualizar automáticamente"
+
diff --git a/Po/et.po b/Po/et.po
new file mode 100755
index 0000000..c5961f7
--- /dev/null
+++ b/Po/et.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 tundi"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Tühista"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Mitte kunagi"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 tundi"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 tund"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 tundi"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Automaatne värskendamine"
+
diff --git a/Po/eu.po b/Po/eu.po
new file mode 100755
index 0000000..edbdb81
--- /dev/null
+++ b/Po/eu.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 ordu"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Ezeztatu"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Inoiz ez"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 ordu"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "Ordu 1"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 ordu"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Freskatu automatikoki"
+
diff --git a/Po/fi.po b/Po/fi.po
new file mode 100755
index 0000000..2d4b69f
--- /dev/null
+++ b/Po/fi.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 tuntia"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Peruuta"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Ei koskaan"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 tuntia"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 tunti"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 tuntia"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Automaattinen päivitys"
+
diff --git a/Po/fr_CA.po b/Po/fr_CA.po
new file mode 100755
index 0000000..388e4e3
--- /dev/null
+++ b/Po/fr_CA.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 heures"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Annuler"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Jamais"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 heures"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 heure"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 heures"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Actualisation automatique"
+
diff --git a/Po/fr_FR.po b/Po/fr_FR.po
new file mode 100755
index 0000000..388e4e3
--- /dev/null
+++ b/Po/fr_FR.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 heures"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Annuler"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Jamais"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 heures"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 heure"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 heures"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Actualisation automatique"
+
diff --git a/Po/ga.po b/Po/ga.po
new file mode 100755
index 0000000..ffadae8
--- /dev/null
+++ b/Po/ga.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 uair an chloig"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Cealaigh"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Choíche"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 huaire an chloig"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 uair an chloig"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 huaire an chloig"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Uath-athnuaigh"
+
diff --git a/Po/gl.po b/Po/gl.po
new file mode 100755
index 0000000..bdef673
--- /dev/null
+++ b/Po/gl.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 horas"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Cancelar"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Nunca"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 horas"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 hora"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 horas"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Actualización automática"
+
diff --git a/Po/hi.po b/Po/hi.po
new file mode 100755
index 0000000..673bf72
--- /dev/null
+++ b/Po/hi.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 घंटे"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "रद्द"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "कभी नहीं"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 घंटे"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 घंटा"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 घंटे"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "स्वतः रीफ्रेश करना"
+
diff --git a/Po/hr.po b/Po/hr.po
new file mode 100755
index 0000000..3705e9a
--- /dev/null
+++ b/Po/hr.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 sati"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Prekid"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Nikad"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 sati"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 sat"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 sata"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Automatsko aktualiziranje"
+
diff --git a/Po/hu.po b/Po/hu.po
new file mode 100755
index 0000000..6eb6d2f
--- /dev/null
+++ b/Po/hu.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 óra"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Mégse"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Soha"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 óra"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 óra"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 óra"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Automatikus frissítés"
+
diff --git a/Po/hy.po b/Po/hy.po
new file mode 100755
index 0000000..ef82cb0
--- /dev/null
+++ b/Po/hy.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 ժամ"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Չեղարկել"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Երբեք"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 ժամ"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 ժամ"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 ժամ"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Ինքնանորացում"
+
diff --git a/Po/is.po b/Po/is.po
new file mode 100755
index 0000000..6e6c7ac
--- /dev/null
+++ b/Po/is.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 klst."
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Hætta v."
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Aldrei"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 klst."
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 klst."
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 klst."
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Sjálfvirk uppfærsla"
+
diff --git a/Po/it_IT.po b/Po/it_IT.po
new file mode 100755
index 0000000..62c0eda
--- /dev/null
+++ b/Po/it_IT.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 ore"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Annulla"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Mai"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 ore"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 ora"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 ore"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Aggiornamento automatico"
+
diff --git a/Po/ja_JP.po b/Po/ja_JP.po
new file mode 100755
index 0000000..2c67453
--- /dev/null
+++ b/Po/ja_JP.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12時間"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "キャンセル"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "なし"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6時間"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1時間"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3時間"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "自動更新"
+
diff --git a/Po/ka.po b/Po/ka.po
new file mode 100755
index 0000000..3a99498
--- /dev/null
+++ b/Po/ka.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 საათი"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "გაუქმება"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "არასოდეს"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 საათი"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 საათი"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 საათი"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "ავტომატური განახლება"
+
diff --git a/Po/kk.po b/Po/kk.po
new file mode 100755
index 0000000..3263792
--- /dev/null
+++ b/Po/kk.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 сағат"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Тоқтату"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Ешқашан"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 cағат"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 сағат"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 сағат"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Авто жаңарту"
+
diff --git a/Po/ko_KR.po b/Po/ko_KR.po
new file mode 100755
index 0000000..598a4c9
--- /dev/null
+++ b/Po/ko_KR.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12시간"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "취소"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "안 함"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6시간"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1시간"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3시간"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "자동 새로고침"
+
diff --git a/Po/lt.po b/Po/lt.po
new file mode 100755
index 0000000..da32502
--- /dev/null
+++ b/Po/lt.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 valandų"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Atšaukti"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Niekada"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 valandos"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 valanda"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 valandos"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Automatinis atnaujinimas"
+
diff --git a/Po/lv.po b/Po/lv.po
new file mode 100755
index 0000000..13821cf
--- /dev/null
+++ b/Po/lv.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 stundas"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Atcelt"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Nekad"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 stundas"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 stunda"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 stundas"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Automātiskā atsvaidzināšana"
+
diff --git a/Po/mk.po b/Po/mk.po
new file mode 100755
index 0000000..8b1736e
--- /dev/null
+++ b/Po/mk.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 часа"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Откажи"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Никогаш"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 часа"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 час"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 часа"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Автоматско обновување"
+
diff --git a/Po/nb.po b/Po/nb.po
new file mode 100755
index 0000000..1729025
--- /dev/null
+++ b/Po/nb.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 timer"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Avbryt"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Aldri"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 timer"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 time"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 timer"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Automatisk oppdatering"
+
diff --git a/Po/nl_NL.po b/Po/nl_NL.po
new file mode 100755
index 0000000..1eef04d
--- /dev/null
+++ b/Po/nl_NL.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 uur"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Annuleer"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Nooit"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 uur"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 uur"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 uur"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Autom. vernieuwen"
+
diff --git a/Po/pl.po b/Po/pl.po
new file mode 100755
index 0000000..ff75551
--- /dev/null
+++ b/Po/pl.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 godz."
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Anuluj"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Nigdy"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 godz."
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 godz."
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 godz."
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Automatyczne odświeżanie"
+
diff --git a/Po/pt_BR.po b/Po/pt_BR.po
new file mode 100755
index 0000000..e4e5127
--- /dev/null
+++ b/Po/pt_BR.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 horas"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Cancelar"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Nunca"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 horas"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 hora"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 horas"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Atualizar automaticamente"
+
diff --git a/Po/pt_PT.po b/Po/pt_PT.po
new file mode 100755
index 0000000..fb1e22d
--- /dev/null
+++ b/Po/pt_PT.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 horas"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Cancelar"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Nunca"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 horas"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 hora"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 horas"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Actualização auto"
+
diff --git a/Po/ro.po b/Po/ro.po
new file mode 100755
index 0000000..a6c6f82
--- /dev/null
+++ b/Po/ro.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 ore"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Anulare"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Niciodată"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 ore"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 oră"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 ore"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Reîmprospătare automată"
+
diff --git a/Po/ru_RU.po b/Po/ru_RU.po
new file mode 100755
index 0000000..aa36a8d
--- /dev/null
+++ b/Po/ru_RU.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 часов"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Отмена"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Никогда"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 часов"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 час"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 часа"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Автообновление"
+
diff --git a/Po/sk.po b/Po/sk.po
new file mode 100755
index 0000000..dab9cf4
--- /dev/null
+++ b/Po/sk.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 hodín"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Zrušiť"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Nikdy"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 hodín"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 hodina"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 hodiny"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Automatické obnovenie"
+
diff --git a/Po/sl.po b/Po/sl.po
new file mode 100755
index 0000000..2f565d2
--- /dev/null
+++ b/Po/sl.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 ur"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Prekliči"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Nikoli"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 ur"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 ura"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 ure"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Samodejno osveževanje"
+
diff --git a/Po/sr.po b/Po/sr.po
new file mode 100755
index 0000000..df0a5d8
--- /dev/null
+++ b/Po/sr.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 sati"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Poništi"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Nikad"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 sati"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 sat"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 sata"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Automatsko osvežavanje"
+
diff --git a/Po/sv.po b/Po/sv.po
new file mode 100755
index 0000000..7016603
--- /dev/null
+++ b/Po/sv.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 timmar"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Avbryt"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Aldrig"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 timmar"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 timme"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 timmar"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Uppdatera automatiskt"
+
diff --git a/Po/tr_TR.po b/Po/tr_TR.po
new file mode 100755
index 0000000..6cc7c51
--- /dev/null
+++ b/Po/tr_TR.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 saat"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "İptal"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Hiçbir zaman"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 saat"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 saat"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 saat"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Otomatik yenileme"
+
diff --git a/Po/uk.po b/Po/uk.po
new file mode 100755
index 0000000..b048476
--- /dev/null
+++ b/Po/uk.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 годин"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Скасувати"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Ніколи"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 годин"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 годину"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 години"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Автоматичне оновлення"
+
diff --git a/Po/uz.po b/Po/uz.po
new file mode 100755
index 0000000..d12f048
--- /dev/null
+++ b/Po/uz.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 soat"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "Bekor q."
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "Hech qachon"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 saot"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 soat"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 soat"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "Avtomatik yangilash"
+
diff --git a/Po/zh_CN.po b/Po/zh_CN.po
new file mode 100755
index 0000000..975d35f
--- /dev/null
+++ b/Po/zh_CN.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 小时"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "取消"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "从不"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 小时"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 小时"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 小时"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "自动刷新"
+
diff --git a/Po/zh_HK.po b/Po/zh_HK.po
new file mode 100755
index 0000000..4a55610
--- /dev/null
+++ b/Po/zh_HK.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 小時"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "取消"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "永不"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 小時"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 小時"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 小時"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "自動重新整理"
+
diff --git a/Po/zh_SG.po b/Po/zh_SG.po
new file mode 100755
index 0000000..6a5ab94
--- /dev/null
+++ b/Po/zh_SG.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12小时"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "取消"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "从不"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6小时"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1小时"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 小时"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "自动刷新"
+
diff --git a/Po/zh_TW.po b/Po/zh_TW.po
new file mode 100755
index 0000000..4a55610
--- /dev/null
+++ b/Po/zh_TW.po
@@ -0,0 +1,21 @@
+msgid "IDS_ST_BODY_12_HOURS"
+msgstr "12 小時"
+
+msgid "IDS_ST_BUTTON_CANCEL"
+msgstr "取消"
+
+msgid "IDS_BR_OPT_NEVER"
+msgstr "永不"
+
+msgid "IDS_ST_BODY_6_HOURS_TMO"
+msgstr "6 小時"
+
+msgid "IDS_ST_BODY_1_HOUR"
+msgstr "1 小時"
+
+msgid "IDS_ST_BODY_3HOURS"
+msgstr "3 小時"
+
+msgid "IDS_BR_HEADER_AUTO_REFRESH"
+msgstr "自動重新整理"
+
diff --git a/cmake/OptionsTizen.cmake b/cmake/OptionsTizen.cmake
new file mode 100644
index 0000000..050d877
--- /dev/null
+++ b/cmake/OptionsTizen.cmake
@@ -0,0 +1,3 @@
+#OptionsTizen.cmake
+
+#ADD_DEFINITIONS(-DENABLE_WEB_PROVIDER_LOAD=1)
diff --git a/data/200.livebox.web-provider.patch.sh b/data/200.livebox.web-provider.patch.sh
new file mode 100644
index 0000000..039f88e
--- /dev/null
+++ b/data/200.livebox.web-provider.patch.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+setfattr -n security.capability -v 0sAQAAAgABAAAAAAAAAgAAAAAAAAA= /usr/apps/livebox.web-provider/bin/web-provider
diff --git a/data/web_provider_db.sql b/data/web_provider_db.sql
new file mode 100644
index 0000000..df1a0c5
--- /dev/null
+++ b/data/web_provider_db.sql
@@ -0,0 +1,11 @@
+BEGIN TRANSACTION;
+CREATE TABLE LiveboxInfo (
+ box_id TEXT not null,
+ app_id TEXT not null,
+ box_type TEXT not null,
+ auto_launch INT,
+ mouse_event INT,
+ pd_fast_open INT,
+ PRIMARY KEY (box_id) ,
+CHECK(1) );
+COMMIT;
diff --git a/data/web_provider_reset_db.sh b/data/web_provider_reset_db.sh
new file mode 100644
index 0000000..d1bd966
--- /dev/null
+++ b/data/web_provider_reset_db.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+
+web_provider_db="/opt/usr/dbspace/.web_provider.db"
+web_provider_sql="/usr/share/web-provider/web_provider_db.sql"
+
+if [ -f $web_provider_db ]; then
+ /bin/echo "DB already exists."
+else
+ /bin/echo "create web livebox DB..."
+ /bin/rm -f $web_provider_db
+ /bin/rm -f $web_provider_db-journal
+ sql="PRAGMA journal_mode = PERSIST;"
+ /usr/bin/sqlite3 $web_provider_db "$sql"
+ sql=".read "$web_provider_sql
+ /usr/bin/sqlite3 $web_provider_db "$sql"
+ /bin/touch $web_provider_db-journal
+ /bin/chown 0:6026 $web_provider_db
+ /bin/chown 0:6026 $web_provider_db-journal
+ /bin/chmod 660 $web_provider_db
+ /bin/chmod 660 $web_provider_db-journal
+ /bin/echo "finish creation of db."
+fi
diff --git a/livebox.web-provider.manifest b/livebox.web-provider.manifest
new file mode 100755
index 0000000..a3b72f9
--- /dev/null
+++ b/livebox.web-provider.manifest
@@ -0,0 +1,16 @@
+<manifest>
+ <!-- web provider label -->
+ <define>
+ <domain name="livebox.web-provider"/>
+ <provide>
+ <label name="livebox.web-provider::db" />
+ </provide>
+ </define>
+ <assign>
+ <filesystem path="/usr/lib/libweb-provider*.so*" label="_" />
+ <filesystem path="/usr/lib/web-provider/libweb-provider*.so*" label="_" />
+ </assign>
+ <request>
+ <domain name="livebox.web-provider" />
+ </request>
+</manifest>
diff --git a/livebox.web-provider.mobile.rule b/livebox.web-provider.mobile.rule
new file mode 100755
index 0000000..d64ce16
--- /dev/null
+++ b/livebox.web-provider.mobile.rule
@@ -0,0 +1,89 @@
+livebox.web-provider livebox.web-provider::db rwxat
+livebox.web-provider system::vconf rwxat
+livebox.web-provider system::homedir rwxat
+livebox.web-provider system::share rwxat
+livebox.web-provider device::app_logging rwxat
+livebox.web-provider data-provider-master rwxat
+livebox.web-provider data-provider-master::share rwxat
+livebox.web-provider data-provider-master::data rwxat
+livebox.web-provider data-provider-master::db rwxat
+livebox.web-provider wrt-security-daemon::db rwxat
+livebox.web-provider wrt-security-daemon rwxat
+livebox.web-provider cert-svc rwxat
+livebox.web-provider wrt-commons::db_wrt rwxat
+livebox.web-provider syslogd rwxat
+livebox.web-provider xorg rwxat
+livebox.web-provider isf rwxat
+livebox.web-provider dbus rwxat
+livebox.web-provider e17 rwxat
+livebox.web-provider pulseaudio rwxat
+livebox.web-provider ail::db rwxat
+livebox.web-provider sys-assert::core rwxat
+livebox.web-provider resman::db rwxat
+livebox.web-provider webkit2-efl rwxat
+livebox.web-provider app-svc rwxat
+livebox.web-provider app-svc::db rwxat
+livebox.web-provider svi-data rwxat
+livebox.web-provider sound_server rwxat
+livebox.web-provider privacy-manager::db rwxat
+livebox.web-provider immvibed rwxat
+livebox.web-provider alarm-server::alarm rwxat
+livebox.web-provider allshare::svc rwxat
+livebox.web-provider aul::launch rwxat
+livebox.web-provider aul::terminate rwxat
+livebox.web-provider badge::db rwxat
+livebox.web-provider browser-provider::bookmark rwxat
+livebox.web-provider bt-service::admin rwxat
+livebox.web-provider bt-service::gap rwxat
+livebox.web-provider bt-service::manager rwxat
+livebox.web-provider bt-service::spp rwxat
+livebox.web-provider calendar-service rwxat
+livebox.web-provider calendar-service::svc rwxat
+livebox.web-provider contacts-service rwxat
+livebox.web-provider contacts-service::phonelog rwxat
+livebox.web-provider contacts-service::svc rwxat
+livebox.web-provider data-provider-master::notification rwxat
+livebox.web-provider data-provider-master::notification.client rwxat
+livebox.web-provider data-provider-master::badge rwxat
+livebox.web-provider data-provider-master::badge.client rwxat
+livebox.web-provider device::bklight rwxat
+livebox.web-provider deviced rwxat
+livebox.web-provider email-service::db rwxat
+livebox.web-provider mdm-server rwxat
+livebox.web-provider media-data::db rwxat
+livebox.web-provider media-server rwxat
+livebox.web-provider msg-service rwxat
+livebox.web-provider msg-service::db rwxat
+livebox.web-provider msg-service::read rwxat
+livebox.web-provider msg-service::smstrigger rwxat
+livebox.web-provider msg-service::write rwxat
+livebox.web-provider msg-service::db rwxat
+livebox.web-provider nfc-manager rwxat
+livebox.web-provider nfc-manager::admin rwxat
+livebox.web-provider nfc-manager::common rwxat
+livebox.web-provider nfc-manager::p2p rwxat
+livebox.web-provider nfc-manager::tag rwxat
+livebox.web-provider notification::db rwxat
+livebox.web-provider oma-ds-agent rwxat
+livebox.web-provider oma-ds-agent::cfg rwxat
+livebox.web-provider oma-ds-agent::svc rwxat
+livebox.web-provider org.tizen.setting::default-resources rwxat
+livebox.web-provider osp::datacontrol rwxat
+livebox.web-provider pkgmgr::db rwxat
+livebox.web-provider pkgmgr::info rwxat
+livebox.web-provider pkgmgr::svc rwxat
+livebox.web-provider push-service rwxat
+livebox.web-provider smartcard-service rwxat
+livebox.web-provider system::media rwxat
+livebox.web-provider system::use_internet rwxat
+livebox.web-provider sync_agent_frwk::oma-ds rwxat
+livebox.web-provider telephony_framework::api_modem rwxat
+livebox.web-provider telephony_framework::api_sim rwxat
+livebox.web-provider security-server::api-data-share rwxat
+system::use_internet livebox.web-provider rwxat
+calendar-service livebox.web-provider rwxat
+contacts-service livebox.web-provider rwxat
+media-server livebox.web-provider rwxat
+nfc-manager livebox.web-provider rwxat
+sync_agent_frwk::oma-ds livebox.web-provider rwxat
+system::use_internet livebox.web-provider rwxat
diff --git a/livebox.web-provider.rule b/livebox.web-provider.rule
new file mode 100755
index 0000000..9410483
--- /dev/null
+++ b/livebox.web-provider.rule
@@ -0,0 +1,40 @@
+livebox.web-provider livebox.web-provider::db rwxat
+livebox.web-provider system::vconf rwxat
+livebox.web-provider system::vconf_inhouse rwxat
+livebox.web-provider system::vconf_multimedia rwxat
+livebox.web-provider system::vconf_network rwxat
+livebox.web-provider system::vconf_system rwxat
+livebox.web-provider system::homedir rwxat
+livebox.web-provider system::use_internet rwxat
+livebox.web-provider system::media rwxat
+livebox.web-provider system::share rwxat
+livebox.web-provider device::app_logging rwxat
+livebox.web-provider data-provider-master rwxat
+livebox.web-provider data-provider-master::share rwxat
+livebox.web-provider data-provider-master::data rwxat
+livebox.web-provider data-provider-master::db rwxat
+livebox.web-provider wrt-security-daemon::db rwxat
+livebox.web-provider wrt-security-daemon rwxat
+livebox.web-provider cert-svc rwxat
+livebox.web-provider wrt-commons::db_wrt rwxat
+livebox.web-provider syslogd rwxat
+livebox.web-provider xorg rwxat
+livebox.web-provider isf rwxat
+livebox.web-provider dbus rwxat
+livebox.web-provider e17 rwxat
+livebox.web-provider pulseaudio rwxat
+livebox.web-provider ail::db rwxat
+livebox.web-provider sys-assert::core rwxat
+livebox.web-provider webkit2-efl rwxat
+livebox.web-provider app-svc rwxat
+livebox.web-provider app-svc::db rwxat
+livebox.web-provider svi-data rwxat
+livebox.web-provider sound_server rwxat
+livebox.web-provider pkgmgr::db rwxat
+livebox.web-provider privacy-manager::db rwxat
+livebox.web-provider media-data::db rwxat
+livebox.web-provider immvibed rwxat
+system::use_internet livebox.web-provider rwxat
+livebox.web-provider aul::launch rwxat
+livebox.web-provider aul::terminate rwxat
+livebox.web-provider tts-server rwxat
diff --git a/livebox.web-provider.xml b/livebox.web-provider.xml
new file mode 100644
index 0000000..1632996
--- /dev/null
+++ b/livebox.web-provider.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<manifest xmlns="http://tizen.org/ns/packages" package="livebox.web-provider" version="1.0" install-location="internal-only">
+ <label>Web Dynamic Box Provider</label>
+ <author email="yunchan.cho@samsung.com" href="www.samsung.com">Yunchan Cho</author>
+ <description>Web Dynamic Box Provider Executable</description>
+ <ui-application appid="dbox.web-provider" exec="/usr/apps/livebox.web-provider/bin/web-provider" nodisplay="true" multiple="false" type="capp" taskmanage="false">
+ <icon>livebox.web-provider.png</icon>
+ <label>Web Dynamic Box Provider</label>
+ <label xml:lang="en-us">Web Dynamic Box Provider</label>
+ <application-service>
+ <operation name="http://tizen.org/appcontrol/operation/dynamicbox/web/update"/>
+ <uri name="box-service"/>
+ </application-service>
+ <application-service>
+ <operation name="http://tizen.org/appcontrol/operation/dynamicbox/web/remove"/>
+ </application-service>
+ </ui-application>
+</manifest>
diff --git a/packaging/livebox.web-provider.spec b/packaging/livebox.web-provider.spec
new file mode 100644
index 0000000..18a98c5
--- /dev/null
+++ b/packaging/livebox.web-provider.spec
@@ -0,0 +1,121 @@
+#git:framework/web/web-provider
+Name: livebox.web-provider
+Summary: web framework for livebox
+Version: 1.100_w2
+Release: 1
+Group: main/app
+License: Flora License, Version 1.1
+Source0: %{name}-%{version}.tar.gz
+BuildRequires: attr
+BuildRequires: cmake, gettext-tools
+BuildRequires: libcap, libcap-devel
+BuildRequires: pkgconfig(ail)
+BuildRequires: pkgconfig(aul)
+BuildRequires: pkgconfig(appcore-efl)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(bundle)
+BuildRequires: pkgconfig(eina)
+BuildRequires: pkgconfig(ecore)
+BuildRequires: pkgconfig(ecore-x)
+BuildRequires: pkgconfig(evas)
+BuildRequires: pkgconfig(ecore-evas)
+BuildRequires: pkgconfig(elementary)
+BuildRequires: pkgconfig(efl-assist)
+BuildRequires: pkgconfig(ewebkit2)
+BuildRequires: pkgconfig(wrt-core)
+BuildRequires: pkgconfig(xmlsec1)
+BuildRequires: pkgconfig(dpl-efl)
+BuildRequires: pkgconfig(provider)
+BuildRequires: pkgconfig(livebox-service)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(json-glib-1.0)
+BuildRequires: pkgconfig(capi-appfw-application)
+BuildRequires: pkgconfig(libsmack)
+
+Requires(post): attr
+
+%description
+This is web framework responsible to manage liveboxes that consist of web contents
+
+%package devel
+Summary: Files for web provider devel.
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+Web Provider library (dev)
+
+%prep
+%setup -q
+
+%build
+%if 0%{?sec_build_binary_debug_enable}
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+%endif
+
+%if "%{_repository}" == "wearable"
+ %define device_profile "wearable"
+ ln -sf src_wearable src
+%else
+ %define device_profile "mobile"
+ ln -sf src_mobile src
+ rm livebox.web-provider.rule
+ mv livebox.web-provider.mobile.rule livebox.web-provider.rule
+%endif
+
+cmake . \
+ -DCMAKE_INSTALL_PREFIX=%{_prefix} \
+ -DCMAKE_PROJECT_VERSION=%{version} \
+ -DDEVICE_PROFILE=%{?device_profile:%device_profile}
+
+#-fpie LDFLAGS="${LDFLAGS} -pie -O3"
+CXXFLAGS="${CXXFLAGS} -Wall -Winline -Werror -fno-builtin-malloc" make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}/usr/share/license
+cp LICENSE.Flora %{buildroot}/usr/share/license/%{name}
+%make_install
+%define app_data /opt/usr/apps/livebox.web-provider/data
+mkdir -p %{buildroot}%{app_data}
+
+%post
+killall -9 web-provider
+/usr/bin/web_provider_reset_db.sh
+echo "smack setting..."
+chsmack -a 'livebox.web-provider::db' /opt/usr/dbspace/.web_provider.db
+chsmack -a 'livebox.web-provider::db' /opt/usr/dbspace/.web_provider.db-journal
+setfattr -n security.capability -v 0sAQAAAgABAAAAAAAAAgAAAAAAAAA= %{_prefix}/apps/livebox.web-provider/bin/web-provider
+chown 5000:5000 %{app_data}
+chmod 755 %{app_data}
+
+%files -n livebox.web-provider
+%manifest livebox.web-provider.manifest
+%defattr(-,root,root,-)
+%{_libdir}/*.so*
+%{_libdir}/web-provider/*.so*
+%{_libdir}/web-provider/*.json
+%{_datadir}/web-provider/*
+%attr(755,root,root) %{_bindir}/web_provider_reset_db.sh
+%{_prefix}/apps/livebox.web-provider/bin/web-provider
+%{_datarootdir}/packages/livebox.web-provider.xml
+%{_prefix}/share/res/*
+
+%if "%{_repository}" == "wearable"
+# wearable
+ %{_sysconfdir}/smack/accesses2.d/livebox.web-provider.rule
+%else
+# mobile
+ %{_sysconfdir}/smack/accesses.d/livebox.web-provider.rule
+%endif
+
+%{app_data}
+%{_datadir}/license/%{name}
+%attr(700,root,root) /etc/opt/upgrade/*.patch.sh
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/web-provider/*
+%{_libdir}/pkgconfig/*.pc
diff --git a/pkgconfig/web-provider-svc.pc.in b/pkgconfig/web-provider-svc.pc.in
new file mode 100644
index 0000000..e85274f
--- /dev/null
+++ b/pkgconfig/web-provider-svc.pc.in
@@ -0,0 +1,11 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: web-provider
+Description: web-provider library
+Version: @PROJECT_VERSION@
+Requires: db-util glib-2.0 json-glib-1.0 ecore ecore-evas evas eina provider ewebkit2 dlog
+Libs: -lweb-provider-api -lweb-provider-core -L${libdir}
+Cflags: -I${includedir}/web-provider -I${includedir}/web-provider/API -I${includedir}/web-provider/Core -I${includedir}/web-provider/Plugin
diff --git a/pkgconfig/web-provider.pc.in b/pkgconfig/web-provider.pc.in
new file mode 100644
index 0000000..e85274f
--- /dev/null
+++ b/pkgconfig/web-provider.pc.in
@@ -0,0 +1,11 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: web-provider
+Description: web-provider library
+Version: @PROJECT_VERSION@
+Requires: db-util glib-2.0 json-glib-1.0 ecore ecore-evas evas eina provider ewebkit2 dlog
+Libs: -lweb-provider-api -lweb-provider-core -L${libdir}
+Cflags: -I${includedir}/web-provider -I${includedir}/web-provider/API -I${includedir}/web-provider/Core -I${includedir}/web-provider/Plugin
diff --git a/src_mobile/API/CMakeLists.txt b/src_mobile/API/CMakeLists.txt
new file mode 100644
index 0000000..bc033fd
--- /dev/null
+++ b/src_mobile/API/CMakeLists.txt
@@ -0,0 +1,68 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_API})
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ db-util
+ glib-2.0
+ json-glib-1.0
+ dlog
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/SqliteDB.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/web_provider_livebox_info.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/web_provider_plugin_info.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} SHARED ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LDFLAGS} "-ldl"
+ ${${DEPS}_LIBRARIES}
+)
+
+INSTALL(TARGETS ${TARGET_NAME}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
+
+GET_FILENAME_COMPONENT(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+INSTALL_FILE(web-provider-info.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME}) # Deprecated
+INSTALL_FILE(web_provider_livebox_info.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(web_provider_plugin_info.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
diff --git a/src_mobile/API/SqliteDB.cpp b/src_mobile/API/SqliteDB.cpp
new file mode 100644
index 0000000..fcd9132
--- /dev/null
+++ b/src_mobile/API/SqliteDB.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 SqliteDB.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <cstring>
+#include <cstdarg>
+#include <sqlite3.h>
+#include <db-util.h>
+
+#include "SqliteDB.h"
+
+SqliteDB::SqliteDB(std::string dbPath)
+ : m_path(dbPath)
+ , m_handle(NULL)
+ , m_stmt(NULL)
+{
+}
+
+SqliteDB::~SqliteDB()
+{
+}
+
+bool SqliteDB::openDB()
+{
+ closeDB();
+ int ret;
+ ret = db_util_open(m_path.c_str(), &m_handle, DB_UTIL_REGISTER_HOOK_METHOD);
+ if (ret != SQLITE_OK) {
+ return false;
+ }
+
+ return true;
+}
+
+void SqliteDB::closeDB()
+{
+ if (!m_handle) {
+ return;
+ }
+
+ if (!m_stmt) {
+ db_util_close(m_handle);
+ m_handle = NULL;
+ return;
+ }
+
+ sqlite3_finalize(m_stmt);
+ db_util_close(m_handle);
+ m_stmt = NULL;
+ m_handle = NULL;
+}
+
+bool SqliteDB::setCommand(std::string& query, const char* fmt, ...)
+{
+ if (!m_handle || !fmt) {
+ return false;
+ }
+
+ int ret =
+ sqlite3_prepare_v2(m_handle, query.c_str(), -1, &m_stmt, NULL);
+
+ if (ret != SQLITE_OK) {
+ return false;
+ }
+
+ // bind values to query
+ int intValue;
+ char* stringValue;
+
+ va_list ap;
+ va_start(ap, fmt);
+ for (unsigned int i = 0; i < strlen(fmt); i++) {
+ switch (fmt[i]) {
+ case 'i':
+ intValue = va_arg(ap, int);
+ ret = sqlite3_bind_int(m_stmt, i + 1, intValue);
+ if (ret != SQLITE_OK) {
+ va_end(ap);
+ return false;
+ }
+ break;
+ case 's':
+ stringValue = va_arg(ap, char*);
+ ret = sqlite3_bind_text(m_stmt, i + 1, stringValue, -1, NULL);
+ if (ret != SQLITE_OK) {
+ va_end(ap);
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ va_end(ap);
+
+ return true;
+}
+
+bool SqliteDB::executeCommand()
+{
+ int ret =
+ sqlite3_step(m_stmt);
+
+ if (ret != SQLITE_ROW) {
+ return false;
+ }
+
+ return true;
+}
+
+const char* SqliteDB::getText(int col)
+{
+ const char* ret =
+ reinterpret_cast<const char*>(sqlite3_column_text(m_stmt, col));
+
+ return ret;
+}
+
+int SqliteDB::getInt(int col)
+{
+ return sqlite3_column_int(m_stmt, col);
+}
diff --git a/src_mobile/API/SqliteDB.h b/src_mobile/API/SqliteDB.h
new file mode 100644
index 0000000..0f7c993
--- /dev/null
+++ b/src_mobile/API/SqliteDB.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 SqliteDB.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef SQLITE_DB_H
+#define SQLITE_DB_H
+
+#include <string>
+#include <sqlite3.h>
+
+class SqliteDB {
+ public:
+ bool openDB();
+ void closeDB();
+ bool setCommand(std::string& query, const char* fmt, ...);
+ bool executeCommand();
+ const char* getText(int col);
+ int getInt(int col);
+
+ explicit SqliteDB(const std::string dbPath);
+ ~SqliteDB();
+
+ private:
+ std::string m_path;
+ sqlite3* m_handle;
+ sqlite3_stmt* m_stmt;
+};
+
+#endif // SQLITE_DB_H
diff --git a/src_mobile/API/WebProviderDB.h b/src_mobile/API/WebProviderDB.h
new file mode 100644
index 0000000..e6f14f6
--- /dev/null
+++ b/src_mobile/API/WebProviderDB.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 WebProviderDB.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef LIVEBOX_DB_H
+#define LIVEBOX_DB_H
+
+#include <string>
+#include "SqliteDB.h"
+
+const std::string dbPath("/opt/usr/dbspace/.web_provider.db");
+
+class WebProviderDB : public SqliteDB {
+ public:
+ WebProviderDB() : SqliteDB (dbPath) {};
+ ~WebProviderDB() {};
+};
+
+#endif //LIVEBOX_DB_H
diff --git a/src_mobile/API/web-provider-info.h b/src_mobile/API/web-provider-info.h
new file mode 100644
index 0000000..6d9a8b8
--- /dev/null
+++ b/src_mobile/API/web-provider-info.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 web-provider-info.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef WEB_PROVIDER_INFO_H
+#define WEB_PROVIDER_INFO_H
+
+#include <API/web_provider_livebox_info.h>
+
+#endif //WEB_PROVIDER_INFO_H
diff --git a/src_mobile/API/web_provider_livebox_info.cpp b/src_mobile/API/web_provider_livebox_info.cpp
new file mode 100644
index 0000000..731a935
--- /dev/null
+++ b/src_mobile/API/web_provider_livebox_info.cpp
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 web_provider_livebox_info.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <cstring>
+#include <memory>
+#include "WebProviderDB.h"
+#include "web_provider_livebox_info.h"
+
+static const std::string infoTable("LiveboxInfo");
+
+enum InfoTableField {
+ BOX_ID = 0,
+ APP_ID,
+ BOX_TYPE,
+ AUTO_LAUNCH,
+ MOUSE_EVENT,
+ PD_FAST_OPEN,
+};
+
+// TODO this default type should be retrieved more automatically
+static const std::string defaultBoxType("app");
+
+const char* web_provider_livebox_get_default_type()
+{
+ return defaultBoxType.c_str();
+}
+
+const char* web_provider_livebox_get_box_type(const char* box_id)
+{
+ if (!box_id) {
+ return NULL;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return NULL;
+ }
+
+ std::string query = "select * from " + infoTable + " where box_id = ?";
+ if (!handle->setCommand(query, "s", box_id)) {
+ handle->closeDB();
+ return NULL;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return NULL;
+ }
+
+ const char* box_type = handle->getText(InfoTableField::BOX_TYPE);
+ const char* box_type_dup = NULL;
+
+ if (box_type) {
+ box_type_dup = strdup(box_type);
+ }
+
+ handle->closeDB();
+
+ return box_type_dup;
+}
+
+const char* web_provider_livebox_get_app_id(const char* box_id)
+{
+ if (!box_id) {
+ return NULL;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return NULL;
+ }
+
+ std::string query = "select * from " + infoTable + " where box_id = ?";
+ if (!handle->setCommand(query, "s", box_id)) {
+ handle->closeDB();
+ return NULL;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return NULL;
+ }
+
+ const char* app_id = handle->getText(InfoTableField::APP_ID);
+ const char* app_id_dup = NULL;
+
+ if (app_id) {
+ app_id_dup = strdup(app_id);
+ }
+
+ handle->closeDB();
+
+ return app_id_dup;
+}
+
+int web_provider_livebox_get_auto_launch(const char* box_id)
+{
+ if (!box_id) {
+ return 0;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return 0;
+ }
+
+ std::string query = "select * from " + infoTable + " where box_id = ?";
+ if (!handle->setCommand(query, "s", box_id)) {
+ handle->closeDB();
+ return 0;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return 0;
+ }
+
+ int autoLaunch = handle->getInt(InfoTableField::AUTO_LAUNCH);
+ handle->closeDB();
+
+ return autoLaunch;
+}
+
+int web_provider_livebox_get_mouse_event(const char* box_id)
+{
+ if (!box_id) {
+ return 0;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return 0;
+ }
+
+ std::string query = "select * from " + infoTable + " where box_id = ?";
+ if (!handle->setCommand(query, "s", box_id)) {
+ handle->closeDB();
+ return 0;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return 0;
+ }
+
+ int mouseEvent = handle->getInt(InfoTableField::MOUSE_EVENT);
+ handle->closeDB();
+
+ return mouseEvent;
+}
+
+int web_provider_livebox_get_pd_fast_open(const char* box_id)
+{
+ if (!box_id) {
+ return 0;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return 0;
+ }
+
+ std::string query = "select * from " + infoTable + " where box_id = ?";
+ if (!handle->setCommand(query, "s", box_id)) {
+ handle->closeDB();
+ return 0;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return 0;
+ }
+
+ int pdFastOpen = handle->getInt(InfoTableField::PD_FAST_OPEN);
+ handle->closeDB();
+
+ return pdFastOpen;
+}
+
+int web_provider_livebox_insert_box_info(
+ const char* box_id,
+ const char* app_id,
+ const char* box_type,
+ int auto_launch,
+ int mouse_event,
+ int pd_fast_open)
+{
+ if (!box_id || !app_id || !box_type) {
+ return -1;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return -1;
+ }
+
+ std::string query =
+ "insert into " + infoTable +
+ " (box_id, app_id, box_type, auto_launch, mouse_event, pd_fast_open) \
+ values (?,?,?,?,?,?)";
+
+ if (!handle->setCommand(
+ query, "sssiii",
+ box_id, app_id, box_type, auto_launch, mouse_event, pd_fast_open)) {
+ handle->closeDB();
+ return -1;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return -1;
+ }
+
+ handle->closeDB();
+ return 0;
+}
+
+int web_provider_livebox_delete_by_box_id(const char* box_id)
+{
+ if (!box_id) {
+ return -1;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return -1;
+ }
+
+ std::string query =
+ "delete from " + infoTable + " where box_id=?";
+
+ if (!handle->setCommand(query, "s", box_id)) {
+ handle->closeDB();
+ return -1;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return -1;
+ }
+
+ handle->closeDB();
+ return 0;
+}
+
+int web_provider_livebox_delete_by_app_id(const char* app_id)
+{
+ if (!app_id) {
+ return -1;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return -1;
+ }
+
+ std::string query =
+ "delete from " + infoTable + " where app_id=?";
+
+ if (!handle->setCommand(query, "s", app_id)) {
+ handle->closeDB();
+ return -1;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return -1;
+ }
+
+ handle->closeDB();
+ return 0;
+}
+
+int web_provider_livebox_delete_by_type(const char* type)
+{
+ if (!type) {
+ return -1;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return -1;
+ }
+
+ std::string query =
+ "delete from " + infoTable + " where type=?";
+
+ if (!handle->setCommand(query, "s", type)) {
+ handle->closeDB();
+ return -1;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return -1;
+ }
+
+ handle->closeDB();
+ return 0;
+}
diff --git a/src_mobile/API/web_provider_livebox_info.h b/src_mobile/API/web_provider_livebox_info.h
new file mode 100644
index 0000000..3cf1c41
--- /dev/null
+++ b/src_mobile/API/web_provider_livebox_info.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 web_provider_livebox_info.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef WEB_PROVIDER_LIVEBOX_INFO_H
+#define WEB_PROVIDER_LIVEBOX_INFO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+#define DEPRECATED_API __attribute__((visibility("default"))) __attribute__((deprecated))
+
+/* TODO doxygen comments are needed to each exported API */
+
+EXPORT_API const char* web_provider_livebox_get_default_type();
+EXPORT_API const char* web_provider_livebox_get_box_type(const char* box_id);
+EXPORT_API const char* web_provider_livebox_get_app_id(const char* box_id);
+EXPORT_API int web_provider_livebox_get_auto_launch(const char* box_id);
+EXPORT_API int web_provider_livebox_get_mouse_event(const char* box_id);
+EXPORT_API int web_provider_livebox_get_pd_fast_open(const char* box_id);
+EXPORT_API int web_provider_livebox_insert_box_info(
+ const char* box_id,
+ const char* app_id,
+ const char* box_type,
+ int auto_launch,
+ int mouse_event,
+ int pd_fast_open);
+EXPORT_API int web_provider_livebox_delete_by_box_id(const char* box_id);
+EXPORT_API int web_provider_livebox_delete_by_app_id(const char* app_id);
+EXPORT_API int web_provider_livebox_delete_by_type(const char* type);
+
+#ifdef __cplusplus
+}
+#endif
+#endif //WEB_PROVIDER_LIVEBOX_INFO_H
diff --git a/src_mobile/API/web_provider_plugin_info.cpp b/src_mobile/API/web_provider_plugin_info.cpp
new file mode 100755
index 0000000..373c95f
--- /dev/null
+++ b/src_mobile/API/web_provider_plugin_info.cpp
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 web_provider_livebox_info.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <string>
+#include <cstring>
+#include <cstdlib>
+#include <list>
+#include <glib.h>
+#include <glib-object.h>
+#include <json-glib/json-glib.h>
+#include <Core/Util/Log.h>
+#include "web_provider_livebox_info.h"
+#include "web_provider_plugin_info.h"
+#include <memory>
+
+// static functions
+static web_provider_plugin_info* get_parsed_json_data(std::string& configPath);
+static bool web_provider_plugin_release_info(web_provider_plugin_info* info);
+
+static const std::string installedPluginDirPath("/usr/lib/web-provider/");
+
+// Json's content for plugin is the following (example)
+// {
+// "type" : "clip",
+// "path" : "/usr/lib/web-provider/libweb-provider-plugin-clipbox.so",
+// "service_boxid" : "org.tizen.browser"
+// }
+//
+// "service_boxid" is only optional member in json file
+
+static const std::string jsonMemberType("type");
+static const std::string jsonMemberPath("path");
+static const std::string jsonMemberBoxId("service_boxid");
+static const std::string jsonMemberBoxScrollable("box_scrollable");
+static const std::string jsonMemberBoxSize("supported_size");
+
+static const std::string jsonValueBoolTrue("true");
+static const std::string jsonValueBoolFalse("false");
+static const std::string jsonFileExtension(".json");
+static const std::string mandatoryBoxSize("1x1");
+
+web_provider_plugin_info** web_provider_plugin_get_installed_list(int* count)
+{
+ LogD("enter");
+
+ // open directory of web provider plugin
+ DIR* dir = opendir(installedPluginDirPath.c_str());
+ if (!dir) {
+ LogD("failed to open directory for web livebox plugins");
+ *count = 0;
+ return NULL;
+ }
+
+ // read plugin directory and store plugin config path
+ std::list<std::string> configList;
+ struct dirent* entry;
+ struct stat configStat;
+ std::string configPath;
+ while ((entry = readdir(dir))) {
+ if ((!strcmp(entry->d_name, ".")) || (!strcmp(entry->d_name, ".."))) {
+ continue;
+ }
+
+ configPath = installedPluginDirPath + entry->d_name;
+
+ if (stat(configPath.c_str(), &configStat) < 0) {
+ LogD("Failed to open file");
+ continue;
+ }
+
+ if (S_ISDIR(configStat.st_mode)) {
+ continue;
+ }
+
+ if (configPath.substr(configPath.find_last_of(".")) == jsonFileExtension) {
+ LogD("config file: %s", configPath.c_str());
+ configList.push_back(configPath);
+ }
+ }
+ // close directory of web provider plugin
+ closedir(dir);
+
+ if (configList.size() == 0) {
+ *count = 0;
+ return NULL;
+ }
+
+ // parse available each plugin json file
+ std::list<web_provider_plugin_info*> pluginList;
+ for (auto it = configList.begin();
+ it != configList.end(); it++) {
+ web_provider_plugin_info* info = get_parsed_json_data(*it) ;
+ if (!info) {
+ continue;
+ }
+
+ pluginList.push_back(info);
+ }
+ *count = pluginList.size();
+ LogD("read plugin count: %d", *count);
+
+ // c style array allocation for return of result
+ web_provider_plugin_info** info_list =
+ static_cast<web_provider_plugin_info**>(
+ malloc((*count) * sizeof(web_provider_plugin_info*)));
+
+ // copy from members in std::list to one in c style array
+ int idx = 0;
+ for (auto it = pluginList.begin();
+ it != pluginList.end(); it++) {
+ LogD("type: %s", (*it)->type);
+ LogD("path: %s", (*it)->path);
+ if ((*it)->service_boxid) {
+ LogD("service_boxid: %s", (*it)->service_boxid);
+ }
+ info_list[idx] = *it;
+ idx++;
+ }
+
+ LogD("success to return plugin information");
+ return info_list;
+}
+
+void web_provider_plugin_release_installed_list(
+ web_provider_plugin_info** info_list,
+ int count)
+{
+ if (!info_list) {
+ return;
+ }
+
+ for (int i = 0; i < count; i++) {
+ web_provider_plugin_release_info(info_list[i]);
+ }
+}
+
+int web_provider_plugin_get_box_scrollable(const char* plugin_type)
+{
+ if (!plugin_type) {
+ return -1;
+ }
+
+ std::string configPath;
+ configPath = installedPluginDirPath;
+ configPath += plugin_type;
+ configPath += jsonFileExtension;
+ web_provider_plugin_info* info = get_parsed_json_data(configPath);
+
+ if (!info) {
+ return -1;
+ }
+ int ret = info->box_scrollable;
+ web_provider_plugin_release_info(info);
+
+ LogD("box_scrollable: %d", ret);
+ return ret;
+}
+
+static web_provider_plugin_info* get_parsed_json_data(std::string& configPath)
+{
+ g_type_init();
+
+ web_provider_plugin_info* info;
+ JsonParser* parser = json_parser_new();
+ GError* error = NULL;
+
+ if (!json_parser_load_from_file(parser, configPath.c_str(), &error)) {
+ LogD("failed to parse json file: %s -> %s", configPath.c_str(), error->message);
+ g_error_free(error);
+ g_object_unref(parser);
+ return NULL;
+ }
+
+ JsonNode* root = json_parser_get_root(parser);
+ JsonObject* object = json_node_get_object(root);
+
+ // check if type member exists on this json file
+ const char* type =
+ static_cast<const char*>(
+ json_object_get_string_member(object, jsonMemberType.c_str()));
+
+ const char* path =
+ static_cast<const char*>(
+ json_object_get_string_member(object, jsonMemberPath.c_str()));
+
+ JsonArray* size =
+ json_object_get_array_member(object, jsonMemberBoxSize.c_str());
+ int sizeCount = static_cast<int>(json_array_get_length(size));
+
+ if (!type || !path || !sizeCount) {
+ LogD("mandatory members don't exist");
+ g_error_free(error);
+ g_object_unref(parser);
+ return NULL;
+ }
+
+ // allocate instance of plugin info struct
+ info = static_cast<web_provider_plugin_info*>(
+ malloc(sizeof(web_provider_plugin_info)));
+ memset(info, 0, sizeof(web_provider_plugin_info));
+
+ info->type = strdup(type);
+ info->path = strdup(path);
+ info->box_size = static_cast<char**>(malloc(sizeof(char*) * sizeCount));
+
+ for (int i = 0; i < sizeCount; i++) {
+ info->box_size[i] =
+ strdup(static_cast<const char*>(json_array_get_string_element(size, i)));
+ }
+ info->box_size_count = sizeCount;
+
+ gboolean hasBoxId = json_object_has_member(object, jsonMemberBoxId.c_str());
+ if (hasBoxId == TRUE) {
+ const char* boxId =
+ static_cast<const char*>(
+ json_object_get_string_member(object, jsonMemberBoxId.c_str()));
+ if (boxId) {
+ info->service_boxid = strdup(boxId);
+ }
+ }
+
+ gboolean hasBoxScrollable =
+ json_object_has_member(object, jsonMemberBoxScrollable.c_str());
+ if (hasBoxScrollable == TRUE) {
+ const char* boxScrollable =
+ static_cast<const char*>(
+ json_object_get_string_member(object, jsonMemberBoxScrollable.c_str()));
+ if (boxScrollable && (jsonValueBoolTrue == boxScrollable)) {
+ info->box_scrollable = 1;
+ } else {
+ info->box_scrollable = 0;
+ }
+ }
+
+ LogD("type: %s", info->type);
+ LogD("path: %s", info->path);
+ if (info->service_boxid) {
+ LogD("service_boxid: %s", info->service_boxid);
+ }
+ LogD("box_scrollable: %d", info->box_scrollable);
+
+ json_node_free(root);
+ g_error_free(error);
+ g_object_unref(parser);
+
+ return info;
+}
+
+bool web_provider_plugin_release_info(web_provider_plugin_info* info)
+{
+ LogD("enter");
+ if (!info) {
+ LogD("empty struct");
+ return false;
+ }
+
+ // only members with buffer are released
+ delete info->type;
+ delete info->path;
+ delete info->service_boxid;
+ for(int i = 0; i < info->box_size_count; i++) {
+ delete[] info->box_size[i];
+ }
+ delete info;
+
+ return true;
+}
+
+int web_provider_plugin_check_supported_size(
+ const char* plugin_type, char** size, int sizeCount)
+{
+ // read plugin directory and store plugin config path
+ std::string configPath;
+ configPath = installedPluginDirPath;
+ configPath += plugin_type;
+ configPath += jsonFileExtension;
+
+ // get the json datas
+ web_provider_plugin_info* jsonData = get_parsed_json_data(configPath);
+ if (!jsonData) {
+ LogD("failed to get the json file");
+ return false;
+ }
+
+ // check if this type is default type
+ bool isDefaultType = false;
+ const char* defaultType = web_provider_livebox_get_default_type();
+ if (!defaultType) {
+ LogD("can't get default type");
+ return false;
+ }
+ if (!strcmp(plugin_type, defaultType)) {
+ isDefaultType = true;
+ }
+
+ // compare the parsed config data with the parsed json data
+ bool mandatoryCheck = false;
+ for (int configCnt = 0; configCnt < sizeCount; configCnt++) {
+ bool supportedSizeCheck = false;
+ for (int jsonCnt = 0; jsonCnt < jsonData->box_size_count; jsonCnt++) {
+
+ // check mandatory size
+ if (isDefaultType && !strcmp(mandatoryBoxSize.c_str(), size[configCnt])) {
+ mandatoryCheck = true;
+ }
+
+ // check supported size
+ if (!strcmp(jsonData->box_size[jsonCnt], size[configCnt])) {
+ supportedSizeCheck = true;
+ break;
+ }
+ }
+
+ if (!supportedSizeCheck) {
+ LogD("Not supported size: %s", size[configCnt]);
+ web_provider_plugin_release_info(jsonData);
+ return false;
+ }
+ }
+
+ //release the jsonData
+ web_provider_plugin_release_info(jsonData);
+ if (isDefaultType && !mandatoryCheck) {
+ LogD("Mandatory members don't exist ");
+ return false;
+ }
+
+ return true;
+}
diff --git a/src_mobile/API/web_provider_plugin_info.h b/src_mobile/API/web_provider_plugin_info.h
new file mode 100755
index 0000000..612497c
--- /dev/null
+++ b/src_mobile/API/web_provider_plugin_info.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 web_provider_plugin_info.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef WEB_PROVIDER_PLUGIN_INFO_H
+#define WEB_PROVIDER_PLUGIN_INFO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+struct _web_provider_plugin_info {
+ const char* type;
+ const char* path;
+ const char* service_boxid;
+ char** box_size;
+ int box_scrollable;
+ int box_size_count;
+};
+typedef _web_provider_plugin_info web_provider_plugin_info;
+
+EXPORT_API web_provider_plugin_info** web_provider_plugin_get_installed_list(
+ int* count);
+EXPORT_API void web_provider_plugin_release_installed_list(
+ web_provider_plugin_info** info_list,
+ int count);
+EXPORT_API int web_provider_plugin_get_box_scrollable(const char* plugin_type);
+EXPORT_API int web_provider_plugin_check_supported_size(const char* plugin_type, char** size, int sizeCount);
+#ifdef __cplusplus
+}
+#endif
+#endif //WEB_PROVIDER_PROVIDER_INFO_H
diff --git a/src_mobile/CMakeLists.txt b/src_mobile/CMakeLists.txt
new file mode 100644
index 0000000..0a978b0
--- /dev/null
+++ b/src_mobile/CMakeLists.txt
@@ -0,0 +1,31 @@
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_API web-provider-api)
+SET(TARGET_CORE web-provider-core)
+SET(TARGET_DAEMON web-provider)
+SET(TARGET_PLUGIN web-provider-plugin)
+
+INCLUDE_DIRECTORIES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/API
+ ${CMAKE_CURRENT_SOURCE_DIR}/Core
+ ${CMAKE_CURRENT_SOURCE_DIR}/Plugin
+)
+
+ADD_SUBDIRECTORY(API)
+ADD_SUBDIRECTORY(Core)
+ADD_SUBDIRECTORY(Daemon)
+ADD_SUBDIRECTORY(Plugin)
diff --git a/src_mobile/Core/Box.cpp b/src_mobile/Core/Box.cpp
new file mode 100644
index 0000000..8d502c8
--- /dev/null
+++ b/src_mobile/Core/Box.cpp
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 Box.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <Ecore.h>
+#include <Plugin/IBoxPluginFactory.h>
+#include "Buffer/IRenderBuffer.h"
+#include "Buffer/RenderBuffer.h"
+#include "Buffer/RenderBufferFactory.h"
+#include "Util/Log.h"
+#include "Util/Util.h"
+#include "BoxData.h"
+#include "IBoxState.h"
+#include "BoxState.h"
+#include "Util/ITimer.h"
+#include "BoxUpdateTimer.h"
+#include "BoxSchemeHandler.h"
+#include "Box.h"
+
+// This is used for informing context of box to web content as value of url parameter
+static const std::string renderTypeCreate("create");
+static const std::string renderTypeResize("resize");
+static const std::string renderTypeOpenPd("pdopen");
+static const std::string renderTypeUpdate("update");
+
+Box::Box(BoxInfoPtr boxInfo, IBoxPluginFactoryPtr factory, EwkContextPtr ewkContext)
+ : m_boxInfo(boxInfo)
+ , m_factory(factory)
+ , m_currentTab(true)
+ , m_paused(false)
+ , m_updateNeeded(false)
+ , m_lastUpdateRequestTime()
+{
+ LogD("enter");
+ try {
+ m_boxBuffer = m_factory->createBoxRenderBuffer(
+ boxInfo->boxId,
+ boxInfo->instanceId,
+ boxInfo->boxWidth,
+ boxInfo->boxHeight,
+ boxInfo->contentInfo);
+ m_boxBuffer->allocate();
+ m_view = m_factory->createRenderView(
+ boxInfo->boxId,
+ boxInfo->instanceId,
+ ewkContext);
+ m_updateTimer = BoxUpdateTimer::create(
+ boxInfo->period,
+ Box::updateCallback,
+ this);
+ BoxSchemeHandler::Instance()->registerBox(boxInfo->instanceId, this);
+
+ // TODO code regarding state needs more testing
+ //m_state = BoxInitState::create(
+ // IBoxContextPtr(dynamic_cast<IBoxContext*>(this)));
+ } catch (...) {
+ throw;
+ }
+}
+
+Box::~Box()
+{
+ LogD("enter");
+ BoxSchemeHandler::Instance()->unregisterBox(m_boxInfo->instanceId);
+}
+
+bool Box::show()
+{
+ LogD("enter");
+ CHECK_BOX_STATE(m_state, permitShow);
+
+ try {
+ m_updateTimer->start();
+ RenderInfoPtr renderInfo = makeRenderInfo(renderTypeCreate, URL_TYPE_BOX);
+ m_view->showBox(renderInfo);
+ } catch (...) {
+ return false;
+ }
+
+ SWITCH_BOX_STATE();
+ return true;
+}
+
+bool Box::hide()
+{
+ LogD("enter");
+ CHECK_BOX_STATE(m_state, permitHide);
+
+ try {
+ if (m_pdBuffer) {
+ m_pdBuffer->stopCanvasUpdate();
+ m_view->hidePd();
+ m_pdBuffer->free();
+ m_pdBuffer.reset();
+ }
+
+ m_updateTimer->stop();
+ m_boxBuffer->stopCanvasUpdate();
+ m_view->hideBox();
+ m_boxBuffer->free();
+ m_boxBuffer.reset();
+ } catch (...) {
+ return false;
+ }
+
+ SWITCH_BOX_STATE();
+ return true;
+}
+
+bool Box::resize(int width, int height)
+{
+ LogD("enter");
+ CHECK_BOX_STATE(m_state, permitShow);
+
+ // reset box info to new width, height
+ m_boxInfo->boxWidth = width;
+ m_boxInfo->boxHeight = height;
+
+ try {
+ m_updateTimer->restart();
+ m_boxBuffer->reallocate(
+ m_boxInfo->boxWidth, m_boxInfo->boxHeight);
+ RenderInfoPtr renderInfo = makeRenderInfo(renderTypeResize, URL_TYPE_BOX);
+ m_view->showBox(renderInfo);
+ } catch (...) {
+ LogD("resize exception");
+ return false;
+ }
+
+ SWITCH_BOX_STATE();
+ return true;
+}
+
+bool Box::resume()
+{
+ LogD("enter");
+ CHECK_BOX_STATE(m_state, permitResume);
+
+ try {
+ m_currentTab = true;
+ m_paused = false;
+
+ if (m_updateNeeded) {
+ m_updateNeeded = false;
+ updateInternal();
+ } else {
+ m_view->resumeBox();
+ }
+ } catch (...) {
+ return false;
+ }
+
+ SWITCH_BOX_STATE();
+ return true;
+}
+
+bool Box::pause(bool background)
+{
+ LogD("enter");
+ CHECK_BOX_STATE(m_state, permitPause);
+
+ try {
+ if (!background) {
+ m_currentTab = false;
+ }
+ m_paused = true;
+ m_view->pauseBox();
+ } catch (...) {
+ return false;
+ }
+
+ SWITCH_BOX_STATE();
+ return true;
+}
+
+bool Box::openPd(int width, int height, double x, double y)
+{
+ LogD("enter");
+ CHECK_BOX_STATE(m_state, permitOpenPd);
+
+ m_boxInfo->pdWidth = width;
+ m_boxInfo->pdHeight = height;
+ m_boxInfo->pdX = x;
+ m_boxInfo->pdY = y;
+
+ try {
+ m_updateTimer->stop();
+ m_pdBuffer = RenderBufferFactory::create(
+ RenderBufferFactory::RENDER_BUFFER_TYPE_PD,
+ m_boxInfo->boxId,
+ m_boxInfo->instanceId,
+ m_boxInfo->pdWidth,
+ m_boxInfo->pdHeight);
+ m_pdBuffer->allocate();
+ m_pdBuffer->stopCanvasUpdate();
+ RenderInfoPtr pdRenderInfo = makeRenderInfo(renderTypeOpenPd, URL_TYPE_PD);
+ RenderInfoPtr boxRenderInfo = makeRenderInfo(renderTypeOpenPd, URL_TYPE_BOX);
+ m_view->showPd(pdRenderInfo, boxRenderInfo);
+ ecore_idler_add(startUpdateRenderBufferIdlerCallback, m_pdBuffer.get());
+ } catch (...) {
+ return false;
+ }
+
+ SWITCH_BOX_STATE();
+ return true;
+}
+
+bool Box::closePd()
+{
+ LogD("enter");
+ CHECK_BOX_STATE(m_state, permitClosePd);
+
+ try {
+ if (m_pdBuffer) {
+ m_pdBuffer->stopCanvasUpdate();
+ m_view->hidePd();
+ m_pdBuffer->free();
+ m_pdBuffer.reset();
+ }
+ m_updateTimer->restart();
+ } catch (...) {
+ return false;
+ }
+
+ // if box update is requested during pd opening
+ if (m_updateNeeded) {
+ updateInternal();
+ }
+
+ SWITCH_BOX_STATE();
+ return true;
+}
+
+bool Box::update(time_t requestTime, std::string& contentInfo)
+{
+ LogD("enter");
+
+ m_lastUpdateRequestTime = requestTime;
+ m_boxInfo->contentInfo = contentInfo;
+ if (m_paused || m_pdBuffer) {
+ // update is dalayed
+ // until this box goes to current tab or pd is closed
+ m_updateNeeded = true;
+ return true;
+ }
+
+ try {
+ updateInternal();
+ } catch (...) {
+ return false;
+ }
+
+ return true;
+}
+
+bool Box::changePeriod(float period)
+{
+ LogD("enter");
+
+ // reset period
+ m_boxInfo->period = period;
+ m_updateTimer->setPeriod(m_boxInfo->period);
+
+ return true;
+}
+
+bool Box::isCurrentTab()
+{
+ return m_currentTab;
+}
+
+time_t Box::getLastUpdateRequestTime()
+{
+ return m_lastUpdateRequestTime;
+}
+
+RenderInfoPtr Box::makeRenderInfo(const std::string& renderType, UrlType urlType) const
+{
+ LogD("enter");
+ RenderInfoPtr renderInfo(new RenderInfo);
+
+ // add width, height, operation type
+ renderInfo->defaultUrlParams = "?type=" + renderType;
+
+ // set width, height
+ switch (urlType) {
+ case URL_TYPE_BOX:
+ renderInfo->window = m_boxBuffer->getWindow();
+ renderInfo->width = m_boxInfo->boxWidth;
+ renderInfo->height = m_boxInfo->boxHeight;
+ break;
+ case URL_TYPE_PD:
+ renderInfo->window = m_pdBuffer->getWindow();
+ renderInfo->width = m_boxInfo->pdWidth;
+ renderInfo->height = m_boxInfo->pdHeight;
+ break;
+ default:
+ LogD("error url type");
+ return RenderInfoPtr();
+ }
+
+ char buff[32];
+ sprintf(buff, "&width=%d&height=%d", renderInfo->width, renderInfo->height);
+ renderInfo->defaultUrlParams += buff;
+
+ // if needed, set pd information
+ if (renderType == renderTypeOpenPd) {
+ renderInfo->defaultUrlParams += "&pdopen-direction=";
+ if (m_boxInfo->pdY == 0.0f) {
+ renderInfo->defaultUrlParams += "down";
+ } else {
+ renderInfo->defaultUrlParams += "up";
+ }
+
+ char buff[32];
+ sprintf(buff, "&pdopen-arrow-xpos=%d",
+ static_cast<int>((m_boxInfo->pdX) * (m_boxInfo->pdWidth)));
+ renderInfo->defaultUrlParams += buff;
+ }
+
+
+ // add content info
+ if (!m_boxInfo->contentInfo.empty()) {
+ renderInfo->defaultUrlParams += "&" + m_boxInfo->contentInfo;
+ }
+
+ LogD("default url param string: %s", renderInfo->defaultUrlParams.c_str());
+ return renderInfo;
+}
+
+void Box::updateInternal()
+{
+ LogD("enter");
+ RenderInfoPtr renderInfo = makeRenderInfo(renderTypeUpdate, URL_TYPE_BOX);
+ m_view->showBox(renderInfo);
+}
+
+void Box::setState(IBoxStatePtr state)
+{
+ UNUSED_PARAM(state);
+ // assign new state
+ //m_state = state;
+}
+
+Eina_Bool Box::updateCallback(void* data)
+{
+ LogD("enter");
+ Box* This = static_cast<Box*>(data);
+
+ This->updateInternal();
+ return ECORE_CALLBACK_RENEW;
+}
+
+Eina_Bool Box::startUpdateRenderBufferIdlerCallback(void* data)
+{
+ LogD("enter");
+ RenderBuffer* buffer = static_cast<RenderBuffer*>(data);
+ if (!buffer) {
+ LogD("no buffer");
+ } else {
+ buffer->startCanvasUpdate();
+ }
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+BoxInfoPtr Box::getBoxInfo()
+{
+ LogD("enter");
+ return m_boxInfo;
+}
diff --git a/src_mobile/Core/Box.h b/src_mobile/Core/Box.h
new file mode 100644
index 0000000..33eaf17
--- /dev/null
+++ b/src_mobile/Core/Box.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 Box.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_H
+#define BOX_H
+
+#include <string>
+#include <memory>
+#include <ctime>
+#include <Ecore.h>
+#include <Plugin/IBoxPluginFactory.h>
+#include "Buffer/IRenderBuffer.h"
+#include "View/IRenderView.h"
+#include "Util/ITimer.h"
+#include "BoxData.h"
+#include "IBoxState.h"
+#include "IBoxContext.h"
+#include "IBox.h"
+#include "Box.h"
+
+class Box: public IBox, public IBoxContext {
+ public:
+ static IBoxPtr create(
+ BoxInfoPtr boxInfo,
+ IBoxPluginFactoryPtr factory,
+ EwkContextPtr ewkContext)
+ {
+ return IBoxPtr(new Box(boxInfo, factory, ewkContext));
+ };
+ // IBox
+ bool show();
+ bool hide();
+ bool resize(int width, int height);
+ bool resume();
+ bool pause(bool background);
+ bool openPd(int width, int height, double x, double y);
+ bool closePd();
+ bool update(time_t requestTime, std::string& contentInfo);
+ bool changePeriod(float period);
+ bool isCurrentTab();
+ time_t getLastUpdateRequestTime();
+ BoxInfoPtr getBoxInfo();
+
+ ~Box();
+
+ private:
+ enum UrlType {
+ URL_TYPE_BOX = 0,
+ URL_TYPE_PD
+ };
+
+ RenderInfoPtr makeRenderInfo(const std::string& renderType, UrlType urlType) const;
+ void updateInternal();
+
+ // IBoxContext
+ void setState(IBoxStatePtr state);
+
+ // static callbacks
+ static Eina_Bool updateCallback(void* data);
+ static Eina_Bool startUpdateRenderBufferIdlerCallback(void* data);
+
+ // constructor
+ explicit Box(
+ BoxInfoPtr boxInfo,
+ IBoxPluginFactoryPtr factory,
+ EwkContextPtr ewkContext);
+
+ BoxInfoPtr m_boxInfo;
+ IBoxPluginFactoryPtr m_factory;
+ IRenderBufferPtr m_boxBuffer;
+ IRenderBufferPtr m_pdBuffer;
+ IRenderViewPtr m_view;
+ ITimerPtr m_updateTimer;
+ //IBoxStatePtr m_state;
+ // flag for knowing this box is on current tab
+ bool m_currentTab;
+ // flag for knowing this box has been already paused
+ bool m_paused;
+ // flag for knowing this box should be updated when the box is resumed
+ bool m_updateNeeded;
+ // timestamp for saving last update request from external app
+ time_t m_lastUpdateRequestTime;
+
+ friend class BoxSchemeHandler;
+};
+
+#endif //BOX_H
+
diff --git a/src_mobile/Core/BoxData.h b/src_mobile/Core/BoxData.h
new file mode 100644
index 0000000..86bdfb4
--- /dev/null
+++ b/src_mobile/Core/BoxData.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxData.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_DATA_H
+#define BOX_DATA_H
+
+#include <memory>
+#include <string>
+
+struct BoxInfo
+{
+ std::string boxType;
+ std::string boxId;
+ std::string instanceId;
+ int boxWidth;
+ int boxHeight;
+ int pdWidth;
+ int pdHeight;
+ double pdX;
+ double pdY;
+ int priority;
+ float period;
+ std::string contentInfo;
+
+ // initialization
+ BoxInfo(std::string boxType,
+ std::string boxId,
+ std::string instanceId) :
+ boxType(boxType),
+ boxId(boxId),
+ instanceId(instanceId),
+ boxWidth(0),
+ boxHeight(0),
+ pdWidth(0),
+ pdHeight(0),
+ pdX(0.0f),
+ pdY(0.0f),
+ priority(0),
+ period(0),
+ contentInfo()
+ {
+ };
+
+ BoxInfo() :
+ boxType(),
+ boxId(),
+ instanceId(),
+ boxWidth(0),
+ boxHeight(0),
+ pdWidth(0),
+ pdHeight(0),
+ pdX(0.0f),
+ pdY(0.0f),
+ priority(0),
+ period(0),
+ contentInfo()
+ {
+ };
+};
+
+typedef std::shared_ptr<struct BoxInfo> BoxInfoPtr;
+typedef struct BoxInfo& BoxInfoRef;
+
+#endif // BOX_DATA_H
diff --git a/src_mobile/Core/BoxManager.cpp b/src_mobile/Core/BoxManager.cpp
new file mode 100644
index 0000000..a4307b4
--- /dev/null
+++ b/src_mobile/Core/BoxManager.cpp
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxManager.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <map>
+#include <ctime>
+#include <ewk_context.h>
+#include <Plugin/IBoxPluginFactory.h>
+#include <Plugin/box_plugin_interface.h>
+#include "Util/Log.h"
+#include "Util/Util.h"
+#include "IBox.h"
+#include "Box.h"
+#include "BoxData.h"
+#include "BoxManager.h"
+
+BoxManager::BoxManager(IBoxPluginFactoryPtr factory)
+ : m_boxFactory(factory)
+{
+ LogD("enter");
+}
+
+BoxManager::~BoxManager()
+{
+ LogD("enter");
+}
+
+bool BoxManager::doCommand(const request_cmd_type type, const BoxInfoPtr& boxInfo)
+{
+ bool result = false;
+
+ switch (type) {
+ case REQUEST_CMD_ADD_BOX:
+ result = requestAddBox(boxInfo, m_defaultContext);
+ break;
+ case REQUEST_CMD_REMOVE_BOX:
+ result = requestRemoveBox(boxInfo->instanceId);
+ break;
+ case REQUEST_CMD_RESIZE_BOX:
+ result = requestResizeBox(boxInfo->instanceId, boxInfo->boxWidth, boxInfo->boxHeight);
+ break;
+ case REQUEST_CMD_RESUME_BOX:
+ result = requestResumeBox(boxInfo->instanceId);
+ break;
+ case REQUEST_CMD_PAUSE_BOX:
+ result = requestPauseBox(boxInfo->instanceId);
+ break;
+ case REQUEST_CMD_RESUME_ALL:
+ result = requestResumeAll();
+ break;
+ case REQUEST_CMD_PAUSE_ALL:
+ result = requestPauseAll();
+ break;
+ case REQUEST_CMD_OPEN_PD:
+ result = requestOpenPd(boxInfo->instanceId,
+ boxInfo->pdWidth, boxInfo->pdHeight,
+ boxInfo->pdX, boxInfo->pdY);
+ break;
+ case REQUEST_CMD_CLOSE_PD:
+ result = requestClosePd(boxInfo->instanceId);
+ break;
+ case REQUEST_CMD_CHANGE_PERIOD:
+ result = requestChangePeriod(boxInfo->instanceId, boxInfo->period);
+ break;
+ case REQUEST_CMD_UPDATE_BOX:
+ result = requestUpdateBox(boxInfo->boxId, boxInfo->contentInfo);
+ break;
+ case REQUEST_CMD_CHANGE_LANGUAGE:
+ result = requestChangeLanguage(boxInfo->instanceId);
+ break;
+ default:
+ LogD("not available request type");
+ break;
+ }
+
+ return result;
+}
+
+bool BoxManager::requestAddBox(BoxInfoPtr boxInfo, EwkContextPtr ewkContext)
+{
+ IBoxPtr box;
+
+ // create new box
+ try {
+ if (!ewkContext) {
+ if (!m_defaultContext) {
+ m_defaultContext = EwkContextPtr(ewk_context_new(), EwkContextDeleter());
+ }
+ ewkContext = m_defaultContext;
+ }
+ box = Box::create(boxInfo, m_boxFactory, ewkContext);
+ } catch (...) {
+ LogD("exection occurs during adding box");
+ return false;
+ }
+
+ // show new box
+ if (!box->show()) {
+ LogD("problem occurs during rendering box");
+ return false;
+ }
+
+ insertBoxMap(boxInfo->instanceId, box);
+ return true;
+}
+
+bool BoxManager::requestRemoveBox(std::string& instanceId)
+{
+ IBoxPtr box = searchBoxMap(instanceId);
+ if (!box) {
+ return false;
+ }
+
+ if (!box->hide()) {
+ return false;
+ }
+
+ eraseBoxMap(instanceId);
+ return true;
+}
+
+bool BoxManager::requestResizeBox(std::string& instanceId, int width, int height)
+{
+ LogD("enter");
+ IBoxPtr box = searchBoxMap(instanceId);
+ if (!box) {
+ return false;
+ }
+
+ return box->resize(width, height);
+}
+
+bool BoxManager::requestResumeBox(std::string& instanceId)
+{
+ LogD("enter");
+ IBoxPtr box = searchBoxMap(instanceId);
+ if (!box) {
+ return false;
+ }
+
+ return box->resume();
+}
+
+bool BoxManager::requestPauseBox(std::string& instanceId)
+{
+ LogD("enter");
+ IBoxPtr box = searchBoxMap(instanceId);
+ if (!box) {
+ return false;
+ }
+
+ // paused by switching other page
+ return box->pause(false);
+}
+
+bool BoxManager::requestResumeAll()
+{
+ LogD("enter");
+ for (auto it = m_boxMap.begin(); it != m_boxMap.end(); it++) {
+ if (it->second->isCurrentTab()) {
+ it->second->resume();
+ }
+ }
+
+ return true;
+}
+
+bool BoxManager::requestPauseAll()
+{
+ LogD("enter");
+ for (auto it = m_boxMap.begin(); it != m_boxMap.end(); it++) {
+ if (it->second->isCurrentTab()) {
+ // paused by entering background
+ it->second->pause(true);
+ }
+ }
+
+ return true;
+}
+
+bool BoxManager::requestOpenPd(
+ std::string& instanceId,
+ int width, int height, double x, double y)
+{
+ LogD("enter");
+ IBoxPtr box = searchBoxMap(instanceId);
+ if (!box) {
+ return false;
+ }
+
+ return box->openPd(width, height, x, y);
+}
+
+bool BoxManager::requestClosePd(std::string& instanceId)
+{
+ LogD("enter");
+ IBoxPtr box = searchBoxMap(instanceId);
+ if (!box) {
+ return false;
+ }
+
+ return box->closePd();
+}
+
+bool BoxManager::requestChangePeriod(std::string& instanceId, float period)
+{
+ LogD("enter");
+ IBoxPtr box = searchBoxMap(instanceId);
+ if (!box) {
+ return false;
+ }
+
+ return box->changePeriod(period);
+}
+
+bool BoxManager::requestUpdateBox(std::string& boxId, std::string& contentInfo)
+{
+ LogD("enter");
+
+ IBoxPtr box;
+ box.reset();
+
+ time_t requestTime = time(NULL);
+
+ for (auto it = m_boxMap.begin(); it != m_boxMap.end(); ++it) {
+ if (it->first.find(boxId) == std::string::npos) {
+ continue;
+ }
+ box = it->second;
+ box->update(requestTime, contentInfo);
+ }
+
+ return true;
+}
+
+bool BoxManager::requestChangeLanguage(std::string& instanceId)
+{
+ LogD("enter");
+ UNUSED_PARAM(instanceId);
+
+ IBoxPtr box;
+ box.reset();
+
+ time_t requestTime = time(NULL);
+
+ for (auto it = m_boxMap.begin(); it != m_boxMap.end(); ++it) {
+ if (it->second) {
+ box = it->second;
+ box->update(requestTime, box->getBoxInfo()->contentInfo);
+ }
+ }
+ return true;
+}
+
+void BoxManager::insertBoxMap(std::string& instanceId, IBoxPtr box)
+{
+ if (!searchBoxMap(instanceId)) {
+ LogD("insert box to map: %s", instanceId.c_str());
+ m_boxMap.insert(BoxMapPair(instanceId, box));
+ } else {
+ LogD("this box was already inserted!");
+ }
+}
+
+void BoxManager::eraseBoxMap(std::string& instanceId)
+{
+ LogD("erase box to map");
+ if (!searchBoxMap(instanceId)) {
+ LogD("not available box");
+ return;
+ }
+
+ m_boxMap.erase(instanceId);
+}
+
+void BoxManager::updateBoxMap(std::string& instanceId, IBoxPtr box)
+{
+ if (searchBoxMap(instanceId)) {
+ eraseBoxMap(instanceId);
+ }
+
+ insertBoxMap(instanceId, box);
+}
+
+IBoxPtr BoxManager::searchBoxMap(std::string& instanceId)
+{
+ LogD("enter");
+ IBoxPtr box;
+ box.reset();
+ auto it = m_boxMap.find(instanceId);
+ if (it != m_boxMap.end()) {
+ LogD("found box: %s (%p)", it->first.c_str(), it->second.get());
+ box = it->second;
+ }
+
+ return box;
+}
+
+void BoxManager::clearBoxMap()
+{
+ m_boxMap.clear();
+}
+
+void BoxManager::EwkContextDeleter::operator()(Ewk_Context* ptr)
+{
+ LogD("ewk context delete");
+ if (ptr) {
+ ewk_context_delete(ptr);
+ }
+}
+
diff --git a/src_mobile/Core/BoxManager.h b/src_mobile/Core/BoxManager.h
new file mode 100644
index 0000000..77806bb
--- /dev/null
+++ b/src_mobile/Core/BoxManager.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxManager.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_MANAGER_H
+#define BOX_MANAGER_H
+
+#include <map>
+#include <string>
+#include <memory>
+#include <Plugin/box_plugin_interface.h>
+#include <Plugin/IBoxPluginFactory.h>
+#include "BoxData.h"
+#include "IBox.h"
+#include "IBoxManager.h"
+
+#define EXPORT_CLASS __attribute__ ((visibility("default"))
+
+class EXPORT_CLASS BoxManager: public IBoxManager {
+ public:
+ static IBoxManagerPtr create(IBoxPluginFactoryPtr factory)
+ {
+ return IBoxManagerPtr(new BoxManager(factory));
+ };
+ virtual bool doCommand(const request_cmd_type type, const BoxInfoPtr& boxInfo);
+ virtual ~BoxManager();
+
+ protected:
+ virtual bool requestAddBox(BoxInfoPtr boxInfo, EwkContextPtr ewkContext);
+ virtual bool requestRemoveBox(std::string& instanceId);
+ virtual bool requestResizeBox(std::string& instanceId, int width, int height);
+ virtual bool requestResumeBox(std::string& instanceId);
+ virtual bool requestPauseBox(std::string& instanceId);
+ virtual bool requestResumeAll();
+ virtual bool requestPauseAll();
+ virtual bool requestOpenPd(
+ std::string& instanceId,
+ int width, int height, double x, double y);
+ virtual bool requestClosePd(std::string& instanceId);
+ virtual bool requestChangePeriod(std::string& instanceId, float period);
+ virtual bool requestUpdateBox(std::string& boxId, std::string& contentInfo);
+ virtual bool requestChangeLanguage(std::string& instanceId);
+
+ // ewk context deleter
+ struct EwkContextDeleter {
+ void operator()(Ewk_Context* ptr);
+ };
+
+ explicit BoxManager(IBoxPluginFactoryPtr factory);
+
+ private:
+ // map operations
+ void insertBoxMap(std::string& instanceId, IBoxPtr box);
+ void eraseBoxMap(std::string& instanceId);
+ void updateBoxMap(std::string& instanceId, IBoxPtr box);
+ IBoxPtr searchBoxMap(std::string& instanceId);
+ void clearBoxMap();
+
+ typedef std::map<std::string, IBoxPtr> BoxMap;
+ typedef std::pair<std::string, IBoxPtr> BoxMapPair;
+ BoxMap m_boxMap;
+ IBoxPluginFactoryPtr m_boxFactory;
+ EwkContextPtr m_defaultContext;
+};
+
+#endif // BOX_MANAGER_H
diff --git a/src_mobile/Core/BoxSchemeHandler.cpp b/src_mobile/Core/BoxSchemeHandler.cpp
new file mode 100755
index 0000000..9e04704
--- /dev/null
+++ b/src_mobile/Core/BoxSchemeHandler.cpp
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxSchemeHandler.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string.h>
+#include <ctime>
+#include "Box.h"
+#include "Service/AppControl.h"
+#include "Service/PeriodChanger.h"
+#include "Service/ScrollHolder.h"
+#include "Service/MessageManager.h"
+#include "Util/Log.h"
+#include "Util/Util.h"
+#include "BoxSchemeHandler.h"
+
+using namespace Service;
+
+static const std::string BOX_SCHEME("box://");
+static const std::string BOX_SCHEME_RELOAD("box://reload");
+static const std::string BOX_SCHEME_CHANGE_PERIOD("box://change-period");
+static const std::string BOX_SCHEME_LAUNCH_BROWSER("box://launch-browser");
+static const std::string BOX_SCHEME_SCROLL_START("box://scroll-start");
+static const std::string BOX_SCHEME_SCROLL_STOP("box://scroll-stop");
+static const std::string BOX_SCHEME_SEND_MESSAGE_TO_PD("box://send-message-to-pd");
+static const std::string BOX_SCHEME_SEND_MESSAGE_TO_BOX("box://send-message-to-box");
+
+static const std::string HTTP_SCHEME("http://");
+static const std::string HTTPS_SCHEME("https://");
+
+// static variable intialization
+BoxSchemeHandler* BoxSchemeHandler::s_instance = NULL;
+
+BoxSchemeHandler::BoxSchemeHandler()
+ : m_boxMap()
+{
+ LogD("enter");
+}
+
+BoxSchemeHandler::~BoxSchemeHandler()
+{
+ LogD("enter");
+}
+
+BoxSchemeHandler* BoxSchemeHandler::Instance()
+{
+ LogD("enter");
+ if (!s_instance) {
+ s_instance = new BoxSchemeHandler();
+ }
+
+ return s_instance;
+}
+
+void BoxSchemeHandler::registerBox(std::string& instanceId, Box* box)
+{
+ LogD("enter");
+
+ if (getBox(instanceId)) {
+ LogD("already registered");
+ return;
+ }
+
+ m_boxMap.insert(BoxMapPair(instanceId, box));
+}
+
+void BoxSchemeHandler::unregisterBox(std::string& instanceId)
+{
+ LogD("enter");
+ m_boxMap.erase(instanceId);
+}
+
+bool BoxSchemeHandler::process(std::string& instanceId, std::string& uri)
+{
+ LogD("enter");
+
+ if (!isBoxScheme(uri)) {
+ return false;
+ }
+
+ if (!uri.compare(BOX_SCHEME_RELOAD)) {
+ return handleReload(instanceId);
+ }
+
+ if (!uri.compare(
+ 0,
+ BOX_SCHEME_CHANGE_PERIOD.size(),
+ BOX_SCHEME_CHANGE_PERIOD))
+ {
+ std::string key("period");
+ std::string period = parse(uri, key);
+ if (period.empty()) {
+ return handleChangePeriod(instanceId);
+ }
+
+ return handleChangePeriod(instanceId, std::atof(period.c_str()));
+ }
+
+ if (!uri.compare(
+ 0,
+ BOX_SCHEME_LAUNCH_BROWSER.size(),
+ BOX_SCHEME_LAUNCH_BROWSER))
+ {
+ std::string key("url");
+ std::string url = parse(uri, key);
+ return handleLaunchBrowser(instanceId, url);
+ }
+
+ if (!uri.compare(BOX_SCHEME_SCROLL_START)) {
+ return handleScroll(instanceId, true);
+ }
+
+ if (!uri.compare(BOX_SCHEME_SCROLL_STOP)) {
+ return handleScroll(instanceId, false);
+ }
+
+ if (!uri.compare(
+ 0,
+ BOX_SCHEME_SEND_MESSAGE_TO_BOX.size(),
+ BOX_SCHEME_SEND_MESSAGE_TO_BOX))
+ {
+ std::string key("message");
+ std::string message = parse(uri, key);
+ return handleSendMessage(instanceId, MessageManager::TO_BOX, message);
+ }
+
+ if (!uri.compare(
+ 0,
+ BOX_SCHEME_SEND_MESSAGE_TO_PD.size(),
+ BOX_SCHEME_SEND_MESSAGE_TO_PD))
+ {
+ std::string key("message");
+ std::string message = parse(uri, key);
+ return handleSendMessage(instanceId, MessageManager::TO_PD, message);
+ }
+ LogD("unknown box scheme protocol");
+ return false;
+}
+
+bool BoxSchemeHandler::isBoxScheme(std::string& uri)
+{
+ LogD("enter");
+ if(!uri.compare(0, BOX_SCHEME.size(), BOX_SCHEME)) {
+ return true;
+ }
+
+ return false;
+}
+
+Box* BoxSchemeHandler::getBox(std::string& instanceId)
+{
+ LogD("enter");
+
+ auto it = m_boxMap.find(instanceId);
+ if (it != m_boxMap.end()) {
+ LogD("registered: %s (%p)", it->first.c_str(), it->second);
+ return it->second;
+ }
+
+ return NULL;
+}
+
+bool BoxSchemeHandler::handleScroll(std::string& instanceId, bool start)
+{
+ using namespace Service::ScrollHolder;
+
+ LogD("enter");
+ Box* box = getBox(instanceId);
+ if (!box) {
+ LogD("unregistered instance");
+ return false;
+ }
+
+ holdHorizontalScroll(box->m_boxInfo->boxId, instanceId, start);
+ return true;
+}
+
+bool BoxSchemeHandler::handleReload(std::string& instanceId)
+{
+ LogD("enter");
+ Box* box = getBox(instanceId);
+ if (!box) {
+ LogD("unregistered instance");
+ return false;
+ }
+
+ // In the future, new content info can be set by caller
+ box->updateInternal();
+ return true;
+}
+
+bool BoxSchemeHandler::handleChangePeriod(std::string& instanceId, double requestedPeriod)
+{
+ LogD("enter");
+
+ Box* box = getBox(instanceId);
+ if (!box) {
+ LogD("no box for update period");
+ return false;
+ }
+
+ if (Service::PeriodChanger::isPopupOpened()) {
+ LogD("preiod popup is already opened!");
+ return false;
+ }
+
+ m_periodChanger =
+ Service::PeriodChanger::create(
+ box->m_boxInfo->boxId, instanceId,
+ box->m_boxInfo->period, requestedPeriod);
+
+ return m_periodChanger->change();
+}
+
+bool BoxSchemeHandler::handleLaunchBrowser(std::string& instanceId, std::string& url)
+{
+ LogD("enter");
+ UNUSED_PARAM(instanceId);
+
+ if (!url.compare(0, HTTP_SCHEME.size(), HTTP_SCHEME) ||
+ !url.compare(0, HTTPS_SCHEME.size(), HTTPS_SCHEME))
+ {
+ return Service::AppControl::launchBrowser(url);
+ }
+
+ return false;
+}
+
+bool BoxSchemeHandler::handleSendMessage(
+ std::string& instanceId,
+ MessageManager::ReceiverType receiver,
+ std::string& message)
+{
+ LogD("enter");
+ Box* box = getBox(instanceId);
+ if (!box) {
+ LogD("no box for update period");
+ return false;
+ };
+
+ // set webview of receiver
+ Evas_Object* webview;
+ switch (receiver) {
+ case MessageManager::TO_BOX:
+ webview = box->m_view->getBoxWebView();
+ break;
+ case MessageManager::TO_PD:
+ webview = box->m_view->getPdWebView();
+ break;
+ default:
+ LogD("not supported receiver");
+ return false;
+ }
+
+ return m_messageManager->send(webview, receiver, message);
+}
+
+std::string BoxSchemeHandler::parse(std::string& uri, std::string& key)
+{
+ LogD("enter");
+
+ // TODO url parameter SHOULD be parsed using std::regex, not manually
+ std::string value("");
+
+ unsigned found = uri.find_first_of("?");
+ if (found == std::string::npos) {
+ LogD("no query");
+ return value;
+ }
+
+ std::string query = std::string(uri, found + 1);
+ found = 0;
+ do {
+ LogD("enter\n");
+ unsigned seperator = query.find_first_of("=", found + 1);
+ if (seperator == std::string::npos) {
+ LogD("no '=' character\n");
+ break;
+ }
+
+ unsigned next = query.find_first_of("@", found + 1);
+ if (!query.compare(found, key.size(), key)) {
+ LogD("key matched!\n");
+ value = std::string(query, seperator + 1, next - seperator - 1);
+ break;
+ }
+
+ found = next + 1;
+ } while (found && found != std::string::npos);
+
+ LogD("URL query parsing result: key -> %s, value -> %s", key.c_str(), value.c_str());
+ return value;
+}
diff --git a/src_mobile/Core/BoxSchemeHandler.h b/src_mobile/Core/BoxSchemeHandler.h
new file mode 100755
index 0000000..f855196
--- /dev/null
+++ b/src_mobile/Core/BoxSchemeHandler.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxSchemeHandler.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_SCHEME_HANDLER_H
+#define BOX_SCHEME_HANDLER_H
+
+#include <string>
+#include <map>
+#include "Service/PeriodChanger.h"
+#include "Service/MessageManager.h"
+
+using namespace Service;
+
+class Box;
+
+#define EXPORT_CLASS __attribute__ ((visibility("default"))
+
+class EXPORT_CLASS BoxSchemeHandler {
+ public:
+ static BoxSchemeHandler* Instance();
+ void registerBox(std::string& instanceId, Box* box);
+ void unregisterBox(std::string& instanceId);
+ bool process(std::string& instanceId, std::string& uri);
+ bool isBoxScheme(std::string& uri);
+
+ private:
+ Box* getBox(std::string& instanceId);
+ bool handleReload(std::string& instanceId);
+ bool handleChangePeriod(std::string& instanceId, double requestedPeriod = -1.0f);
+ bool handleLaunchBrowser(std::string& instanceId, std::string& url);
+ bool handleScroll(std::string& instanceId, bool start);
+ bool handleSendMessage(
+ std::string& instanceId,
+ MessageManager::ReceiverType receiver,
+ std::string& message);
+ std::string parse(std::string& uri, std::string& key);
+
+ BoxSchemeHandler();
+ ~BoxSchemeHandler();
+
+ // members
+ typedef std::map<std::string, Box*> BoxMap;
+ typedef std::pair<std::string, Box*> BoxMapPair;
+ BoxMap m_boxMap;
+ // members for service
+ std::shared_ptr<PeriodChanger> m_periodChanger;
+ std::shared_ptr<MessageManager> m_messageManager;
+ static BoxSchemeHandler* s_instance;
+};
+
+#endif // BOX_SCHEME_HANDLER_H
+
diff --git a/src_mobile/Core/BoxState.cpp b/src_mobile/Core/BoxState.cpp
new file mode 100644
index 0000000..9460857
--- /dev/null
+++ b/src_mobile/Core/BoxState.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxState.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include "IBoxContext.h"
+#include "IBoxState.h"
+#include "BoxState.h"
+
+// BoxState
+void BoxState::switchState()
+{
+ // TODO this creation may be wrong..
+ m_context->setState(IBoxStatePtr(this));
+}
+
+void BoxState::setContext(IBoxContextPtr context)
+{
+ m_context = context;
+}
+
+IBoxContextPtr BoxState::getContext()
+{
+ return m_context;
+}
+
+// BoxReadyState
+IBoxStatePtr BoxInitState::permitShow()
+{
+ return IBoxStatePtr(BoxShowState::create(getContext()));
+}
+
+// BoxShowState
+IBoxStatePtr BoxShowState::permitShow()
+{
+ // In this case, existing state needn't to be changed
+ return IBoxStatePtr(this);
+}
+
+IBoxStatePtr BoxShowState::permitHide()
+{
+ return IBoxStatePtr(BoxHideState::create(getContext()));
+}
+
+IBoxStatePtr BoxShowState::permitOpenPd()
+{
+ return IBoxStatePtr(BoxOpenPdState::create(getContext()));
+}
+
+IBoxStatePtr BoxShowState::permitPause()
+{
+ return IBoxStatePtr(BoxPauseState::create(getContext()));
+}
+
+// BoxHideState
+IBoxStatePtr BoxHideState::permitShutdown()
+{
+ // In this case, existing state needn't to be changed
+ // because there is no state to be changed from Hide State
+ return IBoxStatePtr(this);
+}
+
+// BoxOpenPdState
+IBoxStatePtr BoxOpenPdState::permitClosePd()
+{
+ return IBoxStatePtr(BoxClosePdState::create(getContext()));
+}
+
+// BoxClosePdState
+IBoxStatePtr BoxClosePdState::permitShow()
+{
+ return IBoxStatePtr(BoxShowState::create(getContext()));
+}
+
+// BoxPauseState
+IBoxStatePtr BoxPauseState::permitResume()
+{
+ return IBoxStatePtr(BoxResumeState::create(getContext()));
+}
+
+IBoxStatePtr BoxPauseState::permitHide()
+{
+ return IBoxStatePtr(BoxHideState::create(getContext()));
+}
+
+// BoxResumeState
+IBoxStatePtr BoxResumeState::permitShow()
+{
+ return IBoxStatePtr(BoxShowState::create(getContext()));
+}
+
+IBoxStatePtr BoxResumeState::permitHide()
+{
+ return IBoxStatePtr(BoxHideState::create(getContext()));
+}
diff --git a/src_mobile/Core/BoxState.h b/src_mobile/Core/BoxState.h
new file mode 100644
index 0000000..5023386
--- /dev/null
+++ b/src_mobile/Core/BoxState.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxState.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_STATE
+#define BOX_STATE
+
+#include "IBoxState.h"
+#include "IBoxContext.h"
+
+/*
+#define CHECK_BOX_STATE(currentState, operation) \
+ IBoxStatePtr state; \
+ try { \
+ state = currentState->operation(); \
+ } catch (...) { \
+ return false; \
+ } \
+
+#define SWITCH_BOX_STATE() \
+ state->switchState() \
+*/
+
+#define CHECK_BOX_STATE(currentState, operation)
+#define SWITCH_BOX_STATE()
+
+class BoxState: public IBoxState {
+ public:
+ virtual IBoxStatePtr permitShow() { throw this; };
+ virtual IBoxStatePtr permitHide() { throw this; };
+ virtual IBoxStatePtr permitResume() { throw this; };
+ virtual IBoxStatePtr permitPause() { throw this; };
+ virtual IBoxStatePtr permitOpenPd() { throw this; };
+ virtual IBoxStatePtr permitClosePd() { throw this ; };
+ virtual IBoxStatePtr permitShutdown() { throw this; };
+ virtual void switchState();
+ virtual ~BoxState() {};
+
+ protected:
+ explicit BoxState(IBoxContextPtr context) : m_context(context) {};
+ IBoxContextPtr getContext();
+
+ private:
+ void setContext(IBoxContextPtr context);
+ IBoxContextPtr m_context;
+};
+
+class BoxInitState: public BoxState {
+ public:
+ static IBoxStatePtr create(IBoxContextPtr context)
+ {
+ return IBoxStatePtr(new BoxInitState(context));
+ };
+ virtual IBoxStatePtr permitShow();
+ virtual ~BoxInitState() {};
+
+ private:
+ explicit BoxInitState(IBoxContextPtr context) : BoxState(context) {};
+};
+
+class BoxShowState: public BoxState {
+ public:
+ static IBoxStatePtr create(IBoxContextPtr context)
+ {
+ return IBoxStatePtr(new BoxShowState(context));
+ };
+ virtual IBoxStatePtr permitShow();
+ virtual IBoxStatePtr permitHide();
+ virtual IBoxStatePtr permitOpenPd();
+ virtual IBoxStatePtr permitPause();
+ virtual ~BoxShowState() {};
+
+ private:
+ explicit BoxShowState(IBoxContextPtr context) : BoxState(context) {};
+};
+
+class BoxHideState: public BoxState {
+ public:
+ static IBoxStatePtr create(IBoxContextPtr context)
+ {
+ return IBoxStatePtr(new BoxHideState(context));
+ };
+ virtual IBoxStatePtr permitShutdown();
+ virtual ~BoxHideState() {};
+
+ private:
+ explicit BoxHideState(IBoxContextPtr context) : BoxState(context) {};
+};
+
+class BoxOpenPdState: public BoxState {
+ public:
+ static IBoxStatePtr create(IBoxContextPtr context)
+ {
+ return IBoxStatePtr(new BoxOpenPdState(context));
+ };
+ virtual IBoxStatePtr permitClosePd();
+ virtual ~BoxOpenPdState() {};
+
+ private:
+ explicit BoxOpenPdState(IBoxContextPtr context) : BoxState(context) {};
+};
+
+class BoxClosePdState: public BoxState {
+ public:
+ static IBoxStatePtr create(IBoxContextPtr context)
+ {
+ return IBoxStatePtr(new BoxClosePdState(context));
+ };
+ virtual IBoxStatePtr permitShow();
+ virtual ~BoxClosePdState() {};
+
+ private:
+ explicit BoxClosePdState(IBoxContextPtr context) : BoxState(context) {};
+};
+
+class BoxPauseState: public BoxState {
+ public:
+ static IBoxStatePtr create(IBoxContextPtr context)
+ {
+ return IBoxStatePtr(new BoxPauseState(context));
+ };
+ virtual IBoxStatePtr permitResume();
+ virtual IBoxStatePtr permitHide();
+ virtual ~BoxPauseState() {};
+
+ private:
+ explicit BoxPauseState(IBoxContextPtr context) : BoxState(context) {};
+};
+
+class BoxResumeState: public BoxState {
+ public:
+ static IBoxStatePtr create(IBoxContextPtr context)
+ {
+ return IBoxStatePtr(new BoxResumeState(context));
+ };
+ virtual IBoxStatePtr permitShow();
+ virtual IBoxStatePtr permitHide();
+ virtual ~BoxResumeState() {};
+
+ private:
+ explicit BoxResumeState(IBoxContextPtr context) : BoxState(context) {};
+};
+#endif // BOX_STATE
diff --git a/src_mobile/Core/BoxUpdateTimer.cpp b/src_mobile/Core/BoxUpdateTimer.cpp
new file mode 100644
index 0000000..73974e7
--- /dev/null
+++ b/src_mobile/Core/BoxUpdateTimer.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxUpdateTimer.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <Ecore.h>
+#include <Core/Util/Log.h>
+#include "BoxUpdateTimer.h"
+
+#define UPDATE_TIME_MIN 1800.0f
+
+BoxUpdateTimer::BoxUpdateTimer(float period, Ecore_Task_Cb callback, void* data)
+ : m_period(period)
+ , m_callback(callback)
+ , m_data(data)
+ , m_timer()
+{
+ LogD("enter");
+}
+
+BoxUpdateTimer::~BoxUpdateTimer()
+{
+ LogD("enter");
+}
+
+void BoxUpdateTimer::start()
+{
+ if (m_period <= 0.0f ) {
+ return;
+ }
+
+ if (m_period < UPDATE_TIME_MIN) {
+ LogD("reset to minimum period(%f)", UPDATE_TIME_MIN);
+ m_period = UPDATE_TIME_MIN;
+ }
+
+ if (m_timer) {
+ stop();
+ }
+
+ m_timer = ecore_timer_add(m_period, m_callback, m_data);
+}
+
+void BoxUpdateTimer::stop()
+{
+ if (m_timer) {
+ ecore_timer_del(m_timer);
+ m_timer = NULL;
+ }
+}
+
+void BoxUpdateTimer::resume()
+{
+ LogD("enter");
+ ecore_timer_thaw(m_timer);
+}
+
+void BoxUpdateTimer::pause()
+{
+ LogD("enter");
+ ecore_timer_freeze(m_timer);
+}
+
+void BoxUpdateTimer::restart()
+{
+ if (m_timer) {
+ ecore_timer_reset(m_timer);
+ } else {
+ start();
+ }
+}
+
+void BoxUpdateTimer::setPeriod(float period)
+{
+ m_period = period;
+ restart();
+}
diff --git a/src_mobile/Core/BoxUpdateTimer.h b/src_mobile/Core/BoxUpdateTimer.h
new file mode 100644
index 0000000..04bf046
--- /dev/null
+++ b/src_mobile/Core/BoxUpdateTimer.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxUpdateTimer.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_UPDATE_TIMER_H
+#define BOX_UPDATE_TIMER_H
+
+#include <Ecore.h>
+#include "Util/ITimer.h"
+
+class BoxUpdateTimer: public ITimer {
+ public:
+ static ITimerPtr create(float period, Ecore_Task_Cb callback, void* data)
+ {
+ return ITimerPtr(new BoxUpdateTimer(period, callback, data));
+ };
+ void start();
+ void stop();
+ void resume();
+ void pause();
+ void restart();
+ void setPeriod(float period);
+ ~BoxUpdateTimer();
+
+ private:
+ explicit BoxUpdateTimer(float period, Ecore_Task_Cb callback, void* data);
+ float m_period;
+ Ecore_Task_Cb m_callback;
+ void* m_data;
+ Ecore_Timer* m_timer;
+};
+
+#endif // BOX_UPDATE_TIMER_H
diff --git a/src_mobile/Core/Buffer/BoxRenderBuffer.cpp b/src_mobile/Core/Buffer/BoxRenderBuffer.cpp
new file mode 100644
index 0000000..0599d99
--- /dev/null
+++ b/src_mobile/Core/Buffer/BoxRenderBuffer.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxRenderBuffer.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <Ecore.h>
+#include <Evas.h>
+#include <provider.h>
+#include <provider_buffer.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "RenderBuffer.h"
+#include "BoxRenderBuffer.h"
+
+BoxRenderBuffer::BoxRenderBuffer(
+ std::string boxId, std::string instanceId,
+ int width, int height)
+ : m_boxId(boxId)
+ , m_instanceId(instanceId)
+ , m_width(width)
+ , m_height(height)
+{
+}
+
+BoxRenderBuffer::~BoxRenderBuffer()
+{
+}
+
+BufferInfoPtr BoxRenderBuffer::acquireBuffer()
+{
+ LogD("enter");
+
+ BufferInfoPtr bufferInfo =
+ provider_buffer_acquire(
+ TYPE_LB,
+ m_boxId.c_str(),
+ m_instanceId.c_str(),
+ m_width,
+ m_height,
+ sizeof(int),
+ handleTouchEventCallback,
+ this);
+ return bufferInfo;
+}
+
+void BoxRenderBuffer::updateBuffer()
+{
+ LogD("enter");
+ provider_send_updated(
+ m_boxId.c_str(),
+ m_instanceId.c_str(),
+ m_width, m_height,
+ 0, NULL, NULL);
+}
+
+int BoxRenderBuffer::handleTouchEventCallback(
+ BufferInfoPtr bufferInfo,
+ buffer_event event,
+ double timestamp,
+ double x,
+ double y,
+ void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(bufferInfo);
+
+ BoxRenderBuffer* This = static_cast<BoxRenderBuffer*>(data);
+ TouchType type;
+ switch (event) {
+ case BUFFER_EVENT_MOVE:
+ type = TOUCH_EVENT_MOVE;
+ break;
+ case BUFFER_EVENT_DOWN:
+ type = TOUCH_EVENT_DOWN;
+ break;
+ case BUFFER_EVENT_UP:
+ type = TOUCH_EVENT_UP;
+ break;
+ default:
+ type = TOUCH_EVENT_UNRECOGNIZED;
+ break;
+ }
+
+ if (type != TOUCH_EVENT_UNRECOGNIZED) {
+ This->didHandleTouchEvent(type, timestamp, x, y);
+ }
+ return 0;
+}
+
+void BoxRenderBuffer::didHandleTouchEvent(
+ TouchType type, double timestamp, double x, double y)
+{
+ // timestamp format sent by viewer is not same to the timestamp format used by webkit-efl
+ // so web-provider should get timestamp using ecore_time_get()
+ // and then feed event with the timestamp to webkit
+
+ LogD("enter");
+ switch (type) {
+ case TOUCH_EVENT_MOVE:
+ LogD("move event");
+ evas_event_feed_mouse_move(
+ getCanvas(), x * m_width, y * m_height, ecore_time_get() * 1000, NULL);
+ break;
+ case TOUCH_EVENT_DOWN:
+ LogD("down event");
+ evas_event_feed_mouse_move(
+ getCanvas(), x * m_width, y * m_height, ecore_time_get() * 1000, NULL);
+ evas_event_feed_mouse_down(
+ getCanvas(), 1, EVAS_BUTTON_NONE, 0, NULL);
+ break;
+ case TOUCH_EVENT_UP:
+ LogD("up event");
+ evas_event_feed_mouse_up(
+ getCanvas(), 1, EVAS_BUTTON_NONE, 0, NULL);
+ break;
+ default:
+ LogD("wrong event");
+ break;
+ }
+}
diff --git a/src_mobile/Core/Buffer/BoxRenderBuffer.h b/src_mobile/Core/Buffer/BoxRenderBuffer.h
new file mode 100644
index 0000000..4213e72
--- /dev/null
+++ b/src_mobile/Core/Buffer/BoxRenderBuffer.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxRenderBuffer.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_RENDER_BUFFER_H
+#define BOX_RENDER_BUFFER_H
+
+#include <string>
+#include <provider_buffer.h>
+#include "IRenderBuffer.h"
+#include "RenderBuffer.h"
+
+#define EXPORT_CLASS __attribute__ ((visibility("default"))
+
+class EXPORT_CLASS BoxRenderBuffer: public RenderBuffer {
+ public:
+ enum TouchType {
+ TOUCH_EVENT_UNRECOGNIZED = -1,
+ TOUCH_EVENT_MOVE = 0,
+ TOUCH_EVENT_DOWN,
+ TOUCH_EVENT_UP
+ };
+
+ static IRenderBufferPtr create(
+ std::string boxId, std::string instanceId,
+ int width, int height)
+ {
+ return IRenderBufferPtr(new BoxRenderBuffer(
+ boxId, instanceId, width, height));
+
+ }
+ ~BoxRenderBuffer();
+
+ protected:
+ // this function may be overriden by derived class
+ virtual void didHandleTouchEvent(
+ TouchType type, double timestamp, double x, double y);
+
+ BoxRenderBuffer(
+ std::string boxId, std::string instanceId,
+ int width, int height);
+
+ private:
+ // RenderBuffer Implementation
+ int getWidth() { return m_width; };
+ int getHeight() { return m_height; };
+ void setWidth(int width) { m_width = width; };
+ void setHeight(int height) { m_height = height; };
+ BufferInfoPtr acquireBuffer();
+ void updateBuffer();
+
+ // touch callback
+ static int handleTouchEventCallback(
+ BufferInfoPtr bufferInfo,
+ buffer_event event,
+ double timestamp,
+ double x,
+ double y,
+ void* data);
+
+ // members
+ std::string m_boxId;
+ std::string m_instanceId;
+ int m_width;
+ int m_height;
+};
+
+#endif // BOX_RENDER_BUFFER_H
diff --git a/src_mobile/Core/Buffer/CMakeLists.txt b/src_mobile/Core/Buffer/CMakeLists.txt
new file mode 100644
index 0000000..e710dc3
--- /dev/null
+++ b/src_mobile/Core/Buffer/CMakeLists.txt
@@ -0,0 +1,67 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_CORE_BUFFER})
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ ecore
+ ecore-evas
+ evas
+ provider
+ dlog
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/RenderBuffer.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/RenderBufferFactory.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxRenderBuffer.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/PdRenderBuffer.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} STATIC ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LIBRARIES}
+)
+
+GET_FILENAME_COMPONENT(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+GET_FILENAME_COMPONENT(PARENT_DIR_ABSOLUTE_PATH ${CMAKE_CURRENT_SOURCE_DIR} PATH)
+GET_FILENAME_COMPONENT(PARENT_DIR_NAME ${PARENT_DIR_ABSOLUTE_PATH} NAME)
+
+INSTALL_FILE(IRenderBuffer.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(RenderBuffer.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(RenderBufferFactory.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(BoxRenderBuffer.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
diff --git a/src_mobile/Core/Buffer/IRenderBuffer.h b/src_mobile/Core/Buffer/IRenderBuffer.h
new file mode 100644
index 0000000..0c05e86
--- /dev/null
+++ b/src_mobile/Core/Buffer/IRenderBuffer.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IRenderBuffer.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_RENDER_BUFFER_H
+#define I_RENDER_BUFFER_H
+
+#include <memory>
+#include <Evas.h>
+#include <Util/Noncopyable.h>
+
+class IRenderBuffer: Noncopyable {
+ public:
+ virtual bool allocate() = 0;
+ virtual bool reallocate(int width, int height) = 0;
+ virtual bool free() = 0;
+ virtual void startCanvasUpdate() = 0;
+ virtual void stopCanvasUpdate() = 0;
+ virtual Evas_Object* getWindow() = 0;
+
+ virtual ~IRenderBuffer() {};
+};
+
+typedef std::shared_ptr<IRenderBuffer> IRenderBufferPtr;
+
+#endif
diff --git a/src_mobile/Core/Buffer/PdRenderBuffer.cpp b/src_mobile/Core/Buffer/PdRenderBuffer.cpp
new file mode 100644
index 0000000..af65e08
--- /dev/null
+++ b/src_mobile/Core/Buffer/PdRenderBuffer.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 PdRenderBuffer.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <Ecore.h>
+#include <Evas.h>
+#include <provider.h>
+#include <provider_buffer.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "RenderBuffer.h"
+#include "PdRenderBuffer.h"
+
+PdRenderBuffer::PdRenderBuffer(
+ std::string boxId, std::string instanceId,
+ int width, int height)
+ : m_boxId(boxId)
+ , m_instanceId(instanceId)
+ , m_width(width)
+ , m_height(height)
+{
+}
+
+PdRenderBuffer::~PdRenderBuffer()
+{
+}
+
+BufferInfoPtr PdRenderBuffer::acquireBuffer()
+{
+ BufferInfoPtr bufferInfo =
+ provider_buffer_acquire(
+ TYPE_PD,
+ m_boxId.c_str(),
+ m_instanceId.c_str(),
+ m_width,
+ m_height,
+ sizeof(int),
+ handleTouchEventCallback,
+ this);
+
+ return bufferInfo;
+}
+
+void PdRenderBuffer::updateBuffer()
+{
+ LogD("enter");
+ provider_send_desc_updated(
+ m_boxId.c_str(),
+ m_instanceId.c_str(),
+ NULL);
+}
+
+int PdRenderBuffer::handleTouchEventCallback(
+ BufferInfoPtr bufferInfo,
+ buffer_event event,
+ double timestamp,
+ double x,
+ double y,
+ void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(bufferInfo);
+
+ PdRenderBuffer* This = static_cast<PdRenderBuffer*>(data);
+ TouchType type;
+ switch (event) {
+ case BUFFER_EVENT_MOVE:
+ type = TOUCH_EVENT_MOVE;
+ break;
+ case BUFFER_EVENT_DOWN:
+ type = TOUCH_EVENT_DOWN;
+ break;
+ case BUFFER_EVENT_UP:
+ type = TOUCH_EVENT_UP;
+ break;
+ default:
+ type = TOUCH_EVENT_UNRECOGNIZED;
+ break;
+ }
+
+ if (type != TOUCH_EVENT_UNRECOGNIZED) {
+ This->didHandleTouchEvent(type, timestamp, x, y);
+ }
+ return 0;
+}
+
+void PdRenderBuffer::didHandleTouchEvent(
+ TouchType type, double timestamp, double x, double y)
+{
+ // timestamp format sent by viewer is not same to the timestamp format used by webkit-efl
+ // so web-provider should get timestamp using ecore_time_get()
+ // and then feed event with the timestamp to webkit
+
+ switch (type) {
+ case TOUCH_EVENT_MOVE:
+ LogD("move event");
+ evas_event_feed_mouse_move(
+ getCanvas(), x * m_width, y * m_height, ecore_time_get() * 1000, NULL);
+ break;
+ case TOUCH_EVENT_DOWN:
+ LogD("down event");
+ evas_event_feed_mouse_move(
+ getCanvas(), x * m_width, y * m_height, ecore_time_get() * 1000, NULL);
+ evas_event_feed_mouse_down(
+ getCanvas(), 1, EVAS_BUTTON_NONE, 0, NULL);
+ break;
+ case TOUCH_EVENT_UP:
+ LogD("up event");
+ evas_event_feed_mouse_up(
+ getCanvas(), 1, EVAS_BUTTON_NONE, 0, NULL);
+ break;
+ default:
+ LogD("wrong event");
+ break;
+ }
+}
diff --git a/src_mobile/Core/Buffer/PdRenderBuffer.h b/src_mobile/Core/Buffer/PdRenderBuffer.h
new file mode 100644
index 0000000..b2fd890
--- /dev/null
+++ b/src_mobile/Core/Buffer/PdRenderBuffer.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 PdRenderBuffer.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef PD_RENDER_BUFFER_H
+#define PD_RENDER_BUFFER_H
+
+#include <string>
+#include <provider_buffer.h>
+#include "IRenderBuffer.h"
+#include "RenderBuffer.h"
+
+#define EXPORT_CLASS __attribute__ ((visibility("default"))
+
+class EXPORT_CLASS PdRenderBuffer: public RenderBuffer {
+ public:
+ enum TouchType {
+ TOUCH_EVENT_UNRECOGNIZED = -1,
+ TOUCH_EVENT_MOVE = 0,
+ TOUCH_EVENT_DOWN,
+ TOUCH_EVENT_UP
+ };
+
+ static IRenderBufferPtr create(
+ std::string boxId, std::string instanceId,
+ int width, int height)
+ {
+ return IRenderBufferPtr(new PdRenderBuffer(boxId, instanceId, width, height));
+ }
+ ~PdRenderBuffer();
+
+ private:
+ void didHandleTouchEvent(
+ TouchType type, double timestamp, double x, double y);
+
+ // RenderBuffer Implementation
+ int getWidth() { return m_width; };
+ int getHeight() { return m_height; };
+ void setWidth(int width) { m_width = width; };
+ void setHeight(int height) { m_height = height; };
+ BufferInfoPtr acquireBuffer();
+ void updateBuffer();
+
+ // touch callback
+ static int handleTouchEventCallback(
+ BufferInfoPtr bufferInfo,
+ buffer_event event,
+ double timestamp,
+ double x,
+ double y,
+ void* data);
+
+ PdRenderBuffer(
+ std::string boxId, std::string instanceId,
+ int width, int height);
+
+ // members
+ std::string m_boxId;
+ std::string m_instanceId;
+ int m_width;
+ int m_height;
+};
+
+#endif // PD_RENDER_BUFFER_H
diff --git a/src_mobile/Core/Buffer/RenderBuffer.cpp b/src_mobile/Core/Buffer/RenderBuffer.cpp
new file mode 100755
index 0000000..1bd70b6
--- /dev/null
+++ b/src_mobile/Core/Buffer/RenderBuffer.cpp
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 RenderBuffer.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <Evas.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <provider.h>
+#include <provider_buffer.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "IRenderBuffer.h"
+#include "RenderBuffer.h"
+
+RenderBuffer::RenderBuffer()
+ : m_bufferAddr(NULL)
+ , m_bufferInfo(NULL)
+{
+ LogD("enter");
+}
+
+RenderBuffer::~RenderBuffer()
+{
+ LogD("enter");
+}
+
+bool RenderBuffer::allocate()
+{
+ LogD("enter");
+ if (m_bufferAddr) {
+ free();
+ m_bufferAddr = NULL;
+ }
+
+ Ecore_Evas* ee =
+ ecore_evas_buffer_allocfunc_new(
+ getWidth(), getHeight(),
+ allocateCallback, freeCallback,
+ this);
+ LogD("Using %s engine!", ecore_evas_engine_name_get(ee));
+
+ if (!ee) {
+ LogD("invalid ecore evas object");
+ return false;
+ }
+
+ LogD("evas ecore setting");
+
+ // alpha_set function access the canvas buffer directly,
+ // without pre/post render callback.
+ provider_buffer_pre_render(m_bufferInfo);
+ ecore_evas_alpha_set(ee, EINA_TRUE);
+ provider_buffer_post_render(m_bufferInfo);
+ ecore_evas_manual_render_set(ee, EINA_FALSE);
+
+ // resize function will invoke the freeCallback and allocateCallback again. (internally)
+ ecore_evas_resize(ee, getWidth(), getHeight());
+ ecore_evas_show(ee);
+ ecore_evas_activate(ee);
+
+ LogD("Using %s engine!", ecore_evas_engine_name_get(ee));
+
+ Evas* e = ecore_evas_get(ee);
+ evas_image_cache_flush(e);
+ Evas_Object *eo = evas_object_rectangle_add(e);
+ evas_object_size_hint_weight_set(eo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_color_set(eo, 0, 0, 0, 1);
+ evas_object_resize(eo, getWidth(), getHeight());
+
+ m_canvas = e;
+ m_win = eo;
+
+ startCanvasUpdate();
+ return true;
+}
+
+bool RenderBuffer::reallocate(int width, int height)
+{
+ LogD("enter");
+ stopCanvasUpdate();
+
+ // TODO This function should be implemented due to box resize operation
+ setWidth(width);
+ setHeight(height);
+
+ Ecore_Evas* ee = ecore_evas_ecore_evas_get(m_canvas);
+ // resize function will invoke the freeCallback and allocateCallback again. (internally)
+ ecore_evas_resize(ee, getWidth(), getHeight());
+ evas_object_resize(m_win, getWidth(), getHeight());
+ startCanvasUpdate();
+ return true;
+}
+
+bool RenderBuffer::free()
+{
+ if (!m_canvas) {
+ return false;
+ }
+
+ stopCanvasUpdate();
+ ecore_evas_free(ecore_evas_ecore_evas_get(m_canvas));
+ m_canvas = NULL;
+ m_win = NULL;
+
+ return true;
+}
+
+void RenderBuffer::startCanvasUpdate()
+{
+ LogD("enter");
+ evas_event_callback_del(
+ m_canvas,
+ EVAS_CALLBACK_RENDER_PRE,
+ preRenderCallback);
+
+ evas_event_callback_del(
+ m_canvas,
+ EVAS_CALLBACK_RENDER_POST,
+ postRenderCallback);
+
+ evas_event_callback_add(
+ m_canvas,
+ EVAS_CALLBACK_RENDER_PRE,
+ preRenderCallback, this);
+
+ evas_event_callback_add(
+ m_canvas,
+ EVAS_CALLBACK_RENDER_POST,
+ postRenderCallback, this);
+
+}
+
+void RenderBuffer::stopCanvasUpdate()
+{
+ LogD("enter");
+ evas_event_callback_del(
+ m_canvas,
+ EVAS_CALLBACK_RENDER_PRE,
+ preRenderCallback);
+
+ evas_event_callback_del(
+ m_canvas,
+ EVAS_CALLBACK_RENDER_POST,
+ postRenderCallback);
+}
+
+Evas_Object* RenderBuffer::getWindow()
+{
+ return m_win;
+}
+
+void RenderBuffer::preRenderCallback(void* data, Evas* canvas, void *eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ RenderBuffer *buffer = static_cast<RenderBuffer*>(data);
+ if (!provider_buffer_pixmap_is_support_hw(buffer->m_bufferInfo)) {
+ LogD("not hw backend");
+ return;
+ }
+
+ provider_buffer_pre_render(buffer->m_bufferInfo);
+ evas_damage_rectangle_add(canvas, 0, 0, buffer->getWidth(), buffer->getHeight());
+}
+
+void RenderBuffer::postRenderCallback(void* data, Evas* canvas, void* eventInfo)
+{
+ LogD("enter");
+
+ UNUSED_PARAM(canvas);
+ UNUSED_PARAM(eventInfo);
+
+ RenderBuffer* buffer = static_cast<RenderBuffer*>(data);
+
+ evas_data_argb_unpremul(static_cast<unsigned int*>(buffer->m_bufferAddr), buffer->getWidth() * buffer->getHeight());
+#ifdef RENDER_BUFFER_VERIFY_SHOT
+ {
+ FILE *fp;
+ static int idx = 0;
+ char filename[256];
+ snprintf(filename, sizeof(filename) - 1, "/tmp/render%d-%dx%d.raw", idx++, buffer->getWidth(), buffer->getHeight());
+ fp = fopen(filename, "w+");
+ if (fp) {
+ LogD("RenderShot: %s(%d)\n", filename, buffer->getWidth() * buffer->getHeight() * sizeof(int));
+ fwrite(buffer->m_bufferAddr, buffer->getWidth() * buffer->getHeight() * sizeof(int), 1, fp);
+ fclose(fp);
+ } else {
+ LogD("Failed to open a file: %s", filename);
+ }
+ }
+#endif
+ LogD("/tmp/render-%dx%d.raw", buffer->getWidth(), buffer->getHeight());
+
+ if (!provider_buffer_pixmap_is_support_hw(buffer->m_bufferInfo)) {
+ provider_buffer_sync(buffer->m_bufferInfo);
+ buffer->updateBuffer();
+ } else {
+ provider_buffer_post_render(buffer->m_bufferInfo);
+ buffer->updateBuffer();
+ }
+}
+
+void RenderBuffer::paintColor(unsigned int color)
+{
+ LogD("enter");
+
+ if (!provider_buffer_pixmap_is_support_hw(m_bufferInfo)) {
+ memset(m_bufferAddr, color, getWidth() * getHeight() * 4);
+ provider_buffer_sync(m_bufferInfo);
+ updateBuffer();
+ } else {
+ preRenderCallback(this, m_canvas, NULL);
+ memset(m_bufferAddr, color, getWidth() * getHeight() * 4);
+ postRenderCallback(this, m_canvas, NULL);
+ }
+}
+
+Evas* RenderBuffer::getCanvas()
+{
+ return m_canvas;
+}
+
+void* RenderBuffer::allocateCallback(void* data, int size)
+{
+ LogD("enter");
+ UNUSED_PARAM(size);
+
+ RenderBuffer* buffer = static_cast<RenderBuffer*>(data);
+
+ if (buffer->m_bufferInfo) {
+ freeCallback(data, NULL);
+ }
+
+ buffer->m_bufferInfo = buffer->acquireBuffer();
+ if (!buffer->m_bufferInfo) {
+ return NULL;
+ }
+
+ // set buffer address
+ if (!provider_buffer_pixmap_is_support_hw(buffer->m_bufferInfo)) {
+ LogD("s/w evas backend");
+ buffer->m_bufferAddr = provider_buffer_ref(buffer->m_bufferInfo);
+ } else {
+ LogD("h/w evas backend");
+ int ret = provider_buffer_pixmap_create_hw(buffer->m_bufferInfo);
+ if (ret < 0) {
+ LogD("can't create hw pixmap");
+ }
+ buffer->m_bufferAddr = provider_buffer_pixmap_hw_addr(buffer->m_bufferInfo);
+ }
+
+ LogD("success to allocate buffer");
+ return buffer->m_bufferAddr;
+}
+
+void RenderBuffer::freeCallback(void* data, void *pix)
+{
+ LogD("enter");
+ UNUSED_PARAM(pix);
+
+ RenderBuffer* buffer = static_cast<RenderBuffer*>(data);
+
+ // destroy buffer
+ if (!provider_buffer_pixmap_is_support_hw(buffer->m_bufferInfo)) {
+ provider_buffer_unref(buffer->m_bufferAddr);
+ } else {
+ provider_buffer_pixmap_destroy_hw(buffer->m_bufferInfo);
+ }
+
+ provider_buffer_release(buffer->m_bufferInfo);
+
+ buffer->m_bufferInfo = NULL;
+ buffer->m_bufferAddr = NULL;
+
+ LogD("success to free buffer");
+ return;
+}
+
+Evas_Object *RenderBuffer::getSnapshot(void)
+{
+ LogD("enter");
+ Evas_Object *snapshot;
+ void *tmpBuffer;
+
+ snapshot = evas_object_image_add(m_canvas);
+ if (!snapshot)
+ return NULL;
+ evas_object_image_data_set(snapshot, NULL);
+ evas_object_image_colorspace_set(snapshot, EVAS_COLORSPACE_ARGB8888);
+ evas_object_image_alpha_set(snapshot, EINA_TRUE);
+ evas_object_image_size_set(snapshot, getWidth(), getHeight());
+
+ tmpBuffer = malloc(getWidth() * getHeight() * sizeof(int));
+ if (tmpBuffer) {
+ memcpy(tmpBuffer, m_bufferAddr, getWidth() * getHeight() * sizeof(int));
+ evas_data_argb_premul(
+ static_cast<unsigned int*>(tmpBuffer),
+ getWidth() * getHeight());
+ evas_object_image_data_set(snapshot, tmpBuffer);
+ } else {
+ LogD("Failed to allocate heap");
+ }
+
+ evas_object_image_data_update_add(snapshot, 0, 0, getWidth(), getHeight());
+ evas_object_image_fill_set(snapshot, 0, 0, getWidth(), getHeight());
+ evas_object_resize(snapshot, getWidth(), getHeight());
+
+ return snapshot;
+}
diff --git a/src_mobile/Core/Buffer/RenderBuffer.h b/src_mobile/Core/Buffer/RenderBuffer.h
new file mode 100644
index 0000000..b275e70
--- /dev/null
+++ b/src_mobile/Core/Buffer/RenderBuffer.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 RenderBuffer.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef RENDER_BUFFER_H
+#define RENDER_BUFFER_H
+
+#include <memory>
+#include <Evas.h>
+#include "IRenderBuffer.h"
+
+// forward declaration
+struct livebox_buffer;
+
+// type definition
+typedef struct livebox_buffer* BufferInfoPtr;
+typedef void* BufferAddrPtr;
+
+#define EXPORT_CLASS __attribute__ ((visibility("default"))
+
+class EXPORT_CLASS RenderBuffer: public IRenderBuffer {
+ public:
+ // IRenderBuffer Implementation
+ bool allocate();
+ bool reallocate(int width, int height);
+ bool free();
+ Evas_Object* getWindow();
+ void startCanvasUpdate();
+ void stopCanvasUpdate();
+
+ static void preRenderCallback(void* data, Evas* canvas, void* eventInfo);
+ static void postRenderCallback(void* data, Evas* canvas, void* eventInfo);
+
+ virtual ~RenderBuffer();
+
+ protected:
+ void paintColor(unsigned int color);
+ Evas* getCanvas();
+ Evas_Object* getSnapshot();
+
+ // provided by derived class
+ virtual int getWidth() = 0;
+ virtual int getHeight() = 0;
+ virtual void setWidth(int width) = 0;
+ virtual void setHeight(int height) = 0;
+ virtual BufferInfoPtr acquireBuffer() = 0;
+ virtual void updateBuffer() = 0;
+
+ RenderBuffer();
+
+ private:
+ // callbacks
+ static void* allocateCallback(void* data, int size);
+ static void freeCallback(void* data, void *pix);
+
+ // members
+ Evas* m_canvas;
+ Evas_Object* m_win;
+ BufferAddrPtr m_bufferAddr;
+ BufferInfoPtr m_bufferInfo;
+};
+
+#endif
diff --git a/src_mobile/Core/Buffer/RenderBufferFactory.cpp b/src_mobile/Core/Buffer/RenderBufferFactory.cpp
new file mode 100644
index 0000000..5d6a55f
--- /dev/null
+++ b/src_mobile/Core/Buffer/RenderBufferFactory.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 RenderBufferFactory.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <Core/Util/Log.h>
+#include "IRenderBuffer.h"
+#include "BoxRenderBuffer.h"
+#include "PdRenderBuffer.h"
+#include "RenderBufferFactory.h"
+
+IRenderBufferPtr RenderBufferFactory::create(
+ RenderBufferType type,
+ std::string boxId,
+ std::string instanceId,
+ int width,
+ int height)
+{
+ LogD("enter");
+ IRenderBufferPtr buffer;
+ switch (type) {
+ case RENDER_BUFFER_TYPE_BOX:
+ buffer = BoxRenderBuffer::create(boxId, instanceId, width, height);
+ break;
+ case RENDER_BUFFER_TYPE_PD:
+ buffer = PdRenderBuffer::create(boxId, instanceId, width, height);
+ break;
+ default:
+ LogD("not available type");
+ break;
+ }
+
+ return buffer;
+}
diff --git a/src_mobile/Core/Buffer/RenderBufferFactory.h b/src_mobile/Core/Buffer/RenderBufferFactory.h
new file mode 100644
index 0000000..9eff1e3
--- /dev/null
+++ b/src_mobile/Core/Buffer/RenderBufferFactory.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 RenderBufferFactory.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef RENDER_BUFFER_FACTORY_H
+#define RENDER_BUFFER_FACTORY_H
+
+#include "IRenderBuffer.h"
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__ ((visibility("default")))
+#endif
+
+namespace RenderBufferFactory {
+
+enum RenderBufferType : int
+{
+ RENDER_BUFFER_TYPE_BOX = 0,
+ RENDER_BUFFER_TYPE_PD,
+};
+
+EXPORT_API IRenderBufferPtr create(
+ RenderBufferType type,
+ std::string boxId,
+ std::string instanceId,
+ int width,
+ int height);
+}
+
+#endif // RENDER_BUFFER_FACTORY_H
diff --git a/src_mobile/Core/CMakeLists.txt b/src_mobile/Core/CMakeLists.txt
new file mode 100644
index 0000000..5c4c0e5
--- /dev/null
+++ b/src_mobile/Core/CMakeLists.txt
@@ -0,0 +1,86 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_CORE})
+SET(TARGET_CORE_BUFFER web-provider-core-buffer)
+SET(TARGET_CORE_VIEW web-provider-core-view)
+SET(TARGET_CORE_SERVICE web-provider-core-service)
+SET(TARGET_CORE_UTIL web-provider-core-util)
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ ecore
+ ewebkit2
+ dlog
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/Box.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxManager.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxState.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxUpdateTimer.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxSchemeHandler.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} SHARED ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LIBRARIES}
+ "-Wl,--whole-archive"
+ ${TARGET_CORE_VIEW}
+ ${TARGET_CORE_BUFFER}
+ ${TARGET_CORE_SERVICE}
+ ${TARGET_CORE_UTIL}
+ "-Wl,--no-whole-archive"
+)
+
+ADD_SUBDIRECTORY(Buffer)
+ADD_SUBDIRECTORY(View)
+ADD_SUBDIRECTORY(Service)
+ADD_SUBDIRECTORY(Util)
+
+INSTALL(TARGETS ${TARGET_NAME}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
+
+GET_FILENAME_COMPONENT(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+
+INSTALL_FILE(IBox.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(BoxData.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(IBoxManager.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(BoxManager.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(BoxSchemeHandler.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
diff --git a/src_mobile/Core/IBox.h b/src_mobile/Core/IBox.h
new file mode 100644
index 0000000..bea5570
--- /dev/null
+++ b/src_mobile/Core/IBox.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IBox.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_BOX_H
+#define I_BOX_H
+
+#include <string>
+#include <memory>
+#include <ctime>
+#include <ewk_view.h>
+#include <ewk_context.h>
+
+class IBox {
+ public:
+ // functions for lifecycle
+ virtual bool show() = 0;
+ virtual bool hide() = 0;
+ virtual bool resize(int width, int height) = 0;
+ virtual bool resume() = 0;
+ virtual bool pause(bool background) = 0;
+ virtual bool openPd(int width, int height, double x, double y) = 0;
+ virtual bool closePd() = 0;
+ virtual bool update(time_t requestTime, std::string& contentInfo) = 0;
+
+ // functions for getting/setting box's data by BoxManager
+ virtual bool changePeriod(float period) = 0;
+ virtual bool isCurrentTab() = 0;
+ virtual time_t getLastUpdateRequestTime() = 0;
+ virtual BoxInfoPtr getBoxInfo() = 0;
+
+ //virtual IBox& operator=(const IBox& rhs) = 0;
+ //virtual bool operator==(const IBox& rhs) const = 0;
+ //virtual bool operator!=(const IBox& rhs) const = 0;
+ virtual ~IBox() {};
+};
+
+typedef std::shared_ptr<IBox> IBoxPtr;
+typedef std::shared_ptr<Ewk_Context> EwkContextPtr;
+
+#endif //I_BOX_H
diff --git a/src_mobile/Core/IBoxContext.h b/src_mobile/Core/IBoxContext.h
new file mode 100644
index 0000000..8dfa2a7
--- /dev/null
+++ b/src_mobile/Core/IBoxContext.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IBoxContext.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_BOX_CONTEXT
+#define I_BOX_CONTEXT
+
+#include "IBoxState.h"
+
+class IBoxContext {
+ public:
+ virtual void setState(IBoxStatePtr state) = 0;
+ virtual ~IBoxContext() {};
+};
+
+typedef std::shared_ptr<IBoxContext> IBoxContextPtr;
+
+#endif // I_BOX_CONTEXT
diff --git a/src_mobile/Core/IBoxManager.h b/src_mobile/Core/IBoxManager.h
new file mode 100644
index 0000000..d441ed1
--- /dev/null
+++ b/src_mobile/Core/IBoxManager.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IBoxManager.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_BOX_MANAGER_H
+#define I_BOX_MANAGER_H
+
+#include <string>
+#include <Util/Noncopyable.h>
+#include <Plugin/box_plugin_interface.h>
+#include "BoxData.h"
+
+class IBoxManager: Noncopyable {
+ public:
+ virtual bool doCommand(const request_cmd_type, const BoxInfoPtr&) = 0;
+ virtual ~IBoxManager() {};
+};
+
+typedef std::shared_ptr<IBoxManager> IBoxManagerPtr;
+
+#endif // I_BOX_MANAGER_H
diff --git a/src_mobile/Core/IBoxState.h b/src_mobile/Core/IBoxState.h
new file mode 100644
index 0000000..d798dc1
--- /dev/null
+++ b/src_mobile/Core/IBoxState.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IBoxState.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_BOX_STATE
+#define I_BOX_STATE
+
+#include <memory>
+
+class IBoxState;
+typedef std::shared_ptr<IBoxState> IBoxStatePtr;
+
+class IBoxState {
+ public:
+ virtual IBoxStatePtr permitShow() = 0;
+ virtual IBoxStatePtr permitHide() = 0;
+ virtual IBoxStatePtr permitResume() = 0;
+ virtual IBoxStatePtr permitPause() = 0;
+ virtual IBoxStatePtr permitOpenPd() = 0;
+ virtual IBoxStatePtr permitClosePd() = 0;
+ virtual IBoxStatePtr permitShutdown() = 0;
+ virtual void switchState() = 0;
+ virtual ~IBoxState() {};
+};
+
+#endif // I_BOX_STATE
diff --git a/src_mobile/Core/Service/AppControl.cpp b/src_mobile/Core/Service/AppControl.cpp
new file mode 100644
index 0000000..761dd93
--- /dev/null
+++ b/src_mobile/Core/Service/AppControl.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 LaunchBrowser.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string>
+#include <app_service.h>
+#include <Core/Util/Log.h>
+#include "AppControl.h"
+
+namespace Service {
+namespace AppControl {
+
+bool launchBrowser(std::string& url)
+{
+ LogD("enter");
+
+ service_h handle = NULL;
+ int ret = SERVICE_ERROR_NONE;
+
+ ret = service_create(&handle);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to create service");
+ return false;
+ }
+
+ ret = service_set_operation(handle, SERVICE_OPERATION_VIEW);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to set operation");
+ service_destroy(handle);
+ return false;
+ }
+
+ ret = service_set_uri(handle, url.c_str());
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to set url");
+ service_destroy(handle);
+ return false;
+ }
+
+ ret = service_send_launch_request(handle, NULL, NULL);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to request launch");
+ service_destroy(handle);
+ return false;
+ }
+
+ LogD("success to launch browser: %s", url.c_str());
+ service_destroy(handle);
+
+ return true;
+}
+
+bool launchDownloader(std::string& url, std::string& cookie)
+{
+ LogD("enter");
+
+ service_h handle = NULL;
+ int ret = SERVICE_ERROR_NONE;
+
+ if (url.empty()) {
+ LogD("invalid arguments");
+ return false;
+ }
+
+ ret = service_create(&handle);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to create service");
+ return false;
+ }
+
+ ret = service_set_operation(handle, SERVICE_OPERATION_DOWNLOAD);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to set operation");
+ service_destroy(handle);
+ return false;
+ }
+
+ ret = service_set_uri(handle, url.c_str());
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to set url");
+ service_destroy(handle);
+ return false;
+ }
+
+ if (!cookie.empty()) {
+ ret = service_add_extra_data(handle, "cookie", cookie.c_str());
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to set cookie");
+ service_destroy(handle);
+ return false;
+ }
+ }
+
+ ret = service_send_launch_request(handle, NULL, NULL);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to request launch");
+ service_destroy(handle);
+ return false;
+ }
+
+ LogD("success to launch downloader");
+ service_destroy(handle);
+
+ return true;
+}
+
+} // AppControl
+} // Service
diff --git a/src_mobile/Core/Service/AppControl.h b/src_mobile/Core/Service/AppControl.h
new file mode 100644
index 0000000..5693873
--- /dev/null
+++ b/src_mobile/Core/Service/AppControl.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppControl.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string>
+
+namespace Service {
+namespace AppControl {
+
+bool launchBrowser(std::string& url);
+bool launchDownloader(std::string& url, std::string& cookie);
+
+}
+} // Service
diff --git a/src_mobile/Core/Service/CMakeLists.txt b/src_mobile/Core/Service/CMakeLists.txt
new file mode 100755
index 0000000..ad8fa36
--- /dev/null
+++ b/src_mobile/Core/Service/CMakeLists.txt
@@ -0,0 +1,72 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_CORE_SERVICE})
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ dlog
+ capi-appfw-application
+ livebox-service
+ evas
+ eina
+ ecore-x
+ elementary
+ efl-assist
+ provider
+ ecore
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/AppControl.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/PeriodChanger.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/ScrollHolder.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/MessageManager.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} STATIC ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LIBRARIES}
+)
+
+GET_FILENAME_COMPONENT(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+GET_FILENAME_COMPONENT(PARENT_DIR_ABSOLUTE_PATH ${CMAKE_CURRENT_SOURCE_DIR} PATH)
+GET_FILENAME_COMPONENT(PARENT_DIR_NAME ${PARENT_DIR_ABSOLUTE_PATH} NAME)
+
+INSTALL_FILE(PeriodChanger.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(MessageManager.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(ScrollHolder.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(AppControl.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
diff --git a/src_mobile/Core/Service/MessageManager.cpp b/src_mobile/Core/Service/MessageManager.cpp
new file mode 100755
index 0000000..3199d86
--- /dev/null
+++ b/src_mobile/Core/Service/MessageManager.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 MessageMenager.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string>
+#include <Evas.h>
+#include <Eina.h>
+#include <ewk_view.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "MessageManager.h"
+
+namespace Service {
+
+static const std::string jsFireWindowEventFunction("webprovider.fireAppWidgetEvent");
+static const std::string jsPdMessageEvent("pdmessage");
+static const std::string jsBoxMessageEvent("boxmessage");
+
+MessageManager::MessageManager()
+{
+ LogD("enter");
+}
+
+MessageManager::~MessageManager()
+{
+ LogD("enter");
+}
+
+bool MessageManager::send(Evas_Object* webview, ReceiverType receiver, std::string& message)
+{
+ LogD("enter");
+
+ std::string eventName;
+ if(!webview) {
+ return false;
+ }
+ // set message event name triggered by receiver
+ switch (receiver) {
+ case TO_BOX:
+ eventName = jsPdMessageEvent;
+ break;
+ case TO_PD:
+ eventName = jsBoxMessageEvent;
+ break;
+ default:
+ return false;
+ }
+
+ std::string script = jsFireWindowEventFunction;
+ script += "(\"";
+ script += eventName;
+ script += "\", \"";
+ script += message;
+ script +="\");";
+ LogD("calling javascript: %s", script.c_str());
+
+ // execute js code for sending message
+ if (EINA_FALSE == ewk_view_script_execute(
+ webview, script.c_str(), executeScriptCallback, this)) {
+ LogD("ewk_view_script_execute fail.");
+ }
+
+ return true;
+}
+
+void MessageManager::executeScriptCallback(
+ Evas_Object* webview, const char* result, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(webview);
+ UNUSED_PARAM(data);
+
+ std::string resultStr(result ? result : "null");
+ LogD("result: %s", resultStr.c_str());
+}
+} // Service
diff --git a/src_mobile/Core/Service/MessageManager.h b/src_mobile/Core/Service/MessageManager.h
new file mode 100644
index 0000000..d19b69d
--- /dev/null
+++ b/src_mobile/Core/Service/MessageManager.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 MessageManager.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#ifndef MESSAGE_MANAGER_H
+#define MESSAGE_MANAGER_H
+
+#include <string>
+#include <memory>
+#include <Evas.h>
+
+namespace Service {
+
+class MessageManager;
+typedef std::shared_ptr<MessageManager> MessageManagerPtr;
+
+class MessageManager {
+ public:
+ enum ReceiverType {
+ TO_BOX,
+ TO_PD
+ };
+
+ static MessageManagerPtr create() {
+ return MessageManagerPtr(new MessageManager());
+ }
+ bool send(Evas_Object* webview, ReceiverType receiver, std::string& message);
+ ~MessageManager();
+
+ private:
+ static void executeScriptCallback(
+ Evas_Object* webview, const char* result, void* data);
+ MessageManager();
+};
+} // Service
+
+#endif // MESSAGE_MANAGER_H
diff --git a/src_mobile/Core/Service/PeriodChanger.cpp b/src_mobile/Core/Service/PeriodChanger.cpp
new file mode 100755
index 0000000..91a000a
--- /dev/null
+++ b/src_mobile/Core/Service/PeriodChanger.cpp
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 PeriodChanger.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string>
+#include <Evas.h>
+#include <Ecore_X.h>
+#include <Ecore.h>
+#include <Elementary.h>
+#include <efl_assist.h>
+#include <livebox-service.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "PeriodChanger.h"
+
+#define UPDATE_PERIOD_MIN 1800.0f
+#define UPDATE_PERIOD_HOUR 60.0 * 60.0
+#define U_(str) dgettext("web-provider", str)
+
+namespace Service {
+
+Evas_Object* PeriodChanger::s_window = NULL;
+bool PeriodChanger::s_isPopupOpened = false;
+
+static const char * const TEXT_POPUP_TITLE = "IDS_CLOCK_BODY_UPDATE_INTERVAL";
+static const char * const TEXT_POPUP_CANCEL_BUTTON = "IDS_ST_BUTTON_CANCEL";
+static const char * const TEXT_POPUP_UPDATE_PERIOD_1 ="IDS_ST_BODY_1_HOUR";
+static const char * const TEXT_POPUP_UPDATE_PERIOD_3 ="IDS_ST_BODY_3HOURS";
+static const char * const TEXT_POPUP_UPDATE_PERIOD_6 ="IDS_ST_BODY_6_HOURS_TMO";
+static const char * const TEXT_POPUP_UPDATE_PERIOD_12 ="IDS_ST_BODY_12_HOURS";
+static const char * const TEXT_POPUP_UPDATE_PERIOD_NEVER ="IDS_ST_BODY_NEVER";
+static const char * const MO_INSTALL_DIR = "/usr/share/res/locale";
+static const char * const MO_PROJECT_NAME = "web-provider";
+
+PeriodChanger::PeriodChanger(
+ std::string& boxId, std::string& instanceId,
+ double currentPeriod, double requestedPeriod)
+ : m_boxId(boxId)
+ , m_instanceId(instanceId)
+ , m_currentPeriod(currentPeriod)
+ , m_requestedPeriod(requestedPeriod)
+ , m_hour()
+{
+ LogD("enter");
+}
+
+PeriodChanger::~PeriodChanger()
+{
+ LogD("enter");
+}
+
+bool PeriodChanger::change()
+{
+ LogD("enter");
+
+ if (m_requestedPeriod < 0) {
+ showPeriodPopup();
+ return true;
+ }
+
+ double newPeriod;
+ if (m_requestedPeriod == 0) {
+ newPeriod = 0.0;
+ } else if (m_requestedPeriod > 0) {
+ if (m_requestedPeriod >= UPDATE_PERIOD_MIN) {
+ newPeriod = m_requestedPeriod;
+ } else {
+ newPeriod = UPDATE_PERIOD_MIN;
+ }
+ } else {
+ LogD("negative value can't be handled here");
+ newPeriod = 0.0;
+ }
+
+ // after selecting one among period list, the following should be executed
+ return requestToPlatform(newPeriod);
+}
+
+void PeriodChanger::showPeriodPopup()
+{
+ LogD("enter");
+
+ Evas_Object* window = createWindow();
+ Evas_Object* periodList = elm_list_add(window);
+
+ if (!periodList) {
+ LogD("failed to add elm_list_add");
+ }
+ elm_list_mode_set(periodList, ELM_LIST_EXPAND);
+ bindtextdomain(MO_PROJECT_NAME, MO_INSTALL_DIR);
+ setPopupListData();
+ // TODO Language ID should be used, not static string
+ for(unsigned int i = 0 ; i < sizeof(m_hour) / sizeof(PopupListData); i++) {
+ m_hour[i].radio = elm_radio_add(periodList);
+ elm_radio_state_value_set(m_hour[i].radio,
+ m_currentPeriod == m_hour[i].newPeriod ? EINA_FALSE : EINA_TRUE);
+ elm_list_item_append(periodList,
+ m_hour[i].period,
+ m_hour[i].radio,
+ NULL,
+ selectPeriodCallback, &m_hour[i]);
+ }
+
+ // create popup
+ Evas_Object *popup = elm_popup_add(window);
+ if (!popup) {
+ LogD("failed to add elm_popup_add");
+ return;
+ }
+ elm_object_style_set(popup, "popup-item list");
+ evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ elm_object_part_text_set(popup, "title,text", U_(TEXT_POPUP_TITLE));
+ elm_object_content_set(popup, periodList);
+ evas_object_show(popup);
+ Evas_Object* cancelButton = elm_button_add(popup);
+ if (!cancelButton) {
+ LogD("failed to add elm_button_add");
+ return;
+ }
+ // TODO Language ID should be used, not static string
+ elm_object_text_set(cancelButton, U_(TEXT_POPUP_CANCEL_BUTTON));
+ elm_object_style_set(cancelButton, "popup_button/default");
+ elm_object_part_content_set(popup, "button1", cancelButton);
+ evas_object_show(cancelButton);
+ evas_object_smart_callback_add(cancelButton, "clicked", cancelButtonCallback, this);
+
+ // register back key callback
+ ea_object_event_callback_add(
+ popup, EA_CALLBACK_BACK,
+ pressHardwareBackKeyCallback, this);
+}
+
+void PeriodChanger::destroyPeriodPopup(Evas_Object *obj)
+{
+ LogD("enter");
+ Evas_Object* parent = elm_object_parent_widget_get(obj);
+ Evas_Object* popup = elm_popup_add(parent);
+ while (parent) {
+ const char* type = elm_object_widget_type_get(parent);
+ if (type && !strcmp(type, elm_object_widget_type_get(popup))) {
+ evas_object_del(parent);
+ break;
+ }
+ parent = elm_object_parent_widget_get(parent);
+ }
+
+ // register back key callback
+ ea_object_event_callback_del(popup, EA_CALLBACK_BACK, pressHardwareBackKeyCallback);
+ evas_object_del(popup);
+ destroyWindow();
+}
+
+void PeriodChanger::setPopupListData()
+{
+ LogD("enter");
+
+ m_hour[0].periodChanger = this;
+ m_hour[0].newPeriod = 1.0 * UPDATE_PERIOD_HOUR;
+ m_hour[0].period = U_(TEXT_POPUP_UPDATE_PERIOD_1);
+
+ m_hour[1].periodChanger = this;
+ m_hour[1].newPeriod = 3.0 * UPDATE_PERIOD_HOUR;
+ m_hour[1].period = U_(TEXT_POPUP_UPDATE_PERIOD_3);
+
+ m_hour[2].periodChanger = this;
+ m_hour[2].newPeriod = 6.0 * UPDATE_PERIOD_HOUR;
+ m_hour[2].period = U_(TEXT_POPUP_UPDATE_PERIOD_6);
+
+ m_hour[3].periodChanger = this;
+ m_hour[3].newPeriod = 12.0 * UPDATE_PERIOD_HOUR;
+ m_hour[3].period = U_(TEXT_POPUP_UPDATE_PERIOD_12);
+
+ m_hour[4].periodChanger = this;
+ m_hour[4].newPeriod = 0.0;
+ m_hour[4].period = U_(TEXT_POPUP_UPDATE_PERIOD_NEVER);
+
+}
+
+bool PeriodChanger::requestToPlatform(double newPeriod)
+{
+ int ret = livebox_service_change_period(
+ m_boxId.c_str(), m_instanceId.c_str(), newPeriod);
+
+ if (ret < 0) {
+ LogD("during update period, error occurs");
+ return false;
+ }
+
+ LogD("Instance's period is set to %f", newPeriod);
+ return true;
+}
+
+
+Evas_Object* PeriodChanger::createWindow()
+{
+ LogD("enter");
+
+ if (s_window) {
+ evas_object_show(s_window);
+ elm_win_raise(s_window);
+ return s_window;
+ }
+
+ s_window = elm_win_add(NULL, "web-provider-popup", ELM_WIN_BASIC);
+ elm_win_alpha_set(s_window, EINA_TRUE);
+ elm_win_title_set(s_window, "change update period");
+ elm_win_borderless_set(s_window, EINA_TRUE);
+
+ int width = 0;
+ int height = 0;
+ ecore_x_window_size_get(ecore_x_window_root_first_get(), &width, &height);
+ evas_object_resize(s_window, width, height);
+ elm_win_indicator_mode_set(s_window, ELM_WIN_INDICATOR_SHOW);
+
+ evas_object_color_set(s_window, 255, 255, 255, 0);
+ evas_object_show(s_window);
+ s_isPopupOpened = true;
+ return s_window;
+}
+
+void PeriodChanger::destroyWindow()
+{
+ LogD("enter");
+
+ if (!s_window) {
+ return;
+ }
+ evas_object_del(s_window);
+ s_window = NULL;
+ s_isPopupOpened = false;
+}
+
+void PeriodChanger::selectPeriodCallback(void *data, Evas_Object *obj, void *event_info)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(event_info);
+
+ PopupListData* popupData = static_cast<PopupListData*>(data);
+
+ LogD("Update period is set to %f", popupData->newPeriod);
+ popupData->periodChanger->requestToPlatform(popupData->newPeriod);
+ ecore_idler_add(popupDestroyIdlerCallback, popupData);
+}
+
+void PeriodChanger::cancelButtonCallback(void *data, Evas_Object *obj, void *event_info)
+{
+ LogD("enter");
+ UNUSED_PARAM(event_info);
+
+ PeriodChanger* This = static_cast<PeriodChanger*>(data);
+ This->destroyPeriodPopup(obj);
+}
+
+void PeriodChanger::pressHardwareBackKeyCallback(void *data, Evas_Object *obj, void *event_info)
+{
+ LogD("enter");
+ UNUSED_PARAM(event_info);
+
+ PeriodChanger* This = static_cast<PeriodChanger*>(data);
+ This->destroyPeriodPopup(obj);
+}
+
+Eina_Bool PeriodChanger::popupDestroyIdlerCallback(void *data)
+{
+ LogD("enter");
+ PopupListData* popupData = static_cast<PopupListData*>(data);
+ popupData->periodChanger->destroyPeriodPopup(popupData->radio);
+ return ECORE_CALLBACK_CANCEL;
+}
+} // Service
diff --git a/src_mobile/Core/Service/PeriodChanger.h b/src_mobile/Core/Service/PeriodChanger.h
new file mode 100755
index 0000000..b8902b0
--- /dev/null
+++ b/src_mobile/Core/Service/PeriodChanger.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 PeriodChanger.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef PERIOD_CHNAGER_H
+#define PERIOD_CHNAGER_H
+
+#include <string>
+#include <memory>
+#include <Evas.h>
+
+namespace Service {
+class PeriodChanger;
+typedef std::shared_ptr<PeriodChanger> PeriodChangerPtr;
+
+class PeriodChanger {
+ public:
+ static PeriodChangerPtr create(
+ std::string& boxId, std::string& instanceId,
+ double currentPeriod, double requestedPeriod)
+ {
+ return PeriodChangerPtr(
+ new PeriodChanger(boxId, instanceId, currentPeriod, requestedPeriod));
+ }
+ bool change();
+ static bool isPopupOpened() { return s_isPopupOpened; };
+ ~PeriodChanger();
+
+ private:
+ void showPeriodPopup();
+ void destroyPeriodPopup(Evas_Object *obj);
+ void setPopupListData();
+ bool requestToPlatform(double newPeriod);
+ static Evas_Object* createWindow();
+ static void destroyWindow();
+
+ static void selectPeriodCallback(void *data, Evas_Object *obj, void *event_info);
+ static void cancelButtonCallback(void *data, Evas_Object *obj, void *event_info);
+ static void pressHardwareBackKeyCallback(void *data, Evas_Object *obj, void *event_info);
+ static Eina_Bool popupDestroyIdlerCallback(void *data);
+
+ PeriodChanger(
+ std::string& boxId, std::string& instanceId,
+ double currentPeriod, double requestedPeriod);
+
+ static Evas_Object* s_window;
+ std::string m_boxId;
+ std::string m_instanceId;
+ float m_currentPeriod;
+ float m_requestedPeriod;
+ static bool s_isPopupOpened;
+
+ struct PopupListData {
+ PeriodChanger* periodChanger;
+ double newPeriod;
+ const char* period;
+ Evas_Object* radio;
+ };
+
+ PopupListData m_hour[5];
+};
+} // Service
+
+#endif // PERIOD_CHNAGER_H
diff --git a/src_mobile/Core/Service/ScrollHolder.cpp b/src_mobile/Core/Service/ScrollHolder.cpp
new file mode 100644
index 0000000..3435ff7
--- /dev/null
+++ b/src_mobile/Core/Service/ScrollHolder.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 ScrollHolder.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string>
+#include <provider.h>
+#include <Core/Util/Log.h>
+
+namespace Service {
+namespace ScrollHolder {
+
+void holdHorizontalScroll(std::string& boxId, std::string& instanceId, bool start)
+{
+ LogD("enter");
+
+ if (start) {
+ LogD("scroll start");
+ provider_send_hold_scroll(boxId.c_str(), instanceId.c_str(), 1);
+ } else {
+ LogD("scroll stop");
+ provider_send_hold_scroll(boxId.c_str(), instanceId.c_str(), 0);
+ }
+}
+
+} // AppControl
+} // Service
diff --git a/src_mobile/Core/Service/ScrollHolder.h b/src_mobile/Core/Service/ScrollHolder.h
new file mode 100644
index 0000000..a7373b7
--- /dev/null
+++ b/src_mobile/Core/Service/ScrollHolder.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 ScrollHolder.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string>
+
+namespace Service {
+namespace ScrollHolder {
+
+void holdHorizontalScroll(std::string& boxId, std::string& instanceId, bool start);
+
+}
+} // Service
diff --git a/src_mobile/Core/Util/CMakeLists.txt b/src_mobile/Core/Util/CMakeLists.txt
new file mode 100644
index 0000000..c7c5503
--- /dev/null
+++ b/src_mobile/Core/Util/CMakeLists.txt
@@ -0,0 +1,60 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_CORE_UTIL})
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ dlog
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/Log.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} STATIC ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LIBRARIES}
+)
+
+INCLUDE_DIRECTORIES(${HEADERS})
+GET_FILENAME_COMPONENT(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+GET_FILENAME_COMPONENT(PARENT_DIR_ABSOLUTE_PATH ${CMAKE_CURRENT_SOURCE_DIR} PATH)
+GET_FILENAME_COMPONENT(PARENT_DIR_NAME ${PARENT_DIR_ABSOLUTE_PATH} NAME)
+
+INSTALL_FILE(Noncopyable.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(Log.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
diff --git a/src_mobile/Core/Util/ITimer.h b/src_mobile/Core/Util/ITimer.h
new file mode 100644
index 0000000..c6595cb
--- /dev/null
+++ b/src_mobile/Core/Util/ITimer.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 ITimer.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_TIMER_H
+#define I_TIMER_H
+
+#include <memory>
+
+class ITimer {
+ public:
+ virtual void start() = 0;
+ virtual void stop() = 0;
+ virtual void resume() = 0;
+ virtual void pause() = 0;
+ virtual void restart() = 0;
+ virtual void setPeriod(float period) = 0;
+
+ virtual ~ITimer() {};
+};
+
+typedef std::shared_ptr<ITimer> ITimerPtr;
+
+#endif // I_TIMER_H
diff --git a/src_mobile/Core/Util/Log.cpp b/src_mobile/Core/Util/Log.cpp
new file mode 100644
index 0000000..34712ac
--- /dev/null
+++ b/src_mobile/Core/Util/Log.cpp
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 Log.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
diff --git a/src_mobile/Core/Util/Log.h b/src_mobile/Core/Util/Log.h
new file mode 100644
index 0000000..ff649f7
--- /dev/null
+++ b/src_mobile/Core/Util/Log.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 Log.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef LOG_H
+#define LOG_H
+
+#include <dlog.h>
+#include <string.h>
+
+#define FILE_NAME ((strrchr(__FILE__, '/') ? : __FILE__- 1) + 1)
+
+//#define LogW(fmt, arg...) LOGW( "[%s:%d:%s] " fmt "\n", __FILE__, __LINE__, __func__, ##arg)
+//#define LogD(fmt, arg...) LOGD( "[%s:%d:%s] " fmt "\n", __FILE__, __LINE__, __func__, ##arg)
+//#define LogE(fmt, arg...) LOGE( "[%s:%d:%s] " fmt "\n", __FILE__, __LINE__, __func__, ##arg)
+
+#define LogW(fmt, arg...) LOGW( fmt "\n", ##arg)
+#define LogD(fmt, arg...) LOGD( fmt "\n", ##arg)
+#define LogE(fmt, arg...) LOGE( fmt "\n", ##arg)
+#endif // LOG_H
diff --git a/src_mobile/Core/Util/Noncopyable.h b/src_mobile/Core/Util/Noncopyable.h
new file mode 100644
index 0000000..accdd53
--- /dev/null
+++ b/src_mobile/Core/Util/Noncopyable.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 Noncopyable.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef NONCOPYABLE_H
+#define NONCOPYABLE_H
+
+class Noncopyable {
+ protected:
+ Noncopyable() {};
+ ~Noncopyable() {};
+
+ private:
+ Noncopyable(const Noncopyable&);
+ Noncopyable& operator=(const Noncopyable&);
+};
+
+#endif // NONCOPYABLE_H
diff --git a/src_mobile/Core/Util/Util.h b/src_mobile/Core/Util/Util.h
new file mode 100644
index 0000000..b2c310d
--- /dev/null
+++ b/src_mobile/Core/Util/Util.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 Util.h
+ * @author Soo-Hyun Choi (sh9.choi@samsung.com)
+ */
+#ifndef UTIL_H
+#define UTIL_H
+
+#define UNUSED_PARAM(expr) (void)(expr)
+
+#endif // UTIL_H
diff --git a/src_mobile/Core/View/CMakeLists.txt b/src_mobile/Core/View/CMakeLists.txt
new file mode 100644
index 0000000..083a34b
--- /dev/null
+++ b/src_mobile/Core/View/CMakeLists.txt
@@ -0,0 +1,66 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_CORE_VIEW})
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ evas
+ eina
+ ewebkit2
+ dlog
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/WebView.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/PdHelper.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} STATIC ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LIBRARIES}
+)
+
+GET_FILENAME_COMPONENT(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+GET_FILENAME_COMPONENT(PARENT_DIR_ABSOLUTE_PATH ${CMAKE_CURRENT_SOURCE_DIR} PATH)
+GET_FILENAME_COMPONENT(PARENT_DIR_NAME ${PARENT_DIR_ABSOLUTE_PATH} NAME)
+
+INSTALL_FILE(IRenderView.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(IPdHelper.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(PdHelper.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(IWebView.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(WebView.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(injection.js /usr/share/${PROJECT_NAME})
diff --git a/src_mobile/Core/View/IPdHelper.h b/src_mobile/Core/View/IPdHelper.h
new file mode 100644
index 0000000..b2f7db9
--- /dev/null
+++ b/src_mobile/Core/View/IPdHelper.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IPdHelper.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_PD_HELPER_H
+#define I_PD_HELPER_H
+
+#include <Evas.h>
+#include <memory>
+
+class IPdHelper {
+ public:
+ virtual void startOpen() = 0;
+ virtual void finishOpen(Evas_Object* child) = 0;
+ virtual void close() = 0;
+ virtual void setBoxWebView(Evas_Object* webview) = 0;
+ virtual void setPdWebView(Evas_Object* webview) = 0;
+ virtual Evas_Object* getBoxWebView() const = 0;
+ virtual Evas_Object* getPdWebView() const = 0;
+ virtual Evas* getPdCanvas() const = 0;
+ virtual bool isPdOpened() const = 0;
+};
+
+typedef std::shared_ptr<IPdHelper> IPdHelperPtr;
+
+#endif // I_PD_HELPER_H
diff --git a/src_mobile/Core/View/IRenderView.h b/src_mobile/Core/View/IRenderView.h
new file mode 100644
index 0000000..9e24ed0
--- /dev/null
+++ b/src_mobile/Core/View/IRenderView.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IRenderView.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_RENDER_VIEW_H
+#define I_RENDER_VIEW_H
+
+#include <string>
+#include <memory>
+#include <Evas.h>
+
+struct RenderInfo {
+ int width;
+ int height;
+ Evas_Object* window;
+ std::string defaultUrlParams;
+};
+typedef std::shared_ptr<RenderInfo> RenderInfoPtr;
+
+class IRenderView {
+ public:
+ enum UrlType {
+ URL_TYPE_BOX,
+ URL_TYPE_PD
+ };
+ virtual void showBox(RenderInfoPtr boxRenderInfo) = 0;
+ virtual void hideBox() = 0;
+ virtual void pauseBox() = 0;
+ virtual void resumeBox() = 0;
+ virtual void showPd(RenderInfoPtr pdRenderInfo, RenderInfoPtr boxRenderInfo) = 0;
+ virtual void hidePd() = 0;
+ virtual Evas_Object* getBoxWebView() = 0;
+ virtual Evas_Object* getPdWebView() = 0;
+ virtual ~IRenderView() {};
+};
+typedef std::shared_ptr<IRenderView> IRenderViewPtr;
+
+#endif // I_RENDER_VIEW_H
diff --git a/src_mobile/Core/View/IWebView.h b/src_mobile/Core/View/IWebView.h
new file mode 100644
index 0000000..1260345
--- /dev/null
+++ b/src_mobile/Core/View/IWebView.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IWebView.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_WEB_VIEW_H
+#define I_WEB_VIEW_H
+
+#include <string>
+#include <memory>
+
+class IWebView {
+ public:
+ typedef void (*WebViewCallback)(void* data, void* eventInfo);
+ virtual bool show(
+ std::string& startUrl, int width, int height,
+ WebViewCallback didCreateBaseWebView, void* data) = 0;
+ virtual bool hide() = 0;
+ virtual bool suspend() = 0;
+ virtual bool resume() = 0;
+ virtual bool setBasicSetting(Evas_Object* webview) = 0;
+ virtual bool unsetBasicSetting(Evas_Object* webview) = 0;
+
+ public:
+ virtual ~IWebView() {};
+};
+
+typedef std::shared_ptr<IWebView> IWebViewPtr;
+
+#endif // I_WEB_VIEW_H
diff --git a/src_mobile/Core/View/PdHelper.cpp b/src_mobile/Core/View/PdHelper.cpp
new file mode 100644
index 0000000..ba57c8f
--- /dev/null
+++ b/src_mobile/Core/View/PdHelper.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 PdHelper.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <Evas.h>
+#include <ewk_view.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "IRenderView.h"
+#include "IPdHelper.h"
+#include "PdHelper.h"
+
+PdHelper::PdHelper(RenderInfoPtr pdRenderInfo, std::string pdStartUrl)
+ : m_boxWebView()
+ , m_pdWebView()
+ , m_pdRenderInfo(pdRenderInfo)
+ , m_startUrl(pdStartUrl)
+ , m_opened(false)
+{
+}
+
+PdHelper::~PdHelper()
+{
+}
+
+void PdHelper::startOpen()
+{
+ LogD("enter");
+ if (!m_boxWebView) {
+ return;
+ }
+
+ //make javascript string for pd
+ std::string script = "var pdWindow = window.open(\"";
+ script += validateUrl(m_startUrl);
+ script += "\", \"_blank\");";
+
+ // execute javascript for opening new webview for pd
+ LogD("executed script: %s", script.c_str());
+ ewk_view_script_execute(
+ m_boxWebView, script.c_str(), executeScriptCallback, this);
+}
+
+void PdHelper::finishOpen(Evas_Object* child)
+{
+ LogD("enter");
+
+ // pd webview set and resize
+ m_pdWebView = child;
+ evas_object_resize(m_pdWebView, m_pdRenderInfo->width, m_pdRenderInfo->height);
+ m_opened = true;
+}
+
+void PdHelper::close()
+{
+ LogD("enter");
+}
+
+void PdHelper::setBoxWebView(Evas_Object* webview)
+{
+ LogD("enter");
+ m_boxWebView = webview;
+}
+
+void PdHelper::setPdWebView(Evas_Object* webview)
+{
+ LogD("enter");
+ m_pdWebView = webview;
+}
+
+Evas_Object* PdHelper::getBoxWebView() const
+{
+ LogD("enter");
+ return m_boxWebView;
+}
+
+Evas_Object* PdHelper::getPdWebView() const
+{
+ LogD("enter");
+ return m_pdWebView;
+}
+
+Evas* PdHelper::getPdCanvas() const
+{
+ LogD("enter");
+ return evas_object_evas_get(m_pdRenderInfo->window);
+}
+
+bool PdHelper::isPdOpened() const
+{
+ LogD("enter");
+ return m_opened;
+}
+
+void PdHelper::didExecuteScript(Evas_Object* webview, std::string& result)
+{
+ LogD("enter");
+ UNUSED_PARAM(webview);
+ LogD("javascript execution result: %s", result.c_str());
+}
+
+std::string PdHelper::validateUrl(std::string& url)
+{
+ LogD("enter");
+
+ if (url.empty()) {
+ return std::string();
+ }
+
+ if((!url.compare(0, 4, "http")) ||
+ (!url.compare(0, 5, "https")) ||
+ (!url.compare(0, 4, "file")))
+ {
+ return url;
+ }
+
+ std::string newUrl("file://");
+ newUrl += url;
+ return newUrl;
+}
+
+void PdHelper::executeScriptCallback(
+ Evas_Object* webview, const char* result, void* data)
+{
+ LogD("enter");
+
+ PdHelper* This = static_cast<PdHelper*>(data);
+ std::string resultStr(result ? result : "null");
+ This->didExecuteScript(webview, resultStr);
+}
+
diff --git a/src_mobile/Core/View/PdHelper.h b/src_mobile/Core/View/PdHelper.h
new file mode 100644
index 0000000..6879ba3
--- /dev/null
+++ b/src_mobile/Core/View/PdHelper.h
@@ -0,0 +1,69 @@
+
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 PdHelper.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#ifndef PD_HELPER_H
+#define PD_HELPER_H
+
+#include <string>
+#include <Evas.h>
+#include "IRenderView.h"
+#include "IPdHelper.h"
+
+#define EXPORT_CLASS __attribute__ ((visibility("default"))
+
+class EXPORT_CLASS PdHelper: public IPdHelper {
+ public:
+ static IPdHelperPtr create(
+ RenderInfoPtr pdRenderInfo,
+ std::string pdStartUrl)
+ {
+ return IPdHelperPtr(new PdHelper(pdRenderInfo, pdStartUrl));
+ }
+ virtual void startOpen();
+ virtual void finishOpen(Evas_Object* child);
+ virtual void close();
+ virtual void setBoxWebView(Evas_Object* webview);
+ virtual void setPdWebView(Evas_Object* webview);
+ virtual Evas_Object* getBoxWebView() const;
+ virtual Evas_Object* getPdWebView() const;
+ virtual Evas* getPdCanvas() const;
+ virtual bool isPdOpened() const;
+ virtual ~PdHelper();
+
+ private:
+ virtual void didExecuteScript(Evas_Object* webview, std::string& result);
+
+ std::string validateUrl(std::string& url);
+ static void executeScriptCallback(
+ Evas_Object* webview, const char* result, void* data);
+
+ PdHelper(RenderInfoPtr pdRenderInfo, std::string pdStartUrl);
+
+ //members
+ Evas_Object* m_boxWebView;
+ Evas_Object* m_pdWebView;
+ RenderInfoPtr m_pdRenderInfo;
+ std::string m_startUrl;
+ bool m_opened;
+};
+
+#endif // PD_HELPER_H
+
diff --git a/src_mobile/Core/View/WebView.cpp b/src_mobile/Core/View/WebView.cpp
new file mode 100755
index 0000000..4e58d55
--- /dev/null
+++ b/src_mobile/Core/View/WebView.cpp
@@ -0,0 +1,847 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 WebView.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <fstream>
+#include <streambuf>
+#include <Evas.h>
+#include <Eina.h>
+#include <ewk_context.h>
+#include <ewk_view.h>
+#include <ewk_policy_decision.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include <Core/Service/AppControl.h>
+#include "WebView.h"
+
+// injection javascript file regarding creating js object used by box and pd
+static const std::string injectionFile("/usr/share/web-provider/injection.js");
+
+std::map<const std::string, const Evas_Smart_Cb> WebView::m_smartCallbacksMap =
+{
+ {"load,started", WebView::loadStartedCallback},
+ {"load,finished", WebView::loadFinishedCallback},
+ {"title,changed", WebView::titleChangedCallback},
+ {"uri,changed", WebView::uriChangedCallback},
+ {"load,progress", WebView::loadProgressCallback},
+ {"load,progress,finished", WebView::loadProgressFinishedCallback},
+ {"process,crashed", WebView::processCrashedCallback},
+ {"create,window", WebView::createWindowCallback},
+ {"close,window", WebView::closeWindowCallback},
+ {"policy,navigation,decide", WebView::policyNavigationDecideCallback},
+ {"policy,newwindow,decide", WebView::policyNewWindowDecideCallback},
+ {"policy,response,decide", WebView::pageResponseDecideCallback},
+ {"contextmenu,customize", WebView::contextmenuCustomizeCallback},
+ {"form,submit", WebView::formSubmitCallback},
+ {"request,geolocation,permission", WebView::geolocationPermissionRequestCallback},
+ {"notification,show", WebView::notificationShowCallback},
+ {"notification,cancel", WebView::notificationCancelCallback},
+ {"notification,permission,request", WebView::notificationPermissionRequestCallback},
+ {"database,quota,exceeded", WebView::databaseUsagePermissionRequestCallback},
+ {"filesystem,permission,request", WebView::fileSystemPermissionRequestCallback},
+ {"fullscreen,enterfullscreen", WebView::enterFullscreenCallback},
+ {"fullscreen,exitfullscreen", WebView::exitFullscreenCallback},
+ {"inputmethod,changed", WebView::imeChangedCallback},
+ {"editorclient,ime,opened", WebView::imeOpenedCallback},
+ {"editorclient,ime,closed", WebView::imeClosedCallback},
+ {"usermedia,permission,request", WebView::usermediaPermissionRequestCallback},
+ {"protocolhandler,registration,requested", WebView::protocolHandlerRegistrationCallback},
+ {"protocolhandler,isregistered", WebView::protocolHandlerIsRegisteredCallback},
+ {"protocolhandler,unregistration,requested", WebView::protocolHandlerUnregistrationCallback},
+ {"contenthandler,registration,requested", WebView::contentHandlerRegistrationCallback},
+ {"contenthandler,isregistered", WebView::contentHandlerIsRegisteredCallback},
+ {"contenthandler,unregistration,requested", WebView::contentHandlerUnregistrationCallback},
+ {"request,certificate,confirm", WebView::certificateConfirmRequestCallback}
+};
+
+WebView::WebView(Evas_Object* win, Ewk_Context* ewkContext)
+ : m_topWebview(NULL)
+ , m_win(win)
+ , m_ewkContext(ewkContext)
+{
+}
+
+WebView::~WebView()
+{
+}
+
+bool WebView::show(
+ std::string& startUrl, int width, int height,
+ WebViewCallback didCreateBaseWebView, void* data)
+{
+ LogD("enter");
+ if (!m_topWebview) {
+ m_topWebview = ewk_view_add_with_context(
+ evas_object_evas_get(m_win), m_ewkContext);
+ if (!setBasicSetting(m_topWebview)) {
+ return false;
+ }
+ }
+
+ // inform base webview to caller
+ if (didCreateBaseWebView) {
+ didCreateBaseWebView(data, static_cast<void*>(m_topWebview));
+ }
+
+ // check scheme of url
+ std::string url = validateUrl(startUrl);
+ LogD("load: %s", url.c_str());
+ evas_object_resize(m_topWebview, width, height);
+ evas_object_show(m_topWebview);
+ ewk_view_url_set(m_topWebview, url.c_str());
+
+ return true;
+}
+
+bool WebView::hide()
+{
+ LogD("enter");
+
+ // TODO If created webviews are managed by WebView Class,
+ // add code regarding created all webviews
+ if (!unsetBasicSetting(m_topWebview)) {
+ return false;
+ }
+ if(!m_topWebview) {
+ return false;
+ }
+ evas_object_del(m_topWebview);
+ m_topWebview = NULL;
+
+ return true;
+}
+
+bool WebView::suspend()
+{
+ LogD("enter");
+ ewk_view_page_visibility_state_set(
+ m_topWebview, EWK_PAGE_VISIBILITY_STATE_HIDDEN, EINA_FALSE);
+ ewk_view_visibility_set(m_topWebview, EINA_FALSE);
+ ewk_view_suspend(m_topWebview);
+ return true;
+}
+
+bool WebView::resume()
+{
+ LogD("enter");
+ ewk_view_resume(m_topWebview);
+ ewk_view_page_visibility_state_set(
+ m_topWebview, EWK_PAGE_VISIBILITY_STATE_VISIBLE, EINA_FALSE);
+ ewk_view_visibility_set(m_topWebview, EINA_TRUE);
+ return true;
+}
+
+bool WebView::setBasicSetting(Evas_Object* webview)
+{
+ LogD("enter");
+
+ if (!webview) {
+ return false;
+ }
+
+ for (auto it = m_smartCallbacksMap.begin();
+ it != m_smartCallbacksMap.end(); it++) {
+ evas_object_smart_callback_add(
+ webview, it->first.c_str(), it->second, this);
+ }
+
+ // set specific features
+ Ewk_Settings* setting = ewk_view_settings_get(webview);
+ // set user agent like WRT, or Browser?
+ // ewk_view_user_agent_set(webview, "some_ua_string");
+ ewk_settings_plugins_enabled_set(setting, EINA_TRUE);
+ ewk_settings_javascript_enabled_set(setting, EINA_TRUE);
+ ewk_settings_loads_images_automatically_set(setting, EINA_TRUE);
+ ewk_settings_auto_fitting_set(setting, EINA_FALSE);
+ ewk_settings_default_keypad_enabled_set(setting, EINA_FALSE);
+
+ // set visibility
+ ewk_view_page_visibility_state_set(
+ webview, EWK_PAGE_VISIBILITY_STATE_VISIBLE, EINA_TRUE);
+
+ evas_object_color_set(webview, 0, 0, 0, 1);
+
+ return true;
+}
+
+bool WebView::unsetBasicSetting(Evas_Object* webview)
+{
+ LogD("enter");
+
+ if (!webview) {
+ return false;
+ }
+
+ for (auto it = m_smartCallbacksMap.begin();
+ it != m_smartCallbacksMap.end(); it++) {
+ evas_object_smart_callback_del(
+ m_topWebview, it->first.c_str(), it->second);
+ }
+
+ return true;
+}
+
+std::string WebView::validateUrl(std::string& url)
+{
+ LogD("enter");
+
+ if (url.empty()) {
+ return std::string();
+ }
+
+ if((!url.compare(0, 4, "http")) ||
+ (!url.compare(0, 5, "https")) ||
+ (!url.compare(0, 4, "file")))
+ {
+ return url;
+ }
+
+ std::string newUrl("file://");
+ newUrl += url;
+ return newUrl;
+}
+
+void WebView::loadStartedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+
+ std::ifstream jsFile(injectionFile);
+ std::string script((std::istreambuf_iterator<char>(jsFile)),
+ std::istreambuf_iterator<char>());
+ LogD("injected js code: %s", script.c_str());
+
+ ewk_view_script_execute(obj, script.c_str(), executeScriptCallback, This);
+ This->didLoadStarted(obj);
+}
+
+void WebView::loadFinishedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didLoadFinished(obj);
+}
+
+void WebView::titleChangedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didTitleChanged(obj, eventInfo);
+}
+
+void WebView::uriChangedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didUriChanged(obj, eventInfo);
+}
+
+void WebView::loadProgressCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didLoadProgress(obj, eventInfo);
+}
+
+void WebView::loadProgressFinishedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didLoadProgressFinished(obj);
+}
+
+void WebView::processCrashedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didProcessCrashed(obj);
+}
+
+void WebView::createWindowCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didCreateWindow(obj, eventInfo);
+}
+
+void WebView::closeWindowCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didCloseWindow(obj);
+}
+
+void WebView::policyNavigationDecideCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didPolicyNavigationDecide(obj, eventInfo);
+}
+
+void WebView::policyNewWindowDecideCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didPolicyNewWindowDecide(obj, eventInfo);
+}
+
+void WebView::pageResponseDecideCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ Ewk_Policy_Decision *policyDecision = static_cast<Ewk_Policy_Decision *>(eventInfo);
+ Ewk_Policy_Decision_Type policyType = ewk_policy_decision_type_get(policyDecision);
+ std::string url(ewk_policy_decision_url_get(policyDecision));
+ std::string cookie(ewk_policy_decision_cookie_get(policyDecision));
+ const char* contentType = ewk_policy_decision_response_mime_get(policyDecision);
+
+ switch (policyType) {
+ case EWK_POLICY_DECISION_USE:
+ LogD("policy use");
+ ewk_policy_decision_use(policyDecision);
+ break;
+
+ case EWK_POLICY_DECISION_DOWNLOAD:
+ LogD("policy download: %s, %s, %s", url.c_str(), cookie.c_str(), contentType);
+ ewk_policy_decision_suspend(policyDecision);
+ Service::AppControl::launchDownloader(url, cookie);
+ ewk_policy_decision_ignore(policyDecision);
+ break;
+
+ case EWK_POLICY_DECISION_IGNORE:
+ default:
+ LogD("policy ignore");
+ ewk_policy_decision_ignore(policyDecision);
+ break;
+ }
+
+ if (policyType == EWK_POLICY_DECISION_DOWNLOAD) {
+ if (ewk_view_back_possible(obj)) {
+ ewk_view_back(obj);
+ } else {
+ // TODO Add handling code in case that new window is opened
+ //ecore_idler_add(windowCloseIdlerCallback, data);
+ }
+ }
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didPageResponseDecide(obj);
+}
+
+void WebView::contextmenuCustomizeCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didContextmenuCustomize(obj, eventInfo);
+}
+
+void WebView::formSubmitCallback(
+ void* data, Evas_Object *obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didFormSubmit(obj);
+}
+
+void WebView::geolocationPermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didGeolocationPermissionRequest(obj, eventInfo);
+}
+
+void WebView::notificationShowCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didNotificationShow(obj, eventInfo);
+}
+
+void WebView::notificationCancelCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didNotificationCancel(obj, eventInfo);
+}
+
+void WebView::notificationPermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didNotificationPermissionRequest(obj, eventInfo);
+}
+
+void WebView::databaseUsagePermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didDatabaseUsagePermissionRequest(obj, eventInfo);
+}
+
+void WebView::fileSystemPermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didFilesystemPermissionRequest(obj, eventInfo);
+}
+
+void WebView::enterFullscreenCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didEnterFullscreen(obj);
+}
+
+void WebView::exitFullscreenCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didExitFullscreen(obj);
+}
+
+void WebView::imeChangedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didImeChanged(obj, eventInfo);
+}
+
+void WebView::imeOpenedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didImeOpened(obj);
+}
+
+void WebView::imeClosedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didImeClosed(obj);
+}
+
+void WebView::usermediaPermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didUsermediaPermissionRequest(obj, eventInfo);
+}
+
+void WebView::protocolHandlerRegistrationCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didProtocolHandlerRegistration(obj, eventInfo);
+}
+
+void WebView::protocolHandlerIsRegisteredCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didProtocolHandlerIsRegistered(obj, eventInfo);
+}
+
+void WebView::protocolHandlerUnregistrationCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didProtocolHandlerUnregistration(obj, eventInfo);
+}
+
+void WebView::contentHandlerRegistrationCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didContentHandlerRegistration(obj, eventInfo);
+}
+
+void WebView::contentHandlerIsRegisteredCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didContentHandlerIsRegistered(obj, eventInfo);
+}
+
+void WebView::contentHandlerUnregistrationCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didContentHandlerUnregistration(obj, eventInfo);
+}
+
+void WebView::certificateConfirmRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didCertificateConfirmRequest(obj, eventInfo);
+}
+
+void WebView::didLoadStarted(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+
+ // This Will be implemented by derived class
+}
+
+void WebView::didLoadFinished(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didTitleChanged(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+
+ // This Will be implemented by derived class
+}
+
+void WebView::didUriChanged(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didLoadProgress(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didLoadProgressFinished(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didProcessCrashed(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didCreateWindow(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didCloseWindow(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didPolicyNavigationDecide(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didPolicyNewWindowDecide(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didPageResponseDecide(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didContextmenuCustomize(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didFormSubmit(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didGeolocationPermissionRequest(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didNotificationShow(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didNotificationCancel(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didNotificationPermissionRequest(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didDatabaseUsagePermissionRequest(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didFilesystemPermissionRequest(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didEnterFullscreen(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didExitFullscreen(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didImeChanged(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didImeOpened(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didImeClosed(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didUsermediaPermissionRequest(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didProtocolHandlerRegistration(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didProtocolHandlerIsRegistered(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didProtocolHandlerUnregistration(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didContentHandlerRegistration(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didContentHandlerIsRegistered(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didContentHandlerUnregistration(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didCertificateConfirmRequest(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+Eina_Bool WebView::orientationLockCallback(
+ Evas_Object* obj, Eina_Bool needLock, int orientation, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(needLock);
+ UNUSED_PARAM(orientation);
+ UNUSED_PARAM(data);
+ return EINA_TRUE;
+}
+
+void WebView::executeScriptCallback(
+ Evas_Object* obj, const char* result, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(result);
+ UNUSED_PARAM(data);
+}
+
diff --git a/src_mobile/Core/View/WebView.h b/src_mobile/Core/View/WebView.h
new file mode 100644
index 0000000..42945c7
--- /dev/null
+++ b/src_mobile/Core/View/WebView.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 WebView.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef WEB_VIEW_H
+#define WEB_VIEW_H
+
+#include <string>
+#include <map>
+#include <Eina.h>
+#include <Evas.h>
+#include <ewk_context.h>
+#include "IWebView.h"
+
+#define EXPORT_CLASS __attribute__ ((visibility("default"))
+
+class EXPORT_CLASS WebView: public IWebView {
+ public:
+ static IWebViewPtr create(Evas_Object* win, Ewk_Context* ewkContext)
+ {
+ if (!win || !ewkContext) {
+ return IWebViewPtr();
+ }
+
+ return IWebViewPtr(new WebView(win, ewkContext));
+ }
+ virtual bool show(
+ std::string& startUrl, int width, int height,
+ WebViewCallback didCreateBaseWebView, void* data);
+ virtual bool hide();
+ virtual bool suspend();
+ virtual bool resume();
+ virtual ~WebView();
+
+ protected:
+ bool setBasicSetting(Evas_Object* webview);
+ bool unsetBasicSetting(Evas_Object* webview);
+ explicit WebView(Evas_Object* win, Ewk_Context* ewkContext);
+
+ private:
+ std::string validateUrl(std::string& url);
+
+ // webviw smart callbacks
+ static void loadStartedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void loadFinishedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void titleChangedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void uriChangedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void loadProgressCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void loadProgressFinishedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void processCrashedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void createWindowCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void closeWindowCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void policyNavigationDecideCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void policyNewWindowDecideCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void pageResponseDecideCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void contextmenuCustomizeCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void formSubmitCallback(
+ void *data, Evas_Object *obj, void *eventInfo);
+ static void geolocationPermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void notificationShowCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void notificationCancelCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void notificationPermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void databaseUsagePermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void fileSystemPermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void enterFullscreenCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void exitFullscreenCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void imeChangedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void imeOpenedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void imeClosedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void usermediaPermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void protocolHandlerRegistrationCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void protocolHandlerIsRegisteredCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void protocolHandlerUnregistrationCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void contentHandlerRegistrationCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void contentHandlerIsRegisteredCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void contentHandlerUnregistrationCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void certificateConfirmRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+
+ // internal implementation for smart callbacks
+ virtual void didLoadStarted(Evas_Object* obj);
+ virtual void didLoadFinished(Evas_Object* obj);
+ virtual void didTitleChanged(Evas_Object* obj, void* eventInfo);
+ virtual void didUriChanged(Evas_Object* obj, void* eventInfo);
+ virtual void didLoadProgress(Evas_Object* obj, void* eventInfo);
+ virtual void didLoadProgressFinished(Evas_Object* obj);
+ virtual void didProcessCrashed(Evas_Object* obj);
+ virtual void didCreateWindow(Evas_Object* obj, void* eventInfo);
+ virtual void didCloseWindow(Evas_Object* obj);
+ virtual void didPolicyNavigationDecide(Evas_Object* obj, void* eventInfo);
+ virtual void didPolicyNewWindowDecide(Evas_Object* obj, void* eventInfo);
+ virtual void didPageResponseDecide(Evas_Object* obj);
+ virtual void didContextmenuCustomize(Evas_Object* obj, void* eventInfo);
+ virtual void didFormSubmit(Evas_Object* obj);
+ virtual void didGeolocationPermissionRequest(Evas_Object* obj, void* eventInfo);
+ virtual void didNotificationShow(Evas_Object* obj, void* eventInfo);
+ virtual void didNotificationCancel(Evas_Object* obj, void* eventInfo);
+ virtual void didNotificationPermissionRequest(Evas_Object* obj, void* eventInfo);
+ virtual void didDatabaseUsagePermissionRequest(Evas_Object* obj, void* eventInfo);
+ virtual void didFilesystemPermissionRequest(Evas_Object* obj, void* eventInfo);
+ virtual void didEnterFullscreen(Evas_Object* obj);
+ virtual void didExitFullscreen(Evas_Object* obj);
+ virtual void didImeChanged(Evas_Object* obj, void* eventInfo);
+ virtual void didImeOpened(Evas_Object* obj);
+ virtual void didImeClosed(Evas_Object* obj);
+ virtual void didUsermediaPermissionRequest(Evas_Object* obj, void* eventInfo);
+ virtual void didProtocolHandlerRegistration(Evas_Object* obj, void* eventInfo);
+ virtual void didProtocolHandlerIsRegistered(Evas_Object* obj, void* eventInfo);
+ virtual void didProtocolHandlerUnregistration(Evas_Object* obj, void* eventInfo);
+ virtual void didContentHandlerRegistration(Evas_Object* obj, void* eventInfo);
+ virtual void didContentHandlerIsRegistered(Evas_Object* obj, void* eventInfo);
+ virtual void didContentHandlerUnregistration(Evas_Object* obj, void* eventInfo);
+ virtual void didCertificateConfirmRequest(Evas_Object* obj, void* eventInfo);
+
+ // orientation lock
+ static Eina_Bool orientationLockCallback(
+ Evas_Object* obj, Eina_Bool needLock, int orientation, void* data);
+ static void executeScriptCallback(Evas_Object* obj, const char* result, void* data);
+
+ static std::map<const std::string, const Evas_Smart_Cb> m_smartCallbacksMap;
+
+ // members
+ Evas_Object* m_topWebview;
+ std::string m_startUrl;
+ Evas_Object* m_win;
+ Ewk_Context* m_ewkContext;
+};
+
+#endif // WEB_VIEW_H
diff --git a/src_mobile/Core/View/injection.js b/src_mobile/Core/View/injection.js
new file mode 100644
index 0000000..6616aea
--- /dev/null
+++ b/src_mobile/Core/View/injection.js
@@ -0,0 +1,129 @@
+// set javascript objects for Web APIs of Tizen appwidget
+var appTizenObject = 0;
+if (typeof window.tizen == 'undefined') {
+ window.tizen = new Object();
+ window.tizen.appwidget = new Object();
+} else {
+ appTizenObject = 1;
+}
+
+// For future, only window.appwidget will be used
+window.appwidget = new Object();
+
+
+window.appwidget.fireReadyEvent = function () {
+ // If every functionalities of appwidget are initialized, fire appwidget ready event
+ var readyevent = document.createEvent("CustomEvent");
+ readyevent.initCustomEvent("appwidgetready", true, true);
+ document.dispatchEvent(readyevent);
+};
+
+// these are functions for overriding standard javascript functions regarding event
+var original_addEventListener = window.addEventListener;
+var original_removeEventListener = window.removeEventListener;
+
+// this variable is responsible to keep information of appwidget evetns
+var appWidgetEvents = {};
+
+// define event structure for appwidget
+window.AppWidgetEventInfo = function(event, callback) {
+ this.event = event;
+ this.callback = callback;
+};
+
+window.addEventListener = function(event, callback, capture) {
+ var e = event.toLowerCase();
+ if (typeof appWidgetEvents[e] != 'undefined') {
+ appWidgetEvents[e].callback = callback;
+ } else {
+ original_addEventListener.call(window, event, callback, capture);
+ }
+
+ if (e == 'appwidgetready') {
+ // fire ready event to content
+ setTimeout(window.appwidget.fireReadyEvent(), 0);
+ }
+};
+
+window.removeEventListener = function(event, callback, capture) {
+ var e = event.toLowerCase();
+ if (typeof appWidgetEvents[e] != "undefined") {
+ appWidgetEvents[e].callback = "null";
+ } else {
+ original_removeEventListener.call(window, event, callback, capture);
+ }
+};
+
+window.appwidget.reload = function() {
+ window.location.href = "box://reload";
+};
+
+window.appwidget.changePeriod = function(period) {
+ switch (arguments.length) {
+ case 0:
+ window.location.href = "box://change-period";
+ break;
+ case 1:
+ window.location.href = "box://change-period?period=" + period;
+ break;
+ default:
+ window.location.href = "box://change-period";
+ break;
+ }
+};
+
+window.appwidget.launchBrowser = function(url) {
+ window.location.href = "box://launch-browser?url=" + url;
+};
+
+window.appwidget.scrollStart = function() {
+ window.location.href = "box://scroll-start";
+};
+
+window.appwidget.scrollStop = function() {
+ window.location.href = "box://scroll-stop";
+};
+
+window.appwidget.sendMessageToBox = function(message) {
+ window.location.href = "box://send-message-to-box?message=" + message;
+};
+
+window.appwidget.sendMessageToPd = function(message) {
+ window.location.href = "box://send-message-to-pd?message=" + message;
+};
+
+var webprovider = {
+ // define specific function for registering appwidget event
+ registerAppWidgetEvent: function(event) {
+ return (appWidgetEvents[event] = new AppWidgetEventInfo(event, "null"));
+ },
+
+ // define specific function for firing registered appwidget event
+ fireAppWidgetEvent: function(event, data) {
+ // this is called by web-provider, which is native code
+ if (typeof appWidgetEvents[event] != 'undefined') {
+ setTimeout(function() {
+ appWidgetEvents[event].callback(data);
+ }, 0);
+ console.log("fire appwidget event: " + event);
+ } else {
+ console.log("unknown appwidget event: " + event);
+ }
+ },
+};
+
+// register custom events for appwidget
+webprovider.registerAppWidgetEvent("pdmessage");
+webprovider.registerAppWidgetEvent("boxmessage");
+
+// These objects will be deprecated soon
+if (!appTizenObject) {
+ window.tizen.appwidget.reload = window.appwidget.reload;
+ window.tizen.appwidget.changePeriod = window.appwidget.changePeriod;
+ window.tizen.appwidget.launchBrowser = window.appwidget.launchBrowser;
+ window.tizen.appwidget.scrollStart = window.appwidget.scrollStart;
+ window.tizen.appwidget.scrollStop = window.appwidget.scrollStop;
+}
+
+// fire ready event explicitly
+window.appwidget.fireReadyEvent();
diff --git a/src_mobile/Daemon/BoxDaemon.cpp b/src_mobile/Daemon/BoxDaemon.cpp
new file mode 100644
index 0000000..d58153b
--- /dev/null
+++ b/src_mobile/Daemon/BoxDaemon.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxDaemon.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <app.h>
+#include "BoxDaemon.h"
+#include "BoxDaemonImpl.h"
+
+BoxDaemon::BoxDaemon()
+ : m_impl(new BoxDaemonImpl())
+{
+}
+
+BoxDaemon::~BoxDaemon()
+{
+}
+
+bool BoxDaemon::start(std::string& name)
+{
+ return m_impl->start(name);
+}
+
+bool BoxDaemon::stop()
+{
+ return m_impl->stop();
+}
+
+bool BoxDaemon::handleAppService(service_h service)
+{
+ return m_impl->handleAppService(service);
+}
diff --git a/src_mobile/Daemon/BoxDaemon.h b/src_mobile/Daemon/BoxDaemon.h
new file mode 100644
index 0000000..f1bde75
--- /dev/null
+++ b/src_mobile/Daemon/BoxDaemon.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxDaemon.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_DAEMON_H
+#define BOX_DAEMON_H
+
+#include <string>
+#include <memory>
+#include <app.h>
+#include <Core/Util/Noncopyable.h>
+
+class BoxDaemonImpl;
+
+class BoxDaemon: Noncopyable {
+ public:
+ bool start(std::string& name);
+ bool stop();
+ bool handleAppService(service_h service);
+
+ explicit BoxDaemon();
+ ~BoxDaemon();
+
+ private:
+ std::shared_ptr<BoxDaemonImpl> m_impl;
+};
+
+#endif //BOX_DAEMON_H
diff --git a/src_mobile/Daemon/BoxDaemonImpl.cpp b/src_mobile/Daemon/BoxDaemonImpl.cpp
new file mode 100755
index 0000000..3ff24ba
--- /dev/null
+++ b/src_mobile/Daemon/BoxDaemonImpl.cpp
@@ -0,0 +1,754 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxDaemonImpl.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <API/web_provider_livebox_info.h>
+#include <app.h>
+#include <appcore-efl.h>
+#include <aul.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include <cstring>
+#include <Ecore_X.h>
+#include <Elementary.h>
+#include <livebox-service.h>
+#include <Plugin/IBoxPluginConnector.h>
+#include <Plugin/BoxPluginConnector.h>
+#include <provider.h>
+#include <sys/types.h>
+#include <string>
+#include <unistd.h>
+#include <vconf.h>
+
+#include "BoxDaemonUtil.h"
+#include "BoxDaemonImpl.h"
+
+#define MASTER_PROVIDER_PING_TIME 120.0f
+
+// These are string for handling application service from app
+static const std::string BOX_SERVICE_SCHEME("box-service://");
+static const std::string OPERATION_UPDATE_BOX(
+ "http://tizen.org/appcontrol/operation/dynamicbox/web/update");
+static const std::string CONTENT_INFO_KEY("content-info");
+static const std::string ALARM_CALLER_KEY("__ALARM_MGR_CALLER_APPID");
+
+BoxDaemonImpl::BoxDaemonImpl()
+ : m_pluginConnector(BoxPluginConnector::create())
+{
+ appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, requestChangeLanguageCallback, this);
+ appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, requestLowMemoryCallback, this);
+ appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, requestChangeRegionCallback, this);
+ // reserved
+ appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, NULL, NULL);
+
+ if (vconf_notify_key_changed("db/setting/accessibility/font_name", requestChangeFontCallback, this) != true) {
+ LogD("vconf_notify_key_changed returned FALSE!");
+ }
+ if (vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, requestChangeTimeCallback, this) != true) {
+ LogD("vconf_notify_key_changed returned FALSE!");
+ }
+}
+
+BoxDaemonImpl::~BoxDaemonImpl()
+{
+}
+
+bool BoxDaemonImpl::start(std::string& name)
+{
+ LogD("enter");
+
+ // initialize existing plugins for web livebox
+ if (!m_pluginConnector->initialize()) {
+ LogD("failed to initialize plugins");
+ return false;
+ }
+
+ // set name
+ m_daemonName = name;
+
+ // provider init
+ ProviderCallbacks callbacks;
+ setProviderCallbacks(callbacks);
+
+ int ret = provider_init(ecore_x_display_get(),
+ m_daemonName.c_str(),
+ &callbacks,
+ this);
+ if (ret < 0) {
+ LogD("failed to initialize provider");
+ return false;
+ }
+
+ return true;
+}
+
+bool BoxDaemonImpl::stop()
+{
+ LogD("enter");
+
+ // deinitialize provider
+ provider_fini();
+
+ // deinitialize existing plugins for web livebox
+ if (!m_pluginConnector->shutdown()) {
+ LogD("failed to shutdown plugins");
+ return false;
+ }
+
+ return true;
+}
+
+bool BoxDaemonImpl::handleAppService(service_h service)
+{
+ LogD("enter");
+ bool result = false;
+ char* operation;
+
+ if (service_get_operation(service, &operation) != SERVICE_ERROR_NONE) {
+ LogD("no operation");
+ return false;
+ }
+
+ if (OPERATION_UPDATE_BOX == operation) {
+ BoxInfoPtr info = handleOperationUpdate(service);
+ if (info) {
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_BOX, info, this);
+ if (ecore_job_add(requestBoxJobCallback, jobInfo)) {
+ result = true;
+ }
+ }
+ } else {
+ LogD("unknown operation: %s", operation);
+ }
+
+ delete[] operation;
+ return result;
+}
+
+int BoxDaemonImpl::connectedCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(arg);
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ if (!provider_send_hello()) {
+ This->m_pingTimer =
+ ecore_timer_add(MASTER_PROVIDER_PING_TIME, pingToMasterCallback, This);
+ }
+
+ return 0;
+}
+
+int BoxDaemonImpl::disconnectedCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(arg);
+ UNUSED_PARAM(data);
+
+ return 0;
+}
+
+int BoxDaemonImpl::boxCreateCallback(
+ ProviderEventArgPtr arg,
+ int* width, int* height,
+ double* priority, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(priority);
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+
+ if ((arg->info.lb_create.width == 0) || (arg->info.lb_create.height == 0)) {
+ livebox_service_get_size(LB_SIZE_TYPE_1x1, width, height);
+ } else {
+ *width = arg->info.lb_create.width;
+ *height = arg->info.lb_create.height;
+ }
+
+ info->boxWidth = *width;
+ info->boxHeight = *height;
+ info->priority = 1.0f;
+ info->period = arg->info.lb_create.period;
+ if (arg->info.lb_create.content) {
+ info->contentInfo = std::string(arg->info.lb_create.content);
+ }
+
+ // box information
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("width: %d", info->boxWidth);
+ LogD("height: %d", info->boxHeight);
+ LogD("update period: %f", info->period);
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_ADD_BOX, info, This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::boxReCreateCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+
+ if ((arg->info.lb_recreate.width == 0) || (arg->info.lb_recreate.height == 0)) {
+ livebox_service_get_size(LB_SIZE_TYPE_1x1,
+ &arg->info.lb_recreate.width,
+ &arg->info.lb_recreate.height);
+ }
+
+ info->boxWidth = arg->info.lb_recreate.width;
+ info->boxHeight = arg->info.lb_recreate.height;
+ info->priority = 1.0f;
+ info->period = arg->info.lb_recreate.period;
+ if (arg->info.lb_recreate.content) {
+ info->contentInfo = std::string(arg->info.lb_recreate.content);
+ }
+
+ // box information
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("width: %d", info->boxWidth);
+ LogD("height: %d", info->boxHeight);
+ LogD("update period: %f", info->period);
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_ADD_BOX, info, This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::boxDestroyCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("--------------------------------------------");
+
+ This->m_pluginConnector->requestCommand(REQUEST_CMD_REMOVE_BOX, info);
+
+ return 0;
+}
+
+int BoxDaemonImpl::pdCreateCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+ if (arg->info.pd_create.w == 0 || arg->info.pd_create.h == 0) {
+ return -1;
+ }
+
+ //Use the screen width to fix the device width
+ ecore_x_window_size_get(0, &info->pdWidth, NULL);
+ info->pdHeight = arg->info.pd_create.h;
+ info->pdX = arg->info.pd_create.x;
+ info->pdY = arg->info.pd_create.y;
+
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("width: %d", info->pdWidth);
+ LogD("height: %d", info->pdHeight);
+ LogD("x: %f", info->pdX);
+ LogD("y: %f", info->pdY);
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_OPEN_PD, info, This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::pdDestroyCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CLOSE_PD, info, This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::clickedCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+
+ int flag = web_provider_livebox_get_auto_launch(info->boxId.c_str());
+ if (!flag) {
+ return -1;
+ }
+
+ BoxDaemonUtil::launchApplication(info->boxId, info->instanceId);
+ return 0;
+}
+
+int BoxDaemonImpl::boxResizeCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+ if (arg->info.resize.w == 0 || arg->info.resize.h == 0) {
+ return -1;
+ }
+
+ info->boxWidth = arg->info.resize.w;
+ info->boxHeight = arg->info.resize.h;
+
+ // box information
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("width: %d", info->boxWidth);
+ LogD("height: %d", info->boxHeight);
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESIZE_BOX, info, This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::boxPauseCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+
+ // box information
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_PAUSE_BOX, info, This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::boxResumeCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+
+ // box information
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESUME_BOX, info, This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::pauseCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(arg);
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+
+ LogD("--------------------------------------------");
+ LogD("web-provider is paused");
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_PAUSE_ALL, BoxInfoPtr(), This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::resumeCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(arg);
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+
+ LogD("--------------------------------------------");
+ LogD("web-provider is resumed");
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESUME_ALL, BoxInfoPtr(), This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::boxPeriodChangeCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+ info->period = arg->info.set_period.period;
+
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("period: %f", info->period);
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CHANGE_PERIOD, info, This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::boxUpdateCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_BOX, info, This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+void BoxDaemonImpl::setProviderCallbacks(ProviderCallbacks& callbacks)
+{
+ LogD("enter");
+
+ memset(&callbacks, 0, sizeof(callbacks));
+ callbacks.connected = BoxDaemonImpl::connectedCallback;
+ callbacks.disconnected = BoxDaemonImpl::disconnectedCallback;
+ callbacks.pause = BoxDaemonImpl::pauseCallback;
+ callbacks.resume = BoxDaemonImpl::resumeCallback;
+ callbacks.lb_create = BoxDaemonImpl::boxCreateCallback;
+ callbacks.lb_recreate = BoxDaemonImpl::boxReCreateCallback;
+ callbacks.lb_destroy = BoxDaemonImpl::boxDestroyCallback;
+ callbacks.lb_pause = BoxDaemonImpl::boxPauseCallback;
+ callbacks.lb_resume = BoxDaemonImpl::boxResumeCallback;
+ callbacks.pd_create = BoxDaemonImpl::pdCreateCallback;
+ callbacks.pd_destroy = BoxDaemonImpl::pdDestroyCallback;
+ callbacks.clicked = BoxDaemonImpl::clickedCallback;
+ callbacks.resize = BoxDaemonImpl::boxResizeCallback;
+ callbacks.update_content = BoxDaemonImpl::boxUpdateCallback;
+ callbacks.set_period = BoxDaemonImpl::boxPeriodChangeCallback;
+}
+
+std::string BoxDaemonImpl::getBoxType(const char* boxId)
+{
+ LogD("enter");
+
+ if (!boxId) {
+ return std::string();
+ }
+
+ const char* type = web_provider_livebox_get_box_type(boxId);
+ if (!type) {
+ std::string boxType = m_pluginConnector->getBoxType(boxId);
+ if (boxType.empty()) {
+ LogD("unrecognized box id");
+ } else {
+ LogD("box id: %s, type: %s", boxId, boxType.c_str());
+ }
+ return boxType;
+ }
+
+ LogD("box id: %s, type: %s", boxId, type);
+ std::string result{type};
+ free(const_cast<char*>(type));
+ return result;
+}
+
+BoxInfoPtr BoxDaemonImpl::initializeBoxInfo(ProviderEventArgPtr arg)
+{
+ LogD("enter");
+
+ if (!arg) {
+ return BoxInfoPtr();
+ }
+
+ if (!arg->pkgname || !arg->id) {
+ LogD("pkgname or id don't exist");
+ return BoxInfoPtr();
+ }
+
+ std::string type = getBoxType(arg->pkgname);
+ if (type.empty()) {
+ return BoxInfoPtr();
+ }
+ BoxInfoPtr infoPtr = BoxInfoPtr(new BoxInfo(type, arg->pkgname, arg->id));
+
+ return infoPtr;
+}
+
+std::string BoxDaemonImpl::getBoxIdFromService(service_h service)
+{
+ LogD("enter");
+
+ int ret;
+ char* serviceUri = NULL;
+ ret = service_get_uri(service, &serviceUri);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("no box uri");
+ return std::string();
+ }
+
+ std::string uri(serviceUri);
+ delete[] serviceUri;
+
+ if(uri.compare(0, BOX_SERVICE_SCHEME.size(), BOX_SERVICE_SCHEME)) {
+ // uri is not box-service scheme
+ return std::string();
+ }
+
+ std::string boxId = uri.substr(BOX_SERVICE_SCHEME.size());
+ return boxId;
+}
+
+bool BoxDaemonImpl::isServiceCallerBoxOwner(service_h service)
+{
+ LogD("enter");
+
+ int ret;
+
+ std::string boxId = getBoxIdFromService(service);
+ if (boxId.empty()) {
+ LogD("error box-id");
+ return false;
+ }
+
+ // check if caller is owner of this box
+ const char* appId = web_provider_livebox_get_app_id(boxId.c_str());
+ if (!appId) {
+ return false;
+ }
+ std::string ownerAppId(appId);
+ delete[] appId;
+
+ char* caller = NULL;
+ ret = service_get_caller(service, &caller);
+ if (ret != SERVICE_ERROR_NONE) {
+ ret = service_get_extra_data(
+ service, ALARM_CALLER_KEY.c_str(), &caller);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to get caller's appid from service");
+ return false;
+ }
+ }
+ std::string callerAppId(caller);
+
+ // release strings
+ delete[] caller;
+
+ if (ownerAppId != callerAppId) {
+ LogD("caller is not matched with owner of requested box");
+ return false;
+ }
+
+ return true;
+}
+
+BoxInfoPtr BoxDaemonImpl::handleOperationUpdate(service_h service)
+{
+ LogD("enter");
+
+ if (!isServiceCallerBoxOwner(service)) {
+ return BoxInfoPtr();
+ }
+
+ std::string boxId = getBoxIdFromService(service);
+ if (boxId.empty()) {
+ LogD("error box-id");
+ return BoxInfoPtr();
+ }
+
+ char* contentInfo = NULL;
+ service_get_extra_data(service, CONTENT_INFO_KEY.c_str(), &contentInfo);
+
+ std::string type(getBoxType(boxId.c_str()));
+ if (type.empty()) {
+ LogD("no type for this box");
+ delete[] contentInfo;
+ return BoxInfoPtr();
+ }
+ BoxInfoPtr info = BoxInfoPtr(new BoxInfo(type, boxId, ""));
+ if (contentInfo) {
+ info->contentInfo = std::string(contentInfo);
+ }
+
+ // release string
+ delete[] contentInfo;
+
+ return info;
+}
+
+Eina_Bool BoxDaemonImpl::pingToMasterCallback(void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(data);
+
+ provider_send_ping();
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+void BoxDaemonImpl::requestBoxJobCallback(void* data)
+{
+ JobInfo* jobInfo = static_cast<JobInfo*>(data);
+ if (!jobInfo) {
+ LogD("no information for job");
+ return;
+ }
+
+ // just for debugging
+ //volatile int flag = 0;
+ //while(flag == 0) {;}
+
+ // request box job!
+ jobInfo->daemonImpl->m_pluginConnector->requestCommand(
+ jobInfo->cmdType, jobInfo->boxInfo);
+
+ delete jobInfo;
+}
+
+int BoxDaemonImpl::requestChangeLanguageCallback(void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = BoxInfoPtr(new BoxInfo());
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CHANGE_LANGUAGE, info, This);
+
+ ecore_job_add(requestBoxJobCallback, jobInfo);
+ return 0;
+}
+
+int BoxDaemonImpl::requestChangeRegionCallback(void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = BoxInfoPtr(new BoxInfo());
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CHANGE_LANGUAGE, info, This);
+
+ ecore_job_add(requestBoxJobCallback, jobInfo);
+ return 0;
+}
+int BoxDaemonImpl::requestLowMemoryCallback(void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(data);
+
+ // terminate box daemon and revive
+ elm_exit();
+ return 0;
+}
+
+void BoxDaemonImpl::requestChangeFontCallback(keynode_t* key, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(key);
+
+ char* fontstr = vconf_get_str("db/setting/accessibility/font_name");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = BoxInfoPtr(new BoxInfo());
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CHANGE_LANGUAGE, info, This);
+
+ free(fontstr);
+ ecore_job_add(requestBoxJobCallback, jobInfo);
+}
+
+void BoxDaemonImpl::requestChangeTimeCallback(keynode_t* key, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(key);
+
+ char* timestr = vconf_get_str(VCONFKEY_SYSTEM_TIME_CHANGED);
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = BoxInfoPtr(new BoxInfo());
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CHANGE_LANGUAGE, info, This);
+
+ free(timestr);
+ ecore_job_add(requestBoxJobCallback, jobInfo);
+}
diff --git a/src_mobile/Daemon/BoxDaemonImpl.h b/src_mobile/Daemon/BoxDaemonImpl.h
new file mode 100644
index 0000000..9ee5e10
--- /dev/null
+++ b/src_mobile/Daemon/BoxDaemonImpl.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxDaemonImpl.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_DAEMON_IMPL_H
+#define BOX_DAEMON_IMPL_H
+
+#include <string>
+#include <memory>
+#include <app.h>
+#include <provider.h>
+#include <Eina.h>
+#include <Ecore.h>
+#include <Plugin/box_plugin_interface.h>
+#include <Core/BoxData.h>
+#include <vconf.h>
+
+// forward declaration
+class IBoxManager;
+class IBoxPluginConnector;
+
+class BoxDaemonImpl {
+ public:
+ bool start(std::string& name);
+ bool stop();
+ bool handleAppService(service_h service);
+
+ public:
+ explicit BoxDaemonImpl();
+ ~BoxDaemonImpl();
+
+ private:
+ // type definition
+ typedef struct event_arg ProviderEventArg;
+ typedef ProviderEventArg* ProviderEventArgPtr;
+ typedef struct event_handler ProviderCallbacks;
+ typedef ProviderCallbacks* ProviderCallbacksPtr;
+
+ // livebox's provider callbacks
+ static int connectedCallback(ProviderEventArgPtr arg, void* data);
+ static int disconnectedCallback(ProviderEventArgPtr arg, void* data);
+ static int boxCreateCallback(
+ ProviderEventArgPtr arg,
+ int* width, int* height,
+ double* priority, void* data);
+ static int boxReCreateCallback(ProviderEventArgPtr arg, void* data);
+ static int boxDestroyCallback(ProviderEventArgPtr arg, void* data);
+ static int pdCreateCallback(ProviderEventArgPtr arg, void* data);
+ static int pdDestroyCallback(ProviderEventArgPtr arg, void* data);
+ static int clickedCallback(ProviderEventArgPtr arg, void* data);
+ static int boxResizeCallback(ProviderEventArgPtr arg, void* data);
+ static int boxPauseCallback(ProviderEventArgPtr arg, void* data);
+ static int boxResumeCallback(ProviderEventArgPtr arg, void* data);
+ static int pauseCallback(ProviderEventArgPtr arg, void* data);
+ static int resumeCallback(ProviderEventArgPtr arg, void* data);
+ static int boxPeriodChangeCallback(ProviderEventArgPtr arg, void* data);
+ static int boxUpdateCallback(ProviderEventArgPtr arg, void* data);
+ // callback for app-core event
+ static int requestChangeLanguageCallback(void* data);
+ static int requestChangeRegionCallback(void* data);
+ static int requestLowMemoryCallback(void* data);
+ // callback for vconf event
+ static void requestChangeFontCallback(keynode_t* key, void* data);
+ static void requestChangeTimeCallback(keynode_t* key, void* data);
+ // common private functions
+ void setProviderCallbacks(ProviderCallbacks& callbacks);
+ std::string getBoxType(const char* boxId);
+ BoxInfoPtr initializeBoxInfo(ProviderEventArgPtr arg);
+
+ // functions for handling appcontrol per operation
+ std::string getBoxIdFromService(service_h service);
+ bool isServiceCallerBoxOwner(service_h service);
+ BoxInfoPtr handleOperationUpdate(service_h service);
+
+ // callback for ping to master daemon
+ static Eina_Bool pingToMasterCallback(void* data);
+
+ // callback for requested jobs of boxes
+ static void requestBoxJobCallback(void* data);
+
+ // members
+ std::string m_daemonName;
+ Ecore_Timer* m_pingTimer;
+ std::shared_ptr<IBoxPluginConnector> m_pluginConnector;
+};
+
+struct JobInfo {
+ request_cmd_type cmdType;
+ BoxInfoPtr boxInfo;
+ BoxDaemonImpl* daemonImpl;
+
+ JobInfo(request_cmd_type cmdType,
+ BoxInfoPtr boxInfo,
+ BoxDaemonImpl* daemonImpl) :
+ cmdType(cmdType),
+ boxInfo(boxInfo),
+ daemonImpl(daemonImpl)
+ {
+ };
+};
+
+
+#endif //BOX_DAEMON_IMPL_H
+
diff --git a/src_mobile/Daemon/BoxDaemonUtil.cpp b/src_mobile/Daemon/BoxDaemonUtil.cpp
new file mode 100644
index 0000000..00668a3
--- /dev/null
+++ b/src_mobile/Daemon/BoxDaemonUtil.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxDaemonUtil.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <memory>
+#include <app_service.h>
+#include <Core/Util/Log.h>
+#include <API/web_provider_livebox_info.h>
+#include "BoxDaemonUtil.h"
+
+const std::string BoxDaemonUtil::boxIdKey("box-id");
+const std::string BoxDaemonUtil::instanceIdKey("instance-id");
+
+bool BoxDaemonUtil::launchApplication(std::string& boxId, std::string& instanceId)
+{
+ LogD("enter");
+
+ std::shared_ptr<const char> appId(web_provider_livebox_get_app_id(boxId.c_str()));
+ if (!appId) {
+ LogD("no appid of %s", boxId.c_str());
+ return false;
+ }
+
+ service_h handle = NULL;
+ int ret = SERVICE_ERROR_NONE;
+
+ ret = service_create(&handle);
+ if (ret != SERVICE_ERROR_NONE && !handle) {
+ LogD("failed to create service");
+ return false;
+ }
+
+ ret = service_set_package(handle, appId.get());
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to set package");
+ service_destroy(handle);
+ return false;
+ }
+
+ service_add_extra_data(handle, boxIdKey.c_str(), boxId.c_str());
+ service_add_extra_data(handle, instanceIdKey.c_str(), instanceId.c_str());
+
+ ret = service_send_launch_request(handle, NULL, NULL);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to launch package");
+ service_destroy(handle);
+ return false;
+ }
+
+ service_destroy(handle);
+ LogD("success to launch app of %s", boxId.c_str());
+
+ return true;
+}
diff --git a/src_mobile/Daemon/BoxDaemonUtil.h b/src_mobile/Daemon/BoxDaemonUtil.h
new file mode 100644
index 0000000..0f0406f
--- /dev/null
+++ b/src_mobile/Daemon/BoxDaemonUtil.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxDaemonUtil.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_DAEMON_UTIL_H
+#define BOX_DAEMON_UTIL_H
+
+#include <string>
+
+class BoxDaemonUtil {
+ public:
+ static bool launchApplication(std::string& boxId, std::string& instanceId);
+
+ private:
+ static const std::string boxIdKey;
+ static const std::string instanceIdKey;
+
+};
+
+#endif // BOX_DAEMON_UTIL_H
diff --git a/src_mobile/Daemon/CMakeLists.txt b/src_mobile/Daemon/CMakeLists.txt
new file mode 100644
index 0000000..589c422
--- /dev/null
+++ b/src_mobile/Daemon/CMakeLists.txt
@@ -0,0 +1,66 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_DAEMON})
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ aul
+ bundle
+ appcore-efl
+ elementary
+ ecore-x
+ provider
+ livebox-service
+ capi-appfw-application
+ dlog
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxDaemon.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxDaemonImpl.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxDaemonUtil.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_EXECUTABLE(${TARGET_NAME} ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LDFLAGS} "-ldl -lcap"
+ ${${DEPS}_LIBRARIES}
+ ${TARGET_PLUGIN}
+ ${TARGET_CORE}
+ ${TARGET_API}
+)
+
+INSTALL(TARGETS ${TARGET_NAME}
+ DESTINATION /usr/apps/livebox.${PROJECT_NAME}/bin
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
diff --git a/src_mobile/Daemon/main.cpp b/src_mobile/Daemon/main.cpp
new file mode 100755
index 0000000..1b8863d
--- /dev/null
+++ b/src_mobile/Daemon/main.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 main.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/capability.h>
+#include <Elementary.h>
+#include <aul.h>
+#include <app.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "BoxDaemon.h"
+
+
+// declarations
+static BoxDaemon boxDaemon;
+static bool isDaemonReleased = false;
+
+static void atExitCallback()
+{
+ LogD("enter");
+ if (isDaemonReleased) {
+ return;
+ }
+
+ // this callback is called due to abnormal exit()
+ LogD("release daemon resources explicitly");
+ boxDaemon.stop();
+}
+
+static bool appCreateCallback(void *data)
+{
+ LogD("app create");
+ UNUSED_PARAM(data);
+
+ elm_config_preferred_engine_set("software_x11");
+ return true;
+}
+
+static void appTerminateCallback(void *data)
+{
+ BoxDaemon *boxDaemon = static_cast<BoxDaemon *>(data);
+ boxDaemon->stop();
+ isDaemonReleased = true;
+}
+
+static void appPauseCallback(void *data)
+{
+ LogD("app pasue");
+}
+
+static void appResumeCallback(void *data)
+{
+ LogD("app resume");
+}
+
+static void appServiceCallback(service_h service, void *data)
+{
+ LogD("app service");
+
+ int ret;
+ char* name;
+
+ BoxDaemon *boxDaemon = static_cast<BoxDaemon*>(data);
+ ret = service_get_extra_data(service, "name", &name);
+
+ // check if web-provider is launched, or not
+ if (ret == SERVICE_ERROR_NONE) {
+ std::string daemonName(name);
+ if(!(boxDaemon->start(daemonName))) {
+ LogD("daemon failed to start");
+ elm_exit();
+ }
+ atexit(atExitCallback);
+ return;
+ }
+
+ boxDaemon->handleAppService(service);
+}
+
+static bool grantProcessCapability()
+{
+ cap_user_header_t header;
+ cap_user_data_t data;
+
+ header = static_cast<cap_user_header_t>(malloc(sizeof(*header)));
+ data = static_cast<cap_user_data_t>(calloc(sizeof(*data), _LINUX_CAPABILITY_U32S_3));
+
+ header->pid = getpid();
+ header->version = _LINUX_CAPABILITY_VERSION_3;
+
+ // read already granted capabilities of this process
+ if (capget(header, data) < 0) {
+ LogD("capget error");
+ free(header);
+ free(data);
+ return false;
+ }
+
+ // set only inheritable bit for CAP_MAC_ADMIN to '1'
+ data[CAP_TO_INDEX(CAP_MAC_ADMIN)].inheritable |= CAP_TO_MASK(CAP_MAC_ADMIN);
+
+ // remove capabilities not needed any more
+ data[CAP_TO_INDEX(CAP_MAC_ADMIN)].permitted &= ~CAP_TO_MASK(CAP_MAC_ADMIN);
+ data[CAP_TO_INDEX(CAP_MAC_ADMIN)].effective &= ~CAP_TO_MASK(CAP_MAC_ADMIN);
+ data[CAP_TO_INDEX(CAP_SETPCAP)].permitted &= ~CAP_TO_MASK(CAP_SETPCAP);
+ data[CAP_TO_INDEX(CAP_SETPCAP)].effective &= ~CAP_TO_MASK(CAP_SETPCAP);
+
+ bool ret = true;
+ if (capset(header, data) < 0) {
+ LogD("capset error");
+ ret = false;
+ }
+
+ free(header);
+ free(data);
+
+ return ret;
+}
+
+int main (int argc, char *argv[])
+{
+ // set inheritable bit for CAP_MAC_ADMIN
+ // so that WebProcess will have CAP_MAC_ADMIN capability
+ if (!grantProcessCapability()) {
+ return -1;
+ }
+
+ // set the appcore callbacks
+ app_event_callback_s ops;
+ memset(&ops, 0x00, sizeof(app_event_callback_s));
+ ops.create = appCreateCallback;
+ ops.terminate = appTerminateCallback;
+ ops.pause = appPauseCallback;
+ ops.resume = appResumeCallback;
+ ops.service = appServiceCallback;
+
+ // start appcore
+ int ret = app_efl_main(&argc, &argv, &ops, &boxDaemon);
+ return ret;
+}
diff --git a/src_mobile/Plugin/AppBoxPlugin/AppBoxManager.cpp b/src_mobile/Plugin/AppBoxPlugin/AppBoxManager.cpp
new file mode 100755
index 0000000..6285b5c
--- /dev/null
+++ b/src_mobile/Plugin/AppBoxPlugin/AppBoxManager.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxManager.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <map>
+#include <ail.h>
+#include <ewk_context.h>
+#include <core_module.h>
+#include <Plugin/IBoxPluginFactory.h>
+#include <Core/BoxData.h>
+#include <Core/BoxManager.h>
+#include <Core/IBox.h>
+#include <Core/Util/Log.h>
+#include <API/web_provider_livebox_info.h>
+#include "AppBoxObserver.h"
+#include "AppBoxManager.h"
+
+static const std::string bundlePath("/usr/lib/libwrt-injected-bundle.so");
+
+AppBoxManager::AppBoxManager(IBoxPluginFactoryPtr factory)
+ : BoxManager(factory)
+{
+ bool ret = WRT::CoreModuleSingleton::Instance().Init();
+ if (!ret) {
+ throw; // throw exeception
+ }
+ AppBoxObserver::Instance()->initialize();
+}
+
+AppBoxManager::~AppBoxManager()
+{
+ AppBoxObserver::Instance()->shutdown();
+}
+
+bool AppBoxManager::requestAddBox(BoxInfoPtr boxInfo, EwkContextPtr ewkContext)
+{
+
+ const char* appId =
+ web_provider_livebox_get_app_id(boxInfo->boxId.c_str());
+
+ if (!appId) {
+ LogD("no appid of %s", boxInfo->boxId.c_str());
+ return false;
+ }
+
+ std::string appIdStr(appId);
+ delete appId;
+
+ auto it = m_ewkContextMap.find(appIdStr);
+ if (it == m_ewkContextMap.end()) {
+ ewkContext = getAvailableEwkContext(appIdStr);
+ insertContextMap(appIdStr, ewkContext);
+ } else {
+ ewkContext = it->second;
+ }
+
+ if (!BoxManager::requestAddBox(boxInfo, ewkContext)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool AppBoxManager::requestRemoveBox(std::string& instanceId)
+{
+ if (!BoxManager::requestRemoveBox(instanceId)) {
+ return false;
+ }
+
+ return true;
+}
+
+EwkContextPtr AppBoxManager::getAvailableEwkContext(const std::string& appId)
+{
+
+ // get the base executable path
+ std::string baseExecutablePath = getBaseExecutablePath(appId);
+ if (baseExecutablePath.empty()) {
+ return EwkContextPtr();
+ }
+
+ // get web process path for this box
+ std::string webProcessPath = baseExecutablePath + ".d-box";
+
+ // get plugin process path for this box
+ std::string pluginProcessPath = baseExecutablePath + ".npruntime";
+
+ // box manager should set webprocess path as value of 'WEB_PROCESS_PATH'
+ // before calling ewk_context_new_with_injected_bundle_path().
+ setenv("WEB_PROCESS_EXECUTABLE_PATH", webProcessPath.c_str(), 1);
+ setenv("PLUGIN_PROCESS_EXECUTABLE_PATH", pluginProcessPath.c_str(), 1);
+
+ EwkContextPtr newEwkContext(
+ ewk_context_new_with_injected_bundle_path(bundlePath.c_str()),
+ BoxManager::EwkContextDeleter());
+
+ // unset the following env variables not to affect other ewk context creation
+ unsetenv("WEB_PROCESS_EXECUTABLE_PATH");
+ unsetenv("PLUGIN_PROCESS_EXECUTABLE_PATH");
+
+ return newEwkContext;
+}
+
+void AppBoxManager::insertContextMap(std::string& appId, EwkContextPtr ewkContext)
+{
+ m_ewkContextMap.insert(EwkContextMapPair(appId, ewkContext));
+}
+
+void AppBoxManager::eraseContextMap(std::string& appId)
+{
+ m_ewkContextMap.erase(appId);
+}
+
+std::string AppBoxManager::getBaseExecutablePath(const std::string& appId)
+{
+ ail_error_e ret;
+ ail_appinfo_h handle = NULL;
+
+ char* retStr = NULL;
+ ret = ail_get_appinfo(appId.c_str(), &handle);
+ if (ret != AIL_ERROR_OK) {
+ return std::string();
+ }
+
+ ret = ail_appinfo_get_str(handle, AIL_PROP_X_SLP_EXE_PATH, &retStr);
+ if (ret != AIL_ERROR_OK || !retStr) {
+ return std::string();
+ }
+
+ std::string basePath(retStr);
+
+ ret = ail_destroy_appinfo(handle);
+ if (ret != AIL_ERROR_OK) {
+ return std::string();
+ }
+
+ return basePath;
+}
diff --git a/src_mobile/Plugin/AppBoxPlugin/AppBoxManager.h b/src_mobile/Plugin/AppBoxPlugin/AppBoxManager.h
new file mode 100644
index 0000000..89f942f
--- /dev/null
+++ b/src_mobile/Plugin/AppBoxPlugin/AppBoxManager.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxManager.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef APP_BOX_MANAGER_H
+#define APP_BOX_MANAGER_H
+
+#include <Core/IBox.h>
+#include <Core/IBoxManager.h>
+#include <Core/BoxManager.h>
+#include <Core/BoxData.h>
+#include <Plugin/IBoxPluginFactory.h>
+
+class AppBoxManager: public BoxManager {
+ public:
+ static IBoxManagerPtr create(IBoxPluginFactoryPtr factory)
+ {
+ return IBoxManagerPtr(new AppBoxManager(factory));
+ };
+ ~AppBoxManager();
+
+ private:
+ // BoxManager implementation
+ bool requestAddBox(BoxInfoPtr boxInfo, EwkContextPtr ewkContext);
+ bool requestRemoveBox(std::string& instanceId);
+
+ EwkContextPtr getAvailableEwkContext(const std::string& appId);
+ void insertContextMap(std::string& appId, EwkContextPtr ewkContext);
+ void eraseContextMap(std::string& appId);
+ std::string getBaseExecutablePath(const std::string& appId);
+ explicit AppBoxManager(IBoxPluginFactoryPtr factory);
+
+ // members
+ typedef std::map<std::string, EwkContextPtr> EwkContextMap;
+ typedef std::pair<std::string, EwkContextPtr> EwkContextMapPair;
+ EwkContextMap m_ewkContextMap;
+};
+
+
+#endif // APP_BOX_MANAGER_H
diff --git a/src_mobile/Plugin/AppBoxPlugin/AppBoxObserver.cpp b/src_mobile/Plugin/AppBoxPlugin/AppBoxObserver.cpp
new file mode 100644
index 0000000..45514e8
--- /dev/null
+++ b/src_mobile/Plugin/AppBoxPlugin/AppBoxObserver.cpp
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxObserver.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string>
+#include <map>
+#include <Core/Util/Log.h>
+#include <Elementary.h>
+#include <ewk_view.h>
+#include <ewk_context.h>
+#include "AppBoxRenderView.h"
+#include "AppBoxRenderBuffer.h"
+#include "AppBoxObserver.h"
+
+// static variable intialization
+AppBoxObserver* AppBoxObserver::s_instance = NULL;
+
+static const std::string bundlePath("/usr/lib/libwrt-injected-bundle.so");
+
+AppBoxObserver::AppBoxObserver()
+ : m_initialized(false)
+ , m_renderViewMap()
+ , m_renderBufferMap()
+{
+ LogD("enter");
+ Ewk_Context* ctx = ewk_context_new_with_injected_bundle_path(bundlePath.c_str());
+ m_pdEwkContext.reset(ctx, ewk_context_delete);
+ // create dummy webview to keep PD's WebProcess alive
+ //Evas_Object* win = elm_win_add(NULL, "dummy-win", ELM_WIN_BASIC);
+ //Evas_Object* webview =
+ // ewk_view_add_with_context(evas_object_evas_get(win), m_pdEwkContext.get());
+}
+
+AppBoxObserver::~AppBoxObserver()
+{
+ LogD("enter");
+ if (m_pdEwkContext) {
+ ewk_context_delete(m_pdEwkContext.get());
+ }
+}
+
+AppBoxObserver* AppBoxObserver::Instance()
+{
+ LogD("enter");
+ if (!s_instance) {
+ s_instance = new AppBoxObserver();
+ }
+
+ return s_instance;
+}
+
+void AppBoxObserver::initialize()
+{
+ LogD("enter");
+ if (m_initialized) {
+ LogD("already initialized");
+ return;
+ }
+
+ m_initialized = true;
+}
+
+void AppBoxObserver::shutdown()
+{
+ LogD("enter");
+ if (!m_initialized) {
+ LogD("not yet initialized");
+ return;
+ }
+
+ m_initialized = false;
+}
+
+AppBoxRenderView* AppBoxObserver::getRenderView(std::string instanceId)
+{
+ LogD("enter");
+
+ auto it = m_renderViewMap.find(instanceId);
+ if (it != m_renderViewMap.end()) {
+ LogD("registered: %s (%p)", it->first.c_str(), it->second);
+ return it->second;
+ }
+
+ return NULL;
+}
+
+std::shared_ptr<Ewk_Context> AppBoxObserver::getPdEwkContext()
+{
+ LogD("enter");
+ return m_pdEwkContext;
+}
+
+void AppBoxObserver::registerRenderView(std::string instanceId, AppBoxRenderView* view)
+{
+ LogD("enter");
+
+ if (getRenderView(instanceId)) {
+ LogD("already registered");
+ return;
+ }
+
+ m_renderViewMap.insert(RenderViewMapPair(instanceId, view));
+}
+
+void AppBoxObserver::unregisterRenderView(std::string instanceId)
+{
+ LogD("enter");
+ m_renderViewMap.erase(instanceId);
+}
+
+AppBoxRenderBuffer* AppBoxObserver::getRenderBuffer(std::string instanceId)
+{
+ LogD("enter");
+
+ auto it = m_renderBufferMap.find(instanceId);
+ if (it != m_renderBufferMap.end()) {
+ LogD("registered: %s (%p)", it->first.c_str(), it->second);
+ return it->second;
+ }
+
+ return NULL;
+}
+
+void AppBoxObserver::registerRenderBuffer(std::string instanceId, AppBoxRenderBuffer* buffer)
+{
+ LogD("enter");
+
+ if (getRenderBuffer(instanceId)) {
+ LogD("already registered");
+ return;
+ }
+
+ m_renderBufferMap.insert(RenderBufferMapPair(instanceId, buffer));
+}
+
+void AppBoxObserver::unregisterRenderBuffer(std::string instanceId)
+{
+ LogD("enter");
+ m_renderBufferMap.erase(instanceId);
+}
diff --git a/src_mobile/Plugin/AppBoxPlugin/AppBoxObserver.h b/src_mobile/Plugin/AppBoxPlugin/AppBoxObserver.h
new file mode 100644
index 0000000..8042f33
--- /dev/null
+++ b/src_mobile/Plugin/AppBoxPlugin/AppBoxObserver.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxObserver.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef APP_BOX_OBSERVER_H
+#define APP_BOX_OBSERVER_H
+
+#include <string>
+#include <map>
+#include <memory>
+
+class AppBoxRenderView;
+class AppBoxRenderBuffer;
+
+class AppBoxObserver {
+ public:
+ static AppBoxObserver* Instance();
+ void initialize();
+ void shutdown();
+ void registerRenderView(std::string instanceId, AppBoxRenderView* view);
+ void unregisterRenderView(std::string instanceId);
+ void registerRenderBuffer(std::string instanceId, AppBoxRenderBuffer* view);
+ void unregisterRenderBuffer(std::string instanceId);
+ AppBoxRenderView* getRenderView(std::string instanceId);
+ AppBoxRenderBuffer* getRenderBuffer(std::string instanceId);
+ std::shared_ptr<Ewk_Context> getPdEwkContext();
+
+ private:
+ AppBoxObserver();
+ ~AppBoxObserver();
+
+ typedef std::map<std::string, AppBoxRenderView*> RenderViewMap;
+ typedef std::pair<std::string, AppBoxRenderView*> RenderViewMapPair;
+ typedef std::map<std::string, AppBoxRenderBuffer*> RenderBufferMap;
+ typedef std::pair<std::string, AppBoxRenderBuffer*> RenderBufferMapPair;
+
+ bool m_initialized;
+ RenderViewMap m_renderViewMap;
+ RenderBufferMap m_renderBufferMap;
+ std::shared_ptr<Ewk_Context> m_pdEwkContext;
+ static AppBoxObserver* s_instance;
+};
+
+#endif //APP_BOX_OBSERVER_H
diff --git a/src_mobile/Plugin/AppBoxPlugin/AppBoxPdHelper.cpp b/src_mobile/Plugin/AppBoxPlugin/AppBoxPdHelper.cpp
new file mode 100644
index 0000000..46e0fb9
--- /dev/null
+++ b/src_mobile/Plugin/AppBoxPlugin/AppBoxPdHelper.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxPdHelper.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <Evas.h>
+#include <ewk_view.h>
+#include <Core/Util/Log.h>
+#include "AppBoxPdHelper.h"
+
+AppBoxPdHelper::AppBoxPdHelper(Evas_Object* pdWin)
+ : m_win(pdWin)
+ , m_boxWebView()
+ , m_pdWebView()
+ , m_opened(false)
+{
+}
+
+AppBoxPdHelper::~AppBoxPdHelper()
+{
+}
+
+void AppBoxPdHelper::startOpen()
+{
+ LogD("enter");
+}
+
+void AppBoxPdHelper::finishOpen(Evas_Object* child)
+{
+ LogD("enter");
+ m_opened = true;
+ setPdWebView(child);
+}
+
+void AppBoxPdHelper::close()
+{
+ LogD("enter");
+}
+
+void AppBoxPdHelper::setBoxWebView(Evas_Object* webview)
+{
+ LogD("enter");
+ m_boxWebView = webview;
+}
+
+void AppBoxPdHelper::setPdWebView(Evas_Object* webview)
+{
+ LogD("enter");
+ m_pdWebView = webview;
+}
+
+Evas_Object* AppBoxPdHelper::getBoxWebView() const
+{
+ LogD("enter");
+ return m_boxWebView;
+}
+
+Evas_Object* AppBoxPdHelper::getPdWebView() const
+{
+ LogD("enter");
+ return m_pdWebView;
+}
+
+Evas* AppBoxPdHelper::getPdCanvas() const
+{
+ LogD("enter");
+ return evas_object_evas_get(m_win);
+}
+
+bool AppBoxPdHelper::isPdOpened() const
+{
+ LogD("enter");
+ return m_opened;
+}
diff --git a/src_mobile/Plugin/AppBoxPlugin/AppBoxPdHelper.h b/src_mobile/Plugin/AppBoxPlugin/AppBoxPdHelper.h
new file mode 100644
index 0000000..ae49863
--- /dev/null
+++ b/src_mobile/Plugin/AppBoxPlugin/AppBoxPdHelper.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxPdHelper.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#ifndef APP_BOX_PD_HELPER_H
+#define APP_BOX_PD_HELPER_H
+
+#include <string>
+#include <Evas.h>
+#include <Core/View/IPdHelper.h>
+
+class AppBoxPdHelper: public IPdHelper {
+ public:
+ static IPdHelperPtr create(Evas_Object* pdWin)
+ {
+ return IPdHelperPtr(new AppBoxPdHelper(pdWin));
+ }
+ virtual void startOpen();
+ virtual void finishOpen(Evas_Object* child);
+ virtual void close();
+ virtual void setBoxWebView(Evas_Object* webview);
+ virtual void setPdWebView(Evas_Object* webview);
+ virtual Evas_Object* getBoxWebView() const;
+ virtual Evas_Object* getPdWebView() const;
+ virtual Evas* getPdCanvas() const;
+ virtual bool isPdOpened() const;
+ virtual ~AppBoxPdHelper();
+
+ private:
+ AppBoxPdHelper(Evas_Object* pdWin);
+
+ //members
+ Evas_Object* m_win;
+ Evas_Object* m_boxWebView;
+ Evas_Object* m_pdWebView;
+ bool m_opened;
+};
+
+#endif // APP_BOX_PD_HELPER_H
diff --git a/src_mobile/Plugin/AppBoxPlugin/AppBoxPluginFactory.cpp b/src_mobile/Plugin/AppBoxPlugin/AppBoxPluginFactory.cpp
new file mode 100644
index 0000000..8f0bfb2
--- /dev/null
+++ b/src_mobile/Plugin/AppBoxPlugin/AppBoxPluginFactory.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxPluginFactory.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <memory>
+#include <Core/View/IRenderView.h>
+#include <Core/Buffer/IRenderBuffer.h>
+#include "AppBoxRenderView.h"
+#include "AppBoxRenderBuffer.h"
+#include "AppBoxPluginFactory.h"
+
+IRenderViewPtr AppBoxPluginFactory::createRenderView(
+ std::string boxId, std::string instanceId,
+ std::shared_ptr<Ewk_Context> ewkContext)
+{
+ return AppBoxRenderView::create(boxId, instanceId, ewkContext);
+}
+
+IRenderBufferPtr AppBoxPluginFactory::createBoxRenderBuffer(
+ std::string boxId, std::string instanceId,
+ int width, int height, std::string data)
+{
+ // use appbox render buffer
+ return AppBoxRenderBuffer::create(boxId, instanceId, width, height, data);
+}
diff --git a/src_mobile/Plugin/AppBoxPlugin/AppBoxPluginFactory.h b/src_mobile/Plugin/AppBoxPlugin/AppBoxPluginFactory.h
new file mode 100644
index 0000000..ca5a5f2
--- /dev/null
+++ b/src_mobile/Plugin/AppBoxPlugin/AppBoxPluginFactory.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxPluginFactory.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef APP_BOX_PLUGIN_FACTORY_H
+#define APP_BOX_PLUGIN_FACTORY_H
+
+#include <string>
+#include <memory>
+#include <Plugin/IBoxPluginFactory.h>
+#include <Core/View/IRenderView.h>
+#include <Core/Buffer/IRenderBuffer.h>
+#include <ewk_context.h>
+#include <Evas.h>
+
+class AppBoxPluginFactory: public IBoxPluginFactory {
+ public:
+ IRenderViewPtr createRenderView(
+ std::string boxId, std::string instanceId,
+ std::shared_ptr<Ewk_Context> ewkContext);
+
+ IRenderBufferPtr createBoxRenderBuffer(
+ std::string boxId, std::string instanceId,
+ int width, int height, std::string data);
+
+ AppBoxPluginFactory() {};
+ ~AppBoxPluginFactory() {};
+};
+
+#endif //APP_BOX_PLUGIN_FACTORY_H
diff --git a/src_mobile/Plugin/AppBoxPlugin/AppBoxRenderBuffer.cpp b/src_mobile/Plugin/AppBoxPlugin/AppBoxRenderBuffer.cpp
new file mode 100644
index 0000000..f0c0ae0
--- /dev/null
+++ b/src_mobile/Plugin/AppBoxPlugin/AppBoxRenderBuffer.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxRenderBuffer.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <API/web_provider_livebox_info.h>
+#include <Core/Buffer/RenderBuffer.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "AppBoxRenderView.h"
+#include "AppBoxRenderBuffer.h"
+#include "AppBoxObserver.h"
+
+#define MAX_WAIT_TIME 5.0
+
+AppBoxRenderBuffer::AppBoxRenderBuffer(
+ std::string boxId, std::string instanceId,
+ int width, int height, std::string data)
+ : BoxRenderBuffer(boxId, instanceId, width, height)
+ , m_boxId(boxId)
+ , m_instanceId(instanceId)
+ , m_mouseEventRecievable(false)
+ , m_touchTimer()
+ , m_renderView()
+{
+ LogD("enter");
+ UNUSED_PARAM(data);
+
+ if (web_provider_livebox_get_mouse_event(m_boxId.c_str())) {
+ m_mouseEventRecievable = true;
+ }
+
+ AppBoxObserver::Instance()->registerRenderBuffer(m_instanceId, this);
+}
+
+AppBoxRenderBuffer::~AppBoxRenderBuffer()
+{
+ LogD("enter");
+ AppBoxObserver::Instance()->unregisterRenderBuffer(m_instanceId);
+}
+
+void AppBoxRenderBuffer::didHandleTouchEvent(
+ TouchType type, double timestamp, double x, double y)
+{
+ LogD("enter");
+ if (!m_mouseEventRecievable) {
+ return;
+ }
+
+ m_renderView = AppBoxObserver::Instance()->getRenderView(m_instanceId);
+
+ if (!m_renderView || !(m_renderView->m_boxWrt)) {
+ LogD("no matched render view");
+ return;
+ }
+
+ // if needed, resume render view
+ if (m_renderView->m_fireRenderTimer) {
+ m_renderView->deleteTimer(&(m_renderView->m_fireRenderTimer));
+ } else {
+ if (!m_touchTimer) {
+ startCanvasUpdate();
+
+ // temp condition
+ if (m_renderView->m_boxWrt_isSuspended == true)
+ {
+ m_renderView->m_boxWrt_isSuspended = false;
+ m_renderView->m_boxWrt->Resume();
+ }
+ } else {
+ deleteTouchTimer();
+ }
+ }
+
+ BoxRenderBuffer::didHandleTouchEvent(type, timestamp, x, y);
+ m_touchTimer = ecore_timer_add(MAX_WAIT_TIME, fireTouchTimerCallback, this);
+}
+
+void AppBoxRenderBuffer::deleteTouchTimer()
+{
+ LogD("enter");
+ if (m_touchTimer) {
+ ecore_timer_del(m_touchTimer);
+ m_touchTimer = NULL;
+ }
+}
+
+Eina_Bool AppBoxRenderBuffer::fireTouchTimerCallback(void* data)
+{
+ LogD("enter");
+ AppBoxRenderBuffer* This = static_cast<AppBoxRenderBuffer*>(data);
+ This->stopCanvasUpdate();
+
+ // temp condition
+ if (This->m_renderView->m_boxWrt_isSuspended == false)
+ {
+ This->m_renderView->m_boxWrt_isSuspended = true;
+ This->m_renderView->m_boxWrt->Suspend();
+ }
+
+ This->m_touchTimer = NULL;
+
+ return ECORE_CALLBACK_CANCEL;
+}
diff --git a/src_mobile/Plugin/AppBoxPlugin/AppBoxRenderBuffer.h b/src_mobile/Plugin/AppBoxPlugin/AppBoxRenderBuffer.h
new file mode 100644
index 0000000..ba8462a
--- /dev/null
+++ b/src_mobile/Plugin/AppBoxPlugin/AppBoxRenderBuffer.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxRenderBuffer.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef APP_BOX_RENDER_BUFFER_H
+#define APP_BOX_RENDER_BUFFER_H
+
+#include <string.h>
+#include <Core/Buffer/BoxRenderBuffer.h>
+
+struct _Ecore_Timer;
+typedef _Ecore_Timer Ecore_Timer;
+
+class AppBoxRenderBuffer: public BoxRenderBuffer {
+ public:
+ static IRenderBufferPtr create(
+ std::string boxId, std::string instanceId,
+ int width, int height, std::string data)
+ {
+ return IRenderBufferPtr(new AppBoxRenderBuffer(
+ boxId, instanceId, width, height, data));
+ }
+ ~AppBoxRenderBuffer();
+
+ private:
+ void didHandleTouchEvent(
+ TouchType type, double timestamp, double x, double y);
+ void deleteTouchTimer();
+ static Eina_Bool fireTouchTimerCallback(void* data);
+
+ AppBoxRenderBuffer(
+ std::string boxId, std::string instanceId,
+ int width, int height, std::string data);
+
+ // members
+ std::string m_boxId;
+ std::string m_instanceId;
+ bool m_mouseEventRecievable;
+ Ecore_Timer* m_touchTimer;
+ AppBoxRenderView* m_renderView;
+
+ friend class AppBoxRenderView;
+};
+
+#endif // APP_BOX_RENDER_BUFFER_H
diff --git a/src_mobile/Plugin/AppBoxPlugin/AppBoxRenderView.cpp b/src_mobile/Plugin/AppBoxPlugin/AppBoxRenderView.cpp
new file mode 100755
index 0000000..891e5bb
--- /dev/null
+++ b/src_mobile/Plugin/AppBoxPlugin/AppBoxRenderView.cpp
@@ -0,0 +1,683 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxRenderView.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <sys/types.h>
+#include <unistd.h>
+#include <string>
+#include <fstream>
+#include <streambuf>
+#include <aul.h>
+#include <Eina.h>
+#include <Evas.h>
+#include <Ecore.h>
+#include <EWebKit2.h>
+#include <ewk_view.h>
+#include <ewk_context.h>
+#include <ewk_settings.h>
+#include <livebox-service.h>
+#include <i_runnable_widget_object.h>
+#include <core_module.h>
+#include <dpl/fast_delegate.h>
+#include <Core/BoxSchemeHandler.h>
+#include <Core/View/IRenderView.h>
+#include <Core/View/IPdHelper.h>
+#include <Core/View/PdHelper.h>
+#include <API/web_provider_livebox_info.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "AppBoxObserver.h"
+#include "AppBoxRenderBuffer.h"
+#include "AppBoxPdHelper.h"
+#include "AppBoxRenderView.h"
+
+#define RENDER_MAX_TIME 30.0
+#define SNAPSHOT_REMOVE_TIME 1.0
+#define WEB_DBOX_OBJ_MOVE_TO_OUTSIDE_POINT_VALUE -10000
+
+// injection javascript file regarding creating js object used by box and pd
+static const std::string injectionFile("/usr/share/web-provider/injection.js");
+
+AppBoxRenderView::AppBoxRenderView(
+ std::string boxId, std::string instanceId,
+ EwkContextPtr ewkContext)
+ : m_appId()
+ , m_boxId(boxId)
+ , m_instanceId(instanceId)
+ , m_ewkContext(ewkContext)
+ , m_boxRenderInfo()
+ , m_boxWrt()
+ , m_pdWrt()
+ , m_snapshot()
+ , m_fireRenderTimer()
+ , m_removeSnapShotTimer()
+ , m_pdHelper()
+ , m_boxRenderBuffer()
+ , m_pdFastOpen(false)
+ , m_boxFinishLoad(false)
+ , m_boxFrameRendered(false)
+ , m_boxWrt_isSuspended(false)
+{
+ LogD("enter");
+ m_appId = getAppId(m_boxId);
+ if (m_appId.empty()) {
+ throw; //exception throw!
+ }
+
+ m_boxRenderBuffer = AppBoxObserver::Instance()->getRenderBuffer(m_instanceId);
+
+ // use fastopen to default
+ // m_pdFastOpen = web_provider_livebox_get_pd_fast_open(m_boxId.c_str()) ? true : false;
+ m_pdFastOpen = true;
+ AppBoxObserver::Instance()->registerRenderView(m_instanceId, this);
+}
+
+AppBoxRenderView::~AppBoxRenderView()
+{
+ LogD("enter");
+
+ destroyWrtCore(m_boxWrt);
+ destroyWrtCore(m_pdWrt);
+ AppBoxObserver::Instance()->unregisterRenderView(m_instanceId);
+}
+
+void AppBoxRenderView::showBox(RenderInfoPtr boxRenderInfo)
+{
+ LogD("enter");
+
+ // stop updating render buffer
+ m_boxRenderBuffer->stopCanvasUpdate();
+
+ // clear snapshot if this is not the case of pd open
+ if (!m_pdHelper) {
+ clearSnapShot();
+ }
+
+ // delete already running timer
+ deleteTimer(&m_fireRenderTimer);
+
+ // delete touch timer
+ if (web_provider_livebox_get_mouse_event(m_boxId.c_str())) {
+ m_boxRenderBuffer->deleteTouchTimer();
+ }
+
+ // set boxFinishLoad and m_boxFrameRendered to false
+ m_boxFinishLoad = false;
+ m_boxFrameRendered = false;
+
+ // copy to url
+ std::string boxStartUrl = getStartUrl(URL_TYPE_BOX, boxRenderInfo->defaultUrlParams);
+ if (m_boxWrt) {
+ LogD("existing wrt core is removed");
+ destroyBoxWrtCore();
+ }
+
+ m_boxWrt = createWrtCore(
+ URL_TYPE_BOX, boxStartUrl,
+ boxRenderInfo->window, m_ewkContext);
+ m_boxWrt_isSuspended = false;
+
+ // in case of showing box by request of pd open
+ if (m_pdHelper) {
+ m_pdHelper->setBoxWebView(m_boxWrt->GetCurrentWebview());
+ }
+
+ // resize webview fitted to width, height of Box
+ evas_object_resize(
+ m_boxWrt->GetCurrentWebview(),
+ boxRenderInfo->width,
+ boxRenderInfo->height);
+
+
+ evas_object_show(m_boxWrt->GetCurrentWebview());
+ // webview window move to outside of viewport because of overlap issue with snapshot image
+ evas_object_move(m_boxWrt->GetCurrentWebview(), WEB_DBOX_OBJ_MOVE_TO_OUTSIDE_POINT_VALUE, WEB_DBOX_OBJ_MOVE_TO_OUTSIDE_POINT_VALUE);
+
+ m_boxWrt->Show();
+ m_boxRenderInfo = boxRenderInfo;
+}
+
+AppBoxRenderView::WrtCorePtr AppBoxRenderView::createWrtCore(
+ UrlType type, std::string& startUrl,
+ Evas_Object* win, EwkContextPtr ewkContext)
+{
+ LogD("enter");
+
+ WrtCorePtr wrt;
+ wrt = WRT::CoreModuleSingleton::
+ Instance().getRunnableWidgetObject(m_appId);
+ // prepare webview
+ if (startUrl.empty()) {
+ LogD("no start url");
+ return WrtCorePtr();
+ }
+ wrt->PrepareView(startUrl, win, ewkContext.get());
+ wrt->CheckBeforeLaunch();
+
+ // set callback functions of RunnableWidgetObject
+ WRT::UserDelegatesPtr cbs(new WRT::UserDelegates);
+ cbs->loadStart = DPL::MakeDelegate(this, &AppBoxRenderView::startLoadCallback);
+ if (type == URL_TYPE_BOX) {
+ cbs->loadFinish = DPL::MakeDelegate(this, &AppBoxRenderView::finishBoxLoadCallback);
+ } else {
+ cbs->loadFinish = DPL::MakeDelegate(this, &AppBoxRenderView::finishPdLoadCallback);
+ }
+
+ cbs->bufferSet = DPL::MakeDelegate(this, &AppBoxRenderView::setBufferCallback);
+ cbs->bufferUnset = DPL::MakeDelegate(this, &AppBoxRenderView::unsetBufferCallback);
+ if (!m_pdFastOpen) {
+ cbs->windowCreateBefore =
+ DPL::MakeDelegate(this, &AppBoxRenderView::createWindowBeforeCallback);
+ cbs->windowCreateAfter =
+ DPL::MakeDelegate(this, &AppBoxRenderView::createWindowAfterCallback);
+ }
+
+ cbs->navigationDecide =
+ DPL::MakeDelegate(this, &AppBoxRenderView::decideNavigationCallback);
+ cbs->webCrash = DPL::MakeDelegate(this, &AppBoxRenderView::crashWebProcessCallback);
+ wrt->SetUserDelegates(cbs);
+
+ // set basic webview setting
+ setWebViewBasicSetting(wrt->GetCurrentWebview());
+ return wrt;
+}
+
+void AppBoxRenderView::destroyBoxWrtCore()
+{
+ LogD("enter");
+
+ m_boxRenderBuffer->stopCanvasUpdate();
+ deleteTimer(&m_fireRenderTimer);
+ deleteTimer(&m_removeSnapShotTimer);
+ destroyWrtCore(m_boxWrt);
+ m_boxWrt.reset();
+
+ // temp
+ m_boxWrt_isSuspended = false;
+}
+
+void AppBoxRenderView::destroyPdWrtCore()
+{
+ LogD("enter");
+
+ destroyWrtCore(m_pdWrt);
+ m_pdWrt.reset();
+}
+
+void AppBoxRenderView::destroyWrtCore(WrtCorePtr wrt)
+{
+ LogD("enter");
+
+ if (wrt) {
+ wrt->Hide();
+ }
+}
+
+void AppBoxRenderView::hideBox()
+{
+ LogD("enter");
+ destroyBoxWrtCore();
+ if (m_boxRenderInfo->window) {
+ evas_object_hide(m_boxRenderInfo->window);
+ }
+}
+
+void AppBoxRenderView::pauseBox()
+{
+ LogD("enter");
+}
+
+void AppBoxRenderView::resumeBox()
+{
+ LogD("enter");
+}
+
+void AppBoxRenderView::showPd(RenderInfoPtr pdRenderInfo, RenderInfoPtr boxRenderInfo)
+{
+ LogD("enter");
+
+ std::string pdStartUrl = getStartUrl(URL_TYPE_PD, pdRenderInfo->defaultUrlParams);
+ if (m_pdFastOpen) {
+ destroyPdWrtCore();
+ // if you want to launch new Web Process for PD, use the following line.
+ // EwkContextPtr pdContext = AppBoxObserver::Instance()->getPdEwkContext();
+ m_pdWrt = createWrtCore(URL_TYPE_PD, pdStartUrl, pdRenderInfo->window, m_ewkContext);
+ if (!m_pdWrt) {
+ LogD("no wrt core instance");
+ return;
+ }
+ m_pdHelper = AppBoxPdHelper::create(pdRenderInfo->window);
+
+ // resize webview fitted to width, height of pd
+ evas_object_resize(
+ m_pdWrt->GetCurrentWebview(),
+ pdRenderInfo->width,
+ pdRenderInfo->height);
+ // show pd
+ m_pdWrt->Show();
+ m_pdHelper->finishOpen(m_pdWrt->GetCurrentWebview());
+ } else {
+ m_pdHelper = PdHelper::create(pdRenderInfo, pdStartUrl);
+ }
+
+ // show pd window
+ evas_object_show(pdRenderInfo->window);
+
+ // need to create new snapshot when m_napshot is empty
+ if (!m_snapshot) {
+ evas_object_show(getCurrentSnapShot());
+ }
+
+ // show box
+ showBox(boxRenderInfo);
+
+ // start timer for clearing existing snapshot in case of only pd open
+ addTimer(&m_removeSnapShotTimer, SNAPSHOT_REMOVE_TIME, removeSnapShotTimerCallback);
+
+}
+
+void AppBoxRenderView::hidePd()
+{
+ LogD("enter");
+
+ if (m_pdFastOpen) {
+ destroyPdWrtCore();
+ }
+ m_pdHelper->close();
+ m_pdHelper.reset();
+
+ // start timer for clearing existing snapshot in case of only pd open
+ addTimer(&m_fireRenderTimer, RENDER_MAX_TIME, fireRenderTimerCallback);
+}
+
+Evas_Object* AppBoxRenderView::getBoxWebView()
+{
+ if (!m_pdHelper) {
+ return m_boxWrt->GetCurrentWebview();
+ } else {
+ // Here, we can't use GetCurrentWebView() of wrt-core to get Box' webview,
+ // because in the non fast-open, GetCurrentWebview() returns PD's webview.
+ return m_pdHelper->getBoxWebView();
+ }
+}
+
+Evas_Object* AppBoxRenderView::getPdWebView()
+{
+ if (!m_pdHelper) {
+ return NULL;
+ }
+
+ return m_pdHelper->getPdWebView();
+}
+
+std::string AppBoxRenderView::getAppId(std::string& boxId)
+{
+ LogD("enter");
+
+ const char* appId = web_provider_livebox_get_app_id(boxId.c_str());
+ if (!appId) {
+ LogD("no appid of %s", boxId.c_str());
+ return std::string();
+ }
+
+ return std::string(appId);
+}
+
+std::string AppBoxRenderView::getStartUrl(UrlType type, std::string& defaultParams)
+{
+ const char* path;
+ switch (type) {
+ case URL_TYPE_BOX:
+ path = livebox_service_lb_script_path(m_boxId.c_str());
+ break;
+ case URL_TYPE_PD:
+ path = livebox_service_pd_script_path(m_boxId.c_str());
+ break;
+ default:
+ LogD("no available type");
+ }
+
+ std::string startUrl;
+ if (path) {
+ LogD("path : %s", path);
+ startUrl = path;
+ } else {
+ // TODO In this case, fallback page will be loaded.
+ LogE("Fail to get service lib script path");
+ }
+
+ // add default parameters to start url
+ startUrl += defaultParams;
+
+ return startUrl;
+}
+
+Evas_Object* AppBoxRenderView::getCurrentSnapShot()
+{
+ LogD("enter");
+ clearSnapShot();
+ m_snapshot = m_boxRenderBuffer->getSnapshot();
+
+ return m_snapshot;
+}
+
+void AppBoxRenderView::clearSnapShot()
+{
+ LogD("enter");
+ if (m_snapshot) {
+ evas_object_del(m_snapshot);
+ m_snapshot = NULL;
+ }
+}
+
+void AppBoxRenderView::showSnapShot()
+{
+ LogD("enter");
+ if (m_snapshot) {
+ evas_object_raise(m_snapshot);
+ evas_object_show(m_snapshot);
+ }
+}
+
+void AppBoxRenderView::hideSnapShot()
+{
+ LogD("enter");
+ if (m_snapshot) {
+ evas_object_hide(m_snapshot);
+ evas_object_lower(m_snapshot);
+ }
+}
+
+void AppBoxRenderView::addTimer(Ecore_Timer** timer, double interval, Ecore_Task_Cb callback)
+{
+ LogD("enter");
+ if (*timer) {
+ deleteTimer(timer);
+ }
+
+ *timer = ecore_timer_add(interval, callback, this);
+}
+
+void AppBoxRenderView::deleteTimer(Ecore_Timer** timer)
+{
+ LogD("enter");
+ if (*timer) {
+ ecore_timer_del(*timer);
+ *timer = NULL;
+ }
+}
+
+void AppBoxRenderView::stopRenderBox()
+{
+ deleteTimer(&m_fireRenderTimer);
+ m_boxRenderBuffer->stopCanvasUpdate();
+ if (web_provider_livebox_get_mouse_event(m_boxId.c_str())) {
+ // stop touch timer
+ m_boxRenderBuffer->deleteTouchTimer();
+
+ // temp condition
+ if (m_boxWrt_isSuspended == false)
+ {
+ m_boxWrt_isSuspended = true;
+ m_boxWrt->Suspend();
+ }
+ } else {
+ // Before webview should be removed,
+ // new evas object with last render data should be created
+ // otherwise, after webview is removed, box is white screen.
+ evas_object_show(getCurrentSnapShot());
+ destroyBoxWrtCore();
+ }
+}
+
+void AppBoxRenderView::setWebViewBasicSetting(Evas_Object* webview)
+{
+ LogD("enter");
+
+ if (!webview) {
+ return;
+ }
+ Ewk_Settings* setting = ewk_view_settings_get(webview);
+ // Disable ime features
+ ewk_settings_default_keypad_enabled_set(setting, EINA_FALSE);
+ // To support transparent background
+ evas_object_color_set(webview, 0, 0, 0, 1);
+ ewk_view_draws_transparent_background_set(webview, EINA_TRUE);
+ ewk_view_visibility_set(webview, EINA_TRUE);
+
+ // To know starting point for updating buffer
+ evas_object_smart_callback_add(
+ webview,
+ "load,nonemptylayout,finished",
+ loadNonEmptyLayoutFinishedCallback,
+ this);
+ evas_object_smart_callback_add(
+ webview,
+ "frame,rendered",
+ frameRenderedCallback,
+ this);
+ // To set font type whenever font changed
+ ewk_view_use_settings_font(webview);
+}
+
+Eina_Bool AppBoxRenderView::fireRenderTimerCallback(void* data)
+{
+ LogD("enter");
+
+ AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
+ This->m_fireRenderTimer = NULL;
+ This->stopRenderBox();
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+Eina_Bool AppBoxRenderView::removeSnapShotTimerCallback(void* data)
+{
+ LogD("enter");
+
+ AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
+ if (!(This->m_boxFinishLoad && This->m_boxFrameRendered)) {
+ return ECORE_CALLBACK_RENEW;
+ }
+
+ // hide snapshot because valid frame has been prepared generally.
+ This->clearSnapShot();
+
+ // move to inside of viewport to prevent overlap with snapshot image
+ evas_object_move(This->m_boxWrt->GetCurrentWebview(), 0, 0);
+ evas_object_show(This->m_boxWrt->GetCurrentWebview());
+
+ This->m_removeSnapShotTimer = NULL;
+ return ECORE_CALLBACK_CANCEL;
+}
+
+Eina_Bool AppBoxRenderView::openPdIdlerCallback(void* data)
+{
+ LogD("enter");
+ AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
+ if (This && This->m_pdHelper) {
+ This->m_pdHelper->startOpen();
+ }
+ return ECORE_CALLBACK_CANCEL;
+}
+
+void AppBoxRenderView::executeScriptCallback(
+ Evas_Object* webview, const char* result, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(webview);
+ UNUSED_PARAM(data);
+
+ std::string resultStr(result ? result : "null");
+ LogD("result: %s", resultStr.c_str());
+}
+
+void AppBoxRenderView::startLoadCallback(Evas_Object* webview)
+{
+ LogD("enter");
+ if(!webview) {
+ return;
+ }
+ // execute injection for creating js objects
+ std::ifstream jsFile(injectionFile);
+ std::string script((std::istreambuf_iterator<char>(jsFile)),
+ std::istreambuf_iterator<char>());
+
+ LogD("injected js code: %s", script.c_str());
+ ewk_view_script_execute(webview, script.c_str(), executeScriptCallback, this);
+}
+
+void AppBoxRenderView::finishBoxLoadCallback(Evas_Object* webview)
+{
+ LogD("enter");
+ if (!webview) {
+ return;
+ }
+
+ ewk_view_visibility_set(webview, EINA_TRUE);
+
+ if (!m_pdHelper) {
+ // start render timer
+ addTimer(&m_fireRenderTimer, RENDER_MAX_TIME, fireRenderTimerCallback);
+ } else {
+ if (!m_pdFastOpen) {
+ if (!(m_pdHelper->isPdOpened()) &&
+ webview == m_pdHelper->getBoxWebView())
+ {
+ // open pd
+ ecore_idler_add(openPdIdlerCallback, this);
+ }
+ }
+ }
+
+ // set flag
+ m_boxFinishLoad = true;
+}
+
+void AppBoxRenderView::finishPdLoadCallback(Evas_Object* webview)
+{
+ LogD("enter");
+ if (!webview) {
+ return;
+ }
+
+ ewk_view_visibility_set(webview, EINA_TRUE);
+}
+
+void AppBoxRenderView::createWindowBeforeCallback(Evas** canvas, Evas_Object* parent)
+{
+ LogD("enter");
+
+ if (m_pdHelper) {
+ if (!(m_pdHelper->isPdOpened()) &&
+ parent == m_pdHelper->getBoxWebView())
+ {
+ LogD("pd canvas is used");
+ *canvas = m_pdHelper->getPdCanvas();
+ return;
+ }
+ }
+
+ LogD("canvas of this webview is used");
+ *canvas = evas_object_evas_get(parent);
+}
+
+void AppBoxRenderView::createWindowAfterCallback(Evas_Object* parent, Evas_Object* child)
+{
+ LogD("enter");
+ if (!parent) {
+ return;
+ }
+
+ if (m_pdHelper) {
+ Evas* parentCanvas = evas_object_evas_get(parent);
+ Evas* childCanvas = evas_object_evas_get(child);
+
+ if (parentCanvas != childCanvas) {
+ // wrt-core change visibility value to false internally
+ // So plugin should reset this value to true for painting parent webview
+ ewk_view_visibility_set(parent, EINA_TRUE);
+ evas_object_show(parent);
+ m_pdHelper->finishOpen(child);
+ }
+ }
+
+ setWebViewBasicSetting(child);
+ evas_object_show(child);
+}
+
+void AppBoxRenderView::setBufferCallback(Evas_Object* webview)
+{
+ LogD("enter");
+ evas_object_show(webview);
+ evas_object_focus_set(webview, EINA_TRUE);
+}
+
+void AppBoxRenderView::unsetBufferCallback(Evas_Object* webview)
+{
+ LogD("enter");
+ evas_object_hide(webview);
+}
+
+void AppBoxRenderView::decideNavigationCallback(Evas_Object* webview, std::string& uri)
+{
+ LogD("enter");
+ UNUSED_PARAM(webview);
+
+ // navigation of box scheme should be ignored
+ if(BoxSchemeHandler::Instance()->isBoxScheme(uri)) {
+ LogD("box scheme");
+ BoxSchemeHandler::Instance()->process(m_instanceId, uri);
+ }
+}
+
+void AppBoxRenderView::crashWebProcessCallback()
+{
+ LogD("enter");
+ elm_exit();
+}
+
+void AppBoxRenderView::loadNonEmptyLayoutFinishedCallback(
+ void* data, Evas_Object* webview, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(data);
+ UNUSED_PARAM(webview);
+ UNUSED_PARAM(eventInfo);
+}
+
+void AppBoxRenderView::frameRenderedCallback(
+ void* data, Evas_Object* webview, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(webview);
+ UNUSED_PARAM(eventInfo);
+
+ // start to update render buffer!
+ AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
+ This->m_boxRenderBuffer->startCanvasUpdate();
+
+ // set flag
+ This->m_boxFrameRendered = true;
+
+ // move to inside of viewport to prevent overlap with snapshot image
+ if (!This->m_removeSnapShotTimer) {
+ evas_object_move(This->m_boxWrt->GetCurrentWebview(), 0, 0);
+ }
+
+}
diff --git a/src_mobile/Plugin/AppBoxPlugin/AppBoxRenderView.h b/src_mobile/Plugin/AppBoxPlugin/AppBoxRenderView.h
new file mode 100644
index 0000000..4d0d7a7
--- /dev/null
+++ b/src_mobile/Plugin/AppBoxPlugin/AppBoxRenderView.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxRenderView.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef APP_BOX_RENDER_VIEW_H
+#define APP_BOX_RENDER_VIEW_H
+
+#include <string>
+#include <memory>
+#include <Eina.h>
+#include <Ecore.h>
+#include <Evas.h>
+#include <ewk_context.h>
+#include <i_runnable_widget_object.h>
+#include <Core/View/IRenderView.h>
+#include <Core/View/IPdHelper.h>
+
+class AppBoxRenderBuffer;
+
+class AppBoxRenderView: public IRenderView {
+ public:
+ typedef std::shared_ptr<Ewk_Context> EwkContextPtr;
+
+ static IRenderViewPtr create(
+ std::string boxId, std::string instanceId,
+ EwkContextPtr ewkContext)
+ {
+ return IRenderViewPtr(
+ new AppBoxRenderView(
+ boxId, instanceId, ewkContext));
+ };
+ virtual void showBox(RenderInfoPtr boxRenderInfo);
+ virtual void hideBox();
+ virtual void pauseBox();
+ virtual void resumeBox();
+ virtual void showPd(RenderInfoPtr pdRenderInfo, RenderInfoPtr boxRenderInfo);
+ virtual void hidePd();
+ Evas_Object* getBoxWebView();
+ Evas_Object* getPdWebView();
+ virtual ~AppBoxRenderView();
+
+ private:
+ // type definition
+ typedef std::shared_ptr<WRT::IRunnableWidgetObject> WrtCorePtr;
+ enum UrlType {
+ URL_TYPE_BOX,
+ URL_TYPE_PD
+ };
+
+ WrtCorePtr createWrtCore(
+ UrlType type, std::string& startUrl,
+ Evas_Object* win, EwkContextPtr ewkContext);
+ void setWebViewBasicSetting(Evas_Object* webview);
+ void destroyWrtCore(WrtCorePtr wrt);
+ void destroyBoxWrtCore();
+ void destroyPdWrtCore();
+ std::string getAppId(std::string& boxId);
+ std::string getStartUrl(UrlType type, std::string& defaultParams);
+ Evas_Object* getCurrentSnapShot();
+ void clearSnapShot();
+ void showSnapShot();
+ void hideSnapShot();
+ void addTimer(Ecore_Timer** timer, double interval, Ecore_Task_Cb callback);
+ void deleteTimer(Ecore_Timer** timer);
+ void stopRenderBox();
+
+ // timer and idler callback
+ static Eina_Bool fireRenderTimerCallback(void* data);
+ static Eina_Bool removeSnapShotTimerCallback(void* data);
+ static Eina_Bool openPdIdlerCallback(void* data);
+
+ // ewk view callback
+ static void executeScriptCallback(
+ Evas_Object* webview, const char* result, void* data);
+ static void loadNonEmptyLayoutFinishedCallback(
+ void* data, Evas_Object* webview, void* eventInfo);
+ static void frameRenderedCallback(
+ void* data, Evas_Object* webview, void* eventInfo);
+
+ // user Callbacks of RunnableWidgetObject
+ void startLoadCallback(Evas_Object* webview);
+ void finishBoxLoadCallback(Evas_Object* webview);
+ void finishPdLoadCallback(Evas_Object* webview);
+ void createWindowBeforeCallback(Evas** canvas, Evas_Object* parent);
+ void createWindowAfterCallback(Evas_Object* parent, Evas_Object* child);
+ void setBufferCallback(Evas_Object* webview);
+ void unsetBufferCallback(Evas_Object* webview);
+ void decideNavigationCallback(Evas_Object* webview, std::string& uri);
+ void crashWebProcessCallback();
+
+ // constructor
+ explicit AppBoxRenderView(
+ std::string boxId, std::string instanceId,
+ EwkContextPtr ewkContext);
+
+ // members
+ std::string m_appId;
+ std::string m_boxId;
+ std::string m_instanceId;
+ EwkContextPtr m_ewkContext;
+ RenderInfoPtr m_boxRenderInfo;
+ WrtCorePtr m_boxWrt;
+ WrtCorePtr m_pdWrt;
+ Evas_Object* m_snapshot;
+ Ecore_Timer* m_fireRenderTimer;
+ Ecore_Timer* m_removeSnapShotTimer;
+ IPdHelperPtr m_pdHelper;
+ AppBoxRenderBuffer* m_boxRenderBuffer;
+
+ // for check status of webview
+ bool m_pdFastOpen;
+ bool m_boxFinishLoad;
+ bool m_boxFrameRendered;
+
+ // TODO this temporary flag should removed!
+ bool m_boxWrt_isSuspended;
+
+ friend class AppBoxRenderBuffer;
+};
+
+#endif // APP_BOX_RENDER_VIEW_H
diff --git a/src_mobile/Plugin/AppBoxPlugin/CMakeLists.txt b/src_mobile/Plugin/AppBoxPlugin/CMakeLists.txt
new file mode 100644
index 0000000..a072064
--- /dev/null
+++ b/src_mobile/Plugin/AppBoxPlugin/CMakeLists.txt
@@ -0,0 +1,75 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME web-provider-plugin-app)
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ ail
+ ewebkit2
+ wrt-core
+ dpl-efl
+ evas
+ ecore
+ eina
+ livebox-service
+ dlog
+ provider # this should be removed
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/box_plugin_interface.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/AppBoxManager.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/AppBoxObserver.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/AppBoxPluginFactory.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/AppBoxRenderView.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/AppBoxRenderBuffer.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/AppBoxPdHelper.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} SHARED ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LIBRARIES}
+ ${TARGET_CORE}
+)
+
+INSTALL(TARGETS ${TARGET_NAME}
+ DESTINATION lib/${PROJECT_NAME}
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
+
+INSTALL_FILE(app.json lib/${PROJECT_NAME})
diff --git a/src_mobile/Plugin/AppBoxPlugin/app.json b/src_mobile/Plugin/AppBoxPlugin/app.json
new file mode 100644
index 0000000..6388702
--- /dev/null
+++ b/src_mobile/Plugin/AppBoxPlugin/app.json
@@ -0,0 +1,5 @@
+{
+ "type" : "app",
+ "path" : "/usr/lib/web-provider/libweb-provider-plugin-app.so",
+ "supported_size" : ["1x1","2x1","2x2"]
+}
diff --git a/src_mobile/Plugin/AppBoxPlugin/box_plugin_interface.cpp b/src_mobile/Plugin/AppBoxPlugin/box_plugin_interface.cpp
new file mode 100644
index 0000000..ca5e65e
--- /dev/null
+++ b/src_mobile/Plugin/AppBoxPlugin/box_plugin_interface.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 box_plugin_interface.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <memory>
+#include <Core/BoxData.h>
+#include <Core/Util/Log.h>
+#include <Plugin/box_plugin_interface.h>
+#include "AppBoxManager.h"
+#include "AppBoxPluginFactory.h"
+
+static std::shared_ptr<IBoxManager> g_manager;
+
+int web_provider_plugin_interface_initialize()
+{
+ LogD("enter");
+ IBoxPluginFactoryPtr factory(new AppBoxPluginFactory());
+ g_manager = AppBoxManager::create(factory);
+
+ return 0;
+}
+
+int web_provider_plugin_interface_command(const request_cmd_type type, const BoxInfoPtr& boxInfo)
+{
+ LogD("enter");
+ int ret = g_manager->doCommand(type, boxInfo);
+
+ if (!ret) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int web_provider_plugin_interface_shutdown()
+{
+ LogD("enter");
+ g_manager.reset();
+ return 0;
+}
diff --git a/src_mobile/Plugin/BoxPluginConnector.cpp b/src_mobile/Plugin/BoxPluginConnector.cpp
new file mode 100644
index 0000000..a0cc23a
--- /dev/null
+++ b/src_mobile/Plugin/BoxPluginConnector.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxPluginConnector.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <map>
+#include <dlfcn.h>
+#include <Core/Util/Log.h>
+#include <Core/BoxData.h>
+#include <API/web_provider_plugin_info.h>
+#include "box_plugin_interface.h"
+#include "BoxPluginConnector.h"
+
+BoxPluginConnector::BoxPluginConnector()
+{
+}
+
+BoxPluginConnector::~BoxPluginConnector()
+{
+}
+
+bool BoxPluginConnector::initialize()
+{
+ LogD("enter");
+
+ int count;
+ web_provider_plugin_info** pluginList = NULL;
+ pluginList = web_provider_plugin_get_installed_list(&count);
+
+ if (!pluginList) {
+ LogD("failed to get installed plugin's information");
+ return false;
+ }
+
+ if (count <= 0) {
+ LogD("There is no available livebox plugins");
+ return false;
+ }
+
+ m_pluginMap.clear();
+
+ // get information of installed plugin
+ LogD("get information of installed plugin");
+ for (int i = 0; i < count; i++) {
+ if (!pluginList[i]) {
+ continue;
+ }
+
+ LogD("plugin path: %s", pluginList[i]->path);
+ void* handle = dlopen(pluginList[i]->path, RTLD_LAZY);
+ if (!handle) {
+ LogD("failed to load plugin so: %s", dlerror());
+ continue;
+ }
+
+ std::shared_ptr<plugin_interfaces> pluginInfo(new plugin_interfaces);
+
+ pluginInfo->handle = handle;
+ pluginInfo->service_boxid = NULL;
+ if (pluginList[i]->service_boxid) {
+ pluginInfo->service_boxid = strdup(pluginList[i]->service_boxid);
+ }
+
+ pluginInfo->initialize =
+ reinterpret_cast<plugin_interface_func_initialize>(
+ dlsym(handle, WEB_PROVIDER_PLUGIN_INTERFACE_SYM_INITIALIZE));
+ pluginInfo->command =
+ reinterpret_cast<plugin_interface_func_command>(
+ dlsym(handle, WEB_PROVIDER_PLUGIN_INTERFACE_SYM_COMMAND));
+ pluginInfo->shutdown =
+ reinterpret_cast<plugin_interface_func_shutdown>(
+ dlsym(handle, WEB_PROVIDER_PLUGIN_INTERFACE_SYM_SHUTDOWN));
+
+ if (!pluginInfo->initialize || !pluginInfo->command ||
+ !pluginInfo->shutdown)
+ {
+ LogD("symbol for plugin interface is not found");
+ continue;
+ }
+
+ m_pluginMap[std::string(pluginList[i]->type)] = pluginInfo;
+ }
+
+ // initialize plugins
+ for (auto it = m_pluginMap.begin();
+ it != m_pluginMap.end(); ++it)
+ {
+ if (it->second) {
+ // TODO add exception or abnormal action on loading plugin
+ if (it->second->initialize() < 0) {
+ LogD("fail to intialize plugin");
+ continue;
+ }
+ }
+ }
+
+ // release information
+ LogD("release json data of plugins");
+ web_provider_plugin_release_installed_list(pluginList, count);
+
+ return true;
+}
+
+bool BoxPluginConnector::shutdown()
+{
+ LogD("enter");
+ // if needed, unload each plugin's DSO.
+ for (auto it = m_pluginMap.begin();
+ it != m_pluginMap.end(); ++it)
+ {
+ if (it->second) {
+ it->second->shutdown();
+ dlclose(it->second->handle);
+ }
+ }
+
+ return true;
+}
+
+bool BoxPluginConnector::requestCommand(
+ const request_cmd_type type, const BoxInfoPtr& boxInfo)
+{
+ LogD("enter");
+
+ // in case of request of resume all or pause all, all plugins should handle that.
+ if (type == REQUEST_CMD_RESUME_ALL ||
+ type == REQUEST_CMD_PAUSE_ALL ||
+ type == REQUEST_CMD_CHANGE_LANGUAGE) {
+ for (auto it = m_pluginMap.begin();
+ it != m_pluginMap.end(); ++it)
+ {
+ if (it->second) {
+ it->second->command(type, boxInfo);
+ }
+ }
+ return true;
+ }
+
+ const std::shared_ptr<plugin_interfaces> plugin = m_pluginMap[boxInfo->boxType];
+ if (!plugin) {
+ LogD("not available livebox type");
+ return false;
+ }
+
+ int ret = plugin->command(type, boxInfo);
+ if (ret < 0) {
+ LogD("failed to request command");
+ return false;
+ }
+
+ return true;
+}
+
+std::string BoxPluginConnector::getBoxType(const std::string& serviceBoxId)
+{
+ LogD("enter");
+
+ std::string type;
+ for (auto it = m_pluginMap.begin();
+ it != m_pluginMap.end(); ++it)
+ {
+ if (it->second && it->second->service_boxid) {
+ if (serviceBoxId == it->second->service_boxid) {
+ LogD("service box id is matched!: %s", it->first.c_str());
+ type = it->first;
+ break;
+ }
+ }
+ }
+
+ return type;
+}
diff --git a/src_mobile/Plugin/BoxPluginConnector.h b/src_mobile/Plugin/BoxPluginConnector.h
new file mode 100644
index 0000000..5ada8db
--- /dev/null
+++ b/src_mobile/Plugin/BoxPluginConnector.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxPluginConnector.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_PLUGIN_CONNECTOR_H
+#define BOX_PLUGIN_CONNECTOR_H
+
+#include <map>
+#include <Core/BoxData.h>
+#include "IBoxPluginConnector.h"
+#include "box_plugin_interface.h"
+
+class BoxPluginConnector: public IBoxPluginConnector {
+ public: // IBoxPluginConnector
+ static IBoxPluginConnectorPtr create()
+ {
+ return IBoxPluginConnectorPtr(new BoxPluginConnector());
+ };
+ virtual bool initialize();
+ virtual bool shutdown();
+ virtual bool requestCommand(
+ const request_cmd_type type, const BoxInfoPtr& boxInfo);
+ virtual std::string getBoxType(const std::string& serviceBoxId);
+ virtual ~BoxPluginConnector();
+
+ private:
+ BoxPluginConnector();
+
+ // type definition
+ typedef std::map<std::string, std::shared_ptr<plugin_interfaces> > pluginMap;
+
+ pluginMap m_pluginMap;
+
+};
+
+#endif // BOX_PLUGIN_CONNECTOR_H
diff --git a/src_mobile/Plugin/CMakeLists.txt b/src_mobile/Plugin/CMakeLists.txt
new file mode 100644
index 0000000..349ddb0
--- /dev/null
+++ b/src_mobile/Plugin/CMakeLists.txt
@@ -0,0 +1,67 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_PLUGIN})
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ evas
+ ewebkit2
+ dlog
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxPluginConnector.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} STATIC ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LDFLAGS} "-ldl"
+ ${${DEPS}_LIBRARIES}
+)
+
+INSTALL(TARGETS ${TARGET_NAME}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
+
+GET_FILENAME_COMPONENT(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+INSTALL_FILE(IBoxPluginFactory.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(box_plugin_interface.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+
+# openable plugins of web livebox
+ADD_SUBDIRECTORY(AppBoxPlugin)
diff --git a/src_mobile/Plugin/IBoxPluginConnector.h b/src_mobile/Plugin/IBoxPluginConnector.h
new file mode 100644
index 0000000..3e94fb8
--- /dev/null
+++ b/src_mobile/Plugin/IBoxPluginConnector.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IBoxPluginConnector.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_BOX_PLUGIN_CONNECTOR_H
+#define I_BOX_PLUGIN_CONNECTOR_H
+
+#include <memory>
+#include <Core/BoxData.h>
+#include <Core/Util/Noncopyable.h>
+#include "box_plugin_interface.h"
+
+class IBoxPluginConnector: Noncopyable {
+ public:
+ virtual bool initialize() = 0;
+ virtual bool shutdown() = 0;
+ virtual bool requestCommand(
+ const request_cmd_type type, const BoxInfoPtr& boxInfo) = 0;
+ virtual std::string getBoxType(const std::string& serviceBoxId) = 0;
+ virtual ~IBoxPluginConnector() {};
+};
+
+typedef std::shared_ptr<IBoxPluginConnector> IBoxPluginConnectorPtr;
+
+#endif // I_BOX_PLUGIN_CONNECTOR_H
diff --git a/src_mobile/Plugin/IBoxPluginFactory.h b/src_mobile/Plugin/IBoxPluginFactory.h
new file mode 100644
index 0000000..bbcb1ec
--- /dev/null
+++ b/src_mobile/Plugin/IBoxPluginFactory.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IBoxPluginFactory.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_BOX_PLUGIN_FACTORY_H
+#define I_BOX_PLUGIN_FACTORY_H
+
+#include <string>
+#include <memory>
+#include <Evas.h>
+#include <ewk_context.h>
+
+// forward declaration
+class IRenderView;
+class IRenderBuffer;
+
+class IBoxPluginFactory {
+ public:
+ virtual std::shared_ptr<IRenderView> createRenderView(
+ std::string boxId, std::string instanceId,
+ std::shared_ptr<Ewk_Context> ewkContext) = 0;
+
+ virtual std::shared_ptr<IRenderBuffer> createBoxRenderBuffer(
+ std::string boxId, std::string instanceId,
+ int width, int height, std::string data) = 0;
+
+ virtual ~IBoxPluginFactory() {};
+};
+
+typedef std::shared_ptr<IBoxPluginFactory> IBoxPluginFactoryPtr;
+
+#endif //I_BOX_PLUGIN_FACTORY_H
diff --git a/src_mobile/Plugin/box_plugin_interface.h b/src_mobile/Plugin/box_plugin_interface.h
new file mode 100644
index 0000000..9cc8a14
--- /dev/null
+++ b/src_mobile/Plugin/box_plugin_interface.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 box_plugin_interface.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_PLUGIN_INTERFACE_H
+#define BOX_PLUGIN_INTERFACE_H
+
+#include <string>
+#include <Core/BoxData.h>
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+#define WEB_PROVIDER_PLUGIN_INTERFACE_SYM_INITIALIZE "web_provider_plugin_interface_initialize"
+#define WEB_PROVIDER_PLUGIN_INTERFACE_SYM_COMMAND "web_provider_plugin_interface_command"
+#define WEB_PROVIDER_PLUGIN_INTERFACE_SYM_SHUTDOWN "web_provider_plugin_interface_shutdown"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ REQUEST_CMD_ADD_BOX,
+ REQUEST_CMD_REMOVE_BOX,
+ REQUEST_CMD_OPEN_PD,
+ REQUEST_CMD_CLOSE_PD,
+ REQUEST_CMD_RESIZE_BOX,
+ REQUEST_CMD_RESUME_BOX,
+ REQUEST_CMD_PAUSE_BOX,
+ REQUEST_CMD_RESUME_ALL,
+ REQUEST_CMD_PAUSE_ALL,
+ REQUEST_CMD_CHANGE_PERIOD,
+ REQUEST_CMD_UPDATE_BOX,
+ REQUEST_CMD_CHANGE_LANGUAGE
+} request_cmd_type;
+
+// definition of interface function type
+typedef int (*plugin_interface_func_initialize)(void);
+typedef int (*plugin_interface_func_command)(
+ const request_cmd_type type, const BoxInfoPtr& boxInfo);
+typedef int (*plugin_interface_func_shutdown)(void);
+
+typedef struct {
+ void* handle;
+ const char* service_boxid;
+ plugin_interface_func_initialize initialize;
+ plugin_interface_func_command command;
+ plugin_interface_func_shutdown shutdown;
+} plugin_interfaces;
+
+// inteface functions that should be implemented by each plugin
+EXPORT_API int web_provider_plugin_interface_initialize();
+EXPORT_API int web_provider_plugin_interface_command(
+ const request_cmd_type type, const BoxInfoPtr& boxInfo);
+EXPORT_API int web_provider_plugin_interface_shutdown();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BOX_PLUGIN_INTERFACE_H
diff --git a/src_wearable/API/CMakeLists.txt b/src_wearable/API/CMakeLists.txt
new file mode 100644
index 0000000..ae38767
--- /dev/null
+++ b/src_wearable/API/CMakeLists.txt
@@ -0,0 +1,72 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_API})
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ db-util
+ glib-2.0
+ json-glib-1.0
+ dlog
+ capi-appfw-application
+ libsmack
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/SqliteDB.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/web_provider_livebox_info.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/web_provider_plugin_info.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/web_provider_service.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} SHARED ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LDFLAGS} "-ldl"
+ ${${DEPS}_LIBRARIES}
+)
+
+INSTALL(TARGETS ${TARGET_NAME}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
+
+GET_FILENAME_COMPONENT(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+INSTALL_FILE(web-provider-info.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME}) # Deprecated
+INSTALL_FILE(web_provider_livebox_info.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(web_provider_plugin_info.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(web_provider_service.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
diff --git a/src_wearable/API/SqliteDB.cpp b/src_wearable/API/SqliteDB.cpp
new file mode 100644
index 0000000..32aa302
--- /dev/null
+++ b/src_wearable/API/SqliteDB.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 SqliteDB.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <cstring>
+#include <cstdarg>
+#include <sqlite3.h>
+#include <db-util.h>
+
+#include "SqliteDB.h"
+
+SqliteDB::SqliteDB(std::string dbPath)
+ : m_path(dbPath)
+ , m_handle(NULL)
+ , m_stmt(NULL)
+{
+}
+
+SqliteDB::~SqliteDB()
+{
+}
+
+bool SqliteDB::openDB()
+{
+ closeDB();
+ int ret;
+ ret = db_util_open(m_path.c_str(), &m_handle, DB_UTIL_REGISTER_HOOK_METHOD);
+ if (ret != SQLITE_OK) {
+ return false;
+ }
+
+ return true;
+}
+
+void SqliteDB::closeDB()
+{
+ if (!m_handle) {
+ return;
+ }
+
+ if (!m_stmt) {
+ db_util_close(m_handle);
+ m_handle = NULL;
+ return;
+ }
+
+ sqlite3_finalize(m_stmt);
+ db_util_close(m_handle);
+ m_stmt = NULL;
+ m_handle = NULL;
+}
+
+bool SqliteDB::setCommand(std::string& query, const char* fmt, ...)
+{
+ if (!m_handle || !fmt) {
+ return false;
+ }
+
+ int ret =
+ sqlite3_prepare_v2(m_handle, query.c_str(), -1, &m_stmt, NULL);
+
+ if (ret != SQLITE_OK) {
+ return false;
+ }
+
+ // bind values to query
+ int intValue;
+ char* stringValue;
+
+ va_list ap;
+ va_start(ap, fmt);
+ for (unsigned int i = 0; i < strlen(fmt); i++) {
+ switch (fmt[i]) {
+ case 'i':
+ intValue = va_arg(ap, int);
+ ret = sqlite3_bind_int(m_stmt, i + 1, intValue);
+ if (ret != SQLITE_OK) {
+ va_end(ap);
+ return false;
+ }
+ break;
+ case 's':
+ stringValue = va_arg(ap, char*);
+ ret = sqlite3_bind_text(m_stmt, i + 1, stringValue, -1, NULL);
+ if (ret != SQLITE_OK) {
+ va_end(ap);
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ va_end(ap);
+
+ return true;
+}
+
+bool SqliteDB::executeCommand()
+{
+ int ret = sqlite3_step(m_stmt);
+
+ if (ret != SQLITE_ROW) {
+ return false;
+ }
+
+ return true;
+}
+
+const char* SqliteDB::getText(int col)
+{
+ const char* ret =
+ reinterpret_cast<const char*>(sqlite3_column_text(m_stmt, col));
+
+ return ret;
+}
+
+int SqliteDB::getInt(int col)
+{
+ return sqlite3_column_int(m_stmt, col);
+}
diff --git a/src_wearable/API/SqliteDB.h b/src_wearable/API/SqliteDB.h
new file mode 100644
index 0000000..0f7c993
--- /dev/null
+++ b/src_wearable/API/SqliteDB.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 SqliteDB.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef SQLITE_DB_H
+#define SQLITE_DB_H
+
+#include <string>
+#include <sqlite3.h>
+
+class SqliteDB {
+ public:
+ bool openDB();
+ void closeDB();
+ bool setCommand(std::string& query, const char* fmt, ...);
+ bool executeCommand();
+ const char* getText(int col);
+ int getInt(int col);
+
+ explicit SqliteDB(const std::string dbPath);
+ ~SqliteDB();
+
+ private:
+ std::string m_path;
+ sqlite3* m_handle;
+ sqlite3_stmt* m_stmt;
+};
+
+#endif // SQLITE_DB_H
diff --git a/src_wearable/API/WebProviderDB.h b/src_wearable/API/WebProviderDB.h
new file mode 100644
index 0000000..e6f14f6
--- /dev/null
+++ b/src_wearable/API/WebProviderDB.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 WebProviderDB.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef LIVEBOX_DB_H
+#define LIVEBOX_DB_H
+
+#include <string>
+#include "SqliteDB.h"
+
+const std::string dbPath("/opt/usr/dbspace/.web_provider.db");
+
+class WebProviderDB : public SqliteDB {
+ public:
+ WebProviderDB() : SqliteDB (dbPath) {};
+ ~WebProviderDB() {};
+};
+
+#endif //LIVEBOX_DB_H
diff --git a/src_wearable/API/web-provider-info.h b/src_wearable/API/web-provider-info.h
new file mode 100644
index 0000000..6d9a8b8
--- /dev/null
+++ b/src_wearable/API/web-provider-info.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 web-provider-info.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef WEB_PROVIDER_INFO_H
+#define WEB_PROVIDER_INFO_H
+
+#include <API/web_provider_livebox_info.h>
+
+#endif //WEB_PROVIDER_INFO_H
diff --git a/src_wearable/API/web_provider_livebox_info.cpp b/src_wearable/API/web_provider_livebox_info.cpp
new file mode 100644
index 0000000..6b0f0f3
--- /dev/null
+++ b/src_wearable/API/web_provider_livebox_info.cpp
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 web_provider_livebox_info.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <cstring>
+#include <memory>
+#include <vector>
+#include "WebProviderDB.h"
+#include "web_provider_livebox_info.h"
+
+static const std::string infoTable("LiveboxInfo");
+
+enum InfoTableField {
+ BOX_ID = 0,
+ APP_ID,
+ BOX_TYPE,
+ AUTO_LAUNCH,
+ MOUSE_EVENT,
+ PD_FAST_OPEN,
+};
+
+// TODO this default type should be retrieved more automatically
+static const std::string defaultBoxType("app");
+
+const char* web_provider_livebox_get_default_type()
+{
+ return defaultBoxType.c_str();
+}
+
+const char* web_provider_livebox_get_box_type(const char* box_id)
+{
+ if (!box_id) {
+ return NULL;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return NULL;
+ }
+
+ std::string query = "select * from " + infoTable + " where box_id = ?";
+ if (!handle->setCommand(query, "s", box_id)) {
+ handle->closeDB();
+ return NULL;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return NULL;
+ }
+
+ const char* box_type = handle->getText(InfoTableField::BOX_TYPE);
+ const char* box_type_dup = NULL;
+
+ if (box_type) {
+ box_type_dup = strdup(box_type);
+ }
+
+ handle->closeDB();
+
+ return box_type_dup;
+}
+
+const char* web_provider_livebox_get_app_id(const char* box_id)
+{
+ if (!box_id) {
+ return NULL;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return NULL;
+ }
+
+ std::string query = "select * from " + infoTable + " where box_id = ?";
+ if (!handle->setCommand(query, "s", box_id)) {
+ handle->closeDB();
+ return NULL;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return NULL;
+ }
+
+ const char* app_id = handle->getText(InfoTableField::APP_ID);
+ const char* app_id_dup = NULL;
+
+ if (app_id) {
+ app_id_dup = strdup(app_id);
+ }
+
+ handle->closeDB();
+
+ return app_id_dup;
+}
+
+int web_provider_livebox_get_auto_launch(const char* box_id)
+{
+ if (!box_id) {
+ return 0;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return 0;
+ }
+
+ std::string query = "select * from " + infoTable + " where box_id = ?";
+ if (!handle->setCommand(query, "s", box_id)) {
+ handle->closeDB();
+ return 0;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return 0;
+ }
+
+ int autoLaunch = handle->getInt(InfoTableField::AUTO_LAUNCH);
+ handle->closeDB();
+
+ return autoLaunch;
+}
+
+int web_provider_livebox_get_mouse_event(const char* box_id)
+{
+ if (!box_id) {
+ return 0;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return 0;
+ }
+
+ std::string query = "select * from " + infoTable + " where box_id = ?";
+ if (!handle->setCommand(query, "s", box_id)) {
+ handle->closeDB();
+ return 0;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return 0;
+ }
+
+ int mouseEvent = handle->getInt(InfoTableField::MOUSE_EVENT);
+ handle->closeDB();
+
+ return mouseEvent;
+}
+
+int web_provider_livebox_get_pd_fast_open(const char* box_id)
+{
+ if (!box_id) {
+ return 0;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return 0;
+ }
+
+ std::string query = "select * from " + infoTable + " where box_id = ?";
+ if (!handle->setCommand(query, "s", box_id)) {
+ handle->closeDB();
+ return 0;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return 0;
+ }
+
+ int pdFastOpen = handle->getInt(InfoTableField::PD_FAST_OPEN);
+ handle->closeDB();
+
+ return pdFastOpen;
+}
+
+int web_provider_livebox_insert_box_info(
+ const char* box_id,
+ const char* app_id,
+ const char* box_type,
+ int auto_launch,
+ int mouse_event,
+ int pd_fast_open)
+{
+ if (!box_id || !app_id || !box_type) {
+ return -1;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return -1;
+ }
+
+ std::string query =
+ "insert into " + infoTable +
+ " (box_id, app_id, box_type, auto_launch, mouse_event, pd_fast_open) \
+ values (?,?,?,?,?,?)";
+
+ if (!handle->setCommand(
+ query, "sssiii",
+ box_id, app_id, box_type, auto_launch, mouse_event, pd_fast_open)) {
+ handle->closeDB();
+ return -1;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return -1;
+ }
+
+ handle->closeDB();
+ return 0;
+}
+
+int web_provider_livebox_delete_by_box_id(const char* box_id)
+{
+ if (!box_id) {
+ return -1;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return -1;
+ }
+
+ std::string query =
+ "delete from " + infoTable + " where box_id=?";
+
+ if (!handle->setCommand(query, "s", box_id)) {
+ handle->closeDB();
+ return -1;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return -1;
+ }
+
+ handle->closeDB();
+ return 0;
+}
+
+int web_provider_livebox_delete_by_app_id(const char* app_id)
+{
+ if (!app_id) {
+ return -1;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return -1;
+ }
+
+ std::string query =
+ "delete from " + infoTable + " where app_id=?";
+
+ if (!handle->setCommand(query, "s", app_id)) {
+ handle->closeDB();
+ return -1;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return -1;
+ }
+
+ handle->closeDB();
+ return 0;
+}
+
+int web_provider_livebox_delete_by_type(const char* type)
+{
+ if (!type) {
+ return -1;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return -1;
+ }
+
+ std::string query =
+ "delete from " + infoTable + " where type=?";
+
+ if (!handle->setCommand(query, "s", type)) {
+ handle->closeDB();
+ return -1;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return -1;
+ }
+
+ handle->closeDB();
+ return 0;
+}
+
+char** web_provider_livebox_get_box_id_list(const char* app_id, int* count)
+{
+ if (!app_id) {
+ return NULL;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return NULL;
+ }
+
+ std::string query = "select * from " + infoTable + " where app_id = ?";
+ if (!handle->setCommand(query, "s", app_id)) {
+ handle->closeDB();
+ return NULL;
+ }
+
+ std::vector<char*> boxIdList;
+ while (handle->executeCommand()) {
+ const char* boxId = handle->getText(InfoTableField::BOX_ID);
+ boxIdList.push_back(strdup(boxId));
+ }
+
+ *count = boxIdList.size();
+ if (*count == 0) {
+ handle->closeDB();
+ return NULL;
+ }
+
+ char** boxIds = static_cast<char**>(malloc((*count) * sizeof(char*)));
+ for (int i = 0; i < *count; i++) {
+ boxIds[i] = boxIdList[i];
+ }
+
+ handle->closeDB();
+ return boxIds;
+}
+
+void web_provider_livebox_release_box_id_list(char** box_id_list, int count)
+{
+ if (!box_id_list) {
+ return;
+ }
+
+ for (int i = 0; i < count; i++) {
+ if (!box_id_list[i]) {
+ continue;
+ }
+ free(box_id_list[i]);
+ }
+}
+
+int web_provider_livebox_check_box_installed(const char* box_id)
+{
+ if (!box_id) {
+ return 0;
+ }
+
+ std::shared_ptr<WebProviderDB> handle(new WebProviderDB());
+ if (!handle->openDB()) {
+ return 0;
+ }
+
+ std::string query = "select * from " + infoTable + " where box_id = ?";
+ if (!handle->setCommand(query, "s", box_id)) {
+ handle->closeDB();
+ return 0;
+ }
+
+ if (!handle->executeCommand()) {
+ handle->closeDB();
+ return 0;
+ }
+
+ int count = 0;
+ while (handle->executeCommand()) {
+ count++;
+ }
+ handle->closeDB();
+
+ return count ? 1 : 0;
+}
diff --git a/src_wearable/API/web_provider_livebox_info.h b/src_wearable/API/web_provider_livebox_info.h
new file mode 100644
index 0000000..e170f88
--- /dev/null
+++ b/src_wearable/API/web_provider_livebox_info.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 web_provider_livebox_info.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef WEB_PROVIDER_LIVEBOX_INFO_H
+#define WEB_PROVIDER_LIVEBOX_INFO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+#define DEPRECATED_API __attribute__((visibility("default"))) __attribute__((deprecated))
+
+/* TODO doxygen comments are needed to each exported API */
+
+EXPORT_API const char* web_provider_livebox_get_default_type();
+EXPORT_API const char* web_provider_livebox_get_box_type(const char* box_id);
+EXPORT_API const char* web_provider_livebox_get_app_id(const char* box_id);
+EXPORT_API int web_provider_livebox_get_auto_launch(const char* box_id);
+EXPORT_API int web_provider_livebox_get_mouse_event(const char* box_id);
+EXPORT_API int web_provider_livebox_get_pd_fast_open(const char* box_id);
+EXPORT_API int web_provider_livebox_insert_box_info(
+ const char* box_id,
+ const char* app_id,
+ const char* box_type,
+ int auto_launch,
+ int mouse_event,
+ int pd_fast_open);
+EXPORT_API int web_provider_livebox_delete_by_box_id(const char* box_id);
+EXPORT_API int web_provider_livebox_delete_by_app_id(const char* app_id);
+EXPORT_API int web_provider_livebox_delete_by_type(const char* type);
+
+EXPORT_API char** web_provider_livebox_get_box_id_list(const char* app_id, int* count);
+EXPORT_API void web_provider_livebox_release_box_id_list(char** box_id_list, int count);
+EXPORT_API int web_provider_livebox_check_box_installed(const char* box_id);
+
+#ifdef __cplusplus
+}
+#endif
+#endif //WEB_PROVIDER_LIVEBOX_INFO_H
diff --git a/src_wearable/API/web_provider_plugin_info.cpp b/src_wearable/API/web_provider_plugin_info.cpp
new file mode 100755
index 0000000..dae4588
--- /dev/null
+++ b/src_wearable/API/web_provider_plugin_info.cpp
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 web_provider_livebox_info.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <string>
+#include <cstring>
+#include <cstdlib>
+#include <list>
+#include <glib.h>
+#include <glib-object.h>
+#include <json-glib/json-glib.h>
+#include <Core/Util/Log.h>
+#include "web_provider_livebox_info.h"
+#include "web_provider_plugin_info.h"
+#include <memory>
+
+// static functions
+static web_provider_plugin_info* get_parsed_json_data(std::string& configPath);
+static bool web_provider_plugin_release_info(web_provider_plugin_info* info);
+
+static const std::string installedPluginDirPath("/usr/lib/web-provider/");
+
+// Json's content for plugin is the following (example)
+// {
+// "type" : "clip",
+// "path" : "/usr/lib/web-provider/libweb-provider-plugin-clipbox.so",
+// "service_boxid" : "org.tizen.browser"
+// }
+//
+// "service_boxid" is only optional member in json file
+
+static const std::string jsonMemberType("type");
+static const std::string jsonMemberPath("path");
+static const std::string jsonMemberBoxId("service_boxid");
+static const std::string jsonMemberBoxScrollable("box_scrollable");
+static const std::string jsonMemberBoxSize("supported_size");
+
+static const std::string jsonValueBoolTrue("true");
+static const std::string jsonValueBoolFalse("false");
+static const std::string jsonFileExtension(".json");
+static const std::string mandatoryBoxSize("1x1");
+
+web_provider_plugin_info** web_provider_plugin_get_installed_list(int* count)
+{
+ LogD("enter");
+
+ // open directory of web provider plugin
+ DIR* dir = opendir(installedPluginDirPath.c_str());
+ if (!dir) {
+ LogD("failed to open directory for web livebox plugins");
+ *count = 0;
+ return NULL;
+ }
+
+ // read plugin directory and store plugin config path
+ std::list<std::string> configList;
+ struct dirent* entry;
+ struct stat configStat;
+ std::string configPath;
+ while ((entry = readdir(dir))) {
+ if ((!strcmp(entry->d_name, ".")) || (!strcmp(entry->d_name, ".."))) {
+ continue;
+ }
+
+ configPath = installedPluginDirPath + entry->d_name;
+
+ if (stat(configPath.c_str(), &configStat) < 0) {
+ LogD("Failed to open file");
+ continue;
+ }
+
+ if (S_ISDIR(configStat.st_mode)) {
+ continue;
+ }
+
+ if (configPath.substr(configPath.find_last_of(".")) == jsonFileExtension) {
+ LogD("config file: %s", configPath.c_str());
+ configList.push_back(configPath);
+ }
+ }
+ // close directory of web provider plugin
+ closedir(dir);
+
+ if (configList.size() == 0) {
+ *count = 0;
+ return NULL;
+ }
+
+ // parse available each plugin json file
+ std::list<web_provider_plugin_info*> pluginList;
+ for (auto it = configList.begin();
+ it != configList.end(); it++) {
+ web_provider_plugin_info* info = get_parsed_json_data(*it) ;
+ if (!info) {
+ continue;
+ }
+
+ pluginList.push_back(info);
+ }
+ *count = pluginList.size();
+ LogD("read plugin count: %d", *count);
+
+ // c style array allocation for return of result
+ web_provider_plugin_info** info_list =
+ static_cast<web_provider_plugin_info**>(
+ malloc((*count) * sizeof(web_provider_plugin_info*)));
+
+ // copy from members in std::list to one in c style array
+ int idx = 0;
+ for (auto it = pluginList.begin();
+ it != pluginList.end(); it++) {
+ LogD("type: %s", (*it)->type);
+ LogD("path: %s", (*it)->path);
+ if ((*it)->service_boxid) {
+ LogD("service_boxid: %s", (*it)->service_boxid);
+ }
+ info_list[idx] = *it;
+ idx++;
+ }
+
+ LogD("success to return plugin information");
+ return info_list;
+}
+
+void web_provider_plugin_release_installed_list(
+ web_provider_plugin_info** info_list,
+ int count)
+{
+ if (!info_list) {
+ return;
+ }
+
+ for (int i = 0; i < count; i++) {
+ web_provider_plugin_release_info(info_list[i]);
+ }
+}
+
+int web_provider_plugin_get_box_scrollable(const char* plugin_type)
+{
+ if (!plugin_type) {
+ return -1;
+ }
+
+ std::string configPath;
+ configPath = installedPluginDirPath;
+ configPath += plugin_type;
+ configPath += jsonFileExtension;
+ web_provider_plugin_info* info = get_parsed_json_data(configPath);
+
+ if (!info) {
+ return -1;
+ }
+ int ret = info->box_scrollable;
+ web_provider_plugin_release_info(info);
+
+ LogD("box_scrollable: %d", ret);
+ return ret;
+}
+
+static web_provider_plugin_info* get_parsed_json_data(std::string& configPath)
+{
+ g_type_init();
+
+ web_provider_plugin_info* info;
+ JsonParser* parser = json_parser_new();
+ GError* error = NULL;
+
+ if (!json_parser_load_from_file(parser, configPath.c_str(), &error)) {
+ LogD("failed to parse json file: %s -> %s", configPath.c_str(), error->message);
+ g_error_free(error);
+ g_object_unref(parser);
+ return NULL;
+ }
+
+ JsonNode* root = json_parser_get_root(parser);
+ JsonObject* object = json_node_get_object(root);
+
+ // check if type member exists on this json file
+ const char* type =
+ static_cast<const char*>(
+ json_object_get_string_member(object, jsonMemberType.c_str()));
+
+ const char* path =
+ static_cast<const char*>(
+ json_object_get_string_member(object, jsonMemberPath.c_str()));
+
+ JsonArray* size =
+ json_object_get_array_member(object, jsonMemberBoxSize.c_str());
+ int sizeCount = static_cast<int>(json_array_get_length(size));
+
+ if (!type || !path || !sizeCount) {
+ LogD("mandatory members don't exist");
+ g_error_free(error);
+ g_object_unref(parser);
+ return NULL;
+ }
+
+ // allocate instance of plugin info struct
+ info = static_cast<web_provider_plugin_info*>(
+ malloc(sizeof(web_provider_plugin_info)));
+ memset(info, 0, sizeof(web_provider_plugin_info));
+
+ info->type = strdup(type);
+ info->path = strdup(path);
+ info->box_size = static_cast<char**>(malloc(sizeof(char*) * sizeCount));
+
+ for (int i = 0; i < sizeCount; i++) {
+ info->box_size[i] =
+ strdup(static_cast<const char*>(json_array_get_string_element(size, i)));
+ }
+ info->box_size_count = sizeCount;
+
+ gboolean hasBoxId = json_object_has_member(object, jsonMemberBoxId.c_str());
+ if (hasBoxId == TRUE) {
+ const char* boxId =
+ static_cast<const char*>(
+ json_object_get_string_member(object, jsonMemberBoxId.c_str()));
+ if (boxId) {
+ info->service_boxid = strdup(boxId);
+ }
+ }
+
+ gboolean hasBoxScrollable =
+ json_object_has_member(object, jsonMemberBoxScrollable.c_str());
+ if (hasBoxScrollable == TRUE) {
+ const char* boxScrollable =
+ static_cast<const char*>(
+ json_object_get_string_member(object, jsonMemberBoxScrollable.c_str()));
+ if (boxScrollable && (jsonValueBoolTrue == boxScrollable)) {
+ info->box_scrollable = 1;
+ } else {
+ info->box_scrollable = 0;
+ }
+ }
+
+ LogD("type: %s", info->type);
+ LogD("path: %s", info->path);
+ if (info->service_boxid) {
+ LogD("service_boxid: %s", info->service_boxid);
+ }
+ LogD("box_scrollable: %d", info->box_scrollable);
+
+ g_error_free(error);
+ g_object_unref(parser);
+
+ return info;
+}
+
+bool web_provider_plugin_release_info(web_provider_plugin_info* info)
+{
+ LogD("enter");
+ if (!info) {
+ LogD("empty struct");
+ return false;
+ }
+
+ // only members with buffer are released
+ delete info->type;
+ delete info->path;
+ delete info->service_boxid;
+ for(int i = 0; i < info->box_size_count; i++) {
+ delete[] info->box_size[i];
+ }
+ delete info;
+
+ return true;
+}
+
+int web_provider_plugin_check_supported_size(
+ const char* plugin_type, char** size, int sizeCount)
+{
+ // read plugin directory and store plugin config path
+ std::string configPath;
+ configPath = installedPluginDirPath;
+ configPath += plugin_type;
+ configPath += jsonFileExtension;
+
+ // get the json datas
+ web_provider_plugin_info* jsonData = get_parsed_json_data(configPath);
+ if (!jsonData) {
+ LogD("failed to get the json file");
+ return false;
+ }
+
+ // check if this type is default type
+ bool isDefaultType = false;
+ const char* defaultType = web_provider_livebox_get_default_type();
+ if (!defaultType) {
+ LogD("can't get default type");
+ return false;
+ }
+ if (!strcmp(plugin_type, defaultType)) {
+ isDefaultType = true;
+ }
+
+ // compare the parsed config data with the parsed json data
+ bool mandatoryCheck = false;
+ for (int configCnt = 0; configCnt < sizeCount; configCnt++) {
+ bool supportedSizeCheck = false;
+ for (int jsonCnt = 0; jsonCnt < jsonData->box_size_count; jsonCnt++) {
+
+ // check mandatory size
+ if (isDefaultType && !strcmp(mandatoryBoxSize.c_str(), size[configCnt])) {
+ mandatoryCheck = true;
+ }
+
+ // check supported size
+ if (!strcmp(jsonData->box_size[jsonCnt], size[configCnt])) {
+ supportedSizeCheck = true;
+ break;
+ }
+ }
+
+ if (!supportedSizeCheck) {
+ LogD("Not supported size: %s", size[configCnt]);
+ web_provider_plugin_release_info(jsonData);
+ return false;
+ }
+ }
+
+ //release the jsonData
+ web_provider_plugin_release_info(jsonData);
+ if (isDefaultType && !mandatoryCheck) {
+ LogD("Mandatory members don't exist ");
+ return false;
+ }
+
+ return true;
+}
diff --git a/src_wearable/API/web_provider_plugin_info.h b/src_wearable/API/web_provider_plugin_info.h
new file mode 100755
index 0000000..612497c
--- /dev/null
+++ b/src_wearable/API/web_provider_plugin_info.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 web_provider_plugin_info.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef WEB_PROVIDER_PLUGIN_INFO_H
+#define WEB_PROVIDER_PLUGIN_INFO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+struct _web_provider_plugin_info {
+ const char* type;
+ const char* path;
+ const char* service_boxid;
+ char** box_size;
+ int box_scrollable;
+ int box_size_count;
+};
+typedef _web_provider_plugin_info web_provider_plugin_info;
+
+EXPORT_API web_provider_plugin_info** web_provider_plugin_get_installed_list(
+ int* count);
+EXPORT_API void web_provider_plugin_release_installed_list(
+ web_provider_plugin_info** info_list,
+ int count);
+EXPORT_API int web_provider_plugin_get_box_scrollable(const char* plugin_type);
+EXPORT_API int web_provider_plugin_check_supported_size(const char* plugin_type, char** size, int sizeCount);
+#ifdef __cplusplus
+}
+#endif
+#endif //WEB_PROVIDER_PROVIDER_INFO_H
diff --git a/src_wearable/API/web_provider_service.cpp b/src_wearable/API/web_provider_service.cpp
new file mode 100644
index 0000000..639e1bc
--- /dev/null
+++ b/src_wearable/API/web_provider_service.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 web_provider_service.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <fcntl.h>
+#include <string>
+#include <sstream>
+#include <sys/epoll.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/smack.h>
+#include <string.h>
+#include <unistd.h>
+#include <app_service.h>
+
+#include "web_provider_livebox_info.h"
+#include "web_provider_service.h"
+
+static std::string getFifoFile(const char* appId)
+{
+ int boxCount = 0;
+ char** boxList = web_provider_livebox_get_box_id_list(appId, &boxCount);
+ if (!boxList) {
+ return std::string();
+ }
+ web_provider_livebox_release_box_id_list(boxList, boxCount);
+
+ std::string fifoFile = "/tmp/";
+ fifoFile += appId;
+
+ return fifoFile;
+}
+
+static bool requestRemoveBoxesByAppId(const char* appId)
+{
+ if (!appId) {
+ return false;
+ }
+
+ service_h handle = NULL;
+ int ret = SERVICE_ERROR_NONE;
+
+ ret = service_create(&handle);
+ if (ret != SERVICE_ERROR_NONE && !handle) {
+ return false;
+ }
+
+ ret = service_set_package(handle, SERVICE_WEB_PROVIDER_APPID);
+ if (ret != SERVICE_ERROR_NONE) {
+ service_destroy(handle);
+ return false;
+ }
+
+ ret = service_set_operation(handle, SERVICE_OPERATION_BOX_REMOVE);
+ if (ret != SERVICE_ERROR_NONE) {
+ service_destroy(handle);
+ return false;
+ }
+
+ // set special key as extra data for removing boxes by web-provider
+ service_add_extra_data(handle, SERVICE_REMOVE_APPID_KEY, appId);
+
+ ret = service_send_launch_request(handle, NULL, NULL);
+ if (ret != SERVICE_ERROR_NONE) {
+ service_destroy(handle);
+ return false;
+ }
+
+ service_destroy(handle);
+ return true;
+}
+
+int web_provider_service_wait_boxes_removed(const char* app_id)
+{
+ if (!app_id) {
+ return -1;
+ }
+
+ // 1. request service for removing boxes to web-provider
+ // 2. wait using epoll_wait while fifo file is changed
+ if(!requestRemoveBoxesByAppId(app_id)) {
+ return -1;
+ }
+
+ // create fifo file
+ std::string fifoFile = getFifoFile(app_id);
+ int ret = mkfifo(fifoFile.c_str(), 0666);
+ if (ret < 0) {
+ if (errno != EEXIST) {
+ return -1;
+ }
+ }
+ chown(fifoFile.c_str(), 5000, 5000);
+ ret = smack_setlabel(fifoFile.c_str(), "*", SMACK_LABEL_ACCESS);
+ if (ret < 0) {
+ return -1;
+ }
+
+ int epollMaxSize = 1;
+ int epollFd = epoll_create(epollMaxSize);
+ int fifoFd = open(fifoFile.c_str(), O_RDONLY | O_NONBLOCK);
+ if (fifoFd < 0) {
+ return -1;
+ }
+
+ struct epoll_event fifoEvent;
+ fifoEvent.events = EPOLLIN | EPOLLOUT;
+ fifoEvent.data.fd = fifoFd;
+
+ struct epoll_event events;
+ if (epoll_ctl(epollFd, EPOLL_CTL_ADD, fifoFd, &fifoEvent) < 0) {
+ close(fifoFd);
+ return -1;
+ }
+
+ int epollTimeOut = 10000; // 10 seconds
+ int status = epoll_wait(epollFd, &events, epollMaxSize, epollTimeOut);
+ // epoll is unblocked!
+
+ int result = 0;
+ if (status < 0) {
+ // epoll failed
+ } else if (status == 0) {
+ // epoll timeout
+ } else {
+ int buffMaxSize = 2;
+ char buff[buffMaxSize];
+ memset(buff, 0x0, buffMaxSize);
+ int size = read(fifoFd, buff, buffMaxSize);
+ if (size > 0) {
+ std::string status(buff);
+ std::istringstream inputStream(status);
+ inputStream >> result;
+ }
+ }
+
+ close(fifoFd);
+ close(epollFd);
+ unlink(fifoFile.c_str());
+ return result;
+}
+
+int web_provider_service_wakeup_installer(const char* app_id)
+{
+ if (!app_id) {
+ return -1;
+ }
+
+ std::string fifoFile = getFifoFile(app_id);
+ int fifoFd = open(fifoFile.c_str(), O_WRONLY | O_NONBLOCK);
+ if (fifoFd < 0) {
+ return -1;
+ }
+
+ std::string result("1");
+ write(fifoFd, result.c_str(), result.size() + 1);
+ close(fifoFd);
+ return 0;
+}
diff --git a/src_wearable/API/web_provider_service.h b/src_wearable/API/web_provider_service.h
new file mode 100644
index 0000000..9dc3e21
--- /dev/null
+++ b/src_wearable/API/web_provider_service.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 web_provider_service.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef WEB_PROVIDER_SERVICE_H
+#define WEB_PROVIDER_SERVICE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+// These are string for removing dboxes from wrt-installer
+#define SERVICE_OPERATION_BOX_REMOVE "http://tizen.org/appcontrol/operation/dynamicbox/web/remove"
+#define SERVICE_WEB_PROVIDER_APPID "dbox.web-provider"
+#define SERVICE_REMOVE_APPID_KEY "app_id"
+
+// These are string for updating dboxes from web app
+#define SERVICE_OPERATION_BOX_UPDATE "http://tizen.org/appcontrol/operation/dynamicbox/web/update"
+#define SERVICE_BOX_SERVICE_SCHEME "box-service://"
+#define SERVICE_CONTENT_INFO_KEY "content-info"
+#define SERVICE_ALARM_CALLER_KEY "__ALARM_MGR_CALLER_APPID"
+
+EXPORT_API int web_provider_service_wait_boxes_removed(const char* app_id);
+EXPORT_API int web_provider_service_wakeup_installer(const char* app_id);
+
+#ifdef __cplusplus
+}
+#endif
+#endif //WEB_PROVIDER_SERVICE_H
diff --git a/src_wearable/CMakeLists.txt b/src_wearable/CMakeLists.txt
new file mode 100644
index 0000000..0a978b0
--- /dev/null
+++ b/src_wearable/CMakeLists.txt
@@ -0,0 +1,31 @@
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_API web-provider-api)
+SET(TARGET_CORE web-provider-core)
+SET(TARGET_DAEMON web-provider)
+SET(TARGET_PLUGIN web-provider-plugin)
+
+INCLUDE_DIRECTORIES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/API
+ ${CMAKE_CURRENT_SOURCE_DIR}/Core
+ ${CMAKE_CURRENT_SOURCE_DIR}/Plugin
+)
+
+ADD_SUBDIRECTORY(API)
+ADD_SUBDIRECTORY(Core)
+ADD_SUBDIRECTORY(Daemon)
+ADD_SUBDIRECTORY(Plugin)
diff --git a/src_wearable/Core/Box.cpp b/src_wearable/Core/Box.cpp
new file mode 100644
index 0000000..84aaf6f
--- /dev/null
+++ b/src_wearable/Core/Box.cpp
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 Box.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <sstream>
+#include <Ecore.h>
+#include <Plugin/IBoxPluginFactory.h>
+#include "Util/Log.h"
+#include "Util/Util.h"
+#include "BoxData.h"
+#include "IBoxState.h"
+#include "BoxState.h"
+#include "Util/ITimer.h"
+#include "BoxUpdateTimer.h"
+#include "Box.h"
+
+Box::Box(BoxInfoPtr boxInfo, IBoxPluginFactoryPtr factory, EwkContextPtr ewkContext)
+ : m_boxInfo(boxInfo)
+ , m_factory(factory)
+ , m_currentTab(true)
+ , m_paused(false)
+ , m_updateNeeded(false)
+ , m_remainUpdateRequestTime()
+ , m_showed(false)
+{
+ LogD("enter");
+ try {
+ m_renderView = m_factory->createRenderView(m_boxInfo, ewkContext);
+ m_updateTimer = BoxUpdateTimer::create(
+ boxInfo->period, Box::updateCallback, this);
+ // TODO code regarding state needs more testing
+ //m_state = BoxInitState::create(
+ // IBoxContextPtr(dynamic_cast<IBoxContext*>(this)));
+ } catch (...) {
+ throw;
+ }
+}
+
+Box::~Box()
+{
+ LogD("enter");
+}
+
+bool Box::show()
+{
+ LogD("enter");
+ CHECK_BOX_STATE(m_state, permitShow);
+
+ try {
+ m_updateTimer->start();
+ m_renderView->show();
+ } catch (...) {
+ return false;
+ }
+ m_showed = true;
+ SWITCH_BOX_STATE();
+ return true;
+}
+
+bool Box::hide()
+{
+ LogD("enter");
+ CHECK_BOX_STATE(m_state, permitHide);
+
+ try {
+ m_updateTimer->stop();
+ m_renderView->hide();
+ } catch (...) {
+ return false;
+ }
+
+ SWITCH_BOX_STATE();
+ return true;
+}
+
+bool Box::resize(int width, int height)
+{
+ LogD("enter");
+ CHECK_BOX_STATE(m_state, permitShow);
+
+ // reset box info to new width, height
+ m_boxInfo->boxWidth = width;
+ m_boxInfo->boxHeight = height;
+
+ try {
+ m_updateTimer->restart();
+ m_renderView->resize();
+ } catch (...) {
+ LogD("resize exception");
+ return false;
+ }
+ m_showed = true;
+ SWITCH_BOX_STATE();
+ return true;
+}
+
+bool Box::resume()
+{
+ LogD("enter");
+ CHECK_BOX_STATE(m_state, permitResume);
+
+ try {
+ m_currentTab = true;
+ m_paused = false;
+
+ if (m_updateTimer->getPeriod() > 0) {
+ // check for need updateTimer
+ time_t currentTime = time(NULL);
+ float diffTime = static_cast<float>(difftime(currentTime, m_remainUpdateRequestTime));
+ if (diffTime < m_updateTimer->getPeriod()) {
+ if (!m_updateTimer->isRunning()) {
+ // we need start timer only remained time from first timer launched
+ m_updateTimer->continueTimer(m_updateTimer->getPeriod() - diffTime);
+ }
+ } else {
+ m_updateNeeded = true;
+ }
+ }
+
+ if (m_updateNeeded) {
+ m_updateNeeded = false;
+ m_updateTimer->start();
+ m_renderView->update();
+ } else {
+ m_renderView->resume();
+ }
+ } catch (...) {
+ return false;
+ }
+ m_showed = true;
+ SWITCH_BOX_STATE();
+ return true;
+}
+
+bool Box::needToUpdate()
+{
+ LogD("enter");
+ if (m_updateTimer && m_updateTimer->getPeriod() > 0) {
+ // check for need updateTimer
+ time_t currentTime = time(NULL);
+ float diffTime = static_cast<float>(difftime(currentTime, m_remainUpdateRequestTime));
+ if (diffTime >= m_updateTimer->getPeriod()) {
+ LogD("enter");
+ return true;
+ }
+
+ if (m_updateNeeded) {
+ return true;
+ }
+ return false;
+ }
+
+ if (!m_showed || m_updateNeeded) {
+ return true;
+ }
+
+ return false;
+}
+
+bool Box::pause(bool background)
+{
+ LogD("enter");
+ CHECK_BOX_STATE(m_state, permitPause);
+
+ try {
+ if (!background) {
+ m_currentTab = false;
+ }
+ m_paused = true;
+ m_renderView->pause();
+
+ if (m_updateTimer->isRunning()) {
+ m_remainUpdateRequestTime = m_updateTimer->getStartTime();
+ m_updateTimer->stop();
+ }
+ } catch (...) {
+ return false;
+ }
+
+ SWITCH_BOX_STATE();
+ return true;
+}
+
+bool Box::openPd(int width, int height, double x, double y)
+{
+ LogD("enter");
+ CHECK_BOX_STATE(m_state, permitOpenPd);
+
+ m_boxInfo->pdWidth = width;
+ m_boxInfo->pdHeight = height;
+ m_boxInfo->pdX = x;
+ m_boxInfo->pdY = y;
+
+ try {
+ m_updateTimer->stop();
+ m_renderView->openPd();
+ } catch (...) {
+ return false;
+ }
+ m_showed = true;
+ SWITCH_BOX_STATE();
+ return true;
+}
+
+bool Box::closePd()
+{
+ LogD("enter");
+ CHECK_BOX_STATE(m_state, permitClosePd);
+
+ try {
+ m_renderView->closePd();
+ m_updateTimer->restart();
+ } catch (...) {
+ return false;
+ }
+
+ SWITCH_BOX_STATE();
+ return true;
+}
+
+bool Box::update(std::string& appContentInfo)
+{
+ LogD("enter");
+
+ m_boxInfo->appContentInfo = appContentInfo;
+ if (m_paused) {
+ // update is dalayed
+ m_updateNeeded = true;
+ return true;
+ }
+
+ try {
+ m_updateTimer->start();
+ m_renderView->update();
+ } catch (...) {
+ return false;
+ }
+ m_showed = true;
+ return true;
+}
+
+bool Box::changePeriod(float period)
+{
+ LogD("enter");
+
+ // reset period
+ m_boxInfo->period = period;
+
+ if (m_updateTimer->isRunning()) {
+ m_updateTimer->setPeriod(m_boxInfo->period);
+ }
+
+ return true;
+}
+
+bool Box::isCurrentTab()
+{
+ return m_currentTab;
+}
+
+void Box::setState(IBoxStatePtr state)
+{
+ UNUSED_PARAM(state);
+ // assign new state
+ //m_state = state;
+}
+
+Eina_Bool Box::updateCallback(void* data)
+{
+ LogD("enter");
+ Box* This = static_cast<Box*>(data);
+ This->update(This->m_boxInfo->appContentInfo);
+ return ECORE_CALLBACK_RENEW;
+}
+
+BoxInfoPtr Box::getBoxInfo()
+{
+ LogD("enter");
+ return m_boxInfo;
+}
+
+void Box::setNeedToUpdate()
+{
+ m_updateNeeded = true;
+}
+
+bool Box::isPaused()
+{
+ return m_paused;
+}
+
+void Box::setCurrent()
+{
+ m_currentTab = true;
+ m_paused = false;
+}
diff --git a/src_wearable/Core/Box.h b/src_wearable/Core/Box.h
new file mode 100644
index 0000000..1ad7fda
--- /dev/null
+++ b/src_wearable/Core/Box.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 Box.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_H
+#define BOX_H
+
+#include <string>
+#include <memory>
+#include <ctime>
+#include <Ecore.h>
+#include <Plugin/IBoxPluginFactory.h>
+#include "Buffer/IRenderBuffer.h"
+#include "View/IRenderView.h"
+#include "Util/ITimer.h"
+#include "BoxData.h"
+#include "IBoxState.h"
+#include "IBoxContext.h"
+#include "IBox.h"
+#include "Box.h"
+
+class Box: public IBox, public IBoxContext {
+ public:
+ static IBoxPtr create(
+ BoxInfoPtr boxInfo,
+ IBoxPluginFactoryPtr factory,
+ EwkContextPtr ewkContext)
+ {
+ return IBoxPtr(new Box(boxInfo, factory, ewkContext));
+ };
+ // IBox
+ bool show();
+ bool hide();
+ bool resize(int width, int height);
+ bool resume();
+ bool pause(bool background);
+ bool openPd(int width, int height, double x, double y);
+ bool closePd();
+ bool update(std::string& contentInfo);
+ bool changePeriod(float period);
+ bool isCurrentTab();
+ bool needToUpdate();
+ void setNeedToUpdate();
+ void setCurrent();
+ bool isPaused();
+ BoxInfoPtr getBoxInfo();
+
+ ~Box();
+
+ private:
+ // IBoxContext
+ void setState(IBoxStatePtr state);
+
+ // static callbacks
+ static Eina_Bool updateCallback(void* data);
+
+ // constructor
+ explicit Box(
+ BoxInfoPtr boxInfo,
+ IBoxPluginFactoryPtr factory,
+ EwkContextPtr ewkContext);
+
+ BoxInfoPtr m_boxInfo;
+ IBoxPluginFactoryPtr m_factory;
+ IRenderViewPtr m_renderView;
+ ITimerPtr m_updateTimer;
+ //IBoxStatePtr m_state;
+ // flag for knowing this box is on current tab
+ bool m_currentTab;
+ // flag for knowing this box has been already paused
+ bool m_paused;
+ // flag for knowing this box should be updated when the box is resumed
+ bool m_updateNeeded;
+ // timestamp for updateTimer
+ time_t m_remainUpdateRequestTime;
+ bool m_showed;
+};
+
+#endif //BOX_H
diff --git a/src_wearable/Core/BoxData.h b/src_wearable/Core/BoxData.h
new file mode 100644
index 0000000..123e737
--- /dev/null
+++ b/src_wearable/Core/BoxData.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxData.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_DATA_H
+#define BOX_DATA_H
+
+#include <memory>
+#include <string>
+
+struct BoxInfo
+{
+ std::string boxType;
+ std::string boxId;
+ std::string instanceId;
+ int boxWidth;
+ int boxHeight;
+ int pdWidth;
+ int pdHeight;
+ double pdX;
+ double pdY;
+ int priority;
+ float period;
+ // contentInfo is used differently per box type
+ std::string contentInfo;
+ // appContentInfo is used for saving custom data from box's app
+ std::string appContentInfo;
+
+ // initialization
+ BoxInfo(std::string boxType,
+ std::string boxId,
+ std::string instanceId) :
+ boxType(boxType),
+ boxId(boxId),
+ instanceId(instanceId),
+ boxWidth(0),
+ boxHeight(0),
+ pdWidth(0),
+ pdHeight(0),
+ pdX(0.0f),
+ pdY(0.0f),
+ priority(0),
+ period(0),
+ contentInfo(),
+ appContentInfo()
+ {
+ };
+
+ BoxInfo() :
+ boxType(),
+ boxId(),
+ instanceId(),
+ boxWidth(0),
+ boxHeight(0),
+ pdWidth(0),
+ pdHeight(0),
+ pdX(0.0f),
+ pdY(0.0f),
+ priority(0),
+ period(0),
+ contentInfo(),
+ appContentInfo()
+ {
+ };
+};
+
+typedef std::shared_ptr<struct BoxInfo> BoxInfoPtr;
+typedef struct BoxInfo& BoxInfoRef;
+
+#endif // BOX_DATA_H
diff --git a/src_wearable/Core/BoxLoadBalancer.cpp b/src_wearable/Core/BoxLoadBalancer.cpp
new file mode 100755
index 0000000..e382df7
--- /dev/null
+++ b/src_wearable/Core/BoxLoadBalancer.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxLoadBalancer.cpp
+ * @author Minhyung Ko (minhyung.ko@samsung.com)
+ */
+#include "Util/Log.h"
+#include "Util/Util.h"
+#include "BoxLoadBalancer.h"
+
+// boxLoadBalanceTimer period
+#define BOX_UPDATE_TIME 0.1
+#define BOX_UPDATE_TIME_INC 0.3
+#define BOX_UPDATE_MAX_TIME 5.0f
+#define BOX_UPDATE_QUEUE_SIZE_THRESHOLD 5
+
+BoxAsyncCommandInfo::BoxAsyncCommandInfo(request_box_cmd_type type, IBoxPtr boxPtr, BoxInfoPtr boxInfoPtr)
+{
+ m_type = type;
+ m_box = boxPtr;
+ m_boxInfo = boxInfoPtr;
+}
+
+BoxAsyncCommandInfo::BoxAsyncCommandInfo(request_box_cmd_type type, IBoxPtr boxPtr, std::string& appContentInfo)
+{
+ m_type = type;
+ m_box = boxPtr;
+ m_appContentInfo = appContentInfo;
+}
+
+BoxLoadBalancer::BoxLoadBalancer()
+{
+ m_vecBoxAsyncCommandList.clear();
+ m_boxLoadBalanceTimer = NULL;
+ m_updateTimeCount = 0.0f;
+}
+
+BoxLoadBalancer::~BoxLoadBalancer()
+{
+
+}
+
+Eina_Bool BoxLoadBalancer::requestBoxLoadBalanceCallback(void* data)
+{
+ LogD("requestBoxLoadBalanceCallback");
+ BoxLoadBalancer* This = static_cast<BoxLoadBalancer*>(data);
+
+ if (This->m_vecBoxAsyncCommandList.empty()) {
+ LogD("m_vecBoxAsyncCommandList.size() is empty");
+ This->m_boxLoadBalanceTimer = NULL;
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ BoxAsyncCommandInfoPtr boxCommandPtr = This->m_vecBoxAsyncCommandList.front();
+
+ switch (boxCommandPtr->getType()) {
+ case BOX_AYNC_REQUEST_CMD_SHOW:
+ boxCommandPtr->getBoxPtr()->show();
+ break;
+ case BOX_AYNC_REQUEST_CMD_RESUME:
+ boxCommandPtr->getBoxPtr()->resume();
+ break;
+ case BOX_AYNC_REQUEST_CMD_UPDATE:
+ {
+ std::string contentInfo = boxCommandPtr->getAppContentInfo();
+ boxCommandPtr->getBoxPtr()->update(contentInfo);
+ break;
+ }
+ default:
+ LogW("Wrong command %d", boxCommandPtr->getType());
+ }
+
+ This->m_vecBoxAsyncCommandList.erase(This->m_vecBoxAsyncCommandList.begin());
+ int commandListNumber = This->m_vecBoxAsyncCommandList.size();
+
+ if (commandListNumber > BOX_UPDATE_QUEUE_SIZE_THRESHOLD) {
+ float timecountbefore = BOX_UPDATE_TIME + BOX_UPDATE_TIME_INC * (commandListNumber - BOX_UPDATE_QUEUE_SIZE_THRESHOLD);
+
+ if (timecountbefore > BOX_UPDATE_MAX_TIME) {
+ timecountbefore = BOX_UPDATE_MAX_TIME;
+ }
+ ecore_timer_del(This->m_boxLoadBalanceTimer);
+
+ This->m_updateTimeCount = timecountbefore;
+
+ This->m_boxLoadBalanceTimer = ecore_timer_add( This->m_updateTimeCount, requestBoxLoadBalanceCallback, This);
+ LogD("requestBoxLoadBalanceCallback launched pending until %f m_updateTimeCount %d size", This->m_updateTimeCount, commandListNumber);
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ if (commandListNumber > 0 && (This->m_updateTimeCount > BOX_UPDATE_TIME)) {
+ ecore_timer_del(This->m_boxLoadBalanceTimer);
+ This->m_updateTimeCount = BOX_UPDATE_TIME;
+ This->m_boxLoadBalanceTimer = ecore_timer_add( This->m_updateTimeCount, requestBoxLoadBalanceCallback, This);
+ }
+
+ if (commandListNumber > 0) {
+ LogD("m_vecBoxAsyncCommandList.size() = %d", commandListNumber);
+ return ECORE_CALLBACK_RENEW;
+ }
+
+ This->m_boxLoadBalanceTimer = NULL;
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+void BoxLoadBalancer::eraseBoxAsyncCommandFromQueue(IBoxPtr boxPtr)
+{
+ if (!m_vecBoxAsyncCommandList.empty()) {
+ for (std::vector<BoxAsyncCommandInfoPtr>::iterator it = m_vecBoxAsyncCommandList.begin();
+ it != m_vecBoxAsyncCommandList.end(); it++) {
+ BoxAsyncCommandInfoPtr boxCommandPtr = *it;
+ if ( boxCommandPtr->getBoxPtr() == boxPtr) {
+ m_vecBoxAsyncCommandList.erase(it);
+ LogD("m_vecBoxAsyncCommandList.erase");
+ return;
+ }
+ }
+ }
+}
+
+void BoxLoadBalancer::pushBoxAsyncCommandIntoQueue(request_box_cmd_type cmdType, IBoxPtr boxPtr, BoxInfoPtr boxInfoPtr)
+{
+ BoxAsyncCommandInfoPtr boxAsyncInfo = BoxAsyncCommandInfoPtr(new BoxAsyncCommandInfo(cmdType, boxPtr, boxInfoPtr));
+
+ m_vecBoxAsyncCommandList.push_back(boxAsyncInfo);
+ LogD("m_vecBoxAsyncCommandList added = %d ",m_vecBoxAsyncCommandList.size());
+
+ if (!m_boxLoadBalanceTimer) {
+ // start timer for clearing existing snapshot in case of only pd open
+ m_boxLoadBalanceTimer = ecore_timer_add(BOX_UPDATE_TIME, requestBoxLoadBalanceCallback, this);
+ m_updateTimeCount = BOX_UPDATE_TIME;
+ LogD("timer launched");
+ }
+}
+
+void BoxLoadBalancer::pushBoxAsyncCommandIntoQueue(request_box_cmd_type cmdType, IBoxPtr boxPtr, std::string& appContentInfo)
+{
+ BoxAsyncCommandInfoPtr boxAsyncInfo = BoxAsyncCommandInfoPtr(new BoxAsyncCommandInfo(cmdType, boxPtr, appContentInfo));
+
+ m_vecBoxAsyncCommandList.push_back(boxAsyncInfo);
+ LogD("m_vecBoxAsyncCommandList added = %d ",m_vecBoxAsyncCommandList.size());
+
+ if (!m_boxLoadBalanceTimer) {
+ // start timer for clearing existing snapshot in case of only pd open
+ m_boxLoadBalanceTimer = ecore_timer_add(BOX_UPDATE_TIME, requestBoxLoadBalanceCallback, this);
+ LogD("timer launched");
+ }
+}
+
+void BoxLoadBalancer::pushBoxAsyncCommandIntoTop(request_box_cmd_type cmdType, IBoxPtr boxPtr, BoxInfoPtr boxInfoPtr)
+{
+ BoxAsyncCommandInfoPtr boxAsyncInfo = BoxAsyncCommandInfoPtr(new BoxAsyncCommandInfo(cmdType, boxPtr, boxInfoPtr));
+ m_vecBoxAsyncCommandList.insert(m_vecBoxAsyncCommandList.begin(), boxAsyncInfo);
+ LogD("m_vecBoxAsyncCommandList added = %d ",m_vecBoxAsyncCommandList.size());
+
+ if (!m_boxLoadBalanceTimer) {
+ // start timer for clearing existing snapshot in case of only pd open
+ m_boxLoadBalanceTimer = ecore_timer_add(BOX_UPDATE_TIME, requestBoxLoadBalanceCallback, this);
+ m_updateTimeCount = BOX_UPDATE_TIME;
+ LogD("timer launched");
+ }
+}
+
+void BoxLoadBalancer::stopLoadBalancer()
+{
+ if (m_boxLoadBalanceTimer) {
+ ecore_timer_del(m_boxLoadBalanceTimer);
+ m_boxLoadBalanceTimer = NULL;
+ }
+ m_vecBoxAsyncCommandList.clear();
+}
diff --git a/src_wearable/Core/BoxLoadBalancer.h b/src_wearable/Core/BoxLoadBalancer.h
new file mode 100755
index 0000000..3500396
--- /dev/null
+++ b/src_wearable/Core/BoxLoadBalancer.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxLoadBalancer.h
+ * @author Minhyung Ko (minhyung.ko@samsung.com)
+ */
+#ifndef BOX_LOAD_BALANCER_H
+#define BOX_LOAD_BALANCER_H
+
+#include <Ecore.h>
+#include <memory>
+#include <string>
+#include <vector>
+#include "BoxData.h"
+#include "IBox.h"
+#include "IBoxManager.h"
+
+typedef enum {
+ BOX_AYNC_REQUEST_CMD_SHOW,
+ BOX_AYNC_REQUEST_CMD_RESUME,
+ BOX_AYNC_REQUEST_CMD_UPDATE
+} request_box_cmd_type;
+
+
+class BoxAsyncCommandInfo
+{
+public:
+ BoxAsyncCommandInfo() {};
+ BoxAsyncCommandInfo(request_box_cmd_type, IBoxPtr, BoxInfoPtr);
+ BoxAsyncCommandInfo(request_box_cmd_type, IBoxPtr, std::string&);
+ ~BoxAsyncCommandInfo() {};
+
+ request_box_cmd_type getType() { return m_type; }
+ IBoxPtr getBoxPtr() { return m_box; }
+ BoxInfoPtr getBoxInfoPtr() {return m_boxInfo; }
+ std::string getAppContentInfo() {return m_appContentInfo; }
+
+private:
+ request_box_cmd_type m_type;
+ IBoxPtr m_box;
+ BoxInfoPtr m_boxInfo;
+ std::string m_appContentInfo;
+};
+
+typedef std::shared_ptr<BoxAsyncCommandInfo> BoxAsyncCommandInfoPtr;
+
+class BoxLoadBalancer
+{
+public:
+ BoxLoadBalancer();
+ ~BoxLoadBalancer();
+
+ static Eina_Bool requestBoxLoadBalanceCallback(void* data);
+
+ void eraseBoxAsyncCommandFromQueue(IBoxPtr boxPtr);
+ void pushBoxAsyncCommandIntoQueue(request_box_cmd_type type, IBoxPtr boxPtr, BoxInfoPtr boxInfoPtr);
+ void pushBoxAsyncCommandIntoQueue(request_box_cmd_type, IBoxPtr, std::string&);
+ void pushBoxAsyncCommandIntoTop(request_box_cmd_type cmdType, IBoxPtr boxPtr, BoxInfoPtr boxInfoPtr);
+ void stopLoadBalancer();
+
+private:
+ // timer for load balance of boxes
+ Ecore_Timer* m_boxLoadBalanceTimer;
+ std::vector<BoxAsyncCommandInfoPtr> m_vecBoxAsyncCommandList;
+ float m_updateTimeCount;
+};
+#endif // BOX_LOAD_BALANCER_H
diff --git a/src_wearable/Core/BoxManager.cpp b/src_wearable/Core/BoxManager.cpp
new file mode 100755
index 0000000..8f1bef5
--- /dev/null
+++ b/src_wearable/Core/BoxManager.cpp
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxManager.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include "config.h"
+#include "BoxManager.h"
+
+#include <string>
+#include <map>
+#include <ctime>
+#include <EWebKit2.h>
+#include <Plugin/IBoxPluginFactory.h>
+#include <Plugin/box_plugin_interface.h>
+#include <vconf.h>
+#include "Util/Log.h"
+#include "Util/Util.h"
+#include "IBox.h"
+#include "Box.h"
+#include "BoxData.h"
+
+static const std::string defaultBoxType("app");
+
+BoxManager::BoxManager(IBoxPluginFactoryPtr factory)
+ : m_boxFactory(factory)
+ , m_boxLoadBalancer()
+{
+ LogD("enter");
+}
+
+BoxManager::~BoxManager()
+{
+ LogD("enter");
+}
+
+bool BoxManager::doCommand(const request_cmd_type type, const BoxInfoPtr& boxInfo)
+{
+ bool result = false;
+
+ switch (type) {
+ case REQUEST_CMD_ADD_BOX:
+ result = requestAddBox(boxInfo, m_defaultContext);
+ break;
+ case REQUEST_CMD_REMOVE_BOX:
+ if (boxInfo->instanceId.empty() && !boxInfo->boxId.empty()) {
+ result = requestRemoveBoxByBoxId(boxInfo);
+ break;
+ }
+ if (!boxInfo->instanceId.empty()) {
+ result = requestRemoveBoxByInstanceId(boxInfo);
+ break;
+ }
+ case REQUEST_CMD_RESIZE_BOX:
+ result = requestResizeBox(boxInfo->instanceId, boxInfo->boxWidth, boxInfo->boxHeight);
+ break;
+ case REQUEST_CMD_RESUME_BOX:
+ result = requestResumeBox(boxInfo->instanceId);
+ break;
+ case REQUEST_CMD_PAUSE_BOX:
+ result = requestPauseBox(boxInfo->instanceId);
+ break;
+ case REQUEST_CMD_RESUME_ALL:
+ result = requestResumeAll();
+ break;
+ case REQUEST_CMD_PAUSE_ALL:
+ result = requestPauseAll();
+ break;
+ case REQUEST_CMD_OPEN_PD:
+ result = requestOpenPd(boxInfo->instanceId,
+ boxInfo->pdWidth, boxInfo->pdHeight,
+ boxInfo->pdX, boxInfo->pdY);
+ break;
+ case REQUEST_CMD_CLOSE_PD:
+ result = requestClosePd(boxInfo->instanceId);
+ break;
+ case REQUEST_CMD_CHANGE_PERIOD:
+ result = requestChangePeriod(boxInfo->instanceId, boxInfo->period);
+ break;
+ case REQUEST_CMD_UPDATE_BOX:
+ result = requestUpdateBox(boxInfo->boxId, boxInfo->appContentInfo);
+ break;
+ case REQUEST_CMD_UPDATE_ALL:
+ result = requestUpdateAll(boxInfo->instanceId);
+ break;
+ case REQUEST_CMD_UPDATE_APPBOX:
+ result = requestUpdateAppBox(boxInfo->instanceId);
+ break;
+ default:
+ LogD("not available request type");
+ break;
+ }
+
+ return result;
+}
+
+bool BoxManager::requestAddBox(BoxInfoPtr boxInfo, EwkContextPtr ewkContext)
+{
+ LogD("enter");
+ IBoxPtr box;
+
+ // create new box
+ try {
+ if (!ewkContext) {
+ if (!m_defaultContext) {
+ m_defaultContext = EwkContextPtr(ewk_context_new(), EwkContextDeleter());
+ }
+ ewkContext = m_defaultContext;
+ }
+
+ initEwkContextSetting(ewkContext);
+ box = Box::create(boxInfo, m_boxFactory, ewkContext);
+ } catch (...) {
+ LogD("exection occurs during adding box");
+ return false;
+ }
+
+ m_boxLoadBalancer.pushBoxAsyncCommandIntoTop(BOX_AYNC_REQUEST_CMD_SHOW, box, boxInfo);
+
+ insertBoxMap(boxInfo->instanceId, box);
+ return true;
+}
+
+bool BoxManager::requestRemoveBox(std::string& instanceId)
+{
+ LogD("enter");
+ IBoxPtr box = searchBoxMap(instanceId);
+ if (!box) {
+ return false;
+ }
+
+ if (!box->hide()) {
+ return false;
+ }
+
+ m_boxMap.erase(instanceId);
+ return true;
+}
+
+bool BoxManager::requestRemoveBoxByInstanceId(BoxInfoPtr boxInfo)
+{
+ LogD("enter");
+
+ IBoxPtr box = searchBoxMap(boxInfo->instanceId);
+ m_boxLoadBalancer.eraseBoxAsyncCommandFromQueue(box);
+
+ if (!requestRemoveBox(boxInfo->instanceId)) {
+ return false;
+ }
+ eraseBoxMap(boxInfo->instanceId);
+ updateEwkContext(boxInfo->boxId);
+ return true;
+}
+
+bool BoxManager::requestRemoveBoxByBoxId(BoxInfoPtr boxInfo)
+{
+ LogD("enter");
+
+ bool found = false;
+ for (auto it = m_boxMap.begin(); it != m_boxMap.end(); ) {
+ if (it->first.find(boxInfo->boxId) == std::string::npos) {
+ ++it;
+ continue;
+ }
+
+ IBoxPtr box = searchBoxMap(boxInfo->instanceId);
+ m_boxLoadBalancer.eraseBoxAsyncCommandFromQueue(box);
+
+ found = true;
+ it->second->hide();
+ m_boxMap.erase((it++)->first);
+ }
+
+ if (!found) {
+ return false;
+ }
+
+ updateEwkContext(boxInfo->boxId);
+ return true;
+}
+
+bool BoxManager::requestResizeBox(std::string& instanceId, int width, int height)
+{
+ LogD("enter");
+ IBoxPtr box = searchBoxMap(instanceId);
+ if (!box) {
+ return false;
+ }
+
+ m_boxLoadBalancer.eraseBoxAsyncCommandFromQueue(box);
+ return box->resize(width, height);
+}
+
+bool BoxManager::requestResumeBox(std::string& instanceId)
+{
+ LogD("enter");
+ IBoxPtr box = searchBoxMap(instanceId);
+ if (!box) {
+ return false;
+ }
+ BoxInfoPtr boxInfo;
+ box->setCurrent();
+
+ if (box->needToUpdate()) {
+ m_boxLoadBalancer.pushBoxAsyncCommandIntoQueue(BOX_AYNC_REQUEST_CMD_RESUME, box, boxInfo);
+ }
+ return true;
+}
+
+bool BoxManager::requestPauseBox(std::string& instanceId)
+{
+ LogD("enter");
+ IBoxPtr box = searchBoxMap(instanceId);
+ if (!box) {
+ return false;
+ }
+ m_boxLoadBalancer.eraseBoxAsyncCommandFromQueue(box);
+
+ return box->pause(false);
+}
+
+bool BoxManager::requestResumeAll()
+{
+ LogD("enter");
+ m_boxLoadBalancer.stopLoadBalancer();
+
+ for (auto it = m_boxMap.begin(); it != m_boxMap.end(); it++) {
+ if (it->second->isCurrentTab()) {
+ std::string strBox = it->first;
+ requestResumeBox(strBox);
+ }
+ }
+
+ return true;
+}
+
+bool BoxManager::requestPauseAll()
+{
+ LogD("enter");
+ for (auto it = m_boxMap.begin(); it != m_boxMap.end(); it++) {
+ if (it->second->isCurrentTab()) {
+ // paused by entering background
+ it->second->pause(true);
+ }
+ }
+ m_boxLoadBalancer.stopLoadBalancer();
+ return true;
+}
+
+bool BoxManager::requestOpenPd(
+ std::string& instanceId,
+ int width, int height, double x, double y)
+{
+ LogD("enter");
+ IBoxPtr box = searchBoxMap(instanceId);
+ if (!box) {
+ return false;
+ }
+
+ m_boxLoadBalancer.eraseBoxAsyncCommandFromQueue(box);
+
+ return box->openPd(width, height, x, y);
+}
+
+bool BoxManager::requestClosePd(std::string& instanceId)
+{
+ LogD("enter");
+ IBoxPtr box = searchBoxMap(instanceId);
+ if (!box) {
+ return false;
+ }
+
+ return box->closePd();
+}
+
+bool BoxManager::requestChangePeriod(std::string& instanceId, float period)
+{
+ LogD("enter");
+ IBoxPtr box = searchBoxMap(instanceId);
+ if (!box) {
+ return false;
+ }
+
+ return box->changePeriod(period);
+}
+
+bool BoxManager::requestUpdateBox(std::string& boxId, std::string& appContentInfo)
+{
+ LogD("enter");
+
+ IBoxPtr box;
+ box.reset();
+
+ for (auto it = m_boxMap.begin(); it != m_boxMap.end(); ++it) {
+ if (it->first.find(boxId) == std::string::npos) {
+ continue;
+ }
+ box = it->second;
+ box->setNeedToUpdate();
+ m_boxLoadBalancer.eraseBoxAsyncCommandFromQueue(box);
+ m_boxLoadBalancer.pushBoxAsyncCommandIntoQueue(BOX_AYNC_REQUEST_CMD_UPDATE, box, appContentInfo);
+ }
+
+ return true;
+}
+
+bool BoxManager::requestUpdateAll(std::string& instanceId)
+{
+ LogD("enter");
+ UNUSED_PARAM(instanceId);
+
+ IBoxPtr box;
+ box.reset();
+
+ m_boxLoadBalancer.stopLoadBalancer();
+
+ for (auto it = m_boxMap.begin(); it != m_boxMap.end(); ++it) {
+ if (it->second) {
+ box = it->second;
+ box->setNeedToUpdate();
+
+ if (!box->isPaused()) {
+ m_boxLoadBalancer.pushBoxAsyncCommandIntoQueue(BOX_AYNC_REQUEST_CMD_UPDATE, box, box->getBoxInfo()->appContentInfo);
+ }
+ // TODO: box->update(requestTime, box->getBoxInfo()->appContentInfo);
+ }
+ }
+ return true;
+}
+
+bool BoxManager::requestUpdateAppBox(std::string& instanceId)
+{
+ LogD("enter");
+ UNUSED_PARAM(instanceId);
+
+ IBoxPtr box;
+ box.reset();
+
+ for (auto it = m_boxMap.begin(); it != m_boxMap.end(); ++it) {
+ if (it->second) {
+ box = it->second;
+
+ if(box->getBoxInfo()->boxType.find(defaultBoxType) == std::string::npos) {
+ continue;
+ }
+ m_boxLoadBalancer.eraseBoxAsyncCommandFromQueue(box);
+ box->setNeedToUpdate();
+ if (!box->isPaused()) {
+ m_boxLoadBalancer.pushBoxAsyncCommandIntoQueue(BOX_AYNC_REQUEST_CMD_UPDATE, box, box->getBoxInfo()->appContentInfo);
+ }
+ }
+ }
+ return true;
+}
+
+void BoxManager::updateEwkContext(std::string& boxId)
+{
+ // this should be implemented by derived class
+ UNUSED_PARAM(boxId);
+}
+
+int BoxManager::getBoxCount(std::string appId)
+{
+ int count = 0;
+ for (auto it = m_boxMap.begin(); it != m_boxMap.end(); it++) {
+ if (it->first.find(appId) == std::string::npos) {
+ continue;
+ }
+ count++;
+ }
+ return count;
+}
+
+void BoxManager::insertBoxMap(std::string& instanceId, IBoxPtr box)
+{
+ if (!searchBoxMap(instanceId)) {
+ LogD("insert box to map: %s", instanceId.c_str());
+ m_boxMap.insert(BoxMapPair(instanceId, box));
+ } else {
+ LogD("this box was already inserted!");
+ }
+}
+
+void BoxManager::eraseBoxMap(std::string& instanceId)
+{
+ LogD("erase box to map");
+ if (!searchBoxMap(instanceId)) {
+ LogD("not available box");
+ return;
+ }
+
+ m_boxMap.erase(instanceId);
+}
+
+void BoxManager::updateBoxMap(std::string& instanceId, IBoxPtr box)
+{
+ if (searchBoxMap(instanceId)) {
+ eraseBoxMap(instanceId);
+ }
+
+ insertBoxMap(instanceId, box);
+}
+
+IBoxPtr BoxManager::searchBoxMap(std::string& instanceId)
+{
+ LogD("enter");
+ IBoxPtr box;
+ box.reset();
+ auto it = m_boxMap.find(instanceId);
+ if (it != m_boxMap.end()) {
+ LogD("found box: %s (%p)", it->first.c_str(), it->second.get());
+ box = it->second;
+ }
+
+ return box;
+}
+
+void BoxManager::clearBoxMap()
+{
+ m_boxMap.clear();
+}
+
+void BoxManager::EwkContextDeleter::operator()(Ewk_Context* ptr)
+{
+ LogD("ewk context delete");
+ if (ptr) {
+ ewk_object_unref(ptr);
+ }
+}
+
+void BoxManager::initEwkContextSetting(EwkContextPtr ewkContext)
+{
+ LogD("enter");
+
+ // proxy server setting
+ char *proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY);
+ std::string dummyProxy("0.0.0.0");
+ if (proxy && strlen(proxy) && (dummyProxy != proxy)) {
+ LogD("proxy address: %s", proxy);
+ ewk_context_proxy_uri_set(ewkContext.get(), proxy);
+ } else {
+ LogD("proxy address is empty");
+ ewk_context_proxy_uri_set(ewkContext.get(), NULL);
+ }
+
+ if (proxy) {
+ free(proxy);
+ }
+
+ Ewk_Cookie_Manager *ewkCookieManager;
+ ewkCookieManager =
+ ewk_context_cookie_manager_get(ewkContext.get());
+ ewk_cookie_manager_accept_policy_set(ewkCookieManager,
+ EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
+#if !ENABLE(WEBKIT_UPVERSION)
+ ewk_context_tizen_extensible_api_set(ewkContext.get(), EWK_EXTENSIBLE_API_SUPPORT_MULTIMEDIA, EINA_FALSE);
+#endif
+}
diff --git a/src_wearable/Core/BoxManager.h b/src_wearable/Core/BoxManager.h
new file mode 100755
index 0000000..3617d96
--- /dev/null
+++ b/src_wearable/Core/BoxManager.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxManager.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_MANAGER_H
+#define BOX_MANAGER_H
+
+#include <map>
+#include <string>
+#include <memory>
+#include <Plugin/box_plugin_interface.h>
+#include <Plugin/IBoxPluginFactory.h>
+#include "BoxData.h"
+#include "BoxLoadBalancer.h"
+#include "IBox.h"
+#include "IBoxManager.h"
+
+#define EXPORT_CLASS __attribute__ ((visibility("default")))
+
+class EXPORT_CLASS BoxManager: public IBoxManager {
+ public:
+ static IBoxManagerPtr create(IBoxPluginFactoryPtr factory)
+ {
+ return IBoxManagerPtr(new BoxManager(factory));
+ };
+ virtual bool doCommand(const request_cmd_type type, const BoxInfoPtr& boxInfo);
+ virtual ~BoxManager();
+
+ protected:
+ virtual bool requestAddBox(BoxInfoPtr boxInfo, EwkContextPtr ewkContext);
+ virtual bool requestRemoveBox(std::string& instanceId); // deprecated
+ virtual bool requestRemoveBoxByInstanceId(BoxInfoPtr boxInfo);
+ virtual bool requestRemoveBoxByBoxId(BoxInfoPtr boxInfo);
+ virtual bool requestResizeBox(std::string& instanceId, int width, int height);
+ virtual bool requestResumeBox(std::string& instanceId);
+ virtual bool requestPauseBox(std::string& instanceId);
+ virtual bool requestResumeAll();
+ virtual bool requestPauseAll();
+ virtual bool requestOpenPd(
+ std::string& instanceId,
+ int width, int height, double x, double y);
+ virtual bool requestClosePd(std::string& instanceId);
+ virtual bool requestChangePeriod(std::string& instanceId, float period);
+ virtual bool requestUpdateBox(std::string& boxId, std::string& appContentInfo);
+ virtual bool requestUpdateAll(std::string& instanceId);
+ virtual bool requestUpdateAppBox(std::string& instanceId);
+
+ virtual void updateEwkContext(std::string& boxId);
+ int getBoxCount(std::string appId);
+
+ // ewk context deleter
+ struct EwkContextDeleter {
+ void operator()(Ewk_Context* ptr);
+ };
+
+ explicit BoxManager(IBoxPluginFactoryPtr factory);
+ IBoxPtr searchBoxMap(std::string& instanceId);
+
+ private:
+ void initEwkContextSetting(EwkContextPtr ewkContext);
+ // map operations
+ void insertBoxMap(std::string& instanceId, IBoxPtr box);
+ void eraseBoxMap(std::string& instanceId);
+ void updateBoxMap(std::string& instanceId, IBoxPtr box);
+ void clearBoxMap();
+
+ typedef std::map<std::string, IBoxPtr> BoxMap;
+ typedef std::pair<std::string, IBoxPtr> BoxMapPair;
+ BoxMap m_boxMap;
+ IBoxPluginFactoryPtr m_boxFactory;
+ EwkContextPtr m_defaultContext;
+
+ BoxLoadBalancer m_boxLoadBalancer;
+};
+
+#endif // BOX_MANAGER_H
diff --git a/src_wearable/Core/BoxState.cpp b/src_wearable/Core/BoxState.cpp
new file mode 100644
index 0000000..9460857
--- /dev/null
+++ b/src_wearable/Core/BoxState.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxState.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include "IBoxContext.h"
+#include "IBoxState.h"
+#include "BoxState.h"
+
+// BoxState
+void BoxState::switchState()
+{
+ // TODO this creation may be wrong..
+ m_context->setState(IBoxStatePtr(this));
+}
+
+void BoxState::setContext(IBoxContextPtr context)
+{
+ m_context = context;
+}
+
+IBoxContextPtr BoxState::getContext()
+{
+ return m_context;
+}
+
+// BoxReadyState
+IBoxStatePtr BoxInitState::permitShow()
+{
+ return IBoxStatePtr(BoxShowState::create(getContext()));
+}
+
+// BoxShowState
+IBoxStatePtr BoxShowState::permitShow()
+{
+ // In this case, existing state needn't to be changed
+ return IBoxStatePtr(this);
+}
+
+IBoxStatePtr BoxShowState::permitHide()
+{
+ return IBoxStatePtr(BoxHideState::create(getContext()));
+}
+
+IBoxStatePtr BoxShowState::permitOpenPd()
+{
+ return IBoxStatePtr(BoxOpenPdState::create(getContext()));
+}
+
+IBoxStatePtr BoxShowState::permitPause()
+{
+ return IBoxStatePtr(BoxPauseState::create(getContext()));
+}
+
+// BoxHideState
+IBoxStatePtr BoxHideState::permitShutdown()
+{
+ // In this case, existing state needn't to be changed
+ // because there is no state to be changed from Hide State
+ return IBoxStatePtr(this);
+}
+
+// BoxOpenPdState
+IBoxStatePtr BoxOpenPdState::permitClosePd()
+{
+ return IBoxStatePtr(BoxClosePdState::create(getContext()));
+}
+
+// BoxClosePdState
+IBoxStatePtr BoxClosePdState::permitShow()
+{
+ return IBoxStatePtr(BoxShowState::create(getContext()));
+}
+
+// BoxPauseState
+IBoxStatePtr BoxPauseState::permitResume()
+{
+ return IBoxStatePtr(BoxResumeState::create(getContext()));
+}
+
+IBoxStatePtr BoxPauseState::permitHide()
+{
+ return IBoxStatePtr(BoxHideState::create(getContext()));
+}
+
+// BoxResumeState
+IBoxStatePtr BoxResumeState::permitShow()
+{
+ return IBoxStatePtr(BoxShowState::create(getContext()));
+}
+
+IBoxStatePtr BoxResumeState::permitHide()
+{
+ return IBoxStatePtr(BoxHideState::create(getContext()));
+}
diff --git a/src_wearable/Core/BoxState.h b/src_wearable/Core/BoxState.h
new file mode 100644
index 0000000..5023386
--- /dev/null
+++ b/src_wearable/Core/BoxState.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxState.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_STATE
+#define BOX_STATE
+
+#include "IBoxState.h"
+#include "IBoxContext.h"
+
+/*
+#define CHECK_BOX_STATE(currentState, operation) \
+ IBoxStatePtr state; \
+ try { \
+ state = currentState->operation(); \
+ } catch (...) { \
+ return false; \
+ } \
+
+#define SWITCH_BOX_STATE() \
+ state->switchState() \
+*/
+
+#define CHECK_BOX_STATE(currentState, operation)
+#define SWITCH_BOX_STATE()
+
+class BoxState: public IBoxState {
+ public:
+ virtual IBoxStatePtr permitShow() { throw this; };
+ virtual IBoxStatePtr permitHide() { throw this; };
+ virtual IBoxStatePtr permitResume() { throw this; };
+ virtual IBoxStatePtr permitPause() { throw this; };
+ virtual IBoxStatePtr permitOpenPd() { throw this; };
+ virtual IBoxStatePtr permitClosePd() { throw this ; };
+ virtual IBoxStatePtr permitShutdown() { throw this; };
+ virtual void switchState();
+ virtual ~BoxState() {};
+
+ protected:
+ explicit BoxState(IBoxContextPtr context) : m_context(context) {};
+ IBoxContextPtr getContext();
+
+ private:
+ void setContext(IBoxContextPtr context);
+ IBoxContextPtr m_context;
+};
+
+class BoxInitState: public BoxState {
+ public:
+ static IBoxStatePtr create(IBoxContextPtr context)
+ {
+ return IBoxStatePtr(new BoxInitState(context));
+ };
+ virtual IBoxStatePtr permitShow();
+ virtual ~BoxInitState() {};
+
+ private:
+ explicit BoxInitState(IBoxContextPtr context) : BoxState(context) {};
+};
+
+class BoxShowState: public BoxState {
+ public:
+ static IBoxStatePtr create(IBoxContextPtr context)
+ {
+ return IBoxStatePtr(new BoxShowState(context));
+ };
+ virtual IBoxStatePtr permitShow();
+ virtual IBoxStatePtr permitHide();
+ virtual IBoxStatePtr permitOpenPd();
+ virtual IBoxStatePtr permitPause();
+ virtual ~BoxShowState() {};
+
+ private:
+ explicit BoxShowState(IBoxContextPtr context) : BoxState(context) {};
+};
+
+class BoxHideState: public BoxState {
+ public:
+ static IBoxStatePtr create(IBoxContextPtr context)
+ {
+ return IBoxStatePtr(new BoxHideState(context));
+ };
+ virtual IBoxStatePtr permitShutdown();
+ virtual ~BoxHideState() {};
+
+ private:
+ explicit BoxHideState(IBoxContextPtr context) : BoxState(context) {};
+};
+
+class BoxOpenPdState: public BoxState {
+ public:
+ static IBoxStatePtr create(IBoxContextPtr context)
+ {
+ return IBoxStatePtr(new BoxOpenPdState(context));
+ };
+ virtual IBoxStatePtr permitClosePd();
+ virtual ~BoxOpenPdState() {};
+
+ private:
+ explicit BoxOpenPdState(IBoxContextPtr context) : BoxState(context) {};
+};
+
+class BoxClosePdState: public BoxState {
+ public:
+ static IBoxStatePtr create(IBoxContextPtr context)
+ {
+ return IBoxStatePtr(new BoxClosePdState(context));
+ };
+ virtual IBoxStatePtr permitShow();
+ virtual ~BoxClosePdState() {};
+
+ private:
+ explicit BoxClosePdState(IBoxContextPtr context) : BoxState(context) {};
+};
+
+class BoxPauseState: public BoxState {
+ public:
+ static IBoxStatePtr create(IBoxContextPtr context)
+ {
+ return IBoxStatePtr(new BoxPauseState(context));
+ };
+ virtual IBoxStatePtr permitResume();
+ virtual IBoxStatePtr permitHide();
+ virtual ~BoxPauseState() {};
+
+ private:
+ explicit BoxPauseState(IBoxContextPtr context) : BoxState(context) {};
+};
+
+class BoxResumeState: public BoxState {
+ public:
+ static IBoxStatePtr create(IBoxContextPtr context)
+ {
+ return IBoxStatePtr(new BoxResumeState(context));
+ };
+ virtual IBoxStatePtr permitShow();
+ virtual IBoxStatePtr permitHide();
+ virtual ~BoxResumeState() {};
+
+ private:
+ explicit BoxResumeState(IBoxContextPtr context) : BoxState(context) {};
+};
+#endif // BOX_STATE
diff --git a/src_wearable/Core/BoxUpdateTimer.cpp b/src_wearable/Core/BoxUpdateTimer.cpp
new file mode 100644
index 0000000..67dcd19
--- /dev/null
+++ b/src_wearable/Core/BoxUpdateTimer.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxUpdateTimer.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <Ecore.h>
+#include <Core/Util/Log.h>
+#include "BoxUpdateTimer.h"
+
+#define UPDATE_TIME_MIN 1800.0f
+
+BoxUpdateTimer::BoxUpdateTimer(float period, Ecore_Task_Cb callback, void* data)
+ : m_period(period)
+ , m_callback(callback)
+ , m_data(data)
+ , m_timer()
+ , m_startTime()
+ , m_bTimerRunning(false)
+{
+ LogD("enter");
+}
+
+BoxUpdateTimer::~BoxUpdateTimer()
+{
+ LogD("enter");
+}
+
+void BoxUpdateTimer::start()
+{
+ if (m_period <= 0.0f ) {
+ return;
+ }
+
+ if (m_period < UPDATE_TIME_MIN) {
+ LogD("reset to minimum period(%f)", UPDATE_TIME_MIN);
+ m_period = UPDATE_TIME_MIN;
+ }
+
+ if (m_timer) {
+ stop();
+ }
+
+ m_timer = ecore_timer_add(m_period, m_callback, m_data);
+ m_startTime = time(NULL);
+ m_bTimerRunning = true;
+}
+
+void BoxUpdateTimer::continueTimer(float period)
+{
+ if (period <= 0.0f ) {
+ return;
+ }
+
+ if (m_timer) {
+ stop();
+ }
+
+ m_timer = ecore_timer_add(period, m_callback, m_data);
+ // this function does not need m_startTime beacuse this is concept for continue not really start
+ // box.h update algorithm used boxupdatetimer
+ m_bTimerRunning = true;
+}
+
+void BoxUpdateTimer::stop()
+{
+ if (m_timer) {
+ ecore_timer_del(m_timer);
+ m_timer = NULL;
+ }
+ m_bTimerRunning = false;
+}
+
+void BoxUpdateTimer::resume()
+{
+ LogD("enter");
+ ecore_timer_thaw(m_timer);
+}
+
+void BoxUpdateTimer::pause()
+{
+ LogD("enter");
+ ecore_timer_freeze(m_timer);
+}
+
+void BoxUpdateTimer::restart()
+{
+ if (m_timer) {
+ ecore_timer_reset(m_timer);
+ } else {
+ start();
+ }
+}
+
+void BoxUpdateTimer::setPeriod(float period)
+{
+ m_period = period;
+ restart();
+}
diff --git a/src_wearable/Core/BoxUpdateTimer.h b/src_wearable/Core/BoxUpdateTimer.h
new file mode 100644
index 0000000..1238cc0
--- /dev/null
+++ b/src_wearable/Core/BoxUpdateTimer.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxUpdateTimer.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_UPDATE_TIMER_H
+#define BOX_UPDATE_TIMER_H
+
+#include <ctime>
+#include <Ecore.h>
+#include "Util/ITimer.h"
+
+class BoxUpdateTimer: public ITimer {
+ public:
+ static ITimerPtr create(float period, Ecore_Task_Cb callback, void* data)
+ {
+ return ITimerPtr(new BoxUpdateTimer(period, callback, data));
+ };
+ void start();
+ // instant timer for web-provider box contorl system
+ void continueTimer(float period);
+ void stop();
+ void resume();
+ void pause();
+ void restart();
+ void setPeriod(float period);
+ float getPeriod() { return m_period; }
+ time_t getStartTime() { return m_startTime; }
+ bool isRunning() { return m_bTimerRunning; }
+ ~BoxUpdateTimer();
+
+ private:
+ explicit BoxUpdateTimer(float period, Ecore_Task_Cb callback, void* data);
+ float m_period;
+ Ecore_Task_Cb m_callback;
+ void* m_data;
+ Ecore_Timer* m_timer;
+ time_t m_startTime;
+ bool m_bTimerRunning;
+};
+
+#endif // BOX_UPDATE_TIMER_H
diff --git a/src_wearable/Core/Buffer/BoxRenderBuffer.cpp b/src_wearable/Core/Buffer/BoxRenderBuffer.cpp
new file mode 100755
index 0000000..8a5874b
--- /dev/null
+++ b/src_wearable/Core/Buffer/BoxRenderBuffer.cpp
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxRenderBuffer.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <Ecore.h>
+#include <Evas.h>
+#include <provider.h>
+#include <provider_buffer.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include <API/web_provider_livebox_info.h>
+#include "RenderBuffer.h"
+#include "BoxRenderBuffer.h"
+
+BoxRenderBuffer::BoxRenderBuffer(BoxInfoPtr boxInfo, TouchViewCallback touchCallback)
+ : m_boxId(boxInfo->boxId)
+ , m_instanceId(boxInfo->instanceId)
+ , m_width(boxInfo->boxWidth)
+ , m_height(boxInfo->boxHeight)
+ , m_contentInfo(boxInfo->contentInfo)
+ , m_touchCallback(touchCallback)
+{
+}
+
+BoxRenderBuffer::~BoxRenderBuffer()
+{
+}
+
+BufferInfoPtr BoxRenderBuffer::acquireBuffer()
+{
+ LogD("enter");
+
+ bool touchable = true;
+ const char* type = web_provider_livebox_get_box_type(m_boxId.c_str());
+
+ if (type) {
+ touchable = web_provider_livebox_get_mouse_event(m_boxId.c_str()) ||
+ strncmp(type, "app", 3);
+ }
+
+ BufferInfoPtr bufferInfo =
+ provider_buffer_acquire(
+ TYPE_LB,
+ m_boxId.c_str(),
+ m_instanceId.c_str(),
+ m_width,
+ m_height,
+ sizeof(int),
+ touchable ? handleTouchEventCallback : NULL,
+ this);
+ return bufferInfo;
+}
+
+void BoxRenderBuffer::updateBuffer()
+{
+ provider_send_updated(
+ m_boxId.c_str(),
+ m_instanceId.c_str(),
+ m_width, m_height,
+ 0, m_contentInfo.c_str(), NULL);
+}
+
+int BoxRenderBuffer::handleTouchEventCallback(
+ BufferInfoPtr bufferInfo,
+ buffer_event event,
+ double timestamp,
+ double x,
+ double y,
+ void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(bufferInfo);
+
+ BoxRenderBuffer* This = static_cast<BoxRenderBuffer*>(data);
+ TouchType type;
+ switch (event) {
+ case BUFFER_EVENT_MOVE:
+ type = TOUCH_EVENT_MOVE;
+ break;
+ case BUFFER_EVENT_DOWN:
+ type = TOUCH_EVENT_DOWN;
+ break;
+ case BUFFER_EVENT_UP:
+ type = TOUCH_EVENT_UP;
+ break;
+ default:
+ type = TOUCH_EVENT_UNRECOGNIZED;
+ break;
+ }
+
+ if (type == TOUCH_EVENT_UNRECOGNIZED) {
+ return -1;
+ }
+
+ This->didHandleTouchEvent(type, timestamp, x, y);
+
+ // call touch callback of renderView
+ This->m_touchCallback((int)(x * This->m_width), (int)(y * This->m_height));
+
+ return 0;
+}
+
+void BoxRenderBuffer::didHandleTouchEvent(
+ TouchType type, double timestamp, double x, double y)
+{
+ UNUSED_PARAM(timestamp);
+
+ // timestamp format sent by viewer is not same to the timestamp format used by webkit-efl
+ // so web-provider should get timestamp using ecore_time_get()
+ // and then feed event with the timestamp to webkit
+
+ LogD("enter");
+ switch (type) {
+ case TOUCH_EVENT_MOVE:
+ LogD("move event");
+ evas_event_feed_mouse_move(
+ getCanvas(), x * m_width, y * m_height, ecore_time_get() * 1000, NULL);
+ break;
+ case TOUCH_EVENT_DOWN:
+ LogD("down event");
+ evas_event_feed_mouse_move(
+ getCanvas(), x * m_width, y * m_height, ecore_time_get() * 1000, NULL);
+ evas_event_feed_mouse_down(
+ getCanvas(), 1, EVAS_BUTTON_NONE, 0, NULL);
+ break;
+ case TOUCH_EVENT_UP:
+ LogD("up event");
+ evas_event_feed_mouse_up(
+ getCanvas(), 1, EVAS_BUTTON_NONE, 0, NULL);
+ break;
+ default:
+ LogD("wrong event");
+ break;
+ }
+}
diff --git a/src_wearable/Core/Buffer/BoxRenderBuffer.h b/src_wearable/Core/Buffer/BoxRenderBuffer.h
new file mode 100644
index 0000000..3b0b896
--- /dev/null
+++ b/src_wearable/Core/Buffer/BoxRenderBuffer.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxRenderBuffer.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_RENDER_BUFFER_H
+#define BOX_RENDER_BUFFER_H
+
+#include <string>
+#include <provider_buffer.h>
+#include <Core/BoxData.h>
+#include <Core/View/RenderView.h>
+#include "IRenderBuffer.h"
+#include "RenderBuffer.h"
+
+#define EXPORT_CLASS __attribute__ ((visibility("default")))
+
+class EXPORT_CLASS BoxRenderBuffer: public RenderBuffer {
+ public:
+ enum TouchType {
+ TOUCH_EVENT_UNRECOGNIZED = -1,
+ TOUCH_EVENT_MOVE = 0,
+ TOUCH_EVENT_DOWN,
+ TOUCH_EVENT_UP
+ };
+
+ static IRenderBufferPtr create(BoxInfoPtr boxInfo, TouchViewCallback touchCallback)
+ {
+ return IRenderBufferPtr(new BoxRenderBuffer(boxInfo, touchCallback));
+ };
+ virtual ~BoxRenderBuffer();
+
+ protected:
+ // this function may be overriden by derived class
+ virtual void didHandleTouchEvent(
+ TouchType type, double timestamp, double x, double y);
+ explicit BoxRenderBuffer(BoxInfoPtr boxInfo, TouchViewCallback touchCallback);
+
+ private:
+ // RenderBuffer Implementation
+ int getWidth() { return m_width; };
+ int getHeight() { return m_height; };
+ void setWidth(int width) { m_width = width; };
+ void setHeight(int height) { m_height = height; };
+ BufferInfoPtr acquireBuffer();
+ void updateBuffer();
+
+ // touch callback from master provider
+ static int handleTouchEventCallback(
+ BufferInfoPtr bufferInfo,
+ buffer_event event,
+ double timestamp,
+ double x,
+ double y,
+ void* data);
+
+ // members
+ std::string m_boxId;
+ std::string m_instanceId;
+ std::string m_contentInfo;
+ int m_width;
+ int m_height;
+ TouchViewCallback m_touchCallback;
+};
+
+#endif // BOX_RENDER_BUFFER_H
diff --git a/src_wearable/Core/Buffer/CMakeLists.txt b/src_wearable/Core/Buffer/CMakeLists.txt
new file mode 100644
index 0000000..06396ec
--- /dev/null
+++ b/src_wearable/Core/Buffer/CMakeLists.txt
@@ -0,0 +1,65 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_CORE_BUFFER})
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ ecore
+ ecore-evas
+ evas
+ provider
+ livebox-service
+ elementary
+ dlog
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/RenderBuffer.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxRenderBuffer.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/PdRenderBuffer.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} STATIC ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LIBRARIES}
+)
+
+GET_FILENAME_COMPONENT(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+GET_FILENAME_COMPONENT(PARENT_DIR_ABSOLUTE_PATH ${CMAKE_CURRENT_SOURCE_DIR} PATH)
+GET_FILENAME_COMPONENT(PARENT_DIR_NAME ${PARENT_DIR_ABSOLUTE_PATH} NAME)
+
+INSTALL_FILE(IRenderBuffer.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
diff --git a/src_wearable/Core/Buffer/IRenderBuffer.h b/src_wearable/Core/Buffer/IRenderBuffer.h
new file mode 100644
index 0000000..ac28817
--- /dev/null
+++ b/src_wearable/Core/Buffer/IRenderBuffer.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IRenderBuffer.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_RENDER_BUFFER_H
+#define I_RENDER_BUFFER_H
+
+#include <memory>
+#include <Evas.h>
+#include <Util/Noncopyable.h>
+
+class IRenderBuffer: Noncopyable {
+ public:
+ virtual bool allocate(bool hwEnable = false) = 0;
+ virtual bool reallocate(int width, int height) = 0;
+ virtual bool free() = 0;
+ virtual void startCanvasUpdate() = 0;
+ virtual void stopCanvasUpdate() = 0;
+ virtual Evas_Object* getWindow() = 0;
+ virtual Evas_Object* getSnapshot() = 0;
+ virtual void* getBufferAddr() = 0;
+ virtual ~IRenderBuffer() {};
+ virtual void setWebView(Evas_Object* webview) = 0;
+ virtual Evas_Object* getWebView() = 0;
+ virtual Evas* getCanvas() = 0;
+};
+
+typedef std::shared_ptr<IRenderBuffer> IRenderBufferPtr;
+
+#endif
diff --git a/src_wearable/Core/Buffer/PdRenderBuffer.cpp b/src_wearable/Core/Buffer/PdRenderBuffer.cpp
new file mode 100644
index 0000000..48bf22b
--- /dev/null
+++ b/src_wearable/Core/Buffer/PdRenderBuffer.cpp
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 PdRenderBuffer.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include "PdRenderBuffer.h"
+
+#include "config.h"
+
+#include <string>
+#include <Ecore.h>
+#include <Evas.h>
+#include <ewk_view.h>
+#include <provider.h>
+#include <Elementary.h>
+#include <livebox-service.h>
+#include <provider_buffer.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "RenderBuffer.h"
+
+PdRenderBuffer::PdRenderBuffer(BoxInfoPtr boxInfo, TouchViewCallback touchCallback)
+ : m_boxId(boxInfo->boxId)
+ , m_instanceId(boxInfo->instanceId)
+ , m_width(boxInfo->pdWidth)
+ , m_height(boxInfo->pdHeight)
+ , m_touchCallback(touchCallback)
+{
+}
+
+PdRenderBuffer::~PdRenderBuffer()
+{
+}
+
+BufferInfoPtr PdRenderBuffer::acquireBuffer()
+{
+ BufferInfoPtr bufferInfo =
+ provider_buffer_acquire(
+ TYPE_PD,
+ m_boxId.c_str(),
+ m_instanceId.c_str(),
+ m_width,
+ m_height,
+ sizeof(int),
+ handleTouchEventCallback,
+ this);
+
+ m_accessibiilty = false;
+ return bufferInfo;
+}
+
+void PdRenderBuffer::updateBuffer()
+{
+ LogD("enter");
+ provider_send_desc_updated(
+ m_boxId.c_str(),
+ m_instanceId.c_str(),
+ NULL);
+}
+
+int PdRenderBuffer::handleTouchEventCallback(
+ BufferInfoPtr bufferInfo,
+ buffer_event event,
+ double timestamp,
+ double x,
+ double y,
+ void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(bufferInfo);
+
+ PdRenderBuffer* This = static_cast<PdRenderBuffer*>(data);
+ TouchType type;
+ Elm_Access_Action_Info ActionInfo;
+
+#if !ENABLE(WEBKIT_UPVERSION)
+ switch (event) {
+ case BUFFER_EVENT_HIGHLIGHT:
+ case BUFFER_EVENT_HIGHLIGHT_NEXT:
+ case BUFFER_EVENT_HIGHLIGHT_PREV:
+ case BUFFER_EVENT_ACTIVATE:
+ case BUFFER_EVENT_ACTION_UP:
+ case BUFFER_EVENT_ACTION_DOWN:
+ case BUFFER_EVENT_SCROLL_UP:
+ case BUFFER_EVENT_SCROLL_MOVE:
+ case BUFFER_EVENT_SCROLL_DOWN:
+ case BUFFER_EVENT_UNHIGHLIGHT:
+ {
+ LogD("handleTouchEventCallback event %d x,y %f,%f", event, x,y);
+ int action_type = event;
+ ActionInfo.highlight_cycle = EINA_FALSE;
+
+ if (!This->getWebView())
+ return 0;
+
+ Ewk_View_Smart_Data* pSmartData = (Ewk_View_Smart_Data*) evas_object_smart_data_get(This->getWebView());
+
+ switch (event) {
+ case BUFFER_EVENT_HIGHLIGHT:
+ {
+ ActionInfo.action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
+ ActionInfo.action_by = ELM_ACCESS_ACTION_HIGHLIGHT;
+ if (pSmartData->api->screen_reader_action_execute(pSmartData, &ActionInfo)) {
+ provider_send_access_status(This->m_boxId.c_str(), This->m_instanceId.c_str(), LB_ACCESS_STATUS_DONE);
+ } else {
+ provider_send_access_status(This->m_boxId.c_str(), This->m_instanceId.c_str(), LB_ACCESS_STATUS_DONE);
+ }
+ ActionInfo.action_type = ELM_ACCESS_ACTION_READ;
+ break;
+ }
+ case BUFFER_EVENT_HIGHLIGHT_NEXT:
+ if (!This->m_accessibiilty) {
+ ActionInfo.action_by = ELM_ACCESS_ACTION_HIGHLIGHT;
+ ActionInfo.action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
+ if (pSmartData->api->screen_reader_action_execute(pSmartData, &ActionInfo)) {
+ provider_send_access_status(This->m_boxId.c_str(), This->m_instanceId.c_str(), LB_ACCESS_STATUS_DONE);
+ } else {
+ provider_send_access_status(This->m_boxId.c_str(), This->m_instanceId.c_str(), LB_ACCESS_STATUS_DONE);
+ }
+ ActionInfo.action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
+ This->m_accessibiilty = true;
+ } else {
+ ActionInfo.action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
+ }
+ break;
+ case BUFFER_EVENT_HIGHLIGHT_PREV:
+ if (!This->m_accessibiilty) {
+ ActionInfo.action_by = ELM_ACCESS_ACTION_HIGHLIGHT;
+ ActionInfo.action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
+ if (pSmartData->api->screen_reader_action_execute(pSmartData, &ActionInfo)) {
+ provider_send_access_status(This->m_boxId.c_str(), This->m_instanceId.c_str(), LB_ACCESS_STATUS_DONE);
+ } else {
+ provider_send_access_status(This->m_boxId.c_str(), This->m_instanceId.c_str(), LB_ACCESS_STATUS_DONE);
+ }
+ ActionInfo.action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
+ This->m_accessibiilty = true;
+ } else {
+ ActionInfo.action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
+ }
+ break;
+ case BUFFER_EVENT_ACTIVATE:
+ ActionInfo.action_type = ELM_ACCESS_ACTION_ACTIVATE;
+ break;
+ case BUFFER_EVENT_UNHIGHLIGHT:
+ ActionInfo.action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
+ break;
+ case BUFFER_EVENT_ACTION_UP:
+ case BUFFER_EVENT_ACTION_DOWN:
+ case BUFFER_EVENT_SCROLL_UP:
+ case BUFFER_EVENT_SCROLL_MOVE:
+ case BUFFER_EVENT_SCROLL_DOWN:
+ default:
+ break;
+ }
+ int xWebview,yWebview,w,h;
+ evas_object_geometry_get(This->getWebView(), &xWebview, &yWebview, &w, &h);
+
+ ActionInfo.x = xWebview + static_cast<int>(w*x);
+ ActionInfo.y = yWebview + static_cast<int>(h*y);
+
+ if (pSmartData->api->screen_reader_action_execute(pSmartData, &ActionInfo)) {
+ provider_send_access_status(This->m_boxId.c_str(), This->m_instanceId.c_str(), LB_ACCESS_STATUS_DONE);
+ } else {
+ provider_send_access_status(This->m_boxId.c_str(), This->m_instanceId.c_str(), LB_ACCESS_STATUS_LAST);
+ This->m_accessibiilty = false;
+ }
+ }
+ return 0;
+ default:
+ break;
+ }
+#endif // WEBKIT_UPVERSION
+
+ switch (event) {
+ case BUFFER_EVENT_MOVE:
+ type = TOUCH_EVENT_MOVE;
+ break;
+ case BUFFER_EVENT_DOWN:
+ type = TOUCH_EVENT_DOWN;
+ break;
+ case BUFFER_EVENT_UP:
+ type = TOUCH_EVENT_UP;
+ break;
+ default:
+ type = TOUCH_EVENT_UNRECOGNIZED;
+ break;
+ }
+
+ if (type == TOUCH_EVENT_UNRECOGNIZED) {
+ return -1;
+ }
+
+ This->didHandleTouchEvent(type, timestamp, x, y);
+
+ // call touch callback of renderView
+ This->m_touchCallback((int)(x * This->m_width), (int)(y * This->m_height));
+
+ return 0;
+}
+
+void PdRenderBuffer::didHandleTouchEvent(
+ TouchType type, double timestamp, double x, double y)
+{
+ UNUSED_PARAM(timestamp);
+
+ // timestamp format sent by viewer is not same to the timestamp format used by webkit-efl
+ // so web-provider should get timestamp using ecore_time_get()
+ // and then feed event with the timestamp to webkit
+
+ switch (type) {
+ case TOUCH_EVENT_MOVE:
+ LogD("move event");
+ evas_event_feed_mouse_move(
+ getCanvas(), x * m_width, y * m_height, ecore_time_get() * 1000, NULL);
+ break;
+ case TOUCH_EVENT_DOWN:
+ LogD("down event");
+ evas_event_feed_mouse_move(
+ getCanvas(), x * m_width, y * m_height, ecore_time_get() * 1000, NULL);
+ evas_event_feed_mouse_down(
+ getCanvas(), 1, EVAS_BUTTON_NONE, 0, NULL);
+ break;
+ case TOUCH_EVENT_UP:
+ LogD("up event");
+ evas_event_feed_mouse_up(
+ getCanvas(), 1, EVAS_BUTTON_NONE, 0, NULL);
+ break;
+ default:
+ LogD("wrong event");
+ break;
+ }
+}
diff --git a/src_wearable/Core/Buffer/PdRenderBuffer.h b/src_wearable/Core/Buffer/PdRenderBuffer.h
new file mode 100644
index 0000000..ecf69fd
--- /dev/null
+++ b/src_wearable/Core/Buffer/PdRenderBuffer.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 PdRenderBuffer.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef PD_RENDER_BUFFER_H
+#define PD_RENDER_BUFFER_H
+
+#include <string>
+#include <provider_buffer.h>
+#include <Core/BoxData.h>
+#include <Core/View/RenderView.h>
+#include "IRenderBuffer.h"
+#include "RenderBuffer.h"
+
+#define EXPORT_CLASS __attribute__ ((visibility("default")))
+
+class EXPORT_CLASS PdRenderBuffer: public RenderBuffer {
+ public:
+ enum TouchType {
+ TOUCH_EVENT_UNRECOGNIZED = -1,
+ TOUCH_EVENT_MOVE = 0,
+ TOUCH_EVENT_DOWN,
+ TOUCH_EVENT_UP
+ };
+
+ static IRenderBufferPtr create(BoxInfoPtr boxInfo, TouchViewCallback touchCallback)
+ {
+ return IRenderBufferPtr(new PdRenderBuffer(boxInfo, touchCallback));
+ };
+ ~PdRenderBuffer();
+
+ protected:
+ // this function may be overriden by derived class
+ virtual void didHandleTouchEvent(
+ TouchType type, double timestamp, double x, double y);
+ explicit PdRenderBuffer(BoxInfoPtr boxInfo, TouchViewCallback touchCallback);
+
+ private:
+ // RenderBuffer Implementation
+ int getWidth() { return m_width; };
+ int getHeight() { return m_height; };
+ void setWidth(int width) { m_width = width; };
+ void setHeight(int height) { m_height = height; };
+ BufferInfoPtr acquireBuffer();
+ void updateBuffer();
+
+ // touch callback
+ static int handleTouchEventCallback(
+ BufferInfoPtr bufferInfo,
+ buffer_event event,
+ double timestamp,
+ double x,
+ double y,
+ void* data);
+
+ // members
+ std::string m_boxId;
+ std::string m_instanceId;
+ int m_width;
+ int m_height;
+ TouchViewCallback m_touchCallback;
+ bool m_accessibiilty;
+};
+
+#endif // PD_RENDER_BUFFER_H
diff --git a/src_wearable/Core/Buffer/RenderBuffer.cpp b/src_wearable/Core/Buffer/RenderBuffer.cpp
new file mode 100755
index 0000000..432f847
--- /dev/null
+++ b/src_wearable/Core/Buffer/RenderBuffer.cpp
@@ -0,0 +1,428 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 RenderBuffer.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <Evas.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <provider.h>
+#include <provider_buffer.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "IRenderBuffer.h"
+#include "RenderBuffer.h"
+
+const char * ecoreevasdataforrenderbuffer = "ecoreevasrenderbufferforwebprovider";
+
+RenderBuffer::RenderBuffer()
+ : m_bufferAddr(NULL)
+ , m_bufferInfo(NULL)
+ , m_hwEnable(false)
+ , m_webview(NULL)
+{
+ LogD("enter");
+}
+
+RenderBuffer::~RenderBuffer()
+{
+ LogD("enter");
+}
+
+bool RenderBuffer::allocate(bool hwEnable)
+{
+ bool ret;
+
+ LogD("enter");
+
+ m_hwEnable = hwEnable;
+
+ if (m_bufferAddr) {
+ free();
+ m_bufferAddr = NULL;
+ }
+
+ if (hwEnable) {
+ ret = bufferAllocationForGLRendering();
+ } else
+ ret = bufferAllocationForSWRendering();
+
+ startCanvasUpdate();
+ return true;
+}
+
+bool RenderBuffer::reallocate(int width, int height)
+{
+ LogD("enter");
+ stopCanvasUpdate();
+
+ // TODO This function should be implemented due to box resize operation
+ setWidth(width);
+ setHeight(height);
+
+ Ecore_Evas* ee = ecore_evas_ecore_evas_get(m_canvas);
+ // resize function will invoke the freeCallback and allocateCallback again. (internally)
+ ecore_evas_resize(ee, getWidth(), getHeight());
+ evas_object_resize(m_win, getWidth(), getHeight());
+
+ if (m_hwEnable)
+ {
+ bufferReAllocation(width, height);
+ }
+
+ startCanvasUpdate();
+ return true;
+}
+
+bool RenderBuffer::free()
+{
+ if (!m_canvas) {
+ return false;
+ }
+
+ stopCanvasUpdate();
+ ecore_evas_free(ecore_evas_ecore_evas_get(m_canvas));
+ m_canvas = NULL;
+ m_win = NULL;
+
+ return true;
+}
+
+void RenderBuffer::startCanvasUpdate()
+{
+ LogD("enter");
+ evas_event_callback_del(
+ m_canvas,
+ EVAS_CALLBACK_RENDER_PRE,
+ preRenderCallback);
+
+ evas_event_callback_del(
+ m_canvas,
+ EVAS_CALLBACK_RENDER_POST,
+ postRenderCallback);
+
+ evas_event_callback_add(
+ m_canvas,
+ EVAS_CALLBACK_RENDER_PRE,
+ preRenderCallback, this);
+
+ evas_event_callback_add(
+ m_canvas,
+ EVAS_CALLBACK_RENDER_POST,
+ postRenderCallback, this);
+
+}
+
+void RenderBuffer::stopCanvasUpdate()
+{
+ LogD("enter");
+ evas_event_callback_del(
+ m_canvas,
+ EVAS_CALLBACK_RENDER_PRE,
+ preRenderCallback);
+
+ evas_event_callback_del(
+ m_canvas,
+ EVAS_CALLBACK_RENDER_POST,
+ postRenderCallback);
+}
+
+Evas_Object* RenderBuffer::getWindow()
+{
+ return m_win;
+}
+
+void RenderBuffer::preRenderCallback(void* data, Evas* canvas, void *eventInfo)
+{
+ UNUSED_PARAM(eventInfo);
+
+ RenderBuffer *buffer = static_cast<RenderBuffer*>(data);
+
+ if ((buffer->m_hwEnable == true)) {
+ return;
+ }
+
+ provider_buffer_pre_render(buffer->m_bufferInfo);
+ evas_damage_rectangle_add(canvas, 0, 0, buffer->getWidth(), buffer->getHeight());
+}
+
+void RenderBuffer::postRenderCallback(void* data, Evas* canvas, void* eventInfo)
+{
+ UNUSED_PARAM(canvas);
+ UNUSED_PARAM(eventInfo);
+
+ RenderBuffer* buffer = static_cast<RenderBuffer*>(data);
+
+ if (buffer->m_hwEnable == true) {
+ buffer->updateBuffer();
+ } else {
+ evas_data_argb_unpremul(static_cast<unsigned int*>(buffer->m_bufferAddr), buffer->getWidth() * buffer->getHeight());
+#ifdef RENDER_BUFFER_VERIFY_SHOT
+ {
+ FILE *fp;
+ static int idx = 0;
+ char filename[256];
+ snprintf(filename, sizeof(filename) - 1, "/tmp/render%d-%dx%d.raw", idx++, buffer->getWidth(), buffer->getHeight());
+ fp = fopen(filename, "w+");
+ if (fp) {
+ LogD("RenderShot: %s(%d)\n", filename, buffer->getWidth() * buffer->getHeight() * sizeof(int));
+ fwrite(buffer->m_bufferAddr, buffer->getWidth() * buffer->getHeight() * sizeof(int), 1, fp);
+ fclose(fp);
+ } else {
+ LogD("Failed to open a file: %s", filename);
+ }
+ }
+#endif
+ LogD("/tmp/render-%dx%d.raw", buffer->getWidth(), buffer->getHeight());
+
+ if (!provider_buffer_pixmap_is_support_hw(buffer->m_bufferInfo)) {
+ provider_buffer_sync(buffer->m_bufferInfo);
+ buffer->updateBuffer();
+ } else {
+ provider_buffer_post_render(buffer->m_bufferInfo);
+ buffer->updateBuffer();
+ }
+ }
+}
+
+void RenderBuffer::paintColor(unsigned int color)
+{
+ LogD("enter");
+
+ if (!provider_buffer_pixmap_is_support_hw(m_bufferInfo)) {
+ memset(m_bufferAddr, color, getWidth() * getHeight() * 4);
+ provider_buffer_sync(m_bufferInfo);
+ updateBuffer();
+ } else {
+ preRenderCallback(this, m_canvas, NULL);
+ memset(m_bufferAddr, color, getWidth() * getHeight() * 4);
+ postRenderCallback(this, m_canvas, NULL);
+ }
+}
+
+Evas* RenderBuffer::getCanvas()
+{
+ return m_canvas;
+}
+
+void* RenderBuffer::allocateCallback(void* data, int size)
+{
+ LogD("enter");
+ UNUSED_PARAM(size);
+
+ RenderBuffer* buffer = static_cast<RenderBuffer*>(data);
+
+ if (buffer->m_bufferInfo) {
+ freeCallback(data, NULL);
+ }
+
+ buffer->m_bufferInfo = buffer->acquireBuffer();
+ if (!buffer->m_bufferInfo) {
+ return NULL;
+ }
+
+ // set buffer address
+ if (!provider_buffer_pixmap_is_support_hw(buffer->m_bufferInfo)) {
+ LogD("s/w evas backend");
+ buffer->m_bufferAddr = provider_buffer_ref(buffer->m_bufferInfo);
+ } else {
+ LogD("h/w evas backend");
+ int ret = provider_buffer_pixmap_create_hw(buffer->m_bufferInfo);
+ if (ret < 0) {
+ LogD("can't create hw pixmap");
+ }
+ buffer->m_bufferAddr = provider_buffer_pixmap_hw_addr(buffer->m_bufferInfo);
+ }
+
+ LogD("success to allocate buffer");
+ return buffer->m_bufferAddr;
+}
+
+void RenderBuffer::freeCallback(void* data, void *pix)
+{
+ LogD("enter");
+ UNUSED_PARAM(pix);
+
+ RenderBuffer* buffer = static_cast<RenderBuffer*>(data);
+
+ // destroy buffer
+ if (!provider_buffer_pixmap_is_support_hw(buffer->m_bufferInfo)) {
+ provider_buffer_unref(buffer->m_bufferAddr);
+ } else {
+ provider_buffer_pixmap_destroy_hw(buffer->m_bufferInfo);
+ }
+
+ provider_buffer_release(buffer->m_bufferInfo);
+
+ buffer->m_bufferInfo = NULL;
+ buffer->m_bufferAddr = NULL;
+
+ LogD("success to free buffer");
+ return;
+}
+
+Evas_Object *RenderBuffer::getSnapshot(void)
+{
+ LogD("enter");
+ Evas_Object *snapshot;
+ void *tmpBuffer;
+
+ snapshot = evas_object_image_add(m_canvas);
+ if (!snapshot)
+ return NULL;
+ evas_object_image_data_set(snapshot, NULL);
+ evas_object_image_colorspace_set(snapshot, EVAS_COLORSPACE_ARGB8888);
+ evas_object_image_alpha_set(snapshot, EINA_TRUE);
+ evas_object_image_size_set(snapshot, getWidth(), getHeight());
+
+ tmpBuffer = malloc(getWidth() * getHeight() * sizeof(int));
+ if (tmpBuffer) {
+ memcpy(tmpBuffer, m_bufferAddr, getWidth() * getHeight() * sizeof(int));
+ evas_data_argb_premul(
+ static_cast<unsigned int*>(tmpBuffer),
+ getWidth() * getHeight());
+ evas_object_image_data_set(snapshot, tmpBuffer);
+ } else {
+ LogD("Failed to allocate heap");
+ }
+
+ evas_object_image_data_update_add(snapshot, 0, 0, getWidth(), getHeight());
+ evas_object_image_fill_set(snapshot, 0, 0, getWidth(), getHeight());
+ evas_object_resize(snapshot, getWidth(), getHeight());
+
+ return snapshot;
+}
+
+bool RenderBuffer::bufferAllocationForGLRendering()
+{
+ Ecore_Evas* ee = NULL;
+
+ ee = ecore_evas_gl_x11_new(NULL, 0, 0, 0, getWidth(), getHeight());
+
+ LogD("Using %s engine!", ecore_evas_engine_name_get(ee));
+
+ if (!ee) {
+ LogD("invalid ecore evas object");
+ return false;
+ }
+
+ m_bufferInfo = acquireBuffer();
+ if (!m_bufferInfo) {
+ return NULL;
+ }
+
+ if (!provider_buffer_pixmap_is_support_hw(m_bufferInfo)) {
+ LogD("s/w evas backend");
+ m_bufferAddr = provider_buffer_ref(m_bufferInfo);
+ } else {
+ LogD("h/w evas backend");
+ int ret = provider_buffer_pixmap_create_hw(m_bufferInfo);
+ if (ret < 0) {
+ LogD("can't create hw pixmap");
+ }
+
+ m_bufferAddr = (void *)provider_buffer_pixmap_id(m_bufferInfo);
+ LogD("evas ecore provider_buffer_pixmap_id m_bufferAddr %lu", (unsigned long)m_bufferAddr);
+ }
+
+ ecore_evas_activate(ee);
+
+ Evas* e = ecore_evas_get(ee);
+ evas_image_cache_flush(e);
+ Evas_Object *eo = evas_object_rectangle_add(e);
+ evas_object_size_hint_weight_set(eo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_color_set(eo, 0, 0, 0, 1);
+ evas_object_resize(eo, getWidth(), getHeight());
+
+ m_canvas = e;
+ m_win = eo;
+
+ return true;
+}
+
+bool RenderBuffer::bufferAllocationForSWRendering()
+{
+ Ecore_Evas* ee = NULL;
+
+ ee = ecore_evas_buffer_allocfunc_new(
+ getWidth(), getHeight(),
+ allocateCallback, freeCallback,
+ this);
+
+ LogD("Using %s engine!", ecore_evas_engine_name_get(ee));
+
+ if (!ee) {
+ LogD("invalid ecore evas object");
+ return false;
+ }
+
+ // alpha_set function access the canvas buffer directly,
+ // without pre/post render callback.
+ provider_buffer_pre_render(m_bufferInfo);
+ ecore_evas_alpha_set(ee, EINA_TRUE);
+ provider_buffer_post_render(m_bufferInfo);
+ ecore_evas_manual_render_set(ee, EINA_FALSE);
+
+ // resize function will invoke the freeCallback and allocateCallback again. (internally)
+ ecore_evas_resize(ee, getWidth(), getHeight());
+ ecore_evas_show(ee);
+
+
+ ecore_evas_activate(ee);
+
+ Evas* e = ecore_evas_get(ee);
+ evas_image_cache_flush(e);
+ Evas_Object *eo = evas_object_rectangle_add(e);
+ evas_object_size_hint_weight_set(eo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_color_set(eo, 0, 0, 0, 1);
+ evas_object_resize(eo, getWidth(), getHeight());
+
+ m_canvas = e;
+ m_win = eo;
+
+ return true;
+}
+
+void RenderBuffer::bufferReAllocation(int width, int height)
+{
+ LogD("enter");
+ UNUSED_PARAM(width);
+ UNUSED_PARAM(height);
+
+ provider_buffer_release(m_bufferInfo);
+
+ m_bufferInfo = acquireBuffer();
+ if (!m_bufferInfo) {
+ return;
+ }
+
+ // set buffer address
+ if (!provider_buffer_pixmap_is_support_hw(m_bufferInfo)) {
+ LogD("s/w evas backend");
+ m_bufferAddr = provider_buffer_ref(m_bufferInfo);
+ } else {
+ LogD("h/w evas backend");
+ int ret = provider_buffer_pixmap_create_hw(m_bufferInfo);
+ if (ret < 0) {
+ LogD("can't create hw pixmap");
+ }
+ m_bufferAddr = (void *)provider_buffer_pixmap_id(m_bufferInfo);
+ LogD("evas ecore provider_buffer_pixmap_id m_bufferAddr %lu", (unsigned long)m_bufferAddr);
+ }
+}
+
diff --git a/src_wearable/Core/Buffer/RenderBuffer.h b/src_wearable/Core/Buffer/RenderBuffer.h
new file mode 100644
index 0000000..64f9a91
--- /dev/null
+++ b/src_wearable/Core/Buffer/RenderBuffer.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 RenderBuffer.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef RENDER_BUFFER_H
+#define RENDER_BUFFER_H
+
+#include <memory>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include "IRenderBuffer.h"
+
+// forward declaration
+struct livebox_buffer;
+
+// type definition
+typedef struct livebox_buffer* BufferInfoPtr;
+typedef void* BufferAddrPtr;
+
+#define EXPORT_CLASS __attribute__ ((visibility("default")))
+
+class EXPORT_CLASS RenderBuffer: public IRenderBuffer {
+ public:
+ // IRenderBuffer Implementation
+ bool allocate(bool hwEnable = false);
+ bool reallocate(int width, int height);
+ bool free();
+ void startCanvasUpdate();
+ void stopCanvasUpdate();
+ Evas_Object* getWindow();
+ Evas_Object* getSnapshot();
+ void setWebView(Evas_Object* webview){ m_webview = webview; };
+ Evas_Object* getWebView(){ return m_webview; };
+ Evas* getCanvas();
+
+ static void preRenderCallback(void* data, Evas* canvas, void* eventInfo);
+ static void postRenderCallback(void* data, Evas* canvas, void* eventInfo);
+
+ virtual ~RenderBuffer();
+
+ protected:
+ void paintColor(unsigned int color);
+
+
+ // provided by derived class
+ virtual int getWidth() = 0;
+ virtual int getHeight() = 0;
+ virtual void setWidth(int width) = 0;
+ virtual void setHeight(int height) = 0;
+ virtual BufferInfoPtr acquireBuffer() = 0;
+ virtual void updateBuffer() = 0;
+ void* getBufferAddr() { return m_hwEnable ? m_bufferAddr : 0; }
+ RenderBuffer();
+ Evas_Object* m_win;
+ Evas_Object* m_layout;
+
+ private:
+ // callbacks
+ static void* allocateCallback(void* data, int size);
+ static void freeCallback(void* data, void *pix);
+ bool bufferAllocationForGLRendering();
+ bool bufferAllocationForSWRendering();
+ void bufferReAllocation(int width, int height);
+
+ // members
+ Evas* m_canvas;
+
+ BufferAddrPtr m_bufferAddr;
+ BufferInfoPtr m_bufferInfo;
+ bool m_hwEnable;
+ Evas_Object* m_webview;
+
+};
+
+#endif
diff --git a/src_wearable/Core/CMakeLists.txt b/src_wearable/Core/CMakeLists.txt
new file mode 100644
index 0000000..39977e3
--- /dev/null
+++ b/src_wearable/Core/CMakeLists.txt
@@ -0,0 +1,88 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_CORE})
+SET(TARGET_CORE_BUFFER web-provider-core-buffer)
+SET(TARGET_CORE_VIEW web-provider-core-view)
+SET(TARGET_CORE_UTIL web-provider-core-util)
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ ecore
+ ewebkit2
+ dlog
+ vconf
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/Box.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxLoadBalancer.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxManager.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxState.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxUpdateTimer.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} SHARED ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LIBRARIES}
+ "-Wl,--whole-archive"
+ ${TARGET_CORE_VIEW}
+ ${TARGET_CORE_BUFFER}
+ ${TARGET_CORE_UTIL}
+ "-Wl,--no-whole-archive"
+)
+
+ADD_SUBDIRECTORY(Buffer)
+ADD_SUBDIRECTORY(View)
+ADD_SUBDIRECTORY(Util)
+
+INSTALL(TARGETS ${TARGET_NAME}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
+
+GET_FILENAME_COMPONENT(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+
+
+INSTALL_FILE(IBox.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(BoxData.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(IBoxManager.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(BoxManager.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(Platform.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(config.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(BoxLoadBalancer.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+
diff --git a/src_wearable/Core/IBox.h b/src_wearable/Core/IBox.h
new file mode 100644
index 0000000..6089da7
--- /dev/null
+++ b/src_wearable/Core/IBox.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IBox.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_BOX_H
+#define I_BOX_H
+
+#include <string>
+#include <memory>
+#include <ctime>
+#include <ewk_view.h>
+#include <ewk_context.h>
+
+class IBox {
+ public:
+ // functions for lifecycle
+ virtual bool show() = 0;
+ virtual bool hide() = 0;
+ virtual bool resize(int width, int height) = 0;
+ virtual bool resume() = 0;
+ virtual bool pause(bool background) = 0;
+ virtual bool openPd(int width, int height, double x, double y) = 0;
+ virtual bool closePd() = 0;
+ virtual bool update(std::string& contentInfo) = 0;
+ virtual bool needToUpdate() = 0;
+ virtual void setNeedToUpdate() = 0;
+ virtual bool isPaused() = 0;
+
+ // functions for getting/setting box's data by BoxManager
+ virtual bool changePeriod(float period) = 0;
+ virtual bool isCurrentTab() = 0;
+ virtual void setCurrent() = 0;
+ virtual BoxInfoPtr getBoxInfo() = 0;
+
+ //virtual IBox& operator=(const IBox& rhs) = 0;
+ //virtual bool operator==(const IBox& rhs) const = 0;
+ //virtual bool operator!=(const IBox& rhs) const = 0;
+ virtual ~IBox() {};
+};
+
+typedef std::shared_ptr<IBox> IBoxPtr;
+typedef std::shared_ptr<Ewk_Context> EwkContextPtr;
+
+#endif //I_BOX_H
diff --git a/src_wearable/Core/IBoxContext.h b/src_wearable/Core/IBoxContext.h
new file mode 100644
index 0000000..8dfa2a7
--- /dev/null
+++ b/src_wearable/Core/IBoxContext.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IBoxContext.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_BOX_CONTEXT
+#define I_BOX_CONTEXT
+
+#include "IBoxState.h"
+
+class IBoxContext {
+ public:
+ virtual void setState(IBoxStatePtr state) = 0;
+ virtual ~IBoxContext() {};
+};
+
+typedef std::shared_ptr<IBoxContext> IBoxContextPtr;
+
+#endif // I_BOX_CONTEXT
diff --git a/src_wearable/Core/IBoxManager.h b/src_wearable/Core/IBoxManager.h
new file mode 100644
index 0000000..d441ed1
--- /dev/null
+++ b/src_wearable/Core/IBoxManager.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IBoxManager.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_BOX_MANAGER_H
+#define I_BOX_MANAGER_H
+
+#include <string>
+#include <Util/Noncopyable.h>
+#include <Plugin/box_plugin_interface.h>
+#include "BoxData.h"
+
+class IBoxManager: Noncopyable {
+ public:
+ virtual bool doCommand(const request_cmd_type, const BoxInfoPtr&) = 0;
+ virtual ~IBoxManager() {};
+};
+
+typedef std::shared_ptr<IBoxManager> IBoxManagerPtr;
+
+#endif // I_BOX_MANAGER_H
diff --git a/src_wearable/Core/IBoxState.h b/src_wearable/Core/IBoxState.h
new file mode 100644
index 0000000..d798dc1
--- /dev/null
+++ b/src_wearable/Core/IBoxState.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IBoxState.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_BOX_STATE
+#define I_BOX_STATE
+
+#include <memory>
+
+class IBoxState;
+typedef std::shared_ptr<IBoxState> IBoxStatePtr;
+
+class IBoxState {
+ public:
+ virtual IBoxStatePtr permitShow() = 0;
+ virtual IBoxStatePtr permitHide() = 0;
+ virtual IBoxStatePtr permitResume() = 0;
+ virtual IBoxStatePtr permitPause() = 0;
+ virtual IBoxStatePtr permitOpenPd() = 0;
+ virtual IBoxStatePtr permitClosePd() = 0;
+ virtual IBoxStatePtr permitShutdown() = 0;
+ virtual void switchState() = 0;
+ virtual ~IBoxState() {};
+};
+
+#endif // I_BOX_STATE
diff --git a/src_wearable/Core/Platform.h b/src_wearable/Core/Platform.h
new file mode 100644
index 0000000..c7e5077
--- /dev/null
+++ b/src_wearable/Core/Platform.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 Platform.h
+ * @author Minhyung Ko (minhyung.ko@samsung.com)
+ */
+
+#ifndef WEB_PROVIDER_PLATFORM_H
+#define WEB_PROVIDER_PLATFORM_H
+
+// Use Features definition
+// Use a particular optional platform service or third-party library
+//
+// Description : <text>
+// <text>
+// Author : <text>(<email>) - <date>
+// #define USE_<DEPENDENT_MODULE_NAME>_<FEATURE_NAME> <value>(0 or 1)
+#define USE(FEATURE) (defined WEB_PROVIDER_USE_##FEATURE && WEB_PROVIDER_USE_##FEATURE)
+
+
+// Enable Features definition
+// Turn on a specific feature of WRT
+//
+// Description : <text>
+// <text>
+// Author : <text>(<email>) - <date>
+// #define ENABLE_<FEATURE_NAME> <value>(0 or 1)
+#define ENABLE(FEATURE) (defined WEB_PROVIDER_ENABLE_##FEATURE && WEB_PROVIDER_ENABLE_##FEATURE)
+
+#define WEB_PROVIDER_ENABLE_BOX_LOAD_BALANCER 0
+#define WEB_PROVIDER_ENABLE_GL_RENDERING 1
+#define WEB_PROVIDER_ENABLE_SHOW_PRE_ICON 0
+#define WEB_PROVIDER_ENABLE_WEBKIT_UPVERSION 1
+
+#endif // WEB_PROVIDER_PLATFORM_H
diff --git a/src_wearable/Core/Util/CMakeLists.txt b/src_wearable/Core/Util/CMakeLists.txt
new file mode 100644
index 0000000..11e14dc
--- /dev/null
+++ b/src_wearable/Core/Util/CMakeLists.txt
@@ -0,0 +1,61 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_CORE_UTIL})
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ dlog
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/Log.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} STATIC ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LIBRARIES}
+)
+
+INCLUDE_DIRECTORIES(${HEADERS})
+GET_FILENAME_COMPONENT(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+GET_FILENAME_COMPONENT(PARENT_DIR_ABSOLUTE_PATH ${CMAKE_CURRENT_SOURCE_DIR} PATH)
+GET_FILENAME_COMPONENT(PARENT_DIR_NAME ${PARENT_DIR_ABSOLUTE_PATH} NAME)
+
+INSTALL_FILE(Noncopyable.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(Log.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(Util.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
diff --git a/src_wearable/Core/Util/ITimer.h b/src_wearable/Core/Util/ITimer.h
new file mode 100644
index 0000000..2db0dae
--- /dev/null
+++ b/src_wearable/Core/Util/ITimer.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 ITimer.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_TIMER_H
+#define I_TIMER_H
+
+#include <memory>
+
+class ITimer {
+ public:
+ virtual void start() = 0;
+ virtual void continueTimer(float period) = 0;
+ virtual void stop() = 0;
+ virtual void resume() = 0;
+ virtual void pause() = 0;
+ virtual void restart() = 0;
+ virtual void setPeriod(float period) = 0;
+ virtual float getPeriod() = 0;
+ virtual time_t getStartTime() = 0;
+ virtual bool isRunning() = 0;
+
+ virtual ~ITimer() {};
+};
+
+typedef std::shared_ptr<ITimer> ITimerPtr;
+
+#endif // I_TIMER_H
diff --git a/src_wearable/Core/Util/Log.cpp b/src_wearable/Core/Util/Log.cpp
new file mode 100644
index 0000000..34712ac
--- /dev/null
+++ b/src_wearable/Core/Util/Log.cpp
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 Log.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
diff --git a/src_wearable/Core/Util/Log.h b/src_wearable/Core/Util/Log.h
new file mode 100644
index 0000000..ff649f7
--- /dev/null
+++ b/src_wearable/Core/Util/Log.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 Log.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef LOG_H
+#define LOG_H
+
+#include <dlog.h>
+#include <string.h>
+
+#define FILE_NAME ((strrchr(__FILE__, '/') ? : __FILE__- 1) + 1)
+
+//#define LogW(fmt, arg...) LOGW( "[%s:%d:%s] " fmt "\n", __FILE__, __LINE__, __func__, ##arg)
+//#define LogD(fmt, arg...) LOGD( "[%s:%d:%s] " fmt "\n", __FILE__, __LINE__, __func__, ##arg)
+//#define LogE(fmt, arg...) LOGE( "[%s:%d:%s] " fmt "\n", __FILE__, __LINE__, __func__, ##arg)
+
+#define LogW(fmt, arg...) LOGW( fmt "\n", ##arg)
+#define LogD(fmt, arg...) LOGD( fmt "\n", ##arg)
+#define LogE(fmt, arg...) LOGE( fmt "\n", ##arg)
+#endif // LOG_H
diff --git a/src_wearable/Core/Util/Noncopyable.h b/src_wearable/Core/Util/Noncopyable.h
new file mode 100644
index 0000000..accdd53
--- /dev/null
+++ b/src_wearable/Core/Util/Noncopyable.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 Noncopyable.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef NONCOPYABLE_H
+#define NONCOPYABLE_H
+
+class Noncopyable {
+ protected:
+ Noncopyable() {};
+ ~Noncopyable() {};
+
+ private:
+ Noncopyable(const Noncopyable&);
+ Noncopyable& operator=(const Noncopyable&);
+};
+
+#endif // NONCOPYABLE_H
diff --git a/src_wearable/Core/Util/Util.h b/src_wearable/Core/Util/Util.h
new file mode 100644
index 0000000..b2c310d
--- /dev/null
+++ b/src_wearable/Core/Util/Util.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 Util.h
+ * @author Soo-Hyun Choi (sh9.choi@samsung.com)
+ */
+#ifndef UTIL_H
+#define UTIL_H
+
+#define UNUSED_PARAM(expr) (void)(expr)
+
+#endif // UTIL_H
diff --git a/src_wearable/Core/View/CMakeLists.txt b/src_wearable/Core/View/CMakeLists.txt
new file mode 100644
index 0000000..17f32a6
--- /dev/null
+++ b/src_wearable/Core/View/CMakeLists.txt
@@ -0,0 +1,75 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_CORE_VIEW})
+SET(TARGET_CORE_SERVICE web-provider-core-service)
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ evas
+ eina
+ ewebkit2
+ dlog
+ provider # this should be removed!
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/WebView.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/PdHelper.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/RenderView.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/JsInterface.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} STATIC ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LIBRARIES}
+ ${TARGET_CORE_SERVICE}
+)
+
+ADD_SUBDIRECTORY(Service)
+
+GET_FILENAME_COMPONENT(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+GET_FILENAME_COMPONENT(PARENT_DIR_ABSOLUTE_PATH ${CMAKE_CURRENT_SOURCE_DIR} PATH)
+GET_FILENAME_COMPONENT(PARENT_DIR_NAME ${PARENT_DIR_ABSOLUTE_PATH} NAME)
+
+INSTALL_FILE(IRenderView.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(RenderView.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(IPdHelper.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(PdHelper.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(IWebView.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(WebView.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(IJsInterface.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(injection.js /usr/share/${PROJECT_NAME})
diff --git a/src_wearable/Core/View/IJsInterface.h b/src_wearable/Core/View/IJsInterface.h
new file mode 100644
index 0000000..6de0776
--- /dev/null
+++ b/src_wearable/Core/View/IJsInterface.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IJsInterface.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_JS_INTERFACE_H
+#define I_JS_INTERFACE_H
+
+#include <string>
+#include <memory>
+
+class IJsInterface {
+ public:
+ virtual bool process(std::string& uri) = 0;
+ virtual ~IJsInterface() {};
+};
+
+typedef std::shared_ptr<IJsInterface> IJsInterfacePtr;
+
+#endif //I_JS_INTERFACE_H
diff --git a/src_wearable/Core/View/IPdHelper.h b/src_wearable/Core/View/IPdHelper.h
new file mode 100644
index 0000000..b2f7db9
--- /dev/null
+++ b/src_wearable/Core/View/IPdHelper.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IPdHelper.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_PD_HELPER_H
+#define I_PD_HELPER_H
+
+#include <Evas.h>
+#include <memory>
+
+class IPdHelper {
+ public:
+ virtual void startOpen() = 0;
+ virtual void finishOpen(Evas_Object* child) = 0;
+ virtual void close() = 0;
+ virtual void setBoxWebView(Evas_Object* webview) = 0;
+ virtual void setPdWebView(Evas_Object* webview) = 0;
+ virtual Evas_Object* getBoxWebView() const = 0;
+ virtual Evas_Object* getPdWebView() const = 0;
+ virtual Evas* getPdCanvas() const = 0;
+ virtual bool isPdOpened() const = 0;
+};
+
+typedef std::shared_ptr<IPdHelper> IPdHelperPtr;
+
+#endif // I_PD_HELPER_H
diff --git a/src_wearable/Core/View/IRenderView.h b/src_wearable/Core/View/IRenderView.h
new file mode 100644
index 0000000..10e79ae
--- /dev/null
+++ b/src_wearable/Core/View/IRenderView.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IRenderView.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_RENDER_VIEW_H
+#define I_RENDER_VIEW_H
+
+#include <string>
+#include <memory>
+#include <Evas.h>
+
+class IRenderView {
+ public:
+ enum UrlType {
+ URL_TYPE_BOX,
+ URL_TYPE_PD
+ };
+ virtual void show() = 0;
+ virtual void hide() = 0;
+ virtual void resize() = 0;
+ virtual void update() = 0;
+ virtual void pause() = 0;
+ virtual void resume() = 0;
+ virtual void openPd() = 0;
+ virtual void closePd() = 0;
+ virtual Evas_Object* getBoxWebView() = 0;
+ virtual Evas_Object* getPdWebView() = 0;
+ virtual ~IRenderView() {};
+};
+
+typedef std::shared_ptr<IRenderView> IRenderViewPtr;
+
+#endif // I_RENDER_VIEW_H
diff --git a/src_wearable/Core/View/IWebView.h b/src_wearable/Core/View/IWebView.h
new file mode 100644
index 0000000..1260345
--- /dev/null
+++ b/src_wearable/Core/View/IWebView.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IWebView.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_WEB_VIEW_H
+#define I_WEB_VIEW_H
+
+#include <string>
+#include <memory>
+
+class IWebView {
+ public:
+ typedef void (*WebViewCallback)(void* data, void* eventInfo);
+ virtual bool show(
+ std::string& startUrl, int width, int height,
+ WebViewCallback didCreateBaseWebView, void* data) = 0;
+ virtual bool hide() = 0;
+ virtual bool suspend() = 0;
+ virtual bool resume() = 0;
+ virtual bool setBasicSetting(Evas_Object* webview) = 0;
+ virtual bool unsetBasicSetting(Evas_Object* webview) = 0;
+
+ public:
+ virtual ~IWebView() {};
+};
+
+typedef std::shared_ptr<IWebView> IWebViewPtr;
+
+#endif // I_WEB_VIEW_H
diff --git a/src_wearable/Core/View/JsInterface.cpp b/src_wearable/Core/View/JsInterface.cpp
new file mode 100755
index 0000000..d943c94
--- /dev/null
+++ b/src_wearable/Core/View/JsInterface.cpp
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 JsInterface.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string.h>
+#include <ctime>
+#include <Core/BoxData.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "Service/AppControl.h"
+#include "Service/PeriodChanger.h"
+#include "Service/ScrollHolder.h"
+#include "Service/MessageManager.h"
+#include "JsInterface.h"
+
+using namespace Service;
+
+static const std::string BOX_SCHEME("box://");
+static const std::string BOX_SCHEME_RELOAD("box://reload");
+static const std::string BOX_SCHEME_CHANGE_PERIOD("box://change-period");
+static const std::string BOX_SCHEME_LAUNCH_BROWSER("box://launch-browser");
+static const std::string BOX_SCHEME_SEND_MESSAGE_TO_PD("box://send-message-to-pd");
+static const std::string BOX_SCHEME_SEND_MESSAGE_TO_BOX("box://send-message-to-box");
+static const std::string BOX_SCHEME_SCROLL_START("box://scroll-start");
+static const std::string BOX_SCHEME_SCROLL_STOP("box://scroll-stop");
+
+static const std::string HTTP_SCHEME("http://");
+static const std::string HTTPS_SCHEME("https://");
+
+JsInterface::JsInterface(RenderView* renderView, BoxInfoPtr boxInfo)
+ : m_renderView(renderView)
+ , m_boxInfo(boxInfo)
+{
+ LogD("enter");
+}
+
+JsInterface::~JsInterface()
+{
+ LogD("enter");
+}
+
+bool JsInterface::process(std::string& uri)
+{
+ LogD("enter");
+
+ if (!isBoxScheme(uri)) {
+ return false;
+ }
+
+ if (!uri.compare(BOX_SCHEME_RELOAD)) {
+ return handleReload();
+ }
+
+ if (!uri.compare(
+ 0,
+ BOX_SCHEME_CHANGE_PERIOD.size(),
+ BOX_SCHEME_CHANGE_PERIOD))
+ {
+ std::string key("period");
+ std::string period = parse(uri, key);
+ if (period.empty()) {
+ return handleChangePeriod();
+ }
+
+ return handleChangePeriod(std::atof(period.c_str()));
+ }
+
+ if (!uri.compare(
+ 0,
+ BOX_SCHEME_LAUNCH_BROWSER.size(),
+ BOX_SCHEME_LAUNCH_BROWSER))
+ {
+ std::string key("url");
+ std::string url = parse(uri, key);
+ return handleLaunchBrowser(url);
+ }
+
+ if (!uri.compare(
+ 0,
+ BOX_SCHEME_SEND_MESSAGE_TO_BOX.size(),
+ BOX_SCHEME_SEND_MESSAGE_TO_BOX))
+ {
+ std::string key("message");
+ std::string message = parse(uri, key);
+ return handleSendMessage(MessageManager::TO_BOX, message);
+ }
+
+ if (!uri.compare(
+ 0,
+ BOX_SCHEME_SEND_MESSAGE_TO_PD.size(),
+ BOX_SCHEME_SEND_MESSAGE_TO_PD))
+ {
+ std::string key("message");
+ std::string message = parse(uri, key);
+ return handleSendMessage(MessageManager::TO_PD, message);
+ }
+
+ if (!uri.compare(BOX_SCHEME_SCROLL_START)) {
+ return handleScroll(true);
+ }
+
+ if (!uri.compare(BOX_SCHEME_SCROLL_STOP)) {
+ return handleScroll(false);
+ }
+
+ LogD("unknown box scheme protocol");
+ return false;
+}
+
+bool JsInterface::isBoxScheme(std::string& uri)
+{
+ LogD("enter");
+
+ if(!uri.compare(0, BOX_SCHEME.size(), BOX_SCHEME)) {
+ return true;
+ }
+
+ return false;
+}
+
+bool JsInterface::handleReload()
+{
+ LogD("enter");
+
+ m_renderView->update();
+ return true;
+}
+
+bool JsInterface::handleChangePeriod(float requestedPeriod)
+{
+ LogD("enter");
+
+ if (Service::PeriodChanger::isPopupOpened()) {
+ LogD("preiod popup is already opened!");
+ return false;
+ }
+
+ m_periodChanger =
+ Service::PeriodChanger::create(
+ m_boxInfo->boxId, m_boxInfo->instanceId,
+ m_boxInfo->period, requestedPeriod);
+
+ return m_periodChanger->change();
+}
+
+bool JsInterface::handleLaunchBrowser(std::string& url)
+{
+ LogD("enter");
+
+ if (!url.compare(0, HTTP_SCHEME.size(), HTTP_SCHEME) ||
+ !url.compare(0, HTTPS_SCHEME.size(), HTTPS_SCHEME))
+ {
+ return Service::AppControl::launchBrowser(url);
+ }
+
+ return false;
+}
+
+bool JsInterface::handleSendMessage(
+ MessageManager::ReceiverType receiver,
+ std::string& message)
+{
+ LogD("enter");
+
+ // set webview of receiver
+ Evas_Object* webview;
+ switch (receiver) {
+ case MessageManager::TO_BOX:
+ webview = m_renderView->getBoxWebView();
+ break;
+ case MessageManager::TO_PD:
+ webview = m_renderView->getPdWebView();
+ break;
+ default:
+ LogD("not supported receiver");
+ return false;
+ }
+
+ return m_messageManager->send(webview, receiver, message);
+}
+
+bool JsInterface::handleScroll(bool start)
+{
+ using namespace Service::ScrollHolder;
+
+ LogD("enter");
+
+ holdHorizontalScroll(m_boxInfo->boxId, m_boxInfo->instanceId, start);
+ return true;
+}
+
+std::string JsInterface::parse(std::string& uri, std::string& key)
+{
+ LogD("enter");
+
+ // TODO url parameter SHOULD be parsed using std::regex, not manually
+ std::string value("");
+
+ unsigned found = uri.find_first_of("?");
+ if (found == std::string::npos) {
+ LogD("no query");
+ return value;
+ }
+
+ std::string query = std::string(uri, found + 1);
+ found = 0;
+ do {
+ LogD("enter\n");
+ unsigned seperator = query.find_first_of("=", found + 1);
+ if (seperator == std::string::npos) {
+ LogD("no '=' character\n");
+ break;
+ }
+
+ unsigned next = query.find_first_of("@", found + 1);
+ if (!query.compare(found, key.size(), key)) {
+ LogD("key matched!\n");
+ value = std::string(query, seperator + 1, next - seperator - 1);
+ break;
+ }
+
+ found = next + 1;
+ } while (found && found != std::string::npos);
+
+ LogD("URL query parsing result: key -> %s, value -> %s", key.c_str(), value.c_str());
+ return value;
+}
diff --git a/src_wearable/Core/View/JsInterface.h b/src_wearable/Core/View/JsInterface.h
new file mode 100755
index 0000000..187dac5
--- /dev/null
+++ b/src_wearable/Core/View/JsInterface.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 JsInterface.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef JS_INTERFACE_H
+#define JS_INTERFACE_H
+
+#include <string>
+#include <map>
+#include <Core/BoxData.h>
+#include "Service/PeriodChanger.h"
+#include "Service/MessageManager.h"
+#include "RenderView.h"
+#include "IJsInterface.h"
+
+using namespace Service;
+
+#define EXPORT_CLASS __attribute__ ((visibility("default")))
+
+class EXPORT_CLASS JsInterface: public IJsInterface {
+ public:
+ static IJsInterfacePtr create(RenderView* renderView, BoxInfoPtr boxInfo)
+ {
+ return IJsInterfacePtr(new JsInterface(renderView, boxInfo));
+ }
+ bool process(std::string& uri);
+ ~JsInterface();
+
+ private:
+ bool isBoxScheme(std::string& uri);
+ bool handleReload();
+ bool handleChangePeriod(float requestedPeriod = -1.0f);
+ bool handleLaunchBrowser(std::string& url);
+ bool handleSendMessage(
+ MessageManager::ReceiverType receiver,
+ std::string& message);
+ bool handleScroll(bool start);
+ std::string parse(std::string& uri, std::string& key);
+ explicit JsInterface(RenderView* renderView, BoxInfoPtr boxInfo);
+
+ // members for service
+ std::shared_ptr<PeriodChanger> m_periodChanger;
+ std::shared_ptr<MessageManager> m_messageManager;
+ RenderView* m_renderView;
+ BoxInfoPtr m_boxInfo;
+};
+
+#endif // JS_INTERFACE_H
+
diff --git a/src_wearable/Core/View/PdHelper.cpp b/src_wearable/Core/View/PdHelper.cpp
new file mode 100644
index 0000000..ba57c8f
--- /dev/null
+++ b/src_wearable/Core/View/PdHelper.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 PdHelper.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <Evas.h>
+#include <ewk_view.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "IRenderView.h"
+#include "IPdHelper.h"
+#include "PdHelper.h"
+
+PdHelper::PdHelper(RenderInfoPtr pdRenderInfo, std::string pdStartUrl)
+ : m_boxWebView()
+ , m_pdWebView()
+ , m_pdRenderInfo(pdRenderInfo)
+ , m_startUrl(pdStartUrl)
+ , m_opened(false)
+{
+}
+
+PdHelper::~PdHelper()
+{
+}
+
+void PdHelper::startOpen()
+{
+ LogD("enter");
+ if (!m_boxWebView) {
+ return;
+ }
+
+ //make javascript string for pd
+ std::string script = "var pdWindow = window.open(\"";
+ script += validateUrl(m_startUrl);
+ script += "\", \"_blank\");";
+
+ // execute javascript for opening new webview for pd
+ LogD("executed script: %s", script.c_str());
+ ewk_view_script_execute(
+ m_boxWebView, script.c_str(), executeScriptCallback, this);
+}
+
+void PdHelper::finishOpen(Evas_Object* child)
+{
+ LogD("enter");
+
+ // pd webview set and resize
+ m_pdWebView = child;
+ evas_object_resize(m_pdWebView, m_pdRenderInfo->width, m_pdRenderInfo->height);
+ m_opened = true;
+}
+
+void PdHelper::close()
+{
+ LogD("enter");
+}
+
+void PdHelper::setBoxWebView(Evas_Object* webview)
+{
+ LogD("enter");
+ m_boxWebView = webview;
+}
+
+void PdHelper::setPdWebView(Evas_Object* webview)
+{
+ LogD("enter");
+ m_pdWebView = webview;
+}
+
+Evas_Object* PdHelper::getBoxWebView() const
+{
+ LogD("enter");
+ return m_boxWebView;
+}
+
+Evas_Object* PdHelper::getPdWebView() const
+{
+ LogD("enter");
+ return m_pdWebView;
+}
+
+Evas* PdHelper::getPdCanvas() const
+{
+ LogD("enter");
+ return evas_object_evas_get(m_pdRenderInfo->window);
+}
+
+bool PdHelper::isPdOpened() const
+{
+ LogD("enter");
+ return m_opened;
+}
+
+void PdHelper::didExecuteScript(Evas_Object* webview, std::string& result)
+{
+ LogD("enter");
+ UNUSED_PARAM(webview);
+ LogD("javascript execution result: %s", result.c_str());
+}
+
+std::string PdHelper::validateUrl(std::string& url)
+{
+ LogD("enter");
+
+ if (url.empty()) {
+ return std::string();
+ }
+
+ if((!url.compare(0, 4, "http")) ||
+ (!url.compare(0, 5, "https")) ||
+ (!url.compare(0, 4, "file")))
+ {
+ return url;
+ }
+
+ std::string newUrl("file://");
+ newUrl += url;
+ return newUrl;
+}
+
+void PdHelper::executeScriptCallback(
+ Evas_Object* webview, const char* result, void* data)
+{
+ LogD("enter");
+
+ PdHelper* This = static_cast<PdHelper*>(data);
+ std::string resultStr(result ? result : "null");
+ This->didExecuteScript(webview, resultStr);
+}
+
diff --git a/src_wearable/Core/View/PdHelper.h b/src_wearable/Core/View/PdHelper.h
new file mode 100644
index 0000000..63f9bb1
--- /dev/null
+++ b/src_wearable/Core/View/PdHelper.h
@@ -0,0 +1,69 @@
+
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 PdHelper.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#ifndef PD_HELPER_H
+#define PD_HELPER_H
+
+#include <string>
+#include <Evas.h>
+#include "RenderView.h"
+#include "IPdHelper.h"
+
+#define EXPORT_CLASS __attribute__ ((visibility("default")))
+
+class EXPORT_CLASS PdHelper: public IPdHelper {
+ public:
+ static IPdHelperPtr create(
+ RenderInfoPtr pdRenderInfo,
+ std::string pdStartUrl)
+ {
+ return IPdHelperPtr(new PdHelper(pdRenderInfo, pdStartUrl));
+ }
+ virtual void startOpen();
+ virtual void finishOpen(Evas_Object* child);
+ virtual void close();
+ virtual void setBoxWebView(Evas_Object* webview);
+ virtual void setPdWebView(Evas_Object* webview);
+ virtual Evas_Object* getBoxWebView() const;
+ virtual Evas_Object* getPdWebView() const;
+ virtual Evas* getPdCanvas() const;
+ virtual bool isPdOpened() const;
+ virtual ~PdHelper();
+
+ private:
+ virtual void didExecuteScript(Evas_Object* webview, std::string& result);
+
+ std::string validateUrl(std::string& url);
+ static void executeScriptCallback(
+ Evas_Object* webview, const char* result, void* data);
+
+ PdHelper(RenderInfoPtr pdRenderInfo, std::string pdStartUrl);
+
+ //members
+ Evas_Object* m_boxWebView;
+ Evas_Object* m_pdWebView;
+ RenderInfoPtr m_pdRenderInfo;
+ std::string m_startUrl;
+ bool m_opened;
+};
+
+#endif // PD_HELPER_H
+
diff --git a/src_wearable/Core/View/RenderView.cpp b/src_wearable/Core/View/RenderView.cpp
new file mode 100644
index 0000000..78ad0d8
--- /dev/null
+++ b/src_wearable/Core/View/RenderView.cpp
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 RenderView.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include "config.h"
+#include "RenderView.h"
+
+#include <string>
+#include <sstream>
+#include <functional>
+#include <Ecore.h>
+#include <ewk_view.h>
+#include <Core/Buffer/IRenderBuffer.h>
+#include <Core/Buffer/BoxRenderBuffer.h>
+#include <Core/Buffer/PdRenderBuffer.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "JsInterface.h"
+#include <sys/stat.h>
+
+using namespace std::placeholders;
+
+// This is used for informing context of box to web content as value of url parameter
+static const std::string renderTypeCreate("create");
+static const std::string renderTypeResize("resize");
+static const std::string renderTypeOpenPd("pdopen");
+static const std::string renderTypeUpdate("update");
+
+RenderView::RenderView(BoxInfoPtr boxInfo, bool hwEnable)
+ : m_boxInfo(boxInfo)
+ , m_boxBuffer()
+ , m_pdBuffer()
+ , m_jsInterface()
+ , m_lastShowBoxTime()
+{
+
+ auto touchCallback = std::bind(RenderView::touchBoxCallback, _1, _2, this);
+ m_boxBuffer = BoxRenderBuffer::create(m_boxInfo, touchCallback);
+ m_boxBuffer->allocate(hwEnable);
+ m_jsInterface = JsInterface::create(this, m_boxInfo);
+}
+
+RenderView::~RenderView()
+{
+}
+
+void RenderView::show()
+{
+ LogD("enter");
+ showInternal(renderTypeCreate);
+}
+
+void RenderView::hide()
+{
+ LogD("enter");
+ if (m_pdBuffer) {
+ closePd();
+ }
+ m_boxBuffer->stopCanvasUpdate();
+ hideBox();
+ m_boxBuffer->free();
+ m_boxBuffer.reset();
+}
+
+void RenderView::resize()
+{
+ LogD("enter");
+ m_boxBuffer->reallocate(
+ m_boxInfo->boxWidth, m_boxInfo->boxHeight);
+ showInternal(renderTypeResize);
+}
+
+void RenderView::update()
+{
+ LogD("enter");
+ showInternal(renderTypeUpdate);
+}
+
+void RenderView::resume()
+{
+ LogD("enter");
+ resumeBox();
+}
+
+void RenderView::pause()
+{
+ LogD("enter");
+ pauseBox();
+}
+
+void RenderView::openPd()
+{
+ LogD("enter");
+
+ auto touchCallback = std::bind(RenderView::touchPdCallback, _1, _2, this);
+ m_pdBuffer = PdRenderBuffer::create(m_boxInfo, touchCallback);
+ m_pdBuffer->allocate();
+ m_pdBuffer->stopCanvasUpdate();
+ showInternal(renderTypeOpenPd);
+ ecore_idler_add(startUpdateRenderBufferIdlerCallback, m_pdBuffer.get());
+}
+
+void RenderView::closePd()
+{
+ LogD("enter");
+ if (m_pdBuffer) {
+ m_pdBuffer->stopCanvasUpdate();
+ hidePd();
+ m_pdBuffer->free();
+ m_pdBuffer.reset();
+ }
+}
+
+Evas_Object* RenderView::getBoxWebView()
+{
+ LogD("enter");
+ // this will be implemented by derived class
+ return NULL;
+}
+
+Evas_Object* RenderView::getPdWebView()
+{
+ LogD("enter");
+ // this will be implemented by derived class
+ return NULL;
+}
+
+void RenderView::showBox(RenderInfoPtr boxRenderInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(boxRenderInfo);
+ // this will be implemented by derived class
+}
+
+void RenderView::hideBox()
+{
+ LogD("enter");
+ // this will be implemented by derived class
+}
+
+void RenderView::pauseBox()
+{
+ LogD("enter");
+ // this will be implemented by derived class
+}
+
+void RenderView::resumeBox()
+{
+ LogD("enter");
+ // this will be implemented by derived class
+}
+
+void RenderView::showPd(RenderInfoPtr pdRenderInfo, RenderInfoPtr boxRenderInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(pdRenderInfo);
+ UNUSED_PARAM(boxRenderInfo);
+ // this will be implemented by derived class
+}
+
+void RenderView::hidePd()
+{
+ LogD("enter");
+ // this will be implemented by derived class
+}
+
+IRenderBufferPtr RenderView::getBoxBuffer() const
+{
+ return m_boxBuffer;
+}
+
+IRenderBufferPtr RenderView::getPdBuffer() const
+{
+ return m_pdBuffer;
+}
+
+bool RenderView::processBoxScheme(std::string& uri)
+{
+ LogD("enter");
+ return m_jsInterface->process(uri);
+}
+
+void RenderView::didBoxTouched(int x, int y)
+{
+ UNUSED_PARAM(x);
+ UNUSED_PARAM(y);
+ // this will be implemented by derived class
+}
+
+void RenderView::didPdTouched(int x, int y)
+{
+ UNUSED_PARAM(x);
+ UNUSED_PARAM(y);
+ // this will be implemented by derived class
+}
+
+void RenderView::touchBoxCallback(int x, int y, RenderView* This)
+{
+ This->didBoxTouched(x, y);
+}
+
+void RenderView::touchPdCallback(int x, int y, RenderView* This)
+{
+ This->didPdTouched(x, y);
+}
+
+Eina_Bool RenderView::startUpdateRenderBufferIdlerCallback(void* data)
+{
+ LogD("enter");
+ RenderBuffer* buffer = static_cast<RenderBuffer*>(data);
+ if (!buffer) {
+ LogD("no buffer");
+ } else {
+ buffer->startCanvasUpdate();
+ }
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+RenderInfoPtr RenderView::makeRenderInfo(const std::string& renderType, UrlType urlType) const
+{
+ LogD("enter");
+ RenderInfoPtr renderInfo(new RenderInfo);
+
+ std::ostringstream query;
+
+ // add width, height, operation type
+ query << "?type=" << renderType;
+
+ // set width, height
+ switch (urlType) {
+ case URL_TYPE_BOX:
+ renderInfo->window = m_boxBuffer->getWindow();
+ renderInfo->width = m_boxInfo->boxWidth;
+ renderInfo->height = m_boxInfo->boxHeight;
+ break;
+ case URL_TYPE_PD:
+ renderInfo->window = m_pdBuffer->getWindow();
+ renderInfo->width = m_boxInfo->pdWidth;
+ renderInfo->height = m_boxInfo->pdHeight;
+ break;
+ default:
+ LogD("error url type");
+ return RenderInfoPtr();
+ }
+ query << "&width=" << renderInfo->width << "&height=" << renderInfo->height;
+
+ // if needed, set pd information
+ if (renderType == renderTypeOpenPd) {
+ // add position infomation of pd
+ query << "&pdopen-direction=";
+ if (m_boxInfo->pdY == 0.0f) {
+ query << "down";
+ } else {
+ query << "up";
+ }
+
+ query << "&pdopen-arrow-xpos=";
+ query << static_cast<int>((m_boxInfo->pdX) * (m_boxInfo->pdWidth));
+
+ // add last update time & box's width, height
+ query << "&box-last-update-time=" << m_lastShowBoxTime;
+ query << "&box-width=" << m_boxInfo->boxWidth;
+ query << "&box-height=" << m_boxInfo->boxHeight;
+ }
+
+ // add service content info passed from application
+ if (!m_boxInfo->appContentInfo.empty()) {
+ query << "&" << m_boxInfo->appContentInfo;
+ }
+
+ // add content info passed from master provider
+ // this value can be different per box type
+ if (!m_boxInfo->contentInfo.empty()) {
+ query << "&" << m_boxInfo->contentInfo;
+ }
+
+ LogD("default url param string: %s", query.str().c_str());
+ renderInfo->defaultUrlParams = query.str();
+ return renderInfo;
+}
+
+void RenderView::showInternal(const std::string& renderType)
+{
+ LogD("enter");
+
+ if (renderType == renderTypeOpenPd) {
+ RenderInfoPtr pdRenderInfo = makeRenderInfo(renderType, URL_TYPE_PD);
+ RenderInfoPtr boxRenderInfo = makeRenderInfo(renderType, URL_TYPE_BOX);
+ showPd(pdRenderInfo, boxRenderInfo);
+ } else {
+ // set current time to lastest time for showing box
+ // this should be pre-executed before calling makeRenderInfo.
+ m_lastShowBoxTime = time(NULL);
+ RenderInfoPtr boxRenderInfo = makeRenderInfo(renderType, URL_TYPE_BOX);
+ showBox(boxRenderInfo);
+ }
+
+ struct stat tmp;
+
+ if (stat(WEB_PROVIDER_INSPECTOR_FILE_PATH, &tmp) == 0) {
+ unsigned int portnum = ewk_view_inspector_server_start(
+ getBoxWebView(), WEB_PROVIDER_INSPECTOR_PORT_NUMBER);
+ LogD("WEB_PROVIDER_INSPECTOR enabled port:%d",portnum);
+ }
+}
diff --git a/src_wearable/Core/View/RenderView.h b/src_wearable/Core/View/RenderView.h
new file mode 100644
index 0000000..140b396
--- /dev/null
+++ b/src_wearable/Core/View/RenderView.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 RenderView.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef RENDER_VIEW_H
+#define RENDER_VIEW_H
+
+#include <string>
+#include <memory>
+#include <functional>
+#include <Evas.h>
+#include <Core/BoxData.h>
+#include <Core/Buffer/IRenderBuffer.h>
+#include "IJsInterface.h"
+#include "IRenderView.h"
+
+#define EXPORT_CLASS __attribute__ ((visibility("default")))
+
+typedef std::function<void(int, int)> TouchViewCallback;
+
+struct RenderInfo {
+ int width;
+ int height;
+ Evas_Object* window;
+ std::string defaultUrlParams;
+};
+
+typedef std::shared_ptr<RenderInfo> RenderInfoPtr;
+
+class EXPORT_CLASS RenderView: public IRenderView {
+ public:
+ static IRenderViewPtr create(BoxInfoPtr boxInfo)
+ {
+ return IRenderViewPtr(new RenderView(boxInfo));
+ };
+ void show();
+ void hide();
+ void resize();
+ void update();
+ void resume();
+ void pause();
+ void openPd();
+ void closePd();
+ virtual Evas_Object* getBoxWebView();
+ virtual Evas_Object* getPdWebView();
+ virtual ~RenderView();
+
+ protected:
+ virtual void showBox(RenderInfoPtr boxRenderInfo);
+ virtual void hideBox();
+ virtual void pauseBox();
+ virtual void resumeBox();
+ virtual void showPd(RenderInfoPtr pdRenderInfo, RenderInfoPtr boxRenderInfo);
+ virtual void hidePd();
+ virtual void didBoxTouched(int x, int y);
+ virtual void didPdTouched(int x, int y);
+
+ // To be used by derived class
+ bool processBoxScheme(std::string& uri);
+ IRenderBufferPtr getBoxBuffer() const;
+ IRenderBufferPtr getPdBuffer() const;
+
+ RenderView(BoxInfoPtr boxInfo, bool hwEnable = false);
+ RenderInfoPtr makeRenderInfo(const std::string& renderType, UrlType urlType) const;
+
+ private:
+ void showInternal(const std::string& renderType);
+ static void touchBoxCallback(int x, int y, RenderView* This);
+ static void touchPdCallback(int x, int y, RenderView* This);
+ static Eina_Bool startUpdateRenderBufferIdlerCallback(void* data);
+
+ // members
+ BoxInfoPtr m_boxInfo;
+ IRenderBufferPtr m_boxBuffer;
+ IRenderBufferPtr m_pdBuffer;
+ IJsInterfacePtr m_jsInterface;
+ // timestamp for last time of showing box.
+ time_t m_lastShowBoxTime;
+
+ friend class BoxRenderBuffer;
+ friend class PdRenderBuffer;
+};
+
+#endif // RENDER_VIEW_H
diff --git a/src_wearable/Core/View/Service/AppControl.cpp b/src_wearable/Core/View/Service/AppControl.cpp
new file mode 100644
index 0000000..761dd93
--- /dev/null
+++ b/src_wearable/Core/View/Service/AppControl.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 LaunchBrowser.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string>
+#include <app_service.h>
+#include <Core/Util/Log.h>
+#include "AppControl.h"
+
+namespace Service {
+namespace AppControl {
+
+bool launchBrowser(std::string& url)
+{
+ LogD("enter");
+
+ service_h handle = NULL;
+ int ret = SERVICE_ERROR_NONE;
+
+ ret = service_create(&handle);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to create service");
+ return false;
+ }
+
+ ret = service_set_operation(handle, SERVICE_OPERATION_VIEW);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to set operation");
+ service_destroy(handle);
+ return false;
+ }
+
+ ret = service_set_uri(handle, url.c_str());
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to set url");
+ service_destroy(handle);
+ return false;
+ }
+
+ ret = service_send_launch_request(handle, NULL, NULL);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to request launch");
+ service_destroy(handle);
+ return false;
+ }
+
+ LogD("success to launch browser: %s", url.c_str());
+ service_destroy(handle);
+
+ return true;
+}
+
+bool launchDownloader(std::string& url, std::string& cookie)
+{
+ LogD("enter");
+
+ service_h handle = NULL;
+ int ret = SERVICE_ERROR_NONE;
+
+ if (url.empty()) {
+ LogD("invalid arguments");
+ return false;
+ }
+
+ ret = service_create(&handle);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to create service");
+ return false;
+ }
+
+ ret = service_set_operation(handle, SERVICE_OPERATION_DOWNLOAD);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to set operation");
+ service_destroy(handle);
+ return false;
+ }
+
+ ret = service_set_uri(handle, url.c_str());
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to set url");
+ service_destroy(handle);
+ return false;
+ }
+
+ if (!cookie.empty()) {
+ ret = service_add_extra_data(handle, "cookie", cookie.c_str());
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to set cookie");
+ service_destroy(handle);
+ return false;
+ }
+ }
+
+ ret = service_send_launch_request(handle, NULL, NULL);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to request launch");
+ service_destroy(handle);
+ return false;
+ }
+
+ LogD("success to launch downloader");
+ service_destroy(handle);
+
+ return true;
+}
+
+} // AppControl
+} // Service
diff --git a/src_wearable/Core/View/Service/AppControl.h b/src_wearable/Core/View/Service/AppControl.h
new file mode 100644
index 0000000..5693873
--- /dev/null
+++ b/src_wearable/Core/View/Service/AppControl.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppControl.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string>
+
+namespace Service {
+namespace AppControl {
+
+bool launchBrowser(std::string& url);
+bool launchDownloader(std::string& url, std::string& cookie);
+
+}
+} // Service
diff --git a/src_wearable/Core/View/Service/CMakeLists.txt b/src_wearable/Core/View/Service/CMakeLists.txt
new file mode 100755
index 0000000..ad8fa36
--- /dev/null
+++ b/src_wearable/Core/View/Service/CMakeLists.txt
@@ -0,0 +1,72 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_CORE_SERVICE})
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ dlog
+ capi-appfw-application
+ livebox-service
+ evas
+ eina
+ ecore-x
+ elementary
+ efl-assist
+ provider
+ ecore
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/AppControl.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/PeriodChanger.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/ScrollHolder.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/MessageManager.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} STATIC ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LIBRARIES}
+)
+
+GET_FILENAME_COMPONENT(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+GET_FILENAME_COMPONENT(PARENT_DIR_ABSOLUTE_PATH ${CMAKE_CURRENT_SOURCE_DIR} PATH)
+GET_FILENAME_COMPONENT(PARENT_DIR_NAME ${PARENT_DIR_ABSOLUTE_PATH} NAME)
+
+INSTALL_FILE(PeriodChanger.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(MessageManager.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(ScrollHolder.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(AppControl.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME})
diff --git a/src_wearable/Core/View/Service/MessageManager.cpp b/src_wearable/Core/View/Service/MessageManager.cpp
new file mode 100755
index 0000000..3199d86
--- /dev/null
+++ b/src_wearable/Core/View/Service/MessageManager.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 MessageMenager.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string>
+#include <Evas.h>
+#include <Eina.h>
+#include <ewk_view.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "MessageManager.h"
+
+namespace Service {
+
+static const std::string jsFireWindowEventFunction("webprovider.fireAppWidgetEvent");
+static const std::string jsPdMessageEvent("pdmessage");
+static const std::string jsBoxMessageEvent("boxmessage");
+
+MessageManager::MessageManager()
+{
+ LogD("enter");
+}
+
+MessageManager::~MessageManager()
+{
+ LogD("enter");
+}
+
+bool MessageManager::send(Evas_Object* webview, ReceiverType receiver, std::string& message)
+{
+ LogD("enter");
+
+ std::string eventName;
+ if(!webview) {
+ return false;
+ }
+ // set message event name triggered by receiver
+ switch (receiver) {
+ case TO_BOX:
+ eventName = jsPdMessageEvent;
+ break;
+ case TO_PD:
+ eventName = jsBoxMessageEvent;
+ break;
+ default:
+ return false;
+ }
+
+ std::string script = jsFireWindowEventFunction;
+ script += "(\"";
+ script += eventName;
+ script += "\", \"";
+ script += message;
+ script +="\");";
+ LogD("calling javascript: %s", script.c_str());
+
+ // execute js code for sending message
+ if (EINA_FALSE == ewk_view_script_execute(
+ webview, script.c_str(), executeScriptCallback, this)) {
+ LogD("ewk_view_script_execute fail.");
+ }
+
+ return true;
+}
+
+void MessageManager::executeScriptCallback(
+ Evas_Object* webview, const char* result, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(webview);
+ UNUSED_PARAM(data);
+
+ std::string resultStr(result ? result : "null");
+ LogD("result: %s", resultStr.c_str());
+}
+} // Service
diff --git a/src_wearable/Core/View/Service/MessageManager.h b/src_wearable/Core/View/Service/MessageManager.h
new file mode 100644
index 0000000..d19b69d
--- /dev/null
+++ b/src_wearable/Core/View/Service/MessageManager.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 MessageManager.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#ifndef MESSAGE_MANAGER_H
+#define MESSAGE_MANAGER_H
+
+#include <string>
+#include <memory>
+#include <Evas.h>
+
+namespace Service {
+
+class MessageManager;
+typedef std::shared_ptr<MessageManager> MessageManagerPtr;
+
+class MessageManager {
+ public:
+ enum ReceiverType {
+ TO_BOX,
+ TO_PD
+ };
+
+ static MessageManagerPtr create() {
+ return MessageManagerPtr(new MessageManager());
+ }
+ bool send(Evas_Object* webview, ReceiverType receiver, std::string& message);
+ ~MessageManager();
+
+ private:
+ static void executeScriptCallback(
+ Evas_Object* webview, const char* result, void* data);
+ MessageManager();
+};
+} // Service
+
+#endif // MESSAGE_MANAGER_H
diff --git a/src_wearable/Core/View/Service/PeriodChanger.cpp b/src_wearable/Core/View/Service/PeriodChanger.cpp
new file mode 100755
index 0000000..856191b
--- /dev/null
+++ b/src_wearable/Core/View/Service/PeriodChanger.cpp
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 PeriodChanger.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string>
+#include <Evas.h>
+#include <Ecore_X.h>
+#include <Ecore.h>
+#include <Elementary.h>
+#include <efl_assist.h>
+#include <livebox-service.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "PeriodChanger.h"
+
+#define UPDATE_PERIOD_MIN 1800.0f
+#define UPDATE_PERIOD_HOUR 60.0 * 60.0
+#define U_(str) dgettext("web-provider", str)
+
+namespace Service {
+
+Evas_Object* PeriodChanger::s_window = NULL;
+bool PeriodChanger::s_isPopupOpened = false;
+
+static const char * const TEXT_POPUP_TITLE = "IDS_BR_HEADER_AUTO_REFRESH";
+static const char * const TEXT_POPUP_CANCEL_BUTTON = "IDS_ST_BUTTON_CANCEL";
+static const char * const TEXT_POPUP_UPDATE_PERIOD_1 ="IDS_ST_BODY_1_HOUR";
+static const char * const TEXT_POPUP_UPDATE_PERIOD_3 ="IDS_ST_BODY_3HOURS";
+static const char * const TEXT_POPUP_UPDATE_PERIOD_6 ="IDS_ST_BODY_6_HOURS_TMO";
+static const char * const TEXT_POPUP_UPDATE_PERIOD_12 ="IDS_ST_BODY_12_HOURS";
+static const char * const TEXT_POPUP_UPDATE_PERIOD_NEVER ="IDS_BR_OPT_NEVER";
+static const char * const MO_INSTALL_DIR = "/usr/share/res/locale";
+static const char * const MO_PROJECT_NAME = "web-provider";
+
+PeriodChanger::PeriodChanger(
+ std::string& boxId, std::string& instanceId,
+ double currentPeriod, double requestedPeriod)
+ : m_boxId(boxId)
+ , m_instanceId(instanceId)
+ , m_currentPeriod(currentPeriod)
+ , m_requestedPeriod(requestedPeriod)
+ , m_hour()
+{
+ LogD("enter");
+}
+
+PeriodChanger::~PeriodChanger()
+{
+ LogD("enter");
+}
+
+bool PeriodChanger::change()
+{
+ LogD("enter");
+
+ if (m_requestedPeriod < 0) {
+ showPeriodPopup();
+ return true;
+ }
+
+ double newPeriod;
+ if (m_requestedPeriod == 0) {
+ newPeriod = 0.0;
+ } else if (m_requestedPeriod > 0) {
+ if (m_requestedPeriod >= UPDATE_PERIOD_MIN) {
+ newPeriod = m_requestedPeriod;
+ } else {
+ newPeriod = UPDATE_PERIOD_MIN;
+ }
+ } else {
+ LogD("negative value can't be handled here");
+ newPeriod = 0.0;
+ }
+
+ // after selecting one among period list, the following should be executed
+ return requestToPlatform(newPeriod);
+}
+
+void PeriodChanger::showPeriodPopup()
+{
+ LogD("enter");
+
+ Evas_Object* window = createWindow();
+ Evas_Object* periodList = elm_list_add(window);
+
+ if (!periodList) {
+ LogD("failed to add elm_list_add");
+ }
+ elm_list_mode_set(periodList, ELM_LIST_EXPAND);
+ bindtextdomain(MO_PROJECT_NAME, MO_INSTALL_DIR);
+ setPopupListData();
+ // TODO Language ID should be used, not static string
+ for(unsigned int i = 0 ; i < sizeof(m_hour) / sizeof(PopupListData); i++) {
+ m_hour[i].radio = elm_radio_add(periodList);
+ elm_radio_state_value_set(m_hour[i].radio,
+ m_currentPeriod == m_hour[i].newPeriod ? EINA_FALSE : EINA_TRUE);
+ elm_list_item_append(periodList,
+ m_hour[i].period,
+ m_hour[i].radio,
+ NULL,
+ selectPeriodCallback, &m_hour[i]);
+ }
+
+ // create popup
+ Evas_Object *popup = elm_popup_add(window);
+ if (!popup) {
+ LogD("failed to add elm_popup_add");
+ return;
+ }
+ elm_object_style_set(popup, "popup-item list");
+ evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ elm_object_part_text_set(popup, "title,text", U_(TEXT_POPUP_TITLE));
+ elm_object_content_set(popup, periodList);
+ evas_object_show(popup);
+
+ // register back key callback
+ ea_object_event_callback_add(
+ popup, EA_CALLBACK_BACK,
+ pressHardwareBackKeyCallback, this);
+}
+
+void PeriodChanger::destroyPeriodPopup(Evas_Object *obj)
+{
+ LogD("enter");
+ Evas_Object* parent = elm_object_parent_widget_get(obj);
+ Evas_Object* popup = elm_popup_add(parent);
+ while (parent) {
+ const char* type = elm_object_widget_type_get(parent);
+ if (type && !strcmp(type, elm_object_widget_type_get(popup))) {
+ evas_object_del(parent);
+ break;
+ }
+ parent = elm_object_parent_widget_get(parent);
+ }
+
+ // register back key callback
+ ea_object_event_callback_del(popup, EA_CALLBACK_BACK, pressHardwareBackKeyCallback);
+ evas_object_del(popup);
+ destroyWindow();
+}
+
+void PeriodChanger::setPopupListData()
+{
+ LogD("enter");
+
+ m_hour[0].periodChanger = this;
+ m_hour[0].newPeriod = 1.0 * UPDATE_PERIOD_HOUR;
+ m_hour[0].period = U_(TEXT_POPUP_UPDATE_PERIOD_1);
+
+ m_hour[1].periodChanger = this;
+ m_hour[1].newPeriod = 3.0 * UPDATE_PERIOD_HOUR;
+ m_hour[1].period = U_(TEXT_POPUP_UPDATE_PERIOD_3);
+
+ m_hour[2].periodChanger = this;
+ m_hour[2].newPeriod = 6.0 * UPDATE_PERIOD_HOUR;
+ m_hour[2].period = U_(TEXT_POPUP_UPDATE_PERIOD_6);
+
+ m_hour[3].periodChanger = this;
+ m_hour[3].newPeriod = 12.0 * UPDATE_PERIOD_HOUR;
+ m_hour[3].period = U_(TEXT_POPUP_UPDATE_PERIOD_12);
+
+ m_hour[4].periodChanger = this;
+ m_hour[4].newPeriod = 0.0;
+ m_hour[4].period = U_(TEXT_POPUP_UPDATE_PERIOD_NEVER);
+
+}
+
+bool PeriodChanger::requestToPlatform(double newPeriod)
+{
+ int ret = livebox_service_change_period(
+ m_boxId.c_str(), m_instanceId.c_str(), newPeriod);
+
+ if (ret < 0) {
+ LogD("during update period, error occurs");
+ return false;
+ }
+
+ LogD("Instance's period is set to %f", newPeriod);
+ return true;
+}
+
+
+Evas_Object* PeriodChanger::createWindow()
+{
+ LogD("enter");
+
+ if (s_window) {
+ evas_object_show(s_window);
+ elm_win_raise(s_window);
+ return s_window;
+ }
+
+ s_window = elm_win_add(NULL, "web-provider-popup", ELM_WIN_BASIC);
+ elm_win_alpha_set(s_window, EINA_TRUE);
+ elm_win_title_set(s_window, "change update period");
+ elm_win_borderless_set(s_window, EINA_TRUE);
+
+ int width = 0;
+ int height = 0;
+ ecore_x_window_size_get(ecore_x_window_root_first_get(), &width, &height);
+ evas_object_resize(s_window, width, height);
+ elm_win_indicator_mode_set(s_window, ELM_WIN_INDICATOR_SHOW);
+
+ evas_object_color_set(s_window, 255, 255, 255, 0);
+ evas_object_show(s_window);
+ s_isPopupOpened = true;
+ return s_window;
+}
+
+void PeriodChanger::destroyWindow()
+{
+ LogD("enter");
+
+ if (!s_window) {
+ return;
+ }
+ evas_object_del(s_window);
+ s_window = NULL;
+ s_isPopupOpened = false;
+}
+
+void PeriodChanger::selectPeriodCallback(void *data, Evas_Object *obj, void *event_info)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(event_info);
+
+ PopupListData* popupData = static_cast<PopupListData*>(data);
+
+ LogD("Update period is set to %f", popupData->newPeriod);
+ popupData->periodChanger->requestToPlatform(popupData->newPeriod);
+ ecore_idler_add(popupDestroyIdlerCallback, popupData);
+}
+
+void PeriodChanger::cancelButtonCallback(void *data, Evas_Object *obj, void *event_info)
+{
+ LogD("enter");
+ UNUSED_PARAM(event_info);
+
+ PeriodChanger* This = static_cast<PeriodChanger*>(data);
+ This->destroyPeriodPopup(obj);
+}
+
+void PeriodChanger::pressHardwareBackKeyCallback(void *data, Evas_Object *obj, void *event_info)
+{
+ LogD("enter");
+ UNUSED_PARAM(event_info);
+
+ PeriodChanger* This = static_cast<PeriodChanger*>(data);
+ This->destroyPeriodPopup(obj);
+}
+
+Eina_Bool PeriodChanger::popupDestroyIdlerCallback(void *data)
+{
+ LogD("enter");
+ PopupListData* popupData = static_cast<PopupListData*>(data);
+ popupData->periodChanger->destroyPeriodPopup(popupData->radio);
+ return ECORE_CALLBACK_CANCEL;
+}
+} // Service
diff --git a/src_wearable/Core/View/Service/PeriodChanger.h b/src_wearable/Core/View/Service/PeriodChanger.h
new file mode 100755
index 0000000..b8902b0
--- /dev/null
+++ b/src_wearable/Core/View/Service/PeriodChanger.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 PeriodChanger.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef PERIOD_CHNAGER_H
+#define PERIOD_CHNAGER_H
+
+#include <string>
+#include <memory>
+#include <Evas.h>
+
+namespace Service {
+class PeriodChanger;
+typedef std::shared_ptr<PeriodChanger> PeriodChangerPtr;
+
+class PeriodChanger {
+ public:
+ static PeriodChangerPtr create(
+ std::string& boxId, std::string& instanceId,
+ double currentPeriod, double requestedPeriod)
+ {
+ return PeriodChangerPtr(
+ new PeriodChanger(boxId, instanceId, currentPeriod, requestedPeriod));
+ }
+ bool change();
+ static bool isPopupOpened() { return s_isPopupOpened; };
+ ~PeriodChanger();
+
+ private:
+ void showPeriodPopup();
+ void destroyPeriodPopup(Evas_Object *obj);
+ void setPopupListData();
+ bool requestToPlatform(double newPeriod);
+ static Evas_Object* createWindow();
+ static void destroyWindow();
+
+ static void selectPeriodCallback(void *data, Evas_Object *obj, void *event_info);
+ static void cancelButtonCallback(void *data, Evas_Object *obj, void *event_info);
+ static void pressHardwareBackKeyCallback(void *data, Evas_Object *obj, void *event_info);
+ static Eina_Bool popupDestroyIdlerCallback(void *data);
+
+ PeriodChanger(
+ std::string& boxId, std::string& instanceId,
+ double currentPeriod, double requestedPeriod);
+
+ static Evas_Object* s_window;
+ std::string m_boxId;
+ std::string m_instanceId;
+ float m_currentPeriod;
+ float m_requestedPeriod;
+ static bool s_isPopupOpened;
+
+ struct PopupListData {
+ PeriodChanger* periodChanger;
+ double newPeriod;
+ const char* period;
+ Evas_Object* radio;
+ };
+
+ PopupListData m_hour[5];
+};
+} // Service
+
+#endif // PERIOD_CHNAGER_H
diff --git a/src_wearable/Core/View/Service/ScrollHolder.cpp b/src_wearable/Core/View/Service/ScrollHolder.cpp
new file mode 100644
index 0000000..3435ff7
--- /dev/null
+++ b/src_wearable/Core/View/Service/ScrollHolder.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 ScrollHolder.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string>
+#include <provider.h>
+#include <Core/Util/Log.h>
+
+namespace Service {
+namespace ScrollHolder {
+
+void holdHorizontalScroll(std::string& boxId, std::string& instanceId, bool start)
+{
+ LogD("enter");
+
+ if (start) {
+ LogD("scroll start");
+ provider_send_hold_scroll(boxId.c_str(), instanceId.c_str(), 1);
+ } else {
+ LogD("scroll stop");
+ provider_send_hold_scroll(boxId.c_str(), instanceId.c_str(), 0);
+ }
+}
+
+} // AppControl
+} // Service
diff --git a/src_wearable/Core/View/Service/ScrollHolder.h b/src_wearable/Core/View/Service/ScrollHolder.h
new file mode 100644
index 0000000..a7373b7
--- /dev/null
+++ b/src_wearable/Core/View/Service/ScrollHolder.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 ScrollHolder.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string>
+
+namespace Service {
+namespace ScrollHolder {
+
+void holdHorizontalScroll(std::string& boxId, std::string& instanceId, bool start);
+
+}
+} // Service
diff --git a/src_wearable/Core/View/WebView.cpp b/src_wearable/Core/View/WebView.cpp
new file mode 100755
index 0000000..5e4987d
--- /dev/null
+++ b/src_wearable/Core/View/WebView.cpp
@@ -0,0 +1,904 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 WebView.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include "WebView.h"
+
+#include "config.h"
+
+#include <sstream>
+#include <string>
+#include <fstream>
+#include <streambuf>
+#include <Evas.h>
+#include <Eina.h>
+#include <ewk_context.h>
+#include <ewk_view.h>
+#include <ewk_policy_decision.h>
+#include <ewk_console_message.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "Service/AppControl.h"
+
+// injection javascript file regarding creating js object used by box and pd
+static const std::string injectionFile("/usr/share/web-provider/injection.js");
+static const char* consoleMessageDlogTag = "ConsoleMessage";
+
+std::map<const std::string, const Evas_Smart_Cb> WebView::m_smartCallbacksMap =
+{
+ {"load,started", WebView::loadStartedCallback},
+ {"load,finished", WebView::loadFinishedCallback},
+ {"title,changed", WebView::titleChangedCallback},
+ {"uri,changed", WebView::uriChangedCallback},
+ {"load,progress", WebView::loadProgressCallback},
+ {"load,progress,finished", WebView::loadProgressFinishedCallback},
+ {"process,crashed", WebView::processCrashedCallback},
+ {"create,window", WebView::createWindowCallback},
+ {"close,window", WebView::closeWindowCallback},
+ {"policy,navigation,decide", WebView::policyNavigationDecideCallback},
+ {"policy,newwindow,decide", WebView::policyNewWindowDecideCallback},
+ {"policy,response,decide", WebView::pageResponseDecideCallback},
+ {"contextmenu,customize", WebView::contextmenuCustomizeCallback},
+ {"form,submit", WebView::formSubmitCallback},
+ {"request,geolocation,permission", WebView::geolocationPermissionRequestCallback},
+ {"notification,show", WebView::notificationShowCallback},
+ {"notification,cancel", WebView::notificationCancelCallback},
+ {"notification,permission,request", WebView::notificationPermissionRequestCallback},
+ {"database,quota,exceeded", WebView::databaseUsagePermissionRequestCallback},
+ {"filesystem,permission,request", WebView::fileSystemPermissionRequestCallback},
+ {"fullscreen,enterfullscreen", WebView::enterFullscreenCallback},
+ {"fullscreen,exitfullscreen", WebView::exitFullscreenCallback},
+ {"inputmethod,changed", WebView::imeChangedCallback},
+ {"editorclient,ime,opened", WebView::imeOpenedCallback},
+ {"editorclient,ime,closed", WebView::imeClosedCallback},
+ {"usermedia,permission,request", WebView::usermediaPermissionRequestCallback},
+ {"protocolhandler,registration,requested", WebView::protocolHandlerRegistrationCallback},
+ {"protocolhandler,isregistered", WebView::protocolHandlerIsRegisteredCallback},
+ {"protocolhandler,unregistration,requested", WebView::protocolHandlerUnregistrationCallback},
+ {"contenthandler,registration,requested", WebView::contentHandlerRegistrationCallback},
+ {"contenthandler,isregistered", WebView::contentHandlerIsRegisteredCallback},
+ {"contenthandler,unregistration,requested", WebView::contentHandlerUnregistrationCallback},
+ {"request,certificate,confirm", WebView::certificateConfirmRequestCallback},
+ {"console,message", WebView::consoleMessageCallback}
+};
+
+WebView::WebView(Evas_Object* win, Ewk_Context* ewkContext)
+ : m_topWebview(NULL)
+ , m_win(win)
+ , m_ewkContext(ewkContext)
+{
+}
+
+WebView::~WebView()
+{
+}
+
+bool WebView::show(
+ std::string& startUrl, int width, int height,
+ WebViewCallback didCreateBaseWebView, void* data)
+{
+ LogD("enter");
+ if (!m_topWebview) {
+ m_topWebview = ewk_view_add_with_context(
+ evas_object_evas_get(m_win), m_ewkContext);
+ if (!setBasicSetting(m_topWebview)) {
+ return false;
+ }
+ }
+
+ // inform base webview to caller
+ if (didCreateBaseWebView) {
+ didCreateBaseWebView(data, static_cast<void*>(m_topWebview));
+ }
+
+ // check scheme of url
+ std::string url = validateUrl(startUrl);
+ LogD("load: %s", url.c_str());
+ ewk_view_url_set(m_topWebview, url.c_str());
+
+ evas_object_resize(m_topWebview, width, height);
+ evas_object_show(m_topWebview);
+
+ return true;
+}
+
+bool WebView::hide()
+{
+ LogD("enter");
+
+ // TODO If created webviews are managed by WebView Class,
+ // add code regarding created all webviews
+ if (!unsetBasicSetting(m_topWebview)) {
+ return false;
+ }
+ if(!m_topWebview) {
+ return false;
+ }
+ for (auto it = m_smartCallbacksMap.begin();
+ it != m_smartCallbacksMap.end(); it++) {
+ evas_object_smart_callback_del(
+ m_topWebview, it->first.c_str(), it->second);
+ }
+
+ evas_object_del(m_topWebview);
+ m_topWebview = NULL;
+
+ return true;
+}
+
+bool WebView::suspend()
+{
+ LogD("enter");
+ ewk_view_page_visibility_state_set(
+ m_topWebview, EWK_PAGE_VISIBILITY_STATE_HIDDEN, EINA_FALSE);
+ ewk_view_suspend(m_topWebview);
+ return true;
+}
+
+bool WebView::resume()
+{
+ LogD("enter");
+ ewk_view_resume(m_topWebview);
+ ewk_view_page_visibility_state_set(
+ m_topWebview, EWK_PAGE_VISIBILITY_STATE_VISIBLE, EINA_FALSE);
+ return true;
+}
+
+bool WebView::setBasicSetting(Evas_Object* webview)
+{
+ LogD("enter");
+
+ if (!webview) {
+ return false;
+ }
+
+ for (auto it = m_smartCallbacksMap.begin();
+ it != m_smartCallbacksMap.end(); it++) {
+ evas_object_smart_callback_add(
+ webview, it->first.c_str(), it->second, this);
+ }
+
+ // set specific features
+ Ewk_Settings* setting = ewk_view_settings_get(webview);
+ // set user agent like WRT, or Browser?
+ // ewk_view_user_agent_set(webview, "some_ua_string");
+ ewk_settings_plugins_enabled_set(setting, EINA_TRUE);
+ ewk_settings_javascript_enabled_set(setting, EINA_TRUE);
+ ewk_settings_loads_images_automatically_set(setting, EINA_TRUE);
+ ewk_settings_auto_fitting_set(setting, EINA_FALSE);
+#if !ENABLE(WEBKIT_UPVERSION)
+ ewk_settings_default_keypad_enabled_set(setting, EINA_FALSE);
+#endif
+ ewk_settings_text_selection_enabled_set(setting, EINA_FALSE);
+
+ // set visibility
+ ewk_view_page_visibility_state_set(
+ webview, EWK_PAGE_VISIBILITY_STATE_VISIBLE, EINA_TRUE);
+
+ evas_object_color_set(webview, 0, 0, 0, 1);
+ ewk_view_use_settings_font(webview);
+
+ return true;
+}
+
+bool WebView::unsetBasicSetting(Evas_Object* webview)
+{
+ LogD("enter");
+
+ if (!webview) {
+ return false;
+ }
+
+ for (auto it = m_smartCallbacksMap.begin();
+ it != m_smartCallbacksMap.end(); it++) {
+ evas_object_smart_callback_del(
+ m_topWebview, it->first.c_str(), it->second);
+ }
+
+ return true;
+}
+
+std::string WebView::validateUrl(std::string& url)
+{
+ LogD("enter");
+
+ if (url.empty()) {
+ return std::string();
+ }
+
+ if((!url.compare(0, 4, "http")) ||
+ (!url.compare(0, 5, "https")) ||
+ (!url.compare(0, 4, "file")))
+ {
+ return url;
+ }
+
+ std::string newUrl("file://");
+ newUrl += url;
+ return newUrl;
+}
+
+void WebView::loadStartedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+
+ std::ifstream jsFile(injectionFile);
+ std::string script((std::istreambuf_iterator<char>(jsFile)),
+ std::istreambuf_iterator<char>());
+ LogD("injected js code: %s", script.c_str());
+
+ ewk_view_script_execute(obj, script.c_str(), executeScriptCallback, This);
+ This->didLoadStarted(obj);
+}
+
+void WebView::loadFinishedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didLoadFinished(obj);
+}
+
+void WebView::titleChangedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didTitleChanged(obj, eventInfo);
+}
+
+void WebView::uriChangedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didUriChanged(obj, eventInfo);
+}
+
+void WebView::loadProgressCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didLoadProgress(obj, eventInfo);
+}
+
+void WebView::loadProgressFinishedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didLoadProgressFinished(obj);
+}
+
+void WebView::processCrashedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didProcessCrashed(obj);
+}
+
+void WebView::createWindowCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didCreateWindow(obj, eventInfo);
+}
+
+void WebView::closeWindowCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didCloseWindow(obj);
+}
+
+void WebView::policyNavigationDecideCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didPolicyNavigationDecide(obj, eventInfo);
+}
+
+void WebView::policyNewWindowDecideCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didPolicyNewWindowDecide(obj, eventInfo);
+}
+
+void WebView::pageResponseDecideCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ Ewk_Policy_Decision *policyDecision = static_cast<Ewk_Policy_Decision *>(eventInfo);
+ Ewk_Policy_Decision_Type policyType = ewk_policy_decision_type_get(policyDecision);
+ std::string url(ewk_policy_decision_url_get(policyDecision));
+ std::string cookie(ewk_policy_decision_cookie_get(policyDecision));
+ const char* contentType = ewk_policy_decision_response_mime_get(policyDecision);
+
+ switch (policyType) {
+ case EWK_POLICY_DECISION_USE:
+ LogD("policy use");
+ ewk_policy_decision_use(policyDecision);
+ break;
+
+ case EWK_POLICY_DECISION_DOWNLOAD:
+ LogD("policy download: %s, %s, %s", url.c_str(), cookie.c_str(), contentType);
+ ewk_policy_decision_suspend(policyDecision);
+ Service::AppControl::launchDownloader(url, cookie);
+ ewk_policy_decision_ignore(policyDecision);
+ break;
+
+ case EWK_POLICY_DECISION_IGNORE:
+ default:
+ LogD("policy ignore");
+ ewk_policy_decision_ignore(policyDecision);
+ break;
+ }
+
+ if (policyType == EWK_POLICY_DECISION_DOWNLOAD) {
+ if (ewk_view_back_possible(obj)) {
+ ewk_view_back(obj);
+ } else {
+ // TODO Add handling code in case that new window is opened
+ //ecore_idler_add(windowCloseIdlerCallback, data);
+ }
+ }
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didPageResponseDecide(obj);
+}
+
+void WebView::contextmenuCustomizeCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didContextmenuCustomize(obj, eventInfo);
+}
+
+void WebView::formSubmitCallback(
+ void* data, Evas_Object *obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didFormSubmit(obj);
+}
+
+void WebView::geolocationPermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didGeolocationPermissionRequest(obj, eventInfo);
+}
+
+void WebView::notificationShowCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didNotificationShow(obj, eventInfo);
+}
+
+void WebView::notificationCancelCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didNotificationCancel(obj, eventInfo);
+}
+
+void WebView::notificationPermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didNotificationPermissionRequest(obj, eventInfo);
+}
+
+void WebView::databaseUsagePermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didDatabaseUsagePermissionRequest(obj, eventInfo);
+}
+
+void WebView::fileSystemPermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didFilesystemPermissionRequest(obj, eventInfo);
+}
+
+void WebView::enterFullscreenCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didEnterFullscreen(obj);
+}
+
+void WebView::exitFullscreenCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didExitFullscreen(obj);
+}
+
+void WebView::imeChangedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didImeChanged(obj, eventInfo);
+}
+
+void WebView::imeOpenedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didImeOpened(obj);
+}
+
+void WebView::imeClosedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didImeClosed(obj);
+}
+
+void WebView::usermediaPermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didUsermediaPermissionRequest(obj, eventInfo);
+}
+
+void WebView::protocolHandlerRegistrationCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didProtocolHandlerRegistration(obj, eventInfo);
+}
+
+void WebView::protocolHandlerIsRegisteredCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didProtocolHandlerIsRegistered(obj, eventInfo);
+}
+
+void WebView::protocolHandlerUnregistrationCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didProtocolHandlerUnregistration(obj, eventInfo);
+}
+
+void WebView::contentHandlerRegistrationCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didContentHandlerRegistration(obj, eventInfo);
+}
+
+void WebView::contentHandlerIsRegisteredCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didContentHandlerIsRegistered(obj, eventInfo);
+}
+
+void WebView::contentHandlerUnregistrationCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didContentHandlerUnregistration(obj, eventInfo);
+}
+
+void WebView::certificateConfirmRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didCertificateConfirmRequest(obj, eventInfo);
+}
+
+void WebView::didLoadStarted(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+
+ // This Will be implemented by derived class
+}
+
+void WebView::didLoadFinished(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didTitleChanged(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+
+ // This Will be implemented by derived class
+}
+
+void WebView::didUriChanged(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didLoadProgress(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didLoadProgressFinished(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didProcessCrashed(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didCreateWindow(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didCloseWindow(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didPolicyNavigationDecide(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didPolicyNewWindowDecide(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didPageResponseDecide(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didContextmenuCustomize(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didFormSubmit(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didGeolocationPermissionRequest(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didNotificationShow(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didNotificationCancel(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didNotificationPermissionRequest(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didDatabaseUsagePermissionRequest(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didFilesystemPermissionRequest(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didEnterFullscreen(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didExitFullscreen(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didImeChanged(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didImeOpened(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didImeClosed(Evas_Object* obj)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ // This Will be implemented by derived class
+}
+
+void WebView::didUsermediaPermissionRequest(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didProtocolHandlerRegistration(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didProtocolHandlerIsRegistered(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didProtocolHandlerUnregistration(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didContentHandlerRegistration(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didContentHandlerIsRegistered(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didContentHandlerUnregistration(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+void WebView::didCertificateConfirmRequest(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(eventInfo);
+ // This Will be implemented by derived class
+}
+
+Eina_Bool WebView::orientationLockCallback(
+ Evas_Object* obj, Eina_Bool needLock, int orientation, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(needLock);
+ UNUSED_PARAM(orientation);
+ UNUSED_PARAM(data);
+ return EINA_TRUE;
+}
+
+void WebView::executeScriptCallback(
+ Evas_Object* obj, const char* result, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+ UNUSED_PARAM(result);
+ UNUSED_PARAM(data);
+}
+
+void WebView::consoleMessageCallback(void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(obj);
+
+ WebView* This = static_cast<WebView*>(data);
+
+ Ewk_Console_Message* consoleMessage =
+ static_cast<Ewk_Console_Message*>(eventInfo);
+
+ std::stringstream buf;
+ unsigned int lineNumber = ewk_console_message_line_get(consoleMessage);
+ const char* source = ewk_console_message_source_get(consoleMessage);
+ const char* text = ewk_console_message_text_get(consoleMessage);
+ if (lineNumber) {
+ buf << source << ":" << lineNumber << ":";
+ }
+ buf << text;
+ This->consoleMessage(ewk_console_message_level_get(consoleMessage), buf.str().c_str());
+}
+
+void WebView::consoleMessage(int level, const char* message)
+{
+ LogD("enter");
+
+ // this console message should be secure mode
+ switch (level) {
+ case EWK_CONSOLE_MESSAGE_LEVEL_DEBUG:
+ SECURE_LOG(LOG_DEBUG, consoleMessageDlogTag, "%s", message);
+ break;
+ case EWK_CONSOLE_MESSAGE_LEVEL_WARNING:
+ SECURE_LOG(LOG_WARN, consoleMessageDlogTag, "%s", message);
+ break;
+ case EWK_CONSOLE_MESSAGE_LEVEL_ERROR:
+ SECURE_LOG(LOG_ERROR, consoleMessageDlogTag, "%s", message);
+ break;
+ default:
+ SECURE_LOG(LOG_DEBUG, consoleMessageDlogTag, "%s", message);
+ break;
+ }
+}
diff --git a/src_wearable/Core/View/WebView.h b/src_wearable/Core/View/WebView.h
new file mode 100644
index 0000000..4c9dee1
--- /dev/null
+++ b/src_wearable/Core/View/WebView.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 WebView.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef WEB_VIEW_H
+#define WEB_VIEW_H
+
+#include <string>
+#include <map>
+#include <Eina.h>
+#include <Evas.h>
+#include <ewk_context.h>
+#include "IWebView.h"
+
+#define EXPORT_CLASS __attribute__ ((visibility("default")))
+
+class EXPORT_CLASS WebView: public IWebView {
+ public:
+ static IWebViewPtr create(Evas_Object* win, Ewk_Context* ewkContext)
+ {
+ if (!win || !ewkContext) {
+ return IWebViewPtr();
+ }
+
+ return IWebViewPtr(new WebView(win, ewkContext));
+ }
+ virtual bool show(
+ std::string& startUrl, int width, int height,
+ WebViewCallback didCreateBaseWebView, void* data);
+ virtual bool hide();
+ virtual bool suspend();
+ virtual bool resume();
+ virtual ~WebView();
+
+ protected:
+ bool setBasicSetting(Evas_Object* webview);
+ bool unsetBasicSetting(Evas_Object* webview);
+ explicit WebView(Evas_Object* win, Ewk_Context* ewkContext);
+
+ private:
+ std::string validateUrl(std::string& url);
+ void consoleMessage(int level, const char* message);
+
+ // webviw smart callbacks
+ static void loadStartedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void loadFinishedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void titleChangedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void uriChangedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void loadProgressCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void loadProgressFinishedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void processCrashedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void createWindowCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void closeWindowCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void policyNavigationDecideCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void policyNewWindowDecideCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void pageResponseDecideCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void contextmenuCustomizeCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void formSubmitCallback(
+ void *data, Evas_Object *obj, void *eventInfo);
+ static void geolocationPermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void notificationShowCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void notificationCancelCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void notificationPermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void databaseUsagePermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void fileSystemPermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void enterFullscreenCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void exitFullscreenCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void imeChangedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void imeOpenedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void imeClosedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void usermediaPermissionRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void protocolHandlerRegistrationCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void protocolHandlerIsRegisteredCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void protocolHandlerUnregistrationCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void contentHandlerRegistrationCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void contentHandlerIsRegisteredCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void contentHandlerUnregistrationCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void certificateConfirmRequestCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
+ static void consoleMessageCallback(void* data, Evas_Object* obj, void* eventInfo);
+
+ // internal implementation for smart callbacks
+ virtual void didLoadStarted(Evas_Object* obj);
+ virtual void didLoadFinished(Evas_Object* obj);
+ virtual void didTitleChanged(Evas_Object* obj, void* eventInfo);
+ virtual void didUriChanged(Evas_Object* obj, void* eventInfo);
+ virtual void didLoadProgress(Evas_Object* obj, void* eventInfo);
+ virtual void didLoadProgressFinished(Evas_Object* obj);
+ virtual void didProcessCrashed(Evas_Object* obj);
+ virtual void didCreateWindow(Evas_Object* obj, void* eventInfo);
+ virtual void didCloseWindow(Evas_Object* obj);
+ virtual void didPolicyNavigationDecide(Evas_Object* obj, void* eventInfo);
+ virtual void didPolicyNewWindowDecide(Evas_Object* obj, void* eventInfo);
+ virtual void didPageResponseDecide(Evas_Object* obj);
+ virtual void didContextmenuCustomize(Evas_Object* obj, void* eventInfo);
+ virtual void didFormSubmit(Evas_Object* obj);
+ virtual void didGeolocationPermissionRequest(Evas_Object* obj, void* eventInfo);
+ virtual void didNotificationShow(Evas_Object* obj, void* eventInfo);
+ virtual void didNotificationCancel(Evas_Object* obj, void* eventInfo);
+ virtual void didNotificationPermissionRequest(Evas_Object* obj, void* eventInfo);
+ virtual void didDatabaseUsagePermissionRequest(Evas_Object* obj, void* eventInfo);
+ virtual void didFilesystemPermissionRequest(Evas_Object* obj, void* eventInfo);
+ virtual void didEnterFullscreen(Evas_Object* obj);
+ virtual void didExitFullscreen(Evas_Object* obj);
+ virtual void didImeChanged(Evas_Object* obj, void* eventInfo);
+ virtual void didImeOpened(Evas_Object* obj);
+ virtual void didImeClosed(Evas_Object* obj);
+ virtual void didUsermediaPermissionRequest(Evas_Object* obj, void* eventInfo);
+ virtual void didProtocolHandlerRegistration(Evas_Object* obj, void* eventInfo);
+ virtual void didProtocolHandlerIsRegistered(Evas_Object* obj, void* eventInfo);
+ virtual void didProtocolHandlerUnregistration(Evas_Object* obj, void* eventInfo);
+ virtual void didContentHandlerRegistration(Evas_Object* obj, void* eventInfo);
+ virtual void didContentHandlerIsRegistered(Evas_Object* obj, void* eventInfo);
+ virtual void didContentHandlerUnregistration(Evas_Object* obj, void* eventInfo);
+ virtual void didCertificateConfirmRequest(Evas_Object* obj, void* eventInfo);
+
+ // orientation lock
+ static Eina_Bool orientationLockCallback(
+ Evas_Object* obj, Eina_Bool needLock, int orientation, void* data);
+ static void executeScriptCallback(Evas_Object* obj, const char* result, void* data);
+
+ static std::map<const std::string, const Evas_Smart_Cb> m_smartCallbacksMap;
+
+ // members
+ Evas_Object* m_topWebview;
+ std::string m_startUrl;
+ Evas_Object* m_win;
+ Ewk_Context* m_ewkContext;
+};
+
+#endif // WEB_VIEW_H
diff --git a/src_wearable/Core/View/injection.js b/src_wearable/Core/View/injection.js
new file mode 100644
index 0000000..32ba93c
--- /dev/null
+++ b/src_wearable/Core/View/injection.js
@@ -0,0 +1,151 @@
+// set javascript objects for Web APIs of Tizen appwidget
+var appTizenObject = 0;
+if (typeof window.tizen == 'undefined') {
+ window.tizen = new Object();
+ window.tizen.appwidget = new Object();
+} else {
+ appTizenObject = 1;
+}
+
+// For future, only window.appwidget will be used
+window.appwidget = new Object();
+
+
+window.appwidget.fireReadyEvent = function () {
+ // If every functionalities of appwidget are initialized, fire appwidget ready event
+ var readyevent = document.createEvent("CustomEvent");
+ readyevent.initCustomEvent("appwidgetready", true, true);
+ document.dispatchEvent(readyevent);
+};
+
+// these are functions for overriding standard javascript functions regarding event
+var original_addEventListener = window.addEventListener;
+var original_removeEventListener = window.removeEventListener;
+
+// this variable is responsible to keep information of appwidget evetns
+var appWidgetEvents = {};
+
+// define event structure for appwidget
+window.AppWidgetEventInfo = function(event, callback) {
+ this.event = event;
+ this.callback = callback;
+};
+
+// this variable is responsible to keep information of box
+var appWidgetContexts = {};
+
+// define box info for appwidget (e.g. box id, box instance id)
+window.AppWidgetContextInfo = function(key, value) {
+ this.key = key;
+ this.value = value;
+};
+
+window.addEventListener = function(event, callback, capture) {
+ var e = event.toLowerCase();
+ if (typeof appWidgetEvents[e] != 'undefined') {
+ appWidgetEvents[e].callback = callback;
+ } else {
+ original_addEventListener.call(window, event, callback, capture);
+ }
+
+ if (e == 'appwidgetready') {
+ // fire ready event to content
+ setTimeout(window.appwidget.fireReadyEvent(), 0);
+ }
+};
+
+window.removeEventListener = function(event, callback, capture) {
+ var e = event.toLowerCase();
+ if (typeof appWidgetEvents[e] != "undefined") {
+ appWidgetEvents[e].callback = "null";
+ } else {
+ original_removeEventListener.call(window, event, callback, capture);
+ }
+};
+
+window.appwidget.reload = function() {
+ window.location.href = "box://reload";
+};
+
+window.appwidget.changePeriod = function(period) {
+ switch (arguments.length) {
+ case 0:
+ window.location.href = "box://change-period";
+ break;
+ case 1:
+ window.location.href = "box://change-period?period=" + period;
+ break;
+ default:
+ window.location.href = "box://change-period";
+ break;
+ }
+};
+
+window.appwidget.launchBrowser = function(url) {
+ window.location.href = "box://launch-browser?url=" + url;
+};
+
+window.appwidget.scrollStart = function() {
+ window.location.href = "box://scroll-start";
+};
+
+window.appwidget.scrollStop = function() {
+ window.location.href = "box://scroll-stop";
+};
+
+window.appwidget.sendMessageToBox = function(message) {
+ window.location.href = "box://send-message-to-box?message=" + message;
+};
+
+window.appwidget.sendMessageToPd = function(message) {
+ window.location.href = "box://send-message-to-pd?message=" + message;
+};
+
+window.appwidget.getBoxId = function() {
+ return appWidgetContexts["box-id"].value;
+};
+
+window.appwidget.getBoxInstanceId = function() {
+ return appWidgetContexts["instance-id"].value;
+};
+
+var webprovider = {
+ // define specific function for registering appwidget event
+ registerAppWidgetEvent: function(event) {
+ return (appWidgetEvents[event] = new AppWidgetEventInfo(event, "null"));
+ },
+
+ // register resources for synchronous APIs like getBoxId, getBoxInstanceId
+ registerAppWidgetContextInfo: function(key, value) {
+ return (appWidgetContexts[key] = new AppWidgetContextInfo(key, value));
+ },
+
+ // define specific function for firing registered appwidget event
+ fireAppWidgetEvent: function(event, data) {
+ // this is called by web-provider, which is native code
+ if (typeof appWidgetEvents[event] != 'undefined') {
+ setTimeout(function() {
+ appWidgetEvents[event].callback(data);
+ }, 0);
+ console.log("fire appwidget event: " + event);
+ } else {
+ console.log("unknown appwidget event: " + event);
+ }
+ },
+};
+
+// register custom events for appwidget
+webprovider.registerAppWidgetEvent("pdmessage");
+webprovider.registerAppWidgetEvent("boxmessage");
+
+// These objects will be deprecated soon
+if (!appTizenObject) {
+ window.tizen.appwidget.reload = window.appwidget.reload;
+ window.tizen.appwidget.changePeriod = window.appwidget.changePeriod;
+ window.tizen.appwidget.launchBrowser = window.appwidget.launchBrowser;
+ window.tizen.appwidget.scrollStart = window.appwidget.scrollStart;
+ window.tizen.appwidget.scrollStop = window.appwidget.scrollStop;
+}
+
+// fire ready event explicitly
+window.appwidget.fireReadyEvent();
diff --git a/src_wearable/Core/config.h b/src_wearable/Core/config.h
new file mode 100644
index 0000000..52d0d61
--- /dev/null
+++ b/src_wearable/Core/config.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 config.h
+ * @author Minhyung Ko (minhyung.ko@samsung.com)
+ */
+
+#include <Core/Platform.h>
+
+/*** define list **/
+#define WEB_PROVIDER_INSPECTOR_PORT_NUMBER 9980
+#define WEB_PROVIDER_INSPECTOR_FILE_PATH "/tmp/inspector"
diff --git a/src_wearable/Daemon/BoxDaemon.cpp b/src_wearable/Daemon/BoxDaemon.cpp
new file mode 100644
index 0000000..d58153b
--- /dev/null
+++ b/src_wearable/Daemon/BoxDaemon.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxDaemon.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <app.h>
+#include "BoxDaemon.h"
+#include "BoxDaemonImpl.h"
+
+BoxDaemon::BoxDaemon()
+ : m_impl(new BoxDaemonImpl())
+{
+}
+
+BoxDaemon::~BoxDaemon()
+{
+}
+
+bool BoxDaemon::start(std::string& name)
+{
+ return m_impl->start(name);
+}
+
+bool BoxDaemon::stop()
+{
+ return m_impl->stop();
+}
+
+bool BoxDaemon::handleAppService(service_h service)
+{
+ return m_impl->handleAppService(service);
+}
diff --git a/src_wearable/Daemon/BoxDaemon.h b/src_wearable/Daemon/BoxDaemon.h
new file mode 100644
index 0000000..f1bde75
--- /dev/null
+++ b/src_wearable/Daemon/BoxDaemon.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxDaemon.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_DAEMON_H
+#define BOX_DAEMON_H
+
+#include <string>
+#include <memory>
+#include <app.h>
+#include <Core/Util/Noncopyable.h>
+
+class BoxDaemonImpl;
+
+class BoxDaemon: Noncopyable {
+ public:
+ bool start(std::string& name);
+ bool stop();
+ bool handleAppService(service_h service);
+
+ explicit BoxDaemon();
+ ~BoxDaemon();
+
+ private:
+ std::shared_ptr<BoxDaemonImpl> m_impl;
+};
+
+#endif //BOX_DAEMON_H
diff --git a/src_wearable/Daemon/BoxDaemonImpl.cpp b/src_wearable/Daemon/BoxDaemonImpl.cpp
new file mode 100755
index 0000000..5cf22eb
--- /dev/null
+++ b/src_wearable/Daemon/BoxDaemonImpl.cpp
@@ -0,0 +1,790 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxDaemonImpl.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <cstring>
+#include <sys/types.h>
+#include <string>
+#include <unistd.h>
+#include <vector>
+
+#include <app.h>
+#include <appcore-efl.h>
+#include <aul.h>
+#include <Ecore_X.h>
+#include <Elementary.h>
+#include <livebox-service.h>
+#include <provider.h>
+#include <vconf.h>
+
+#include <API/web_provider_livebox_info.h>
+#include <API/web_provider_service.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include <Plugin/IBoxPluginConnector.h>
+#include <Plugin/BoxPluginConnector.h>
+
+#include "BoxDaemonUtil.h"
+#include "BoxDaemonImpl.h"
+
+#define MASTER_PROVIDER_PING_TIME 120.0f
+
+BoxDaemonImpl::BoxDaemonImpl()
+ : m_pluginConnector(BoxPluginConnector::create())
+{
+ appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, requestUpdateAllCallback, this);
+ appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, requestLowMemoryCallback, this);
+ appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, requestUpdateAllCallback, this);
+ // reserved
+ appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, NULL, NULL);
+
+ if (vconf_notify_key_changed("db/setting/accessibility/font_name", requestUpdateAllCallback, this) != 0) {
+ LogD("vconf_notify_key_changed returned FALSE!");
+ }
+ if (vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, requestUpdateAppBoxCallback, this) != 0) {
+ LogD("vconf_notify_key_changed returned FALSE!");
+ }
+ if (vconf_notify_key_changed(VCONFKEY_NETWORK_WIFI_STATE, requestUpdateAppBoxCallback, this) != 0) {
+ LogD("vconf_notify_key_changed returned FALSE!");
+ }
+ if (vconf_notify_key_changed(VCONFKEY_NETWORK_CELLULAR_STATE, requestUpdateAppBoxCallback, this) != 0) {
+ LogD("vconf_notify_key_changed returned FALSE!");
+ }
+}
+
+BoxDaemonImpl::~BoxDaemonImpl()
+{
+}
+
+bool BoxDaemonImpl::start(std::string& name)
+{
+ LogD("enter");
+
+ // initialize existing plugins for web livebox
+ if (!m_pluginConnector->initialize()) {
+ LogD("failed to initialize plugins");
+ return false;
+ }
+
+ // set name
+ m_daemonName = name;
+
+ // provider init
+ ProviderCallbacks callbacks;
+ setProviderCallbacks(callbacks);
+
+ int ret = provider_init_with_options(ecore_x_display_get(),
+ m_daemonName.c_str(),
+ &callbacks,
+ this, 1, 1);
+ if (ret < 0) {
+ LogD("failed to initialize provider");
+ return false;
+ }
+
+ return true;
+}
+
+bool BoxDaemonImpl::stop()
+{
+ LogD("enter");
+
+ // deinitialize provider
+ provider_fini();
+
+ // deinitialize existing plugins for web livebox
+ if (!m_pluginConnector->shutdown()) {
+ LogD("failed to shutdown plugins");
+ return false;
+ }
+
+ return true;
+}
+
+bool BoxDaemonImpl::handleAppService(service_h service)
+{
+ LogD("enter");
+ bool result = false;
+ char* operation;
+
+ if (service_get_operation(service, &operation) != SERVICE_ERROR_NONE) {
+ LogD("no operation");
+ return false;
+ }
+
+ if (!strcmp(SERVICE_OPERATION_BOX_UPDATE, operation)) {
+ BoxInfoPtr info = handleOperationUpdate(service);
+ if (info) {
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_BOX, info, this);
+ if (ecore_job_add(requestBoxJobCallback, jobInfo)) {
+ result = true;
+ }
+ }
+ } else if (!strcmp(SERVICE_OPERATION_BOX_REMOVE, operation)) {
+ std::vector<BoxInfoPtr> container = handleOperationRemove(service);
+ for (unsigned i = 0; i < container.size(); i++) {
+ // directly remove box not using ecore job,
+ // because removing box is timing-senstive job
+ m_pluginConnector->requestCommand(REQUEST_CMD_REMOVE_BOX, container[i]);
+ }
+
+ // wake up pended process like installer
+ char* appId;
+ service_get_extra_data(service, SERVICE_REMOVE_APPID_KEY, &appId);
+ web_provider_service_wakeup_installer(appId);
+ result = true;
+ } else {
+ LogD("unknown operation: %s", operation);
+ }
+
+ delete[] operation;
+ return result;
+}
+
+int BoxDaemonImpl::connectedCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(arg);
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ if (!provider_send_hello()) {
+ This->m_pingTimer =
+ ecore_timer_add(MASTER_PROVIDER_PING_TIME, pingToMasterCallback, This);
+ }
+
+ return 0;
+}
+
+int BoxDaemonImpl::disconnectedCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(arg);
+ UNUSED_PARAM(data);
+
+ return 0;
+}
+
+int BoxDaemonImpl::boxCreateCallback(
+ ProviderEventArgPtr arg,
+ int* width, int* height,
+ double* priority, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(priority);
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+
+ if ((arg->info.lb_create.width == 0) || (arg->info.lb_create.height == 0)) {
+ livebox_service_get_size(LB_SIZE_TYPE_1x1, width, height);
+ } else {
+ *width = arg->info.lb_create.width;
+ *height = arg->info.lb_create.height;
+ }
+
+ info->boxWidth = *width;
+ info->boxHeight = *height;
+ info->priority = 1.0f;
+ info->period = arg->info.lb_create.period;
+ if (arg->info.lb_create.content && strlen(arg->info.lb_create.content)) {
+ info->contentInfo = std::string(arg->info.lb_create.content);
+ } else {
+ // we generate our instance id
+ info->contentInfo = BoxDaemonUtil::createWebInstanceId(info->boxId);
+ }
+
+ // box information
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("width: %d", info->boxWidth);
+ LogD("height: %d", info->boxHeight);
+ LogD("update period: %f", info->period);
+ LogD("content info: %s", info->contentInfo.c_str());
+ LogD("--------------------------------------------");
+
+ bool ret = This->m_pluginConnector->requestCommand(REQUEST_CMD_ADD_BOX, info);
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::boxReCreateCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+
+ if ((arg->info.lb_recreate.width == 0) || (arg->info.lb_recreate.height == 0)) {
+ livebox_service_get_size(LB_SIZE_TYPE_1x1,
+ &arg->info.lb_recreate.width,
+ &arg->info.lb_recreate.height);
+ }
+
+ info->boxWidth = arg->info.lb_recreate.width;
+ info->boxHeight = arg->info.lb_recreate.height;
+ info->priority = 1.0f;
+ info->period = arg->info.lb_recreate.period;
+ if (arg->info.lb_recreate.content) {
+ info->contentInfo = std::string(arg->info.lb_recreate.content);
+ }
+
+ // box information
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("width: %d", info->boxWidth);
+ LogD("height: %d", info->boxHeight);
+ LogD("update period: %f", info->period);
+ LogD("content info: %s", info->contentInfo.c_str());
+ LogD("--------------------------------------------");
+
+ bool ret = This->m_pluginConnector->requestCommand(REQUEST_CMD_ADD_BOX, info);
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::boxDestroyCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("--------------------------------------------");
+
+ This->m_pluginConnector->requestCommand(REQUEST_CMD_REMOVE_BOX, info);
+
+ return 0;
+}
+
+int BoxDaemonImpl::pdCreateCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+ if (arg->info.pd_create.w == 0 || arg->info.pd_create.h == 0) {
+ return -1;
+ }
+
+ //Use the screen width to fix the device width
+ ecore_x_window_size_get(0, &info->pdWidth, NULL);
+ info->pdHeight = arg->info.pd_create.h;
+ info->pdX = arg->info.pd_create.x;
+ info->pdY = arg->info.pd_create.y;
+
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("width: %d", info->pdWidth);
+ LogD("height: %d", info->pdHeight);
+ LogD("x: %f", info->pdX);
+ LogD("y: %f", info->pdY);
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_OPEN_PD, info, This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::pdDestroyCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CLOSE_PD, info, This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::clickedCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+
+ int flag = web_provider_livebox_get_auto_launch(info->boxId.c_str());
+ if (!flag) {
+ return -1;
+ }
+
+ BoxDaemonUtil::launchApplication(info->boxId, info->instanceId);
+ return 0;
+}
+
+int BoxDaemonImpl::boxResizeCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+ if (arg->info.resize.w == 0 || arg->info.resize.h == 0) {
+ return -1;
+ }
+
+ info->boxWidth = arg->info.resize.w;
+ info->boxHeight = arg->info.resize.h;
+
+ // box information
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("width: %d", info->boxWidth);
+ LogD("height: %d", info->boxHeight);
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESIZE_BOX, info, This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::boxPauseCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+
+ // box information
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_PAUSE_BOX, info, This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::boxResumeCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+
+ // box information
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESUME_BOX, info, This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::pauseCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(arg);
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+
+ LogD("--------------------------------------------");
+ LogD("web-provider is paused");
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_PAUSE_ALL, BoxInfoPtr(), This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::resumeCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(arg);
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+
+ LogD("--------------------------------------------");
+ LogD("web-provider is resumed");
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_RESUME_ALL, BoxInfoPtr(), This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::boxPeriodChangeCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+ info->period = arg->info.set_period.period;
+
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("period: %f", info->period);
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_CHANGE_PERIOD, info, This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+int BoxDaemonImpl::boxUpdateCallback(ProviderEventArgPtr arg, void* data)
+{
+ LogD("enter");
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = This->initializeBoxInfo(arg);
+ if (!info) {
+ return -1;
+ }
+
+ LogD("--------------------------------------------");
+ LogD("boxId: %s", info->boxId.c_str());
+ LogD("InstanceId: %s", info->instanceId.c_str());
+ LogD("--------------------------------------------");
+
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_BOX, info, This);
+ Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo);
+
+ return ret ? 0 : -1;
+}
+
+void BoxDaemonImpl::setProviderCallbacks(ProviderCallbacks& callbacks)
+{
+ LogD("enter");
+
+ memset(&callbacks, 0, sizeof(callbacks));
+ callbacks.connected = BoxDaemonImpl::connectedCallback;
+ callbacks.disconnected = BoxDaemonImpl::disconnectedCallback;
+ callbacks.pause = BoxDaemonImpl::pauseCallback;
+ callbacks.resume = BoxDaemonImpl::resumeCallback;
+ callbacks.lb_create = BoxDaemonImpl::boxCreateCallback;
+ callbacks.lb_recreate = BoxDaemonImpl::boxReCreateCallback;
+ callbacks.lb_destroy = BoxDaemonImpl::boxDestroyCallback;
+ callbacks.lb_pause = BoxDaemonImpl::boxPauseCallback;
+ callbacks.lb_resume = BoxDaemonImpl::boxResumeCallback;
+ callbacks.pd_create = BoxDaemonImpl::pdCreateCallback;
+ callbacks.pd_destroy = BoxDaemonImpl::pdDestroyCallback;
+ callbacks.clicked = BoxDaemonImpl::clickedCallback;
+ callbacks.resize = BoxDaemonImpl::boxResizeCallback;
+ callbacks.update_content = BoxDaemonImpl::boxUpdateCallback;
+ callbacks.set_period = BoxDaemonImpl::boxPeriodChangeCallback;
+}
+
+std::string BoxDaemonImpl::getBoxType(const char* boxId)
+{
+ LogD("enter");
+
+ if (!boxId) {
+ return std::string();
+ }
+
+ const char* type = web_provider_livebox_get_box_type(boxId);
+ if (!type) {
+ std::string boxType = m_pluginConnector->getBoxType(boxId);
+ if (boxType.empty()) {
+ LogD("unrecognized box id");
+ } else {
+ LogD("box id: %s, type: %s", boxId, boxType.c_str());
+ }
+ return boxType;
+ }
+
+ LogD("box id: %s, type: %s", boxId, type);
+ std::string result{type};
+ free(const_cast<char*>(type));
+ return result;
+}
+
+BoxInfoPtr BoxDaemonImpl::initializeBoxInfo(ProviderEventArgPtr arg)
+{
+ LogD("enter");
+
+ if (!arg) {
+ return BoxInfoPtr();
+ }
+
+ if (!arg->pkgname || !arg->id) {
+ LogD("pkgname or id don't exist");
+ return BoxInfoPtr();
+ }
+
+ std::string type = getBoxType(arg->pkgname);
+ if (type.empty()) {
+ return BoxInfoPtr();
+ }
+ BoxInfoPtr infoPtr = BoxInfoPtr(new BoxInfo(type, arg->pkgname, arg->id));
+
+ return infoPtr;
+}
+
+std::string BoxDaemonImpl::getBoxIdFromService(service_h service)
+{
+ LogD("enter");
+
+ int ret;
+ char* serviceUri = NULL;
+ ret = service_get_uri(service, &serviceUri);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("no box uri");
+ return std::string();
+ }
+
+ std::string uri(serviceUri);
+ delete[] serviceUri;
+
+ if(uri.compare(0, strlen(SERVICE_BOX_SERVICE_SCHEME), SERVICE_BOX_SERVICE_SCHEME)) {
+ // uri is not box-service scheme
+ return std::string();
+ }
+
+ std::string boxId = uri.substr(strlen(SERVICE_BOX_SERVICE_SCHEME));
+ return boxId;
+}
+
+bool BoxDaemonImpl::isServiceCallerBoxOwner(service_h service)
+{
+ LogD("enter");
+
+ int ret;
+
+ std::string boxId = getBoxIdFromService(service);
+ if (boxId.empty()) {
+ LogD("error box-id");
+ return false;
+ }
+
+ // check if caller is owner of this box
+ const char* appId = web_provider_livebox_get_app_id(boxId.c_str());
+ if (!appId) {
+ return false;
+ }
+ std::string ownerAppId(appId);
+ delete[] appId;
+
+ char* caller = NULL;
+ ret = service_get_caller(service, &caller);
+ if (ret != SERVICE_ERROR_NONE) {
+ ret = service_get_extra_data(
+ service, SERVICE_ALARM_CALLER_KEY, &caller);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to get caller's appid from service");
+ return false;
+ }
+ }
+ std::string callerAppId(caller);
+
+ // release strings
+ delete[] caller;
+
+ if (ownerAppId != callerAppId) {
+ LogD("caller is not matched with owner of requested box");
+ return false;
+ }
+
+ return true;
+}
+
+BoxInfoPtr BoxDaemonImpl::handleOperationUpdate(service_h service)
+{
+ LogD("enter");
+
+ if (!isServiceCallerBoxOwner(service)) {
+ return BoxInfoPtr();
+ }
+
+ std::string boxId = getBoxIdFromService(service);
+ if (boxId.empty()) {
+ LogD("error box-id");
+ return BoxInfoPtr();
+ }
+
+ char* appContentInfo = NULL;
+ service_get_extra_data(service, SERVICE_CONTENT_INFO_KEY, &appContentInfo);
+
+ std::string type(getBoxType(boxId.c_str()));
+ if (type.empty()) {
+ LogD("no type for this box");
+ delete[] appContentInfo;
+ return BoxInfoPtr();
+ }
+
+ BoxInfoPtr info = BoxInfoPtr(new BoxInfo(type, boxId, ""));
+ if (appContentInfo) {
+ LogD("service content info: %s", appContentInfo);
+ info->appContentInfo = std::string(appContentInfo);
+ }
+
+ // release string
+ delete[] appContentInfo;
+
+ return info;
+}
+
+int BoxDaemonImpl::requestUpdateAll(void)
+{
+ LogD("enter");
+
+ BoxInfoPtr info = BoxInfoPtr(new BoxInfo());
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_ALL, info, this);
+
+ ecore_job_add(requestBoxJobCallback, jobInfo);
+ return 0;
+}
+
+std::vector<BoxInfoPtr> BoxDaemonImpl::handleOperationRemove(service_h service)
+{
+ LogD("enter");
+
+ char* appId = NULL;
+ service_get_extra_data(service, SERVICE_REMOVE_APPID_KEY, &appId);
+ LogD("request appid: %s", appId);
+
+ // check if this appId has dynamic boxes
+ int boxCount = 0;
+ char** boxIdList = web_provider_livebox_get_box_id_list(appId, &boxCount);
+ if (!boxIdList) {
+ return std::vector<BoxInfoPtr>();
+ }
+
+ std::vector<BoxInfoPtr> boxInfoPtrContainer;
+ for (int i = 0; i < boxCount; i++) {
+ // get plugin type of each box id
+ std::string type(getBoxType(boxIdList[i]));
+ if (type.empty()) {
+ LogD("no type for this box: %s", boxIdList[i]);
+ continue;
+ }
+
+ BoxInfoPtr info = BoxInfoPtr(new BoxInfo(type, boxIdList[i], ""));
+ boxInfoPtrContainer.push_back(info);
+ }
+
+ return boxInfoPtrContainer;
+}
+
+Eina_Bool BoxDaemonImpl::pingToMasterCallback(void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(data);
+
+ provider_send_ping();
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+void BoxDaemonImpl::requestBoxJobCallback(void* data)
+{
+ JobInfo* jobInfo = static_cast<JobInfo*>(data);
+ if (!jobInfo) {
+ LogD("no information for job");
+ return;
+ }
+
+ // just for debugging
+ //volatile int flag = 0;
+ //while(flag == 0) {;}
+
+ // request box job!
+ jobInfo->daemonImpl->m_pluginConnector->requestCommand(
+ jobInfo->cmdType, jobInfo->boxInfo);
+
+ delete jobInfo;
+}
+
+int BoxDaemonImpl::requestUpdateAllCallback(void* data)
+{
+ LogD("enter");
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ return This->requestUpdateAll();
+}
+
+int BoxDaemonImpl::requestLowMemoryCallback(void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(data);
+
+ // terminate box daemon and revive
+ elm_exit();
+ return 0;
+}
+
+void BoxDaemonImpl::requestUpdateAllCallback(keynode_t* key, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(key);
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ This->requestUpdateAll();
+}
+
+void BoxDaemonImpl::requestUpdateAppBoxCallback(keynode_t* key, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(key);
+
+ BoxDaemonImpl* This = static_cast<BoxDaemonImpl*>(data);
+ BoxInfoPtr info = BoxInfoPtr(new BoxInfo());
+ JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_APPBOX, info, This);
+
+ ecore_job_add(requestBoxJobCallback, jobInfo);
+}
diff --git a/src_wearable/Daemon/BoxDaemonImpl.h b/src_wearable/Daemon/BoxDaemonImpl.h
new file mode 100755
index 0000000..c82edfd
--- /dev/null
+++ b/src_wearable/Daemon/BoxDaemonImpl.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxDaemonImpl.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_DAEMON_IMPL_H
+#define BOX_DAEMON_IMPL_H
+
+#include <string>
+#include <memory>
+#include <vector>
+
+#include <app.h>
+#include <provider.h>
+#include <Eina.h>
+#include <Ecore.h>
+#include <vconf.h>
+
+#include <Plugin/box_plugin_interface.h>
+#include <Core/BoxData.h>
+
+// forward declaration
+class IBoxManager;
+class IBoxPluginConnector;
+
+class BoxDaemonImpl {
+ public:
+ bool start(std::string& name);
+ bool stop();
+ bool handleAppService(service_h service);
+
+ public:
+ explicit BoxDaemonImpl();
+ ~BoxDaemonImpl();
+
+ private:
+ // type definition
+ typedef struct event_arg ProviderEventArg;
+ typedef ProviderEventArg* ProviderEventArgPtr;
+ typedef struct event_handler ProviderCallbacks;
+ typedef ProviderCallbacks* ProviderCallbacksPtr;
+
+ // livebox's provider callbacks
+ static int connectedCallback(ProviderEventArgPtr arg, void* data);
+ static int disconnectedCallback(ProviderEventArgPtr arg, void* data);
+ static int boxCreateCallback(
+ ProviderEventArgPtr arg,
+ int* width, int* height,
+ double* priority, void* data);
+ static int boxReCreateCallback(ProviderEventArgPtr arg, void* data);
+ static int boxDestroyCallback(ProviderEventArgPtr arg, void* data);
+ static int pdCreateCallback(ProviderEventArgPtr arg, void* data);
+ static int pdDestroyCallback(ProviderEventArgPtr arg, void* data);
+ static int clickedCallback(ProviderEventArgPtr arg, void* data);
+ static int boxResizeCallback(ProviderEventArgPtr arg, void* data);
+ static int boxPauseCallback(ProviderEventArgPtr arg, void* data);
+ static int boxResumeCallback(ProviderEventArgPtr arg, void* data);
+ static int pauseCallback(ProviderEventArgPtr arg, void* data);
+ static int resumeCallback(ProviderEventArgPtr arg, void* data);
+ static int boxPeriodChangeCallback(ProviderEventArgPtr arg, void* data);
+ static int boxUpdateCallback(ProviderEventArgPtr arg, void* data);
+ // callback for app-core event
+ static int requestUpdateAllCallback(void* data);
+ static int requestLowMemoryCallback(void* data);
+ // callback for vconf event
+ static void requestUpdateAllCallback(keynode_t* key, void* data);
+ static void requestUpdateAppBoxCallback(keynode_t* key, void* data);
+
+ // common private functions
+ void setProviderCallbacks(ProviderCallbacks& callbacks);
+ std::string getBoxType(const char* boxId);
+ BoxInfoPtr initializeBoxInfo(ProviderEventArgPtr arg);
+ int requestUpdateAll(void);
+
+ // functions for handling appcontrol per operation
+ std::string getBoxIdFromService(service_h service);
+ bool isServiceCallerBoxOwner(service_h service);
+ BoxInfoPtr handleOperationUpdate(service_h service);
+ std::vector<BoxInfoPtr> handleOperationRemove(service_h service);
+
+ // callback for ping to master daemon
+ static Eina_Bool pingToMasterCallback(void* data);
+
+ // callback for requested jobs of boxes
+ static void requestBoxJobCallback(void* data);
+
+ // members
+ std::string m_daemonName;
+ Ecore_Timer* m_pingTimer;
+ std::shared_ptr<IBoxPluginConnector> m_pluginConnector;
+};
+
+struct JobInfo {
+ request_cmd_type cmdType;
+ BoxInfoPtr boxInfo;
+ BoxDaemonImpl* daemonImpl;
+
+ JobInfo(request_cmd_type cmdType,
+ BoxInfoPtr boxInfo,
+ BoxDaemonImpl* daemonImpl) :
+ cmdType(cmdType),
+ boxInfo(boxInfo),
+ daemonImpl(daemonImpl)
+ {
+ };
+};
+
+
+#endif //BOX_DAEMON_IMPL_H
+
diff --git a/src_wearable/Daemon/BoxDaemonUtil.cpp b/src_wearable/Daemon/BoxDaemonUtil.cpp
new file mode 100644
index 0000000..7df1a0f
--- /dev/null
+++ b/src_wearable/Daemon/BoxDaemonUtil.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxDaemonUtil.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <sstream>
+#include <string>
+#include <memory>
+#include <time.h>
+#include <app_service.h>
+#include <Core/Util/Log.h>
+#include <API/web_provider_livebox_info.h>
+#include "BoxDaemonUtil.h"
+
+const std::string BoxDaemonUtil::boxIdKey("box-id");
+const std::string BoxDaemonUtil::instanceIdKey("instance-id");
+
+bool BoxDaemonUtil::launchApplication(std::string& boxId, std::string& instanceId)
+{
+ LogD("enter");
+
+ std::shared_ptr<const char> appId(web_provider_livebox_get_app_id(boxId.c_str()));
+ if (!appId) {
+ LogD("no appid of %s", boxId.c_str());
+ return false;
+ }
+
+ service_h handle = NULL;
+ int ret = SERVICE_ERROR_NONE;
+
+ ret = service_create(&handle);
+ if (ret != SERVICE_ERROR_NONE && !handle) {
+ LogD("failed to create service");
+ return false;
+ }
+
+ ret = service_set_package(handle, appId.get());
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to set package");
+ service_destroy(handle);
+ return false;
+ }
+
+ service_add_extra_data(handle, boxIdKey.c_str(), boxId.c_str());
+ service_add_extra_data(handle, instanceIdKey.c_str(), instanceId.c_str());
+
+ ret = service_send_launch_request(handle, NULL, NULL);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to launch package");
+ service_destroy(handle);
+ return false;
+ }
+
+ service_destroy(handle);
+ LogD("success to launch app of %s", boxId.c_str());
+
+ return true;
+}
+
+std::string BoxDaemonUtil::createWebInstanceId(std::string& boxId)
+{
+ LogD("enter");
+ std::ostringstream webInstanceId;
+
+ webInstanceId << boxId;
+
+ struct timespec timeSpec;
+ if (clock_gettime(CLOCK_REALTIME, &timeSpec) < 0) {
+ return std::string();
+ }
+
+ webInstanceId << "." << timeSpec.tv_sec << timeSpec.tv_nsec;
+ LogD("Web instance id: %s", webInstanceId.str().c_str());
+ return webInstanceId.str();
+}
diff --git a/src_wearable/Daemon/BoxDaemonUtil.h b/src_wearable/Daemon/BoxDaemonUtil.h
new file mode 100644
index 0000000..3d58396
--- /dev/null
+++ b/src_wearable/Daemon/BoxDaemonUtil.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxDaemonUtil.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_DAEMON_UTIL_H
+#define BOX_DAEMON_UTIL_H
+
+#include <string>
+
+class BoxDaemonUtil {
+ public:
+ static bool launchApplication(std::string& boxId, std::string& instanceId);
+ static std::string createWebInstanceId(std::string& boxId);
+
+ private:
+ static const std::string boxIdKey;
+ static const std::string instanceIdKey;
+
+};
+
+#endif // BOX_DAEMON_UTIL_H
diff --git a/src_wearable/Daemon/CMakeLists.txt b/src_wearable/Daemon/CMakeLists.txt
new file mode 100644
index 0000000..2384519
--- /dev/null
+++ b/src_wearable/Daemon/CMakeLists.txt
@@ -0,0 +1,66 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_DAEMON})
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ aul
+ bundle
+ appcore-efl
+ elementary
+ ecore-x
+ provider
+ livebox-service
+ capi-appfw-application
+ dlog
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxDaemon.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxDaemonImpl.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxDaemonUtil.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_EXECUTABLE(${TARGET_NAME} ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LDFLAGS} "-ldl -lcap -lrt"
+ ${${DEPS}_LIBRARIES}
+ ${TARGET_PLUGIN}
+ ${TARGET_CORE}
+ ${TARGET_API}
+)
+
+INSTALL(TARGETS ${TARGET_NAME}
+ DESTINATION /usr/apps/livebox.${PROJECT_NAME}/bin
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
diff --git a/src_wearable/Daemon/main.cpp b/src_wearable/Daemon/main.cpp
new file mode 100755
index 0000000..85b1940
--- /dev/null
+++ b/src_wearable/Daemon/main.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 main.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/capability.h>
+#include <Elementary.h>
+#include <aul.h>
+#include <app.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+#include "BoxDaemon.h"
+
+
+// declarations
+static BoxDaemon boxDaemon;
+static bool isDaemonReleased = false;
+
+static void atExitCallback()
+{
+ LogD("enter");
+ if (isDaemonReleased) {
+ return;
+ }
+
+ // this callback is called due to abnormal exit()
+ LogD("release daemon resources explicitly");
+ boxDaemon.stop();
+}
+
+static bool appCreateCallback(void *data)
+{
+ LogD("app create");
+ UNUSED_PARAM(data);
+
+ elm_config_preferred_engine_set("software_x11");
+ return true;
+}
+
+static void appTerminateCallback(void *data)
+{
+ BoxDaemon *boxDaemon = static_cast<BoxDaemon *>(data);
+ boxDaemon->stop();
+ isDaemonReleased = true;
+}
+
+static void appPauseCallback(void *data)
+{
+ LogD("app pasue");
+ UNUSED_PARAM(data);
+}
+
+static void appResumeCallback(void *data)
+{
+ LogD("app resume");
+ UNUSED_PARAM(data);
+}
+
+static void appServiceCallback(service_h service, void *data)
+{
+ LogD("app service");
+
+ int ret;
+ char* name;
+
+ BoxDaemon *boxDaemon = static_cast<BoxDaemon*>(data);
+ ret = service_get_extra_data(service, "name", &name);
+
+ // check if web-provider is launched, or not
+ if (ret == SERVICE_ERROR_NONE) {
+ std::string daemonName(name);
+ if(!(boxDaemon->start(daemonName))) {
+ LogD("daemon failed to start");
+ elm_exit();
+ }
+ atexit(atExitCallback);
+ return;
+ }
+
+ boxDaemon->handleAppService(service);
+}
+
+static bool grantProcessCapability()
+{
+ cap_user_header_t header;
+ cap_user_data_t data;
+
+ header = static_cast<cap_user_header_t>(malloc(sizeof(*header)));
+ data = static_cast<cap_user_data_t>(calloc(sizeof(*data), _LINUX_CAPABILITY_U32S_3));
+
+ header->pid = getpid();
+ header->version = _LINUX_CAPABILITY_VERSION_3;
+
+ // read already granted capabilities of this process
+ if (capget(header, data) < 0) {
+ LogD("capget error");
+ free(header);
+ free(data);
+ return false;
+ }
+
+ // set only inheritable bit for CAP_MAC_ADMIN to '1'
+ data[CAP_TO_INDEX(CAP_MAC_ADMIN)].inheritable |= CAP_TO_MASK(CAP_MAC_ADMIN);
+
+ // remove capabilities not needed any more
+ data[CAP_TO_INDEX(CAP_MAC_ADMIN)].permitted &= ~CAP_TO_MASK(CAP_MAC_ADMIN);
+ data[CAP_TO_INDEX(CAP_MAC_ADMIN)].effective &= ~CAP_TO_MASK(CAP_MAC_ADMIN);
+ data[CAP_TO_INDEX(CAP_SETPCAP)].permitted &= ~CAP_TO_MASK(CAP_SETPCAP);
+ data[CAP_TO_INDEX(CAP_SETPCAP)].effective &= ~CAP_TO_MASK(CAP_SETPCAP);
+
+ bool ret = true;
+ if (capset(header, data) < 0) {
+ LogD("capset error");
+ ret = false;
+ }
+
+ free(header);
+ free(data);
+
+ return ret;
+}
+
+int main (int argc, char *argv[])
+{
+ // set inheritable bit for CAP_MAC_ADMIN
+ // so that WebProcess will have CAP_MAC_ADMIN capability
+ if (!grantProcessCapability()) {
+ return -1;
+ }
+
+ // set the appcore callbacks
+ app_event_callback_s ops;
+ memset(&ops, 0x00, sizeof(app_event_callback_s));
+ ops.create = appCreateCallback;
+ ops.terminate = appTerminateCallback;
+ ops.pause = appPauseCallback;
+ ops.resume = appResumeCallback;
+ ops.service = appServiceCallback;
+
+ // start appcore
+ int ret = app_efl_main(&argc, &argv, &ops, &boxDaemon);
+ return ret;
+}
diff --git a/src_wearable/Plugin/AppBoxPlugin/AppBoxManager.cpp b/src_wearable/Plugin/AppBoxPlugin/AppBoxManager.cpp
new file mode 100755
index 0000000..ae41127
--- /dev/null
+++ b/src_wearable/Plugin/AppBoxPlugin/AppBoxManager.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxManager.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <map>
+#include <ail.h>
+#include <ewk_context.h>
+#include <core_module.h>
+#include <Plugin/IBoxPluginFactory.h>
+#include <Core/BoxData.h>
+#include <Core/BoxManager.h>
+#include <Core/IBox.h>
+#include <Core/Util/Log.h>
+#include <API/web_provider_livebox_info.h>
+#include "AppBoxManager.h"
+
+static const std::string bundlePath("/usr/lib/libwrt-injected-bundle.so");
+
+AppBoxManager::AppBoxManager(IBoxPluginFactoryPtr factory)
+ : BoxManager(factory)
+{
+ bool ret = WRT::CoreModuleSingleton::Instance().Init();
+ if (!ret) {
+ throw; // throw exeception
+ }
+}
+
+AppBoxManager::~AppBoxManager()
+{
+}
+
+bool AppBoxManager::requestAddBox(BoxInfoPtr boxInfo, EwkContextPtr ewkContext)
+{
+ const char* appId =
+ web_provider_livebox_get_app_id(boxInfo->boxId.c_str());
+
+ if (!appId) {
+ LogD("no appid of %s", boxInfo->boxId.c_str());
+ return false;
+ }
+
+ std::string appIdStr(appId);
+ delete appId;
+
+ auto it = m_ewkContextMap.find(appIdStr);
+ if (it == m_ewkContextMap.end()) {
+ ewkContext = getAvailableEwkContext(appIdStr);
+ insertContextMap(appIdStr, ewkContext);
+ } else {
+ ewkContext = it->second;
+ }
+
+ if (!BoxManager::requestAddBox(boxInfo, ewkContext)) {
+ return false;
+ }
+
+ return true;
+}
+
+void AppBoxManager::updateEwkContext(std::string& boxId)
+{
+ LogD("enter");
+ const char* appId = web_provider_livebox_get_app_id(boxId.c_str());
+ if (!appId) {
+ LogD("no appid of %s", boxId.c_str());
+ return;
+ }
+
+ std::string appIdStr(appId);
+ delete appId;
+
+ int count = BoxManager::getBoxCount(appIdStr);
+ LogD("count: %d", count);
+ if (!count) {
+ LogD("%s's ewk context removed", appIdStr.c_str());
+ // remove ewk context
+ eraseContextMap(appIdStr);
+ }
+}
+
+EwkContextPtr AppBoxManager::getAvailableEwkContext(const std::string& appId)
+{
+
+ // get the base executable path
+ std::string baseExecutablePath = getBaseExecutablePath(appId);
+ if (baseExecutablePath.empty()) {
+ return EwkContextPtr();
+ }
+
+ // get web process path for this box
+ std::string webProcessPath = baseExecutablePath + ".d-box";
+
+ // get plugin process path for this box
+ std::string pluginProcessPath = baseExecutablePath + ".npruntime";
+
+ // box manager should set webprocess path as value of 'WEB_PROCESS_PATH'
+ // before calling ewk_context_new_with_injected_bundle_path().
+ setenv("WEB_PROCESS_EXECUTABLE_PATH", webProcessPath.c_str(), 1);
+ setenv("PLUGIN_PROCESS_EXECUTABLE_PATH", pluginProcessPath.c_str(), 1);
+
+ EwkContextPtr newEwkContext(
+ ewk_context_new_with_injected_bundle_path(bundlePath.c_str()),
+ BoxManager::EwkContextDeleter());
+
+ // unset the following env variables not to affect other ewk context creation
+ unsetenv("WEB_PROCESS_EXECUTABLE_PATH");
+ unsetenv("PLUGIN_PROCESS_EXECUTABLE_PATH");
+
+ return newEwkContext;
+}
+
+void AppBoxManager::insertContextMap(std::string& appId, EwkContextPtr ewkContext)
+{
+ m_ewkContextMap.insert(EwkContextMapPair(appId, ewkContext));
+}
+
+void AppBoxManager::eraseContextMap(std::string& appId)
+{
+ m_ewkContextMap.erase(appId);
+}
+
+std::string AppBoxManager::getBaseExecutablePath(const std::string& appId)
+{
+ ail_error_e ret;
+ ail_appinfo_h handle = NULL;
+
+ char* retStr = NULL;
+ ret = ail_get_appinfo(appId.c_str(), &handle);
+ if (ret != AIL_ERROR_OK) {
+ return std::string();
+ }
+
+ ret = ail_appinfo_get_str(handle, AIL_PROP_X_SLP_EXE_PATH, &retStr);
+ if (ret != AIL_ERROR_OK || !retStr) {
+ return std::string();
+ }
+
+ std::string basePath(retStr);
+
+ ret = ail_destroy_appinfo(handle);
+ if (ret != AIL_ERROR_OK) {
+ return std::string();
+ }
+
+ return basePath;
+}
diff --git a/src_wearable/Plugin/AppBoxPlugin/AppBoxManager.h b/src_wearable/Plugin/AppBoxPlugin/AppBoxManager.h
new file mode 100644
index 0000000..7ef82a6
--- /dev/null
+++ b/src_wearable/Plugin/AppBoxPlugin/AppBoxManager.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxManager.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef APP_BOX_MANAGER_H
+#define APP_BOX_MANAGER_H
+
+#include <Core/IBox.h>
+#include <Core/IBoxManager.h>
+#include <Core/BoxManager.h>
+#include <Core/BoxData.h>
+#include <Plugin/IBoxPluginFactory.h>
+
+class AppBoxManager: public BoxManager {
+ public:
+ static IBoxManagerPtr create(IBoxPluginFactoryPtr factory)
+ {
+ return IBoxManagerPtr(new AppBoxManager(factory));
+ };
+ ~AppBoxManager();
+
+ private:
+ // BoxManager implementation
+ bool requestAddBox(BoxInfoPtr boxInfo, EwkContextPtr ewkContext);
+ void updateEwkContext(std::string& boxId);
+
+ EwkContextPtr getAvailableEwkContext(const std::string& appId);
+ void insertContextMap(std::string& appId, EwkContextPtr ewkContext);
+ void eraseContextMap(std::string& appId);
+ std::string getBaseExecutablePath(const std::string& appId);
+ explicit AppBoxManager(IBoxPluginFactoryPtr factory);
+
+ // members
+ typedef std::map<std::string, EwkContextPtr> EwkContextMap;
+ typedef std::pair<std::string, EwkContextPtr> EwkContextMapPair;
+ EwkContextMap m_ewkContextMap;
+};
+
+
+#endif // APP_BOX_MANAGER_H
diff --git a/src_wearable/Plugin/AppBoxPlugin/AppBoxPdHelper.cpp b/src_wearable/Plugin/AppBoxPlugin/AppBoxPdHelper.cpp
new file mode 100644
index 0000000..46e0fb9
--- /dev/null
+++ b/src_wearable/Plugin/AppBoxPlugin/AppBoxPdHelper.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxPdHelper.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <Evas.h>
+#include <ewk_view.h>
+#include <Core/Util/Log.h>
+#include "AppBoxPdHelper.h"
+
+AppBoxPdHelper::AppBoxPdHelper(Evas_Object* pdWin)
+ : m_win(pdWin)
+ , m_boxWebView()
+ , m_pdWebView()
+ , m_opened(false)
+{
+}
+
+AppBoxPdHelper::~AppBoxPdHelper()
+{
+}
+
+void AppBoxPdHelper::startOpen()
+{
+ LogD("enter");
+}
+
+void AppBoxPdHelper::finishOpen(Evas_Object* child)
+{
+ LogD("enter");
+ m_opened = true;
+ setPdWebView(child);
+}
+
+void AppBoxPdHelper::close()
+{
+ LogD("enter");
+}
+
+void AppBoxPdHelper::setBoxWebView(Evas_Object* webview)
+{
+ LogD("enter");
+ m_boxWebView = webview;
+}
+
+void AppBoxPdHelper::setPdWebView(Evas_Object* webview)
+{
+ LogD("enter");
+ m_pdWebView = webview;
+}
+
+Evas_Object* AppBoxPdHelper::getBoxWebView() const
+{
+ LogD("enter");
+ return m_boxWebView;
+}
+
+Evas_Object* AppBoxPdHelper::getPdWebView() const
+{
+ LogD("enter");
+ return m_pdWebView;
+}
+
+Evas* AppBoxPdHelper::getPdCanvas() const
+{
+ LogD("enter");
+ return evas_object_evas_get(m_win);
+}
+
+bool AppBoxPdHelper::isPdOpened() const
+{
+ LogD("enter");
+ return m_opened;
+}
diff --git a/src_wearable/Plugin/AppBoxPlugin/AppBoxPdHelper.h b/src_wearable/Plugin/AppBoxPlugin/AppBoxPdHelper.h
new file mode 100644
index 0000000..ae49863
--- /dev/null
+++ b/src_wearable/Plugin/AppBoxPlugin/AppBoxPdHelper.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxPdHelper.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#ifndef APP_BOX_PD_HELPER_H
+#define APP_BOX_PD_HELPER_H
+
+#include <string>
+#include <Evas.h>
+#include <Core/View/IPdHelper.h>
+
+class AppBoxPdHelper: public IPdHelper {
+ public:
+ static IPdHelperPtr create(Evas_Object* pdWin)
+ {
+ return IPdHelperPtr(new AppBoxPdHelper(pdWin));
+ }
+ virtual void startOpen();
+ virtual void finishOpen(Evas_Object* child);
+ virtual void close();
+ virtual void setBoxWebView(Evas_Object* webview);
+ virtual void setPdWebView(Evas_Object* webview);
+ virtual Evas_Object* getBoxWebView() const;
+ virtual Evas_Object* getPdWebView() const;
+ virtual Evas* getPdCanvas() const;
+ virtual bool isPdOpened() const;
+ virtual ~AppBoxPdHelper();
+
+ private:
+ AppBoxPdHelper(Evas_Object* pdWin);
+
+ //members
+ Evas_Object* m_win;
+ Evas_Object* m_boxWebView;
+ Evas_Object* m_pdWebView;
+ bool m_opened;
+};
+
+#endif // APP_BOX_PD_HELPER_H
diff --git a/src_wearable/Plugin/AppBoxPlugin/AppBoxPluginFactory.cpp b/src_wearable/Plugin/AppBoxPlugin/AppBoxPluginFactory.cpp
new file mode 100644
index 0000000..58f149c
--- /dev/null
+++ b/src_wearable/Plugin/AppBoxPlugin/AppBoxPluginFactory.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxPluginFactory.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <string>
+#include <memory>
+#include <Core/View/IRenderView.h>
+#include <Core/BoxData.h>
+#include "AppBoxRenderView.h"
+#include "AppBoxPluginFactory.h"
+
+IRenderViewPtr AppBoxPluginFactory::createRenderView(
+ std::shared_ptr<BoxInfo> boxInfo,
+ std::shared_ptr<Ewk_Context> ewkContext)
+{
+ return AppBoxRenderView::create(boxInfo, ewkContext);
+}
diff --git a/src_wearable/Plugin/AppBoxPlugin/AppBoxPluginFactory.h b/src_wearable/Plugin/AppBoxPlugin/AppBoxPluginFactory.h
new file mode 100644
index 0000000..e54d409
--- /dev/null
+++ b/src_wearable/Plugin/AppBoxPlugin/AppBoxPluginFactory.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxPluginFactory.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef APP_BOX_PLUGIN_FACTORY_H
+#define APP_BOX_PLUGIN_FACTORY_H
+
+#include <string>
+#include <memory>
+#include <Plugin/IBoxPluginFactory.h>
+#include <Core/View/IRenderView.h>
+#include <Core/Buffer/IRenderBuffer.h>
+#include <ewk_context.h>
+#include <Evas.h>
+
+// forward declaration
+struct BoxInfo;
+
+class AppBoxPluginFactory: public IBoxPluginFactory {
+ public:
+ IRenderViewPtr createRenderView(
+ std::shared_ptr<BoxInfo> boxInfo,
+ std::shared_ptr<Ewk_Context> ewkContext);
+
+ AppBoxPluginFactory() {};
+ ~AppBoxPluginFactory() {};
+};
+
+#endif //APP_BOX_PLUGIN_FACTORY_H
diff --git a/src_wearable/Plugin/AppBoxPlugin/AppBoxRenderView.cpp b/src_wearable/Plugin/AppBoxPlugin/AppBoxRenderView.cpp
new file mode 100755
index 0000000..6513973
--- /dev/null
+++ b/src_wearable/Plugin/AppBoxPlugin/AppBoxRenderView.cpp
@@ -0,0 +1,950 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxRenderView.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include "config.h"
+#include "AppBoxRenderView.h"
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <string>
+#include <fstream>
+#include <functional>
+#include <streambuf>
+#include <ail.h>
+#include <aul.h>
+#include <Eina.h>
+#include <Evas.h>
+#include <Ecore.h>
+#include <Elementary.h>
+#include <EWebKit2.h>
+#include <ewk_view.h>
+#include <ewk_context.h>
+#include <ewk_settings.h>
+#include <livebox-service.h>
+#include <i_runnable_widget_object.h>
+#include <core_module.h>
+#include <provider.h>
+#include <API/web_provider_livebox_info.h>
+#include <Core/BoxData.h>
+#include <Core/View/IPdHelper.h>
+#include <Core/View/PdHelper.h>
+#include <Core/Util/Log.h>
+#include <Core/Util/Util.h>
+
+#include "AppBoxPdHelper.h"
+
+
+#define RENDER_MAX_TIME 30.0
+#define RENDER_MAX_TIME_FOR_INSPECTOR 1200.0
+#define SNAPSHOT_REMOVE_TIME 0.5
+#define TOUCH_MAX_WAIT_TIME 10.0
+#define WEB_DBOX_OBJ_MOVE_TO_OUTSIDE_POINT_VALUE -10000
+
+// injection javascript file regarding creating js object used by box and pd
+static const std::string injectionFile("/usr/share/web-provider/injection.js");
+static const std::string consoleMessageLogTag("ConsoleMessage");
+static const std::string jsRegisterBoxInfoFunction(
+ "webprovider.registerAppWidgetContextInfo");
+
+AppBoxRenderView::AppBoxRenderView(
+ BoxInfoPtr boxInfo,
+ EwkContextPtr ewkContext)
+ : RenderView(boxInfo, false)
+ , m_appId()
+ , m_boxId()
+ , m_instanceId()
+ , m_contentInfo()
+ , m_ewkContext(ewkContext)
+ , m_boxRenderInfo()
+ , m_boxWrt()
+ , m_pdWrt()
+ , m_boxRenderBuffer()
+ , m_pdRenderBuffer()
+ , m_boxSnapshot()
+ , m_boxRenderTimer()
+ , m_boxTouchTimer()
+ , m_boxRemoveSnapShotTimer()
+ , m_pdHelper()
+ , m_boxIcon()
+ , m_pdFastOpen(false)
+ , m_boxFinishLoad(false)
+ , m_boxFrameRendered(false)
+ , m_boxWaitFrameRender(false)
+ , m_isTouchableBox(false)
+ , m_boxWrt_isSuspended(false)
+ , m_showed(false)
+ , m_showIcon(false)
+{
+ LogD("enter");
+
+ // member initialization
+ m_boxId = boxInfo->boxId;
+ m_instanceId = boxInfo->instanceId;
+ m_contentInfo = boxInfo->contentInfo;
+ m_appId = getAppId(m_boxId);
+ if (m_appId.empty()) {
+ throw; //exception throw!
+ }
+
+
+ // get box render buffer
+ m_boxRenderBuffer = getBoxBuffer();
+
+ if (!m_showIcon) {
+ ail_appinfo_h handle;
+ ail_error_e ret;
+ char *icon;
+ ret = ail_get_appinfo(m_appId.c_str(), &handle);
+ if (ret != AIL_ERROR_OK) {
+ LogE("[%s] DB_FAILED(0x) : failed to get the app-info", __FUNCTION__);
+ } else {
+ ail_appinfo_get_str(handle, AIL_PROP_ICON_STR, &icon);
+ }
+#if ENABLE(SHOW_PRE_ICON)
+ showIcon(icon, boxInfo->boxWidth, boxInfo->boxHeight);
+#endif
+ ail_destroy_appinfo(handle);
+ }
+ // use fastopen to default
+ // m_pdFastOpen = web_provider_livebox_get_pd_fast_open(m_boxId.c_str()) ? true : false;
+ m_pdFastOpen = true;
+ m_isTouchableBox =
+ web_provider_livebox_get_mouse_event(m_boxId.c_str()) ? true : false;
+}
+
+AppBoxRenderView::~AppBoxRenderView()
+{
+ LogD("enter");
+
+ destroyWrtCore(m_boxWrt);
+ destroyWrtCore(m_pdWrt);
+}
+
+void AppBoxRenderView::showBox(RenderInfoPtr boxRenderInfo)
+{
+ LogD("enter");
+
+ // stop updating render buffer
+ m_boxRenderBuffer->stopCanvasUpdate();
+
+ if (m_boxRenderTimer) {
+ // delete already running timer
+ stopRenderBox();
+ }
+
+ // delete touch timer
+ if (m_isTouchableBox) {
+ deleteTimer(&m_boxTouchTimer);
+ }
+
+ // set boxFinishLoad and m_boxFrameRendered to false
+ m_boxFinishLoad = false;
+ m_boxFrameRendered = false;
+ m_boxWaitFrameRender = false;
+
+ // copy to url
+ std::string boxStartUrl = getStartUrl(URL_TYPE_BOX, boxRenderInfo->defaultUrlParams);
+ if (m_boxWrt) {
+ LogD("existing wrt core is removed");
+ destroyBoxWrtCore();
+ }
+
+ m_boxWrt = createWrtCore(
+ URL_TYPE_BOX, boxStartUrl,
+ boxRenderInfo->window, m_ewkContext);
+ m_boxWrt_isSuspended = false;
+
+ // in case of showing box by request of pd open
+ if (m_pdHelper) {
+ m_pdHelper->setBoxWebView(m_boxWrt->GetCurrentWebview());
+ }
+
+ // resize webview fitted to width, height of Box
+ evas_object_resize(
+ m_boxWrt->GetCurrentWebview(),
+ boxRenderInfo->width,
+ boxRenderInfo->height);
+
+ showSnapShot();
+ evas_object_show(m_boxWrt->GetCurrentWebview());
+ // webview window move to outside of viewport because of overlap issue with snapshot image
+ evas_object_move(m_boxWrt->GetCurrentWebview(), WEB_DBOX_OBJ_MOVE_TO_OUTSIDE_POINT_VALUE, WEB_DBOX_OBJ_MOVE_TO_OUTSIDE_POINT_VALUE);
+
+ m_boxWrt->Show();
+ m_boxRenderInfo = boxRenderInfo;
+
+ // start timer for clearing existing snapshot in case of only pd open
+ addTimer(&m_boxRemoveSnapShotTimer,
+ SNAPSHOT_REMOVE_TIME, removeBoxSnapShotTimerCallback);
+ m_showed = true;
+}
+
+AppBoxRenderView::WrtCorePtr AppBoxRenderView::createWrtCore(
+ UrlType type, std::string& startUrl,
+ Evas_Object* win, EwkContextPtr ewkContext)
+{
+ LogD("enter");
+
+ WrtCorePtr wrt;
+ wrt = WRT::CoreModuleSingleton::
+ Instance().getRunnableWidgetObject(m_appId);
+
+ // prepare webview
+ if (startUrl.empty()) {
+ LogD("no start url");
+ return WrtCorePtr();
+ }
+ wrt->PrepareView(startUrl, win, ewkContext.get());
+ wrt->CheckBeforeLaunch();
+
+ // set callback functions of RunnableWidgetObject
+ WRT::UserDelegatesPtr cbs(new WRT::UserDelegates);
+ using namespace std::placeholders;
+ cbs->loadStartedCallback = std::bind(&AppBoxRenderView::startLoadCallback, this, _1, _2);
+ if (type == URL_TYPE_BOX) {
+ cbs->loadFinishedCallback = std::bind(&AppBoxRenderView::finishBoxLoadCallback, this, _1, _2);
+ } else {
+ cbs->loadFinishedCallback = std::bind(&AppBoxRenderView::finishPdLoadCallback, this, _1, _2);
+ }
+
+ cbs->setWebviewCallback = std::bind(&AppBoxRenderView::setBufferCallback, this, _1);
+ cbs->unsetWebviewCallback = std::bind(&AppBoxRenderView::unsetBufferCallback, this, _1);
+
+ cbs->policyNavigationDecideCallback = std::bind(&AppBoxRenderView::decideNavigationCallback, this, _1, _2);
+ cbs->processCrashedCallback = std::bind(&AppBoxRenderView::crashWebProcessCallback, this, _1, _2);
+ cbs->consoleMessageCallback = std::bind(&AppBoxRenderView::consoleMessageCallback, this, _1, _2);
+ wrt->SetUserDelegates(cbs);
+
+ // set basic webview setting
+ setWebViewBasicSetting(wrt->GetCurrentWebview());
+
+ // only box type needed
+ if (type == URL_TYPE_BOX) {
+ Ewk_Settings* setting = ewk_view_settings_get(wrt->GetCurrentWebview());
+ ewk_settings_link_effect_enabled_set(setting, EINA_FALSE);
+ }
+
+ return wrt;
+}
+
+void AppBoxRenderView::destroyBoxWrtCore()
+{
+ LogD("enter");
+
+ // stop updating render buffer
+ m_boxRenderBuffer->stopCanvasUpdate();
+ deleteTimer(&m_boxRenderTimer);
+ deleteTimer(&m_boxRemoveSnapShotTimer);
+ destroyWrtCore(m_boxWrt);
+ m_boxWrt.reset();
+
+ // temp
+ m_boxWrt_isSuspended = false;
+}
+
+void AppBoxRenderView::destroyPdWrtCore()
+{
+ LogD("enter");
+
+ destroyWrtCore(m_pdWrt);
+ m_pdWrt.reset();
+}
+
+void AppBoxRenderView::destroyWrtCore(WrtCorePtr wrt)
+{
+ LogD("enter");
+
+ if (wrt) {
+ wrt->Hide();
+ }
+}
+
+void AppBoxRenderView::hideBox()
+{
+ LogD("enter");
+ if (m_isTouchableBox) {
+ deleteTimer(&m_boxTouchTimer);
+ }
+
+ if (m_boxRenderInfo) {
+ destroyBoxWrtCore();
+ if (m_boxRenderInfo->window) {
+ evas_object_hide(m_boxRenderInfo->window);
+ }
+ }
+}
+
+void AppBoxRenderView::pauseBox()
+{
+ LogD("enter");
+}
+
+void AppBoxRenderView::resumeBox()
+{
+ LogD("enter");
+ if (!m_showed) {
+ RenderView::show();
+ }
+}
+
+void AppBoxRenderView::showPd(RenderInfoPtr pdRenderInfo, RenderInfoPtr boxRenderInfo)
+{
+ LogD("enter");
+
+ std::string pdStartUrl = getStartUrl(URL_TYPE_PD, pdRenderInfo->defaultUrlParams);
+ if (m_pdFastOpen) {
+ destroyPdWrtCore();
+ m_pdWrt = createWrtCore(URL_TYPE_PD, pdStartUrl, pdRenderInfo->window, m_ewkContext);
+ if (!m_pdWrt) {
+ LogD("no wrt core instance");
+ return;
+ }
+ m_pdHelper = AppBoxPdHelper::create(pdRenderInfo->window);
+
+ // resize webview fitted to width, height of pd
+ evas_object_resize(
+ m_pdWrt->GetCurrentWebview(),
+ pdRenderInfo->width,
+ pdRenderInfo->height);
+ // show pd
+ m_pdWrt->Show();
+ m_pdHelper->finishOpen(m_pdWrt->GetCurrentWebview());
+ } else {
+ m_pdHelper = PdHelper::create(pdRenderInfo, pdStartUrl);
+ }
+
+ // show pd window
+ evas_object_show(pdRenderInfo->window);
+
+ // need to create new snapshot when m_napshot is empty
+ if (!m_boxSnapshot) {
+ evas_object_show(getCurrentSnapShot());
+ }
+ getPdBuffer()->setWebView(m_pdWrt->GetCurrentWebview());
+ // show box
+ showBox(boxRenderInfo);
+
+ // start timer for clearing existing snapshot in case of only pd open
+ addTimer(&m_boxRemoveSnapShotTimer, SNAPSHOT_REMOVE_TIME, removeBoxSnapShotTimerCallback);
+}
+
+void AppBoxRenderView::hidePd()
+{
+ LogD("enter");
+
+ if (m_pdFastOpen) {
+ destroyPdWrtCore();
+ }
+ m_pdHelper->close();
+ m_pdHelper.reset();
+
+ // start timer for clearing existing snapshot in case of only pd open
+ struct stat tmp;
+ if (stat(WEB_PROVIDER_INSPECTOR_FILE_PATH, &tmp) == 0) {
+ addTimer(&m_boxRenderTimer, RENDER_MAX_TIME_FOR_INSPECTOR, fireBoxRenderTimerCallback);
+ } else {
+ addTimer(&m_boxRenderTimer, RENDER_MAX_TIME, fireBoxRenderTimerCallback);
+ }
+
+}
+
+void AppBoxRenderView::didBoxTouched(int x, int y)
+{
+ LogD("x : %d, y: %d", x, y);
+ if (!m_isTouchableBox) {
+ return;
+ }
+
+ if (!m_boxWrt) {
+ LogD("no webview");
+ return;
+ }
+
+ // if needed, resume render view
+ if (m_boxRenderTimer) {
+ deleteTimer(&m_boxRenderTimer);
+ } else {
+ if (!m_boxTouchTimer) {
+ m_boxRenderBuffer->startCanvasUpdate();
+
+ // temp condition
+ if (m_boxWrt_isSuspended == true)
+ {
+ m_boxWrt_isSuspended = false;
+ m_boxWrt->Resume();
+ }
+ } else {
+ deleteTimer(&m_boxTouchTimer);
+ }
+ }
+ addTimer(&m_boxTouchTimer, TOUCH_MAX_WAIT_TIME, fireBoxTouchTimerCallback);
+}
+
+void AppBoxRenderView::didPdTouched(int x, int y)
+{
+ LogD("x : %d, y: %d", x, y);
+}
+
+Evas_Object* AppBoxRenderView::getBoxWebView()
+{
+ if (!m_pdHelper) {
+ return m_boxWrt->GetCurrentWebview();
+ } else {
+ // Here, we can't use GetCurrentWebView() of wrt-core to get Box' webview,
+ // because in the non fast-open, GetCurrentWebview() returns PD's webview.
+ return m_pdHelper->getBoxWebView();
+ }
+}
+
+Evas_Object* AppBoxRenderView::getPdWebView()
+{
+ if (!m_pdHelper) {
+ return NULL;
+ }
+
+ return m_pdHelper->getPdWebView();
+}
+
+std::string AppBoxRenderView::getAppId(std::string& boxId)
+{
+ LogD("enter");
+
+ const char* appId = web_provider_livebox_get_app_id(boxId.c_str());
+ if (!appId) {
+ LogD("no appid of %s", boxId.c_str());
+ return std::string();
+ }
+
+ return std::string(appId);
+}
+
+std::string AppBoxRenderView::getStartUrl(UrlType type, std::string& defaultParams)
+{
+ const char* path = NULL;
+ switch (type) {
+ case URL_TYPE_BOX:
+ path = livebox_service_lb_script_path(m_boxId.c_str());
+ break;
+ case URL_TYPE_PD:
+ path = livebox_service_pd_script_path(m_boxId.c_str());
+ break;
+ default:
+ LogD("no available type");
+ }
+
+ std::string startUrl;
+ if (path) {
+ LogD("path : %s", path);
+ startUrl = path;
+ } else {
+ // TODO In this case, fallback page will be loaded.
+ LogE("Fail to get service lib script path");
+ }
+
+ // add default parameters to start url
+ startUrl += defaultParams;
+
+ return startUrl;
+}
+
+Evas_Object* AppBoxRenderView::getCurrentSnapShot()
+{
+ LogD("enter");
+
+ clearSnapShot();
+ m_boxSnapshot = m_boxRenderBuffer->getSnapshot();
+
+ return m_boxSnapshot;
+}
+
+void AppBoxRenderView::clearSnapShot()
+{
+ LogD("enter");
+ if (m_boxSnapshot) {
+ evas_object_del(m_boxSnapshot);
+ m_boxSnapshot = NULL;
+ }
+}
+
+void AppBoxRenderView::showSnapShot()
+{
+ LogD("enter");
+ if (m_boxSnapshot) {
+ evas_object_raise(m_boxSnapshot);
+ evas_object_show(m_boxSnapshot);
+ }
+}
+
+void AppBoxRenderView::hideSnapShot()
+{
+ LogD("enter");
+ if (m_boxSnapshot) {
+ evas_object_hide(m_boxSnapshot);
+ evas_object_lower(m_boxSnapshot);
+ }
+}
+
+void AppBoxRenderView::addTimer(Ecore_Timer** timer, double interval, Ecore_Task_Cb callback)
+{
+ LogD("enter");
+ if (*timer) {
+ deleteTimer(timer);
+ }
+
+ *timer = ecore_timer_add(interval, callback, this);
+}
+
+void AppBoxRenderView::deleteTimer(Ecore_Timer** timer)
+{
+ LogD("enter");
+ if (*timer) {
+ ecore_timer_del(*timer);
+ *timer = NULL;
+ }
+}
+
+void AppBoxRenderView::stopRenderBox()
+{
+ deleteTimer(&m_boxRenderTimer);
+ m_boxRenderBuffer->stopCanvasUpdate();
+ if (m_isTouchableBox) {
+ // stop touch timer
+ deleteTimer(&m_boxTouchTimer);
+
+ // temp condition
+ if (m_boxWrt_isSuspended == false)
+ {
+ m_boxWrt_isSuspended = true;
+ m_boxWrt->Suspend();
+ }
+ } else {
+ // Before webview should be removed,
+ // new evas object with last render data should be created
+ // otherwise, after webview is removed, box is white screen.
+ evas_object_show(getCurrentSnapShot());
+ destroyBoxWrtCore();
+ }
+}
+
+void AppBoxRenderView::setWebViewBasicSetting(Evas_Object* webview)
+{
+ LogD("enter");
+
+ if (!webview) {
+ return;
+ }
+ Ewk_Settings* setting = ewk_view_settings_get(webview);
+ // disable shadow effect on scrolling
+#if !ENABLE(WEBKIT_UPVERSION)
+ ewk_settings_edge_effect_enabled_set(setting, EINA_FALSE);
+ // Disable ime features
+ ewk_settings_default_keypad_enabled_set(setting, EINA_FALSE);
+#endif
+ // To support transparent background
+ ewk_view_bg_color_set(webview, 0, 0, 0, 1);
+ ewk_view_visibility_set(webview, EINA_TRUE);
+
+ // To know starting point for updating buffer
+ evas_object_smart_callback_add(
+ webview,
+ "load,nonemptylayout,finished",
+ loadNonEmptyLayoutFinishedCallback,
+ this);
+ evas_object_smart_callback_add(
+ webview,
+ "frame,rendered",
+ frameRenderedCallback,
+ this);
+ // To set font type whenever font changed
+ ewk_view_use_settings_font(webview);
+}
+
+void AppBoxRenderView::consoleMessage(int level, const char* format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ switch (level) {
+ case DLOG_DEBUG:
+ ALOG_VA(LOG_DEBUG, consoleMessageLogTag.c_str(), format, args);
+ break;
+ case DLOG_WARN:
+ ALOG_VA(LOG_WARN, consoleMessageLogTag.c_str(), format, args);
+ break;
+ case DLOG_ERROR:
+ ALOG_VA(LOG_ERROR, consoleMessageLogTag.c_str(), format, args);
+ break;
+ default:
+ ALOG_VA(LOG_DEBUG, consoleMessageLogTag.c_str(), format, args);
+ break;
+ }
+ va_end(args);
+}
+
+Eina_Bool AppBoxRenderView::fireBoxRenderTimerCallback(void* data)
+{
+ LogD("enter");
+
+ AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
+ This->m_boxRenderTimer = NULL;
+ This->stopRenderBox();
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+Eina_Bool AppBoxRenderView::fireBoxTouchTimerCallback(void* data)
+{
+
+ LogD("enter");
+ AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
+ This->m_boxRenderBuffer->stopCanvasUpdate();
+
+ // temp condition
+ if (This->m_boxWrt_isSuspended == false)
+ {
+ This->m_boxWrt_isSuspended = true;
+ This->m_boxWrt->Suspend();
+ }
+
+ This->m_boxTouchTimer = NULL;
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+
+Eina_Bool AppBoxRenderView::removeBoxSnapShotTimerCallback(void* data)
+{
+ LogD("enter");
+
+ AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
+ if (!(This->m_boxFinishLoad && This->m_boxFrameRendered)) {
+ return ECORE_CALLBACK_RENEW;
+ }
+
+ if (!This->m_boxWaitFrameRender) {
+ This->m_boxWaitFrameRender = true;
+ return ECORE_CALLBACK_RENEW;
+ }
+ // hide snapshot because valid frame has been prepared generally.
+ This->clearSnapShot();
+ This->m_boxRenderBuffer->startCanvasUpdate();
+
+ if (This->m_showIcon) {
+ evas_object_del(This->m_boxIcon);
+ This->m_showIcon = false;
+ }
+
+ // move to inside of viewport to prevent overlap with snapshot image
+ evas_object_move(This->m_boxWrt->GetCurrentWebview(), 0, 0);
+ evas_object_show(This->m_boxWrt->GetCurrentWebview());
+
+ This->m_boxRemoveSnapShotTimer = NULL;
+ return ECORE_CALLBACK_CANCEL;
+}
+
+Eina_Bool AppBoxRenderView::openPdIdlerCallback(void* data)
+{
+ LogD("enter");
+ AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
+ if (This && This->m_pdHelper) {
+ This->m_pdHelper->startOpen();
+ }
+ return ECORE_CALLBACK_CANCEL;
+}
+
+void AppBoxRenderView::executeScriptCallback(
+ Evas_Object* webview, const char* result, void* data)
+{
+ LogD("enter");
+ UNUSED_PARAM(webview);
+ UNUSED_PARAM(data);
+
+ std::string resultStr(result ? result : "null");
+ LogD("result: %s", resultStr.c_str());
+}
+
+void AppBoxRenderView::startLoadCallback(Evas_Object* webview, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+ if(!webview) {
+ return;
+ }
+ // execute injection for creating js objects
+ std::ifstream jsFile(injectionFile);
+ std::string jsString((std::istreambuf_iterator<char>(jsFile)),
+ std::istreambuf_iterator<char>());
+
+ std::ostringstream script;
+ script << jsString;
+
+ // add javascripts for operation of synchronous call
+ script << jsRegisterBoxInfoFunction << "('box-id', '" << m_boxId << "');";
+ script << jsRegisterBoxInfoFunction << "('instance-id', '" << m_contentInfo << "');";
+
+ //LogD("injected js code: %s", script.str().c_str());
+ ewk_view_script_execute(webview, script.str().c_str(), executeScriptCallback, this);
+}
+
+void AppBoxRenderView::finishBoxLoadCallback(Evas_Object* webview, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+ if (!webview) {
+ return;
+ }
+
+ ewk_view_visibility_set(webview, EINA_TRUE);
+
+ if (!m_pdHelper) {
+ // start render timer
+ struct stat tmp;
+ if (stat(WEB_PROVIDER_INSPECTOR_FILE_PATH, &tmp) == 0) {
+ addTimer(&m_boxRenderTimer, RENDER_MAX_TIME_FOR_INSPECTOR, fireBoxRenderTimerCallback);
+ } else {
+ addTimer(&m_boxRenderTimer, RENDER_MAX_TIME, fireBoxRenderTimerCallback);
+ }
+ } else {
+ if (!m_pdFastOpen) {
+ if (!(m_pdHelper->isPdOpened()) &&
+ webview == m_pdHelper->getBoxWebView())
+ {
+ // open pd
+ ecore_idler_add(openPdIdlerCallback, this);
+ }
+ }
+ }
+
+ // set flag
+ m_boxFinishLoad = true;
+}
+
+void AppBoxRenderView::finishPdLoadCallback(Evas_Object* webview, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(eventInfo);
+ if (!webview) {
+ return;
+ }
+
+ ewk_view_visibility_set(webview, EINA_TRUE);
+}
+
+void AppBoxRenderView::createWindowBeforeCallback(Evas** canvas, Evas_Object* parent)
+{
+ LogD("enter");
+
+ if (m_pdHelper) {
+ if (!(m_pdHelper->isPdOpened()) &&
+ parent == m_pdHelper->getBoxWebView())
+ {
+ LogD("pd canvas is used");
+ *canvas = m_pdHelper->getPdCanvas();
+ return;
+ }
+ }
+
+ LogD("canvas of this webview is used");
+ *canvas = evas_object_evas_get(parent);
+}
+
+void AppBoxRenderView::createWindowAfterCallback(Evas_Object* parent, Evas_Object* child)
+{
+ LogD("enter");
+ if (!parent) {
+ return;
+ }
+
+ if (m_pdHelper) {
+ Evas* parentCanvas = evas_object_evas_get(parent);
+ Evas* childCanvas = evas_object_evas_get(child);
+
+ if (parentCanvas != childCanvas) {
+ // wrt-core change visibility value to false internally
+ // So plugin should reset this value to true for painting parent webview
+ ewk_view_visibility_set(parent, EINA_TRUE);
+ evas_object_show(parent);
+ m_pdHelper->finishOpen(child);
+ }
+ }
+
+ setWebViewBasicSetting(child);
+ evas_object_show(child);
+}
+
+void AppBoxRenderView::setBufferCallback(Evas_Object* webview)
+{
+ LogD("enter");
+ evas_object_show(webview);
+ evas_object_focus_set(webview, EINA_TRUE);
+}
+
+void AppBoxRenderView::unsetBufferCallback(Evas_Object* webview)
+{
+ LogD("enter");
+ evas_object_hide(webview);
+}
+
+void AppBoxRenderView::decideNavigationCallback(Evas_Object* webview, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(webview);
+
+ Ewk_Policy_Decision* policyDecision = static_cast<Ewk_Policy_Decision*>(eventInfo);
+ const char* url = ewk_policy_decision_url_get(policyDecision);
+ if (!url || !*url) {
+ LogE("url is empty");
+ return;
+ }
+ std::string uri(url);
+
+ // navigation of box scheme should be ignored
+ processBoxScheme(uri);
+}
+
+void AppBoxRenderView::crashWebProcessCallback(Evas_Object* webview, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(webview);
+ UNUSED_PARAM(eventInfo);
+ LogD("instanceId: %s", m_instanceId.c_str());
+ elm_exit();
+}
+
+void AppBoxRenderView::loadNonEmptyLayoutFinishedCallback(
+ void* data, Evas_Object* webview, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(data);
+ UNUSED_PARAM(webview);
+ UNUSED_PARAM(eventInfo);
+}
+
+void AppBoxRenderView::frameRenderedCallback(
+ void* data, Evas_Object* webview, void* eventInfo)
+{
+ LogD("enter");
+ UNUSED_PARAM(webview);
+ UNUSED_PARAM(eventInfo);
+
+ // start to update render buffer!
+ AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
+
+ // set flag
+ This->m_boxFrameRendered = true;
+
+ // move to inside of viewport to prevent overlap with snapshot image
+ if (!This->m_boxRemoveSnapShotTimer) {
+ evas_object_move(This->m_boxWrt->GetCurrentWebview(), 0, 0);
+ }
+}
+
+void AppBoxRenderView::consoleMessageCallback(Evas_Object* webview, void* eventInfo)
+{
+ UNUSED_PARAM(webview);
+
+ Ewk_Console_Message* consoleMessage = static_cast<Ewk_Console_Message*>(eventInfo);
+
+ std::stringstream buf;
+ unsigned int lineNumber = ewk_console_message_line_get(consoleMessage);
+ const char* text = ewk_console_message_text_get(consoleMessage);
+ const char* source = ewk_console_message_source_get(consoleMessage);
+ if (lineNumber) {
+ buf << source << ":";
+ buf << lineNumber << ":";
+ }
+ buf << text;
+
+ int level;
+ switch (ewk_console_message_level_get(consoleMessage)) {
+ case EWK_CONSOLE_MESSAGE_LEVEL_TIP:
+ case EWK_CONSOLE_MESSAGE_LEVEL_LOG:
+ case EWK_CONSOLE_MESSAGE_LEVEL_DEBUG:
+ level = DLOG_DEBUG;
+ break;
+ case EWK_CONSOLE_MESSAGE_LEVEL_WARNING:
+ level = DLOG_WARN;
+ break;
+ case EWK_CONSOLE_MESSAGE_LEVEL_ERROR:
+ level = DLOG_ERROR;
+ break;
+ default:
+ level = DLOG_DEBUG;
+ break;
+ }
+ AppBoxRenderView::consoleMessage(level, "%s", buf.str().c_str());
+}
+
+
+void AppBoxRenderView::showIcon(char *iconString, int width, int height)
+{
+ LogD("enter");
+
+ Evas_Load_Error err;
+ Evas_Object *snapshot;
+ int w,h;
+ int x = 0;
+ int y = 0;
+
+ if (!iconString) {
+ LogE("iconString is NULL");
+ return;
+ }
+
+ snapshot = evas_object_image_add(m_boxRenderBuffer->getCanvas());
+ if (!snapshot) {
+ LogE("evas_object_image_add FAILED");
+ return;
+ }
+
+ const char *string = const_cast<const char *>(iconString);
+ evas_object_image_colorspace_set(snapshot, EVAS_COLORSPACE_ARGB8888);
+ evas_object_image_alpha_set(snapshot, EINA_TRUE);
+ evas_object_image_file_set(snapshot, string, NULL);
+ err = evas_object_image_load_error_get(snapshot);
+ if (err != EVAS_LOAD_ERROR_NONE) {
+ LogE("Load error: %s\n", evas_load_error_str(err));
+ evas_object_del(snapshot);
+ return;
+ }
+ evas_object_image_size_get(snapshot, &w, &h);
+ evas_object_image_filled_set(snapshot, EINA_TRUE);
+
+
+ if (width > w) {
+ x = (width - w) >> 1;
+ }
+
+ if (height > h) {
+ y = (height - h) >> 1;
+ }
+
+ evas_object_image_fill_set(snapshot, 0, 0, w, h);
+ evas_object_move(snapshot, x, y);
+ evas_object_show(snapshot);
+ evas_object_resize(snapshot, w, h);
+
+ provider_send_updated(
+ m_boxId.c_str(),
+ m_instanceId.c_str(),
+ width, height,
+ 0, m_contentInfo.c_str(), NULL);
+
+ m_boxIcon = snapshot;
+ m_showIcon = true;
+}
diff --git a/src_wearable/Plugin/AppBoxPlugin/AppBoxRenderView.h b/src_wearable/Plugin/AppBoxPlugin/AppBoxRenderView.h
new file mode 100755
index 0000000..0812d0e
--- /dev/null
+++ b/src_wearable/Plugin/AppBoxPlugin/AppBoxRenderView.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 AppBoxRenderView.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef APP_BOX_RENDER_VIEW_H
+#define APP_BOX_RENDER_VIEW_H
+
+#include <string>
+#include <memory>
+#include <Eina.h>
+#include <Ecore.h>
+#include <Evas.h>
+#include <ewk_context.h>
+#include <i_runnable_widget_object.h>
+#include <Core/BoxData.h>
+#include <Core/View/IPdHelper.h>
+#include <Core/View/RenderView.h>
+
+class AppBoxRenderBuffer;
+
+class AppBoxRenderView: public RenderView {
+ public:
+ typedef std::shared_ptr<Ewk_Context> EwkContextPtr;
+
+ static IRenderViewPtr create(BoxInfoPtr boxInfo, EwkContextPtr ewkContext)
+ {
+ return IRenderViewPtr(new AppBoxRenderView(boxInfo, ewkContext));
+ };
+ virtual void showBox(RenderInfoPtr boxRenderInfo);
+ virtual void hideBox();
+ virtual void pauseBox();
+ virtual void resumeBox();
+ virtual void showPd(RenderInfoPtr pdRenderInfo, RenderInfoPtr boxRenderInfo);
+ virtual void hidePd();
+ virtual void didBoxTouched(int x, int y);
+ virtual void didPdTouched(int x, int y);
+ virtual ~AppBoxRenderView();
+
+ private:
+ // type definition
+ typedef std::shared_ptr<WRT::IRunnableWidgetObject> WrtCorePtr;
+ enum UrlType {
+ URL_TYPE_BOX,
+ URL_TYPE_PD
+ };
+
+ WrtCorePtr createWrtCore(
+ UrlType type, std::string& startUrl,
+ Evas_Object* win, EwkContextPtr ewkContext);
+ void setWebViewBasicSetting(Evas_Object* webview);
+ void destroyWrtCore(WrtCorePtr wrt);
+ void destroyBoxWrtCore();
+ void destroyPdWrtCore();
+ Evas_Object* getBoxWebView();
+ Evas_Object* getPdWebView();
+ std::string getAppId(std::string& boxId);
+ std::string getStartUrl(UrlType type, std::string& defaultParams);
+ Evas_Object* getCurrentSnapShot();
+ void clearSnapShot();
+ void showSnapShot();
+ void hideSnapShot();
+ void addTimer(Ecore_Timer** timer, double interval, Ecore_Task_Cb callback);
+ void deleteTimer(Ecore_Timer** timer);
+ void stopRenderBox();
+ void consoleMessage(int level, const char* format, ...);
+ void showIcon(char *iconString, int width, int height);
+
+ // timer and idler callback
+ static Eina_Bool fireBoxRenderTimerCallback(void* data);
+ static Eina_Bool fireBoxTouchTimerCallback(void* data);
+ static Eina_Bool removeBoxSnapShotTimerCallback(void* data);
+ static Eina_Bool openPdIdlerCallback(void* data);
+
+ // ewk view callback
+ static void executeScriptCallback(
+ Evas_Object* webview, const char* result, void* data);
+ static void loadNonEmptyLayoutFinishedCallback(
+ void* data, Evas_Object* webview, void* eventInfo);
+ static void frameRenderedCallback(
+ void* data, Evas_Object* webview, void* eventInfo);
+
+ // user Callbacks of RunnableWidgetObject
+ void startLoadCallback(Evas_Object* webview, void* eventInfo);
+ void finishBoxLoadCallback(Evas_Object* webview, void* eventInfo);
+ void finishPdLoadCallback(Evas_Object* webview, void* eventInfo);
+ void createWindowBeforeCallback(Evas** canvas, Evas_Object* parent);
+ void createWindowAfterCallback(Evas_Object* parent, Evas_Object* child);
+ void setBufferCallback(Evas_Object* webview);
+ void unsetBufferCallback(Evas_Object* webview);
+ void decideNavigationCallback(Evas_Object* webview, void* eventInfo);
+ void crashWebProcessCallback(Evas_Object* webview, void* eventInfo);
+ void consoleMessageCallback(Evas_Object* webview, void* eventInfo);
+
+ // constructor
+ explicit AppBoxRenderView(BoxInfoPtr boxInfo, EwkContextPtr ewkContext);
+
+ // members
+ std::string m_appId;
+ std::string m_boxId;
+ std::string m_instanceId;
+ std::string m_contentInfo;
+ EwkContextPtr m_ewkContext;
+ RenderInfoPtr m_boxRenderInfo;
+ WrtCorePtr m_boxWrt;
+ WrtCorePtr m_pdWrt;
+ IRenderBufferPtr m_boxRenderBuffer;
+ IRenderBufferPtr m_pdRenderBuffer;
+ Evas_Object* m_boxSnapshot;
+ Ecore_Timer* m_boxRenderTimer;
+ Ecore_Timer* m_boxTouchTimer;
+ Ecore_Timer* m_boxRemoveSnapShotTimer;
+ IPdHelperPtr m_pdHelper;
+ Evas_Object* m_boxIcon;
+
+ // for check status of webview
+ bool m_pdFastOpen;
+ bool m_boxFinishLoad;
+ bool m_boxFrameRendered;
+ bool m_boxWaitFrameRender;
+ bool m_isTouchableBox;
+
+ // TODO this temporary flag should removed!
+ bool m_boxWrt_isSuspended;
+ bool m_showed;
+ bool m_showIcon;
+};
+
+#endif // APP_BOX_RENDER_VIEW_H
diff --git a/src_wearable/Plugin/AppBoxPlugin/CMakeLists.txt b/src_wearable/Plugin/AppBoxPlugin/CMakeLists.txt
new file mode 100644
index 0000000..df14513
--- /dev/null
+++ b/src_wearable/Plugin/AppBoxPlugin/CMakeLists.txt
@@ -0,0 +1,73 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME web-provider-plugin-app)
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ ail
+ ewebkit2
+ wrt-core
+ dpl-efl
+ evas
+ ecore
+ eina
+ livebox-service
+ dlog
+ provider # this should be removed
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/box_plugin_interface.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/AppBoxManager.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/AppBoxPluginFactory.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/AppBoxRenderView.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/AppBoxPdHelper.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} SHARED ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LIBRARIES}
+ ${TARGET_CORE}
+)
+
+INSTALL(TARGETS ${TARGET_NAME}
+ DESTINATION lib/${PROJECT_NAME}
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
+
+INSTALL_FILE(app.json lib/${PROJECT_NAME})
diff --git a/src_wearable/Plugin/AppBoxPlugin/app.json b/src_wearable/Plugin/AppBoxPlugin/app.json
new file mode 100644
index 0000000..6388702
--- /dev/null
+++ b/src_wearable/Plugin/AppBoxPlugin/app.json
@@ -0,0 +1,5 @@
+{
+ "type" : "app",
+ "path" : "/usr/lib/web-provider/libweb-provider-plugin-app.so",
+ "supported_size" : ["1x1","2x1","2x2"]
+}
diff --git a/src_wearable/Plugin/AppBoxPlugin/box_plugin_interface.cpp b/src_wearable/Plugin/AppBoxPlugin/box_plugin_interface.cpp
new file mode 100644
index 0000000..ca5e65e
--- /dev/null
+++ b/src_wearable/Plugin/AppBoxPlugin/box_plugin_interface.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 box_plugin_interface.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <memory>
+#include <Core/BoxData.h>
+#include <Core/Util/Log.h>
+#include <Plugin/box_plugin_interface.h>
+#include "AppBoxManager.h"
+#include "AppBoxPluginFactory.h"
+
+static std::shared_ptr<IBoxManager> g_manager;
+
+int web_provider_plugin_interface_initialize()
+{
+ LogD("enter");
+ IBoxPluginFactoryPtr factory(new AppBoxPluginFactory());
+ g_manager = AppBoxManager::create(factory);
+
+ return 0;
+}
+
+int web_provider_plugin_interface_command(const request_cmd_type type, const BoxInfoPtr& boxInfo)
+{
+ LogD("enter");
+ int ret = g_manager->doCommand(type, boxInfo);
+
+ if (!ret) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int web_provider_plugin_interface_shutdown()
+{
+ LogD("enter");
+ g_manager.reset();
+ return 0;
+}
diff --git a/src_wearable/Plugin/BoxPluginConnector.cpp b/src_wearable/Plugin/BoxPluginConnector.cpp
new file mode 100755
index 0000000..d50bc1b
--- /dev/null
+++ b/src_wearable/Plugin/BoxPluginConnector.cpp
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxPluginConnector.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#include <map>
+#include <dlfcn.h>
+#include <Core/Util/Log.h>
+#include <Core/BoxData.h>
+#include <API/web_provider_plugin_info.h>
+#include "box_plugin_interface.h"
+#include "BoxPluginConnector.h"
+
+BoxPluginConnector::BoxPluginConnector()
+{
+}
+
+BoxPluginConnector::~BoxPluginConnector()
+{
+}
+
+bool BoxPluginConnector::initialize()
+{
+ LogD("enter");
+
+ int count;
+ web_provider_plugin_info** pluginList = NULL;
+ pluginList = web_provider_plugin_get_installed_list(&count);
+
+ if (!pluginList) {
+ LogD("failed to get installed plugin's information");
+ return false;
+ }
+
+ if (count <= 0) {
+ LogD("There is no available livebox plugins");
+ return false;
+ }
+
+ m_pluginMap.clear();
+
+ // get information of installed plugin
+ LogD("get information of installed plugin");
+ for (int i = 0; i < count; i++) {
+ if (!pluginList[i]) {
+ continue;
+ }
+
+ LogD("plugin path: %s", pluginList[i]->path);
+ void* handle = dlopen(pluginList[i]->path, RTLD_LAZY);
+ if (!handle) {
+ LogD("failed to load plugin so: %s", dlerror());
+ continue;
+ }
+
+ std::shared_ptr<plugin_interfaces> pluginInfo(new plugin_interfaces);
+
+ pluginInfo->handle = handle;
+ pluginInfo->service_boxid = NULL;
+ if (pluginList[i]->service_boxid) {
+ pluginInfo->service_boxid = strdup(pluginList[i]->service_boxid);
+ }
+
+ pluginInfo->initialize =
+ reinterpret_cast<plugin_interface_func_initialize>(
+ dlsym(handle, WEB_PROVIDER_PLUGIN_INTERFACE_SYM_INITIALIZE));
+ pluginInfo->command =
+ reinterpret_cast<plugin_interface_func_command>(
+ dlsym(handle, WEB_PROVIDER_PLUGIN_INTERFACE_SYM_COMMAND));
+ pluginInfo->shutdown =
+ reinterpret_cast<plugin_interface_func_shutdown>(
+ dlsym(handle, WEB_PROVIDER_PLUGIN_INTERFACE_SYM_SHUTDOWN));
+
+ if (!pluginInfo->initialize || !pluginInfo->command ||
+ !pluginInfo->shutdown)
+ {
+ LogD("symbol for plugin interface is not found");
+ continue;
+ }
+
+ m_pluginMap[std::string(pluginList[i]->type)] = pluginInfo;
+ }
+
+ // initialize plugins
+ for (auto it = m_pluginMap.begin();
+ it != m_pluginMap.end(); ++it)
+ {
+ if (it->second) {
+ // TODO add exception or abnormal action on loading plugin
+ if (it->second->initialize() < 0) {
+ LogD("fail to intialize plugin");
+ continue;
+ }
+ }
+ }
+
+ // release information
+ LogD("release json data of plugins");
+ web_provider_plugin_release_installed_list(pluginList, count);
+
+ return true;
+}
+
+bool BoxPluginConnector::shutdown()
+{
+ LogD("enter");
+ // if needed, unload each plugin's DSO.
+ for (auto it = m_pluginMap.begin();
+ it != m_pluginMap.end(); ++it)
+ {
+ if (it->second) {
+ it->second->shutdown();
+ dlclose(it->second->handle);
+ }
+ }
+
+ return true;
+}
+
+bool BoxPluginConnector::requestCommand(
+ const request_cmd_type type, const BoxInfoPtr& boxInfo)
+{
+ LogD("enter");
+
+ // in case of request of resume all or pause all, all plugins should handle that.
+ if (type == REQUEST_CMD_RESUME_ALL ||
+ type == REQUEST_CMD_PAUSE_ALL ||
+ type == REQUEST_CMD_UPDATE_ALL ||
+ type == REQUEST_CMD_UPDATE_APPBOX) {
+ for (auto it = m_pluginMap.begin();
+ it != m_pluginMap.end(); ++it)
+ {
+ if (it->second) {
+ it->second->command(type, boxInfo);
+ }
+ }
+ return true;
+ }
+
+ const std::shared_ptr<plugin_interfaces> plugin = m_pluginMap[boxInfo->boxType];
+ if (!plugin) {
+ LogD("not available livebox type");
+ return false;
+ }
+
+ int ret = plugin->command(type, boxInfo);
+ if (ret < 0) {
+ LogD("failed to request command");
+ return false;
+ }
+
+ return true;
+}
+
+std::string BoxPluginConnector::getBoxType(const std::string& serviceBoxId)
+{
+ LogD("enter");
+
+ std::string type;
+ for (auto it = m_pluginMap.begin();
+ it != m_pluginMap.end(); ++it)
+ {
+ if (it->second && it->second->service_boxid) {
+ if (serviceBoxId == it->second->service_boxid) {
+ LogD("service box id is matched!: %s", it->first.c_str());
+ type = it->first;
+ break;
+ }
+ }
+ }
+
+ return type;
+}
diff --git a/src_wearable/Plugin/BoxPluginConnector.h b/src_wearable/Plugin/BoxPluginConnector.h
new file mode 100644
index 0000000..5ada8db
--- /dev/null
+++ b/src_wearable/Plugin/BoxPluginConnector.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 BoxPluginConnector.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_PLUGIN_CONNECTOR_H
+#define BOX_PLUGIN_CONNECTOR_H
+
+#include <map>
+#include <Core/BoxData.h>
+#include "IBoxPluginConnector.h"
+#include "box_plugin_interface.h"
+
+class BoxPluginConnector: public IBoxPluginConnector {
+ public: // IBoxPluginConnector
+ static IBoxPluginConnectorPtr create()
+ {
+ return IBoxPluginConnectorPtr(new BoxPluginConnector());
+ };
+ virtual bool initialize();
+ virtual bool shutdown();
+ virtual bool requestCommand(
+ const request_cmd_type type, const BoxInfoPtr& boxInfo);
+ virtual std::string getBoxType(const std::string& serviceBoxId);
+ virtual ~BoxPluginConnector();
+
+ private:
+ BoxPluginConnector();
+
+ // type definition
+ typedef std::map<std::string, std::shared_ptr<plugin_interfaces> > pluginMap;
+
+ pluginMap m_pluginMap;
+
+};
+
+#endif // BOX_PLUGIN_CONNECTOR_H
diff --git a/src_wearable/Plugin/CMakeLists.txt b/src_wearable/Plugin/CMakeLists.txt
new file mode 100644
index 0000000..349ddb0
--- /dev/null
+++ b/src_wearable/Plugin/CMakeLists.txt
@@ -0,0 +1,67 @@
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_PLUGIN})
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ evas
+ ewebkit2
+ dlog
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxPluginConnector.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} STATIC ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LDFLAGS} "-ldl"
+ ${${DEPS}_LIBRARIES}
+)
+
+INSTALL(TARGETS ${TARGET_NAME}
+ DESTINATION lib
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
+
+GET_FILENAME_COMPONENT(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+INSTALL_FILE(IBoxPluginFactory.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(box_plugin_interface.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+
+# openable plugins of web livebox
+ADD_SUBDIRECTORY(AppBoxPlugin)
diff --git a/src_wearable/Plugin/IBoxPluginConnector.h b/src_wearable/Plugin/IBoxPluginConnector.h
new file mode 100644
index 0000000..3e94fb8
--- /dev/null
+++ b/src_wearable/Plugin/IBoxPluginConnector.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IBoxPluginConnector.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_BOX_PLUGIN_CONNECTOR_H
+#define I_BOX_PLUGIN_CONNECTOR_H
+
+#include <memory>
+#include <Core/BoxData.h>
+#include <Core/Util/Noncopyable.h>
+#include "box_plugin_interface.h"
+
+class IBoxPluginConnector: Noncopyable {
+ public:
+ virtual bool initialize() = 0;
+ virtual bool shutdown() = 0;
+ virtual bool requestCommand(
+ const request_cmd_type type, const BoxInfoPtr& boxInfo) = 0;
+ virtual std::string getBoxType(const std::string& serviceBoxId) = 0;
+ virtual ~IBoxPluginConnector() {};
+};
+
+typedef std::shared_ptr<IBoxPluginConnector> IBoxPluginConnectorPtr;
+
+#endif // I_BOX_PLUGIN_CONNECTOR_H
diff --git a/src_wearable/Plugin/IBoxPluginFactory.h b/src_wearable/Plugin/IBoxPluginFactory.h
new file mode 100644
index 0000000..e0ff5ba
--- /dev/null
+++ b/src_wearable/Plugin/IBoxPluginFactory.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 IBoxPluginFactory.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef I_BOX_PLUGIN_FACTORY_H
+#define I_BOX_PLUGIN_FACTORY_H
+
+#include <string>
+#include <memory>
+#include <Evas.h>
+#include <ewk_context.h>
+
+// forward declaration
+class IRenderView;
+struct BoxInfo;
+
+class IBoxPluginFactory {
+ public:
+ virtual std::shared_ptr<IRenderView> createRenderView(
+ std::shared_ptr<BoxInfo> boxInfo,
+ std::shared_ptr<Ewk_Context> ewkContext) = 0;
+ virtual ~IBoxPluginFactory() {};
+};
+
+typedef std::shared_ptr<IBoxPluginFactory> IBoxPluginFactoryPtr;
+
+#endif //I_BOX_PLUGIN_FACTORY_H
diff --git a/src_wearable/Plugin/box_plugin_interface.h b/src_wearable/Plugin/box_plugin_interface.h
new file mode 100755
index 0000000..28ef571
--- /dev/null
+++ b/src_wearable/Plugin/box_plugin_interface.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 box_plugin_interface.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_PLUGIN_INTERFACE_H
+#define BOX_PLUGIN_INTERFACE_H
+
+#include <string>
+#include <Core/BoxData.h>
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+#define WEB_PROVIDER_PLUGIN_INTERFACE_SYM_INITIALIZE "web_provider_plugin_interface_initialize"
+#define WEB_PROVIDER_PLUGIN_INTERFACE_SYM_COMMAND "web_provider_plugin_interface_command"
+#define WEB_PROVIDER_PLUGIN_INTERFACE_SYM_SHUTDOWN "web_provider_plugin_interface_shutdown"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ REQUEST_CMD_ADD_BOX,
+ REQUEST_CMD_REMOVE_BOX,
+ REQUEST_CMD_OPEN_PD,
+ REQUEST_CMD_CLOSE_PD,
+ REQUEST_CMD_RESIZE_BOX,
+ REQUEST_CMD_RESUME_BOX,
+ REQUEST_CMD_PAUSE_BOX,
+ REQUEST_CMD_RESUME_ALL,
+ REQUEST_CMD_PAUSE_ALL,
+ REQUEST_CMD_CHANGE_PERIOD,
+ REQUEST_CMD_UPDATE_BOX,
+ REQUEST_CMD_UPDATE_ALL,
+ REQUEST_CMD_UPDATE_APPBOX
+} request_cmd_type;
+
+// definition of interface function type
+typedef int (*plugin_interface_func_initialize)(void);
+typedef int (*plugin_interface_func_command)(
+ const request_cmd_type type, const BoxInfoPtr& boxInfo);
+typedef int (*plugin_interface_func_shutdown)(void);
+
+typedef struct {
+ void* handle;
+ const char* service_boxid;
+ plugin_interface_func_initialize initialize;
+ plugin_interface_func_command command;
+ plugin_interface_func_shutdown shutdown;
+} plugin_interfaces;
+
+// inteface functions that should be implemented by each plugin
+EXPORT_API int web_provider_plugin_interface_initialize();
+EXPORT_API int web_provider_plugin_interface_command(
+ const request_cmd_type type, const BoxInfoPtr& boxInfo);
+EXPORT_API int web_provider_plugin_interface_shutdown();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BOX_PLUGIN_INTERFACE_H
diff --git a/uncrustify.cfg b/uncrustify.cfg
new file mode 100644
index 0000000..2bf1d96
--- /dev/null
+++ b/uncrustify.cfg
@@ -0,0 +1,170 @@
+indent_align_string=true
+indent_braces=false
+indent_braces_no_func=false
+indent_brace_parent=false
+indent_namespace=false
+indent_extern=false
+indent_class=true
+indent_class_colon=false
+indent_else_if=false
+indent_func_call_param=false
+indent_func_def_param=false
+indent_func_proto_param=false
+indent_func_class_param=false
+indent_func_ctor_var_param=false
+indent_template_param=false
+indent_func_param_double=false
+indent_relative_single_line_comments=false
+indent_col1_comment=true
+indent_access_spec_body=false
+indent_paren_nl=false
+indent_comma_paren=false
+indent_bool_paren=false
+indent_square_nl=false
+indent_preserve_sql=false
+indent_align_assign=false
+sp_balance_nested_parens=false
+align_keep_tabs=false
+align_with_tabs=false
+align_on_tabstop=false
+align_number_left=false
+align_func_params=false
+align_same_func_call_params=false
+align_var_def_colon=false
+align_var_def_attribute=false
+align_var_def_inline=false
+align_right_cmt_mix=false
+align_on_operator=false
+align_mix_var_proto=false
+align_single_line_func=false
+align_single_line_brace=false
+align_nl_cont=false
+align_left_shift=true
+nl_collapse_empty_body=true
+nl_assign_leave_one_liners=false
+nl_class_leave_one_liners=false
+nl_enum_leave_one_liners=false
+nl_getset_leave_one_liners=false
+nl_func_leave_one_liners=false
+nl_if_leave_one_liners=false
+nl_multi_line_cond=true
+nl_multi_line_define=false
+nl_before_case=false
+nl_after_case=false
+nl_after_return=false
+nl_after_semicolon=true
+nl_after_brace_open=false
+nl_after_brace_open_cmt=false
+nl_after_vbrace_open=false
+nl_after_brace_close=false
+nl_define_macro=false
+nl_squeeze_ifdef=false
+nl_ds_struct_enum_cmt=false
+nl_ds_struct_enum_close_brace=false
+nl_create_if_one_liner=false
+nl_create_for_one_liner=false
+nl_create_while_one_liner=false
+ls_for_split_full=true
+ls_func_split_full=true
+nl_after_multiline_comment=false
+eat_blanks_after_open_brace=true
+eat_blanks_before_close_brace=true
+mod_pawn_semicolon=false
+mod_full_paren_if_bool=false
+mod_remove_extra_semicolon=true
+mod_sort_import=false
+mod_sort_using=false
+mod_sort_include=false
+mod_move_case_break=false
+mod_remove_empty_return=false
+cmt_indent_multi=true
+cmt_c_group=false
+cmt_c_nl_start=false
+cmt_c_nl_end=false
+cmt_cpp_group=false
+cmt_cpp_nl_start=false
+cmt_cpp_nl_end=false
+cmt_cpp_to_c=false
+cmt_star_cont=true
+cmt_multi_check_last=true
+cmt_insert_before_preproc=false
+pp_indent_at_level=false
+pp_region_indent_code=false
+pp_if_indent_code=false
+pp_define_at_level=false
+indent_columns=4
+indent_member=4
+indent_access_spec=-2
+code_width=80
+nl_max=2
+nl_before_access_spec=2
+cmt_width=80
+indent_with_tabs=0
+sp_arith=force
+sp_assign=force
+sp_enum_assign=force
+sp_pp_concat=remove
+sp_pp_stringify=remove
+sp_bool=force
+sp_compare=force
+sp_paren_brace=force
+sp_angle_paren=remove
+sp_before_sparen=force
+sp_inside_sparen=remove
+sp_after_sparen=force
+sp_sparen_brace=force
+sp_before_semi=remove
+sp_after_semi_for_empty=remove
+sp_before_square=remove
+sp_before_squares=remove
+sp_inside_square=remove
+sp_after_comma=force
+sp_before_comma=remove
+sp_after_class_colon=force
+sp_before_class_colon=force
+sp_before_case_colon=remove
+sp_inside_braces=add
+sp_inside_fparens=remove
+sp_inside_fparen=remove
+sp_func_call_paren=remove
+sp_func_class_paren=remove
+sp_else_brace=force
+sp_brace_else=force
+sp_catch_brace=force
+sp_brace_catch=force
+sp_try_brace=force
+sp_before_dc=remove
+sp_after_dc=remove
+sp_not=remove
+sp_inv=remove
+sp_addr=remove
+sp_member=remove
+sp_deref=remove
+sp_sign=remove
+sp_incdec=remove
+sp_cond_colon=force
+sp_cond_question=force
+sp_case_label=force
+nl_assign_brace=remove
+nl_if_brace=remove
+nl_brace_else=remove
+nl_elseif_brace=remove
+nl_else_brace=remove
+nl_else_if=remove
+nl_try_brace=remove
+nl_for_brace=remove
+nl_catch_brace=remove
+nl_brace_catch=remove
+nl_while_brace=remove
+nl_do_brace=remove
+nl_brace_while=remove
+nl_switch_brace=remove
+nl_namespace_brace=remove
+nl_class_brace=force
+nl_fdef_brace=force
+pos_class_comma=trail
+pos_class_colon=trail
+mod_full_brace_do=add
+mod_full_brace_for=add
+mod_full_brace_if=add
+mod_full_brace_while=add
diff --git a/uncrustify.sh b/uncrustify.sh
new file mode 100755
index 0000000..c370f4a
--- /dev/null
+++ b/uncrustify.sh
@@ -0,0 +1 @@
+uncrustify -c uncrustify.cfg --no-backup `find . -regex "\(.*\.cpp\|.*\.h\|.*\.c\|.*\.cc\)"`