From f354e5639742dd7c8e9bf0587f6c99fc88925520 Mon Sep 17 00:00:00 2001 From: "jk7744.park" Date: Wed, 9 Sep 2015 00:25:23 +0900 Subject: [PATCH] tizen 2.3.1 release --- CMakeLists.txt | 96 +++ LICENSE.Flora | 206 +++++ Po/CMakeLists.txt | 45 + Po/ar.po | 21 + Po/az.po | 21 + Po/bg.po | 21 + Po/ca.po | 21 + Po/cs.po | 21 + Po/da.po | 21 + Po/de_DE.po | 21 + Po/el_GR.po | 21 + Po/en.po | 21 + Po/en_PH.po | 21 + Po/en_US.po | 21 + Po/es_ES.po | 21 + Po/es_MX.po | 21 + Po/es_US.po | 21 + Po/et.po | 21 + Po/eu.po | 21 + Po/fi.po | 21 + Po/fr_CA.po | 21 + Po/fr_FR.po | 21 + Po/ga.po | 21 + Po/gl.po | 21 + Po/hi.po | 21 + Po/hr.po | 21 + Po/hu.po | 21 + Po/hy.po | 21 + Po/is.po | 21 + Po/it_IT.po | 21 + Po/ja_JP.po | 21 + Po/ka.po | 21 + Po/kk.po | 21 + Po/ko_KR.po | 21 + Po/lt.po | 21 + Po/lv.po | 21 + Po/mk.po | 21 + Po/nb.po | 21 + Po/nl_NL.po | 21 + Po/pl.po | 21 + Po/pt_BR.po | 21 + Po/pt_PT.po | 21 + Po/ro.po | 21 + Po/ru_RU.po | 21 + Po/sk.po | 21 + Po/sl.po | 21 + Po/sr.po | 21 + Po/sv.po | 21 + Po/tr_TR.po | 21 + Po/uk.po | 21 + Po/uz.po | 21 + Po/zh_CN.po | 21 + Po/zh_HK.po | 21 + Po/zh_SG.po | 21 + Po/zh_TW.po | 21 + cmake/OptionsTizen.cmake | 3 + data/200.widget.web-provider.patch.sh | 3 + data/web_provider_db.sql | 11 + data/web_provider_reset_db.sh | 36 + packaging/widget.web-provider.spec | 98 +++ pkgconfig/web-provider-svc.pc.in | 11 + pkgconfig/web-provider.pc.in | 11 + src/API/CMakeLists.txt | 72 ++ src/API/SqliteDB.cpp | 137 ++++ src/API/SqliteDB.h | 44 + src/API/WebProviderDB.h | 34 + src/API/web-provider-info.h | 25 + src/API/web_provider_plugin_info.cpp | 356 ++++++++ src/API/web_provider_plugin_info.h | 51 ++ src/API/web_provider_service.cpp | 185 +++++ src/API/web_provider_service.h | 48 ++ src/API/web_provider_widget_info.cpp | 405 +++++++++ src/API/web_provider_widget_info.h | 59 ++ src/CMakeLists.txt | 44 + src/Core/Box.cpp | 303 +++++++ src/Core/Box.h | 94 +++ src/Core/BoxData.h | 84 ++ src/Core/BoxLoadBalancer.cpp | 190 +++++ src/Core/BoxLoadBalancer.h | 81 ++ src/Core/BoxManager.cpp | 493 +++++++++++ src/Core/BoxManager.h | 94 +++ src/Core/BoxState.cpp | 109 +++ src/Core/BoxState.h | 158 ++++ src/Core/BoxUpdateTimer.cpp | 112 +++ src/Core/BoxUpdateTimer.h | 56 ++ src/Core/Buffer/BoxRenderBuffer.cpp | 193 +++++ src/Core/Buffer/BoxRenderBuffer.h | 77 ++ src/Core/Buffer/CMakeLists.txt | 65 ++ src/Core/Buffer/GbarRenderBuffer.cpp | 279 +++++++ src/Core/Buffer/GbarRenderBuffer.h | 77 ++ src/Core/Buffer/IRenderBuffer.h | 45 + src/Core/Buffer/RenderBuffer.cpp | 436 ++++++++++ src/Core/Buffer/RenderBuffer.h | 89 ++ src/Core/CMakeLists.txt | 89 ++ src/Core/IBox.h | 59 ++ src/Core/IBoxContext.h | 33 + src/Core/IBoxManager.h | 36 + src/Core/IBoxState.h | 41 + src/Core/Platform.h | 48 ++ src/Core/Util/CMakeLists.txt | 61 ++ src/Core/Util/ITimer.h | 43 + src/Core/Util/Log.cpp | 19 + src/Core/Util/Log.h | 35 + src/Core/Util/Noncopyable.h | 33 + src/Core/Util/Util.h | 25 + src/Core/View/CMakeLists.txt | 72 ++ src/Core/View/GbarHelper.cpp | 146 ++++ src/Core/View/GbarHelper.h | 68 ++ src/Core/View/IGbarHelper.h | 41 + src/Core/View/IJsInterface.h | 34 + src/Core/View/IRenderView.h | 48 ++ src/Core/View/JsInterface.cpp | 250 ++++++ src/Core/View/JsInterface.h | 64 ++ src/Core/View/RenderView.cpp | 322 ++++++++ src/Core/View/RenderView.h | 99 +++ src/Core/View/Service/AppControl.cpp | 124 +++ src/Core/View/Service/AppControl.h | 30 + src/Core/View/Service/CMakeLists.txt | 72 ++ src/Core/View/Service/MessageManager.cpp | 93 +++ src/Core/View/Service/MessageManager.h | 53 ++ src/Core/View/Service/PeriodChanger.cpp | 277 +++++++ src/Core/View/Service/PeriodChanger.h | 79 ++ src/Core/View/Service/ScrollHolder.cpp | 42 + src/Core/View/Service/ScrollHolder.h | 29 + src/Core/View/injection.js | 151 ++++ src/Core/config.h | 25 + src/Daemon/BoxDaemon.cpp | 47 ++ src/Daemon/BoxDaemon.h | 43 + src/Daemon/BoxDaemonImpl.cpp | 923 +++++++++++++++++++++ src/Daemon/BoxDaemonImpl.h | 124 +++ src/Daemon/BoxDaemonUtil.cpp | 91 +++ src/Daemon/BoxDaemonUtil.h | 36 + src/Daemon/CMakeLists.txt | 66 ++ src/Daemon/main.cpp | 171 ++++ src/Plugin/AppBoxPlugin/AppBoxGbarHelper.cpp | 90 ++ src/Plugin/AppBoxPlugin/AppBoxGbarHelper.h | 55 ++ src/Plugin/AppBoxPlugin/AppBoxManager.cpp | 213 +++++ src/Plugin/AppBoxPlugin/AppBoxManager.h | 59 ++ src/Plugin/AppBoxPlugin/AppBoxPluginFactory.cpp | 32 + src/Plugin/AppBoxPlugin/AppBoxPluginFactory.h | 45 + src/Plugin/AppBoxPlugin/AppBoxRenderView.cpp | 998 +++++++++++++++++++++++ src/Plugin/AppBoxPlugin/AppBoxRenderView.h | 146 ++++ src/Plugin/AppBoxPlugin/CMakeLists.txt | 73 ++ src/Plugin/AppBoxPlugin/app.json | 5 + src/Plugin/AppBoxPlugin/box_plugin_interface.cpp | 55 ++ src/Plugin/BoxPluginConnector.cpp | 188 +++++ src/Plugin/BoxPluginConnector.h | 51 ++ src/Plugin/CMakeLists.txt | 67 ++ src/Plugin/IBoxPluginConnector.h | 40 + src/Plugin/IBoxPluginFactory.h | 43 + src/Plugin/box_plugin_interface.h | 78 ++ uncrustify.cfg | 170 ++++ uncrustify.sh | 1 + widget.web-provider.efl | 44 + widget.web-provider.manifest | 16 + widget.web-provider.xml | 18 + 156 files changed, 12736 insertions(+) create mode 100755 CMakeLists.txt create mode 100755 LICENSE.Flora create mode 100755 Po/CMakeLists.txt create mode 100755 Po/ar.po create mode 100755 Po/az.po create mode 100755 Po/bg.po create mode 100755 Po/ca.po create mode 100755 Po/cs.po create mode 100755 Po/da.po create mode 100755 Po/de_DE.po create mode 100755 Po/el_GR.po create mode 100755 Po/en.po create mode 100755 Po/en_PH.po create mode 100755 Po/en_US.po create mode 100755 Po/es_ES.po create mode 100755 Po/es_MX.po create mode 100644 Po/es_US.po create mode 100755 Po/et.po create mode 100755 Po/eu.po create mode 100755 Po/fi.po create mode 100755 Po/fr_CA.po create mode 100755 Po/fr_FR.po create mode 100755 Po/ga.po create mode 100755 Po/gl.po create mode 100755 Po/hi.po create mode 100755 Po/hr.po create mode 100755 Po/hu.po create mode 100755 Po/hy.po create mode 100755 Po/is.po create mode 100755 Po/it_IT.po create mode 100755 Po/ja_JP.po create mode 100755 Po/ka.po create mode 100755 Po/kk.po create mode 100755 Po/ko_KR.po create mode 100755 Po/lt.po create mode 100755 Po/lv.po create mode 100755 Po/mk.po create mode 100755 Po/nb.po create mode 100755 Po/nl_NL.po create mode 100755 Po/pl.po create mode 100755 Po/pt_BR.po create mode 100755 Po/pt_PT.po create mode 100755 Po/ro.po create mode 100755 Po/ru_RU.po create mode 100755 Po/sk.po create mode 100755 Po/sl.po create mode 100755 Po/sr.po create mode 100755 Po/sv.po create mode 100755 Po/tr_TR.po create mode 100755 Po/uk.po create mode 100755 Po/uz.po create mode 100755 Po/zh_CN.po create mode 100755 Po/zh_HK.po create mode 100755 Po/zh_SG.po create mode 100755 Po/zh_TW.po create mode 100644 cmake/OptionsTizen.cmake create mode 100755 data/200.widget.web-provider.patch.sh create mode 100644 data/web_provider_db.sql create mode 100644 data/web_provider_reset_db.sh create mode 100755 packaging/widget.web-provider.spec create mode 100644 pkgconfig/web-provider-svc.pc.in create mode 100644 pkgconfig/web-provider.pc.in create mode 100644 src/API/CMakeLists.txt create mode 100644 src/API/SqliteDB.cpp create mode 100644 src/API/SqliteDB.h create mode 100644 src/API/WebProviderDB.h create mode 100644 src/API/web-provider-info.h create mode 100755 src/API/web_provider_plugin_info.cpp create mode 100755 src/API/web_provider_plugin_info.h create mode 100644 src/API/web_provider_service.cpp create mode 100644 src/API/web_provider_service.h create mode 100755 src/API/web_provider_widget_info.cpp create mode 100755 src/API/web_provider_widget_info.h create mode 100644 src/CMakeLists.txt create mode 100644 src/Core/Box.cpp create mode 100644 src/Core/Box.h create mode 100644 src/Core/BoxData.h create mode 100755 src/Core/BoxLoadBalancer.cpp create mode 100755 src/Core/BoxLoadBalancer.h create mode 100755 src/Core/BoxManager.cpp create mode 100755 src/Core/BoxManager.h create mode 100644 src/Core/BoxState.cpp create mode 100644 src/Core/BoxState.h create mode 100644 src/Core/BoxUpdateTimer.cpp create mode 100644 src/Core/BoxUpdateTimer.h create mode 100755 src/Core/Buffer/BoxRenderBuffer.cpp create mode 100644 src/Core/Buffer/BoxRenderBuffer.h create mode 100644 src/Core/Buffer/CMakeLists.txt create mode 100755 src/Core/Buffer/GbarRenderBuffer.cpp create mode 100755 src/Core/Buffer/GbarRenderBuffer.h create mode 100644 src/Core/Buffer/IRenderBuffer.h create mode 100755 src/Core/Buffer/RenderBuffer.cpp create mode 100644 src/Core/Buffer/RenderBuffer.h create mode 100644 src/Core/CMakeLists.txt create mode 100644 src/Core/IBox.h create mode 100644 src/Core/IBoxContext.h create mode 100644 src/Core/IBoxManager.h create mode 100644 src/Core/IBoxState.h create mode 100644 src/Core/Platform.h create mode 100644 src/Core/Util/CMakeLists.txt create mode 100644 src/Core/Util/ITimer.h create mode 100644 src/Core/Util/Log.cpp create mode 100644 src/Core/Util/Log.h create mode 100644 src/Core/Util/Noncopyable.h create mode 100644 src/Core/Util/Util.h create mode 100644 src/Core/View/CMakeLists.txt create mode 100755 src/Core/View/GbarHelper.cpp create mode 100755 src/Core/View/GbarHelper.h create mode 100755 src/Core/View/IGbarHelper.h create mode 100644 src/Core/View/IJsInterface.h create mode 100644 src/Core/View/IRenderView.h create mode 100755 src/Core/View/JsInterface.cpp create mode 100755 src/Core/View/JsInterface.h create mode 100644 src/Core/View/RenderView.cpp create mode 100644 src/Core/View/RenderView.h create mode 100644 src/Core/View/Service/AppControl.cpp create mode 100644 src/Core/View/Service/AppControl.h create mode 100755 src/Core/View/Service/CMakeLists.txt create mode 100755 src/Core/View/Service/MessageManager.cpp create mode 100644 src/Core/View/Service/MessageManager.h create mode 100755 src/Core/View/Service/PeriodChanger.cpp create mode 100755 src/Core/View/Service/PeriodChanger.h create mode 100644 src/Core/View/Service/ScrollHolder.cpp create mode 100644 src/Core/View/Service/ScrollHolder.h create mode 100644 src/Core/View/injection.js create mode 100644 src/Core/config.h create mode 100644 src/Daemon/BoxDaemon.cpp create mode 100644 src/Daemon/BoxDaemon.h create mode 100755 src/Daemon/BoxDaemonImpl.cpp create mode 100755 src/Daemon/BoxDaemonImpl.h create mode 100644 src/Daemon/BoxDaemonUtil.cpp create mode 100644 src/Daemon/BoxDaemonUtil.h create mode 100644 src/Daemon/CMakeLists.txt create mode 100755 src/Daemon/main.cpp create mode 100755 src/Plugin/AppBoxPlugin/AppBoxGbarHelper.cpp create mode 100755 src/Plugin/AppBoxPlugin/AppBoxGbarHelper.h create mode 100755 src/Plugin/AppBoxPlugin/AppBoxManager.cpp create mode 100644 src/Plugin/AppBoxPlugin/AppBoxManager.h create mode 100644 src/Plugin/AppBoxPlugin/AppBoxPluginFactory.cpp create mode 100644 src/Plugin/AppBoxPlugin/AppBoxPluginFactory.h create mode 100755 src/Plugin/AppBoxPlugin/AppBoxRenderView.cpp create mode 100755 src/Plugin/AppBoxPlugin/AppBoxRenderView.h create mode 100644 src/Plugin/AppBoxPlugin/CMakeLists.txt create mode 100644 src/Plugin/AppBoxPlugin/app.json create mode 100644 src/Plugin/AppBoxPlugin/box_plugin_interface.cpp create mode 100755 src/Plugin/BoxPluginConnector.cpp create mode 100644 src/Plugin/BoxPluginConnector.h create mode 100644 src/Plugin/CMakeLists.txt create mode 100644 src/Plugin/IBoxPluginConnector.h create mode 100644 src/Plugin/IBoxPluginFactory.h create mode 100755 src/Plugin/box_plugin_interface.h create mode 100644 uncrustify.cfg create mode 100755 uncrustify.sh create mode 100644 widget.web-provider.efl create mode 100755 widget.web-provider.manifest create mode 100644 widget.web-provider.xml diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..116ab71 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,96 @@ +# 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) + +OPTION(DPL_LOG "DPL logs status" ON) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(RESDIR "${PREFIX}/apps/${CMAKE_PROJECT_NAME}/res") +SET(LOCALE_DIR "${RESDIR}/locale") +# 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() + +IF(DPL_LOG AND NOT CMAKE_BUILD_TYPE MATCHES "profiling") + MESSAGE(STATUS "Logging enabled for DPL") + ADD_DEFINITIONS("-DDPL_LOGS_ENABLED") +ELSE(DPL_LOG AND NOT CMAKE_BUILD_TYPE MATCHES "profiling") + MESSAGE(STATUS "Logging disabled for DPL") +ENDIF(DPL_LOG AND NOT CMAKE_BUILD_TYPE MATCHES "profiling") + +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(widget.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.widget.web-provider.patch.sh /etc/opt/upgrade) +INSTALL_FILE(widget.web-provider.efl /etc/smack/accesses.d) +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..63bb1d6 --- /dev/null +++ b/Po/CMakeLists.txt @@ -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. +# +# @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 es_US.po) + +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/es_US.po b/Po/es_US.po new file mode 100644 index 0000000..85f5dc5 --- /dev/null +++ b/Po/es_US.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.widget.web-provider.patch.sh b/data/200.widget.web-provider.patch.sh new file mode 100755 index 0000000..a2da54a --- /dev/null +++ b/data/200.widget.web-provider.patch.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +setfattr -n security.capability -v 0sAQAAAgABAAAAAAAAAgAAAAAAAAA= /usr/apps/widget.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/packaging/widget.web-provider.spec b/packaging/widget.web-provider.spec new file mode 100755 index 0000000..a73b740 --- /dev/null +++ b/packaging/widget.web-provider.spec @@ -0,0 +1,98 @@ +#git:framework/web/web-provider +Name: widget.web-provider +Summary: web framework for widget +Version: 1.101 +Release: 1 +Group: main/app +License: Flora-1.1 +Source0: %{name}-%{version}.tar.gz +BuildRequires: attr +BuildRequires: cmake, gettext-tools +BuildRequires: libcap, libcap-devel +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(widget_provider) +BuildRequires: pkgconfig(pkgmgr-info) +BuildRequires: pkgconfig(widget_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 widget 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 + +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + -DCMAKE_PROJECT_VERSION=%{version} \ + -DCMAKE_PROJECT_NAME=%{name} \ + -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/widget.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 'widget.web-provider::db' /opt/usr/dbspace/.web_provider.db +chsmack -a 'widget.web-provider::db' /opt/usr/dbspace/.web_provider.db-journal +setfattr -n security.capability -v 0sAQAAAgABAAAAAAAAAgAAAAAAAAA= %{_prefix}/apps/widget.web-provider/bin/web-provider +chown 5000:5000 %{app_data} +chmod 755 %{app_data} + +%files -n widget.web-provider +%manifest widget.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/widget.web-provider/bin/web-provider +%{_datarootdir}/packages/widget.web-provider.xml +%{_prefix}/apps/%{name}/res/locale/* +%{_sysconfdir}/smack/accesses.d/widget.web-provider.efl +%{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..35acbfa --- /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 widget_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..35acbfa --- /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 widget_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/API/CMakeLists.txt b/src/API/CMakeLists.txt new file mode 100644 index 0000000..8a7f570 --- /dev/null +++ b/src/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_widget_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_widget_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/API/SqliteDB.cpp b/src/API/SqliteDB.cpp new file mode 100644 index 0000000..84fc1ed --- /dev/null +++ b/src/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 +#include +#include +#include +#include + +#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(const 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; + } + + va_list ap; + va_start(ap, fmt); + for (unsigned int i = 0; i < strlen(fmt); i++) { + switch (fmt[i]) { + case 'i': + { + int 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': + { + char* 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(sqlite3_column_text(m_stmt, col)); + + return ret; +} + +int SqliteDB::getInt(int col) +{ + return sqlite3_column_int(m_stmt, col); +} diff --git a/src/API/SqliteDB.h b/src/API/SqliteDB.h new file mode 100644 index 0000000..b906fce --- /dev/null +++ b/src/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 +#include + +class SqliteDB { + public: + bool openDB(); + void closeDB(); + bool setCommand(const 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/API/WebProviderDB.h b/src/API/WebProviderDB.h new file mode 100644 index 0000000..81c962b --- /dev/null +++ b/src/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 WIDGET_DB_H +#define WIDGET_DB_H + +#include +#include "SqliteDB.h" + +const std::string dbPath("/opt/usr/dbspace/.web_provider.db"); + +class WebProviderDB : public SqliteDB { + public: + WebProviderDB() : SqliteDB (dbPath) {}; + ~WebProviderDB() {}; +}; + +#endif //WIDGET_DB_H diff --git a/src/API/web-provider-info.h b/src/API/web-provider-info.h new file mode 100644 index 0000000..c4e3338 --- /dev/null +++ b/src/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 + +#endif //WEB_PROVIDER_INFO_H diff --git a/src/API/web_provider_plugin_info.cpp b/src/API/web_provider_plugin_info.cpp new file mode 100755 index 0000000..f2b7ffc --- /dev/null +++ b/src/API/web_provider_plugin_info.cpp @@ -0,0 +1,356 @@ +/* + * 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_widget_info.cpp + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "web_provider_widget_info.h" +#include "web_provider_plugin_info.h" +#include + +// static functions +static web_provider_plugin_info* get_parsed_json_data(const std::string& configPath); +static bool web_provider_plugin_release_info(web_provider_plugin_info* info); + +namespace{ + static const std::string kInstalledPluginDirPath("/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 + +namespace{ +static const std::string kJsonMemberType("type"); +static const std::string kJsonMemberPath("path"); +static const std::string kJsonMemberBoxId("service_boxid"); +static const std::string kJsonMemberBoxScrollable("box_scrollable"); +static const std::string kJsonMemberBoxSize("supported_size"); + +static const std::string kJsonValueBoolTrue("true"); +static const std::string kJsonValueBoolFalse("false"); +static const std::string kJsonFileExtension(".json"); +static const std::string kMandatoryBoxSize("1x1"); +} +web_provider_plugin_info** web_provider_plugin_get_installed_list(int* count) +{ + LogD("enter"); + + // open directory of web provider plugin + DIR* dir = opendir(kInstalledPluginDirPath.c_str()); + if (!dir) { + LogD("failed to open directory for web widget plugins"); + *count = 0; + return NULL; + } + + // read plugin directory and store plugin config path + std::list configList; + struct dirent* entry; + + while ((entry = readdir(dir))) { + if ((!strcmp(entry->d_name, ".")) || (!strcmp(entry->d_name, ".."))) { + continue; + } + + std::string configPath = kInstalledPluginDirPath + entry->d_name; + struct stat configStat; + 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(".")) == kJsonFileExtension) { + 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 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( + malloc((*count) * sizeof(web_provider_plugin_info*))); + if (info_list) { + // 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]); + } + free(info_list); +} + +int web_provider_plugin_get_box_scrollable(const char* plugin_type) +{ + if (!plugin_type) { + return -1; + } + + std::string configPath; + configPath = kInstalledPluginDirPath; + configPath += plugin_type; + configPath += kJsonFileExtension; + 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(const std::string& configPath) +{ +#if !GLIB_CHECK_VERSION(2, 35, 0) + g_type_init(); +#endif + + 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( + json_object_get_string_member(object, kJsonMemberType.c_str())); + + const char* path = + static_cast( + json_object_get_string_member(object, kJsonMemberPath.c_str())); + + JsonArray* size = + json_object_get_array_member(object, kJsonMemberBoxSize.c_str()); + int sizeCount = static_cast(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( + 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(malloc(sizeof(char*) * sizeCount)); + + for (int i = 0; i < sizeCount; i++) { + info->box_size[i] = + strdup(static_cast(json_array_get_string_element(size, i))); + } + info->box_size_count = sizeCount; + + gboolean hasBoxId = json_object_has_member(object, kJsonMemberBoxId.c_str()); + if (hasBoxId == TRUE) { + const char* boxId = + static_cast( + json_object_get_string_member(object, kJsonMemberBoxId.c_str())); + if (boxId) { + info->service_boxid = strdup(boxId); + } + } + + gboolean hasBoxScrollable = + json_object_has_member(object, kJsonMemberBoxScrollable.c_str()); + if (hasBoxScrollable == TRUE) { + const char* boxScrollable = + static_cast( + json_object_get_string_member(object, kJsonMemberBoxScrollable.c_str())); + if (boxScrollable && (kJsonValueBoolTrue == 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 + free(info->type); + free(info->path); + free(info->service_boxid); + for(int i = 0; i < info->box_size_count; i++) { + free(info->box_size[i]); + } + free(info->box_size); + free(info); + + return true; +} + +bool 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 = kInstalledPluginDirPath; + configPath += plugin_type; + configPath += kJsonFileExtension; + + // 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_widget_get_default_type(); + if (!defaultType) { + LogD("can't get default type"); + web_provider_plugin_release_info(jsonData); + 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(kMandatoryBoxSize.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/API/web_provider_plugin_info.h b/src/API/web_provider_plugin_info.h new file mode 100755 index 0000000..f737bd8 --- /dev/null +++ b/src/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 { + char* type; + char* path; + 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 bool 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/API/web_provider_service.cpp b/src/API/web_provider_service.cpp new file mode 100644 index 0000000..8cb9817 --- /dev/null +++ b/src/API/web_provider_service.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 web_provider_service.cpp + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "web_provider_widget_info.h" +#include "web_provider_service.h" + +static std::string getFifoFile(const char* appId) +{ + int boxCount = 0; + char** boxList = web_provider_widget_get_box_id_list(appId, &boxCount); + if (!boxList) { + return std::string(); + } + web_provider_widget_release_box_id_list(boxList, boxCount); + + std::string fifoFile = "/tmp/"; + fifoFile += appId; + + return fifoFile; +} + +static bool requestRemoveBoxesByAppId(const char* appId) +{ + if (!appId) { + return false; + } + + app_control_h handle = NULL; + int ret = APP_CONTROL_ERROR_NONE; + + ret = app_control_create(&handle); + if (ret != APP_CONTROL_ERROR_NONE && !handle) { + return false; + } + + ret = app_control_set_app_id(handle, APP_CONTROL_WEB_PROVIDER_APPID); + if (ret != APP_CONTROL_ERROR_NONE) { + app_control_destroy(handle); + return false; + } + + ret = app_control_set_operation(handle, APP_CONTROL_OPERATION_BOX_REMOVE); + if (ret != APP_CONTROL_ERROR_NONE) { + app_control_destroy(handle); + return false; + } + + // set special key as extra data for removing boxes by web-provider + app_control_add_extra_data(handle, APP_CONTROL_REMOVE_APPID_KEY, appId); + + ret = app_control_send_launch_request(handle, NULL, NULL); + if (ret != APP_CONTROL_ERROR_NONE) { + app_control_destroy(handle); + return false; + } + + app_control_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); + if( fifoFile.empty() ) + return -1; + int ret = mkfifo(fifoFile.c_str(), 0666); + if (ret < 0) { + if (errno != EEXIST) { + return -1; + } + } + if (chown(fifoFile.c_str(), 5000, 5000) < 0) { + return -1; + } + + 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 = 3; + 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); + if(fifoFile.empty()) + return -1; + int fifoFd = open(fifoFile.c_str(), O_WRONLY | O_NONBLOCK); + if (fifoFd < 0) { + return -1; + } + + std::string result("1"); + if (write(fifoFd, result.c_str(), result.size() + 1) < 0) { + close(fifoFd); + return -1; + } + close(fifoFd); + return 0; +} diff --git a/src/API/web_provider_service.h b/src/API/web_provider_service.h new file mode 100644 index 0000000..b612285 --- /dev/null +++ b/src/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 widget from wrt-installer +#define APP_CONTROL_OPERATION_BOX_REMOVE "http://tizen.org/appcontrol/operation/dynamicbox/web/remove" +#define APP_CONTROL_WEB_PROVIDER_APPID "widget.web-provider" +#define APP_CONTROL_REMOVE_APPID_KEY "app_id" + +// These are string for updating widget from web app +#define APP_CONTROL_OPERATION_BOX_UPDATE "http://tizen.org/appcontrol/operation/dynamicbox/web/update" +#define APP_CONTROL_BOX_SERVICE_SCHEME "box-service://" +#define APP_CONTROL_CONTENT_INFO_KEY "content-info" +#define APP_CONTROL_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/API/web_provider_widget_info.cpp b/src/API/web_provider_widget_info.cpp new file mode 100755 index 0000000..19d0d2d --- /dev/null +++ b/src/API/web_provider_widget_info.cpp @@ -0,0 +1,405 @@ +/* + * 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_widget_info.cpp + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ +#include +#include +#include +#include "WebProviderDB.h" +#include "web_provider_widget_info.h" + +namespace { +static const std::string kInfoTable("LiveboxInfo"); +} + +enum InfoTableField { + BOX_ID = 0, + APP_ID, + BOX_TYPE, + AUTO_LAUNCH, + MOUSE_EVENT, + GBAR_FAST_OPEN, +}; + +// TODO this default type should be retrieved more automatically +namespace{ +static const std::string kDefaultBoxType("app"); +} + +const char* web_provider_widget_get_default_type() +{ + return kDefaultBoxType.c_str(); +} + +char* web_provider_widget_get_box_type(const char* box_id) +{ + if (!box_id) { + return NULL; + } + + std::shared_ptr handle(new WebProviderDB()); + if (!handle->openDB()) { + return NULL; + } + + std::string query = "select * from " + kInfoTable + " 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); + char* box_type_dup = NULL; + + if (box_type) { + box_type_dup = strdup(box_type); + } + + handle->closeDB(); + + return box_type_dup; +} + +char* web_provider_widget_get_app_id(const char* box_id) +{ + if (!box_id) { + return NULL; + } + + std::shared_ptr handle(new WebProviderDB()); + if (!handle->openDB()) { + return NULL; + } + + std::string query = "select * from " + kInfoTable + " 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); + char* app_id_dup = NULL; + + if (app_id) { + app_id_dup = strdup(app_id); + } + + handle->closeDB(); + + return app_id_dup; +} + +int web_provider_widget_get_auto_launch(const char* box_id) +{ + if (!box_id) { + return 0; + } + + std::shared_ptr handle(new WebProviderDB()); + if (!handle->openDB()) { + return 0; + } + + std::string query = "select * from " + kInfoTable + " 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_widget_get_mouse_event(const char* box_id) +{ + if (!box_id) { + return 0; + } + + std::shared_ptr handle(new WebProviderDB()); + if (!handle->openDB()) { + return 0; + } + + std::string query = "select * from " + kInfoTable + " 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; +} + +bool web_provider_widget_get_gbar_fast_open(const char* box_id) +{ + if (!box_id) { + return 0; + } + + std::shared_ptr handle(new WebProviderDB()); + if (!handle->openDB()) { + return 0; + } + + std::string query = "select * from " + kInfoTable + " where box_id = ?"; + if (!handle->setCommand(query, "s", box_id)) { + handle->closeDB(); + return 0; + } + + if (!handle->executeCommand()) { + handle->closeDB(); + return 0; + } + + int gbarFastOpen = handle->getInt(InfoTableField::GBAR_FAST_OPEN); + handle->closeDB(); + + return gbarFastOpen; +} + +int web_provider_widget_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 handle(new WebProviderDB()); + if (!handle->openDB()) { + return -1; + } + + std::string query = + "insert into " + kInfoTable + + " (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_widget_delete_by_box_id(const char* box_id) +{ + if (!box_id) { + return -1; + } + + std::shared_ptr handle(new WebProviderDB()); + if (!handle->openDB()) { + return -1; + } + + std::string query = + "delete from " + kInfoTable + " 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_widget_delete_by_app_id(const char* app_id) +{ + if (!app_id) { + return -1; + } + + std::shared_ptr handle(new WebProviderDB()); + if (!handle->openDB()) { + return -1; + } + + std::string query = + "delete from " + kInfoTable + " 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_widget_delete_by_type(const char* type) +{ + if (!type) { + return -1; + } + + std::shared_ptr handle(new WebProviderDB()); + if (!handle->openDB()) { + return -1; + } + + std::string query = + "delete from " + kInfoTable + " 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_widget_get_box_id_list(const char* app_id, int* count) +{ + if (!app_id) { + return NULL; + } + + std::shared_ptr handle(new WebProviderDB()); + if (!handle->openDB()) { + return NULL; + } + + std::string query = "select * from " + kInfoTable + " where app_id = ?"; + if (!handle->setCommand(query, "s", app_id)) { + handle->closeDB(); + return NULL; + } + + std::vector boxIdList; + while (handle->executeCommand()) { + const char* boxId = handle->getText(InfoTableField::BOX_ID); + if (boxId != NULL) { + boxIdList.push_back(strdup(boxId)); + } + } + + *count = boxIdList.size(); + if (*count == 0) { + handle->closeDB(); + return NULL; + } + + char** boxIds = static_cast(malloc((*count) * sizeof(char*))); + if (boxIds != NULL) { + for (int i = 0; i < *count; i++) { + boxIds[i] = boxIdList[i]; + } + } + + handle->closeDB(); + return boxIds; +} + +void web_provider_widget_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]); + } + + free(box_id_list); +} + +bool web_provider_widget_check_box_installed(const char* box_id) +{ + if (!box_id) { + return 0; + } + + std::shared_ptr handle(new WebProviderDB()); + if (!handle->openDB()) { + return 0; + } + + std::string query = "select count(box_id) from " + kInfoTable + " where box_id = ?"; + if (!handle->setCommand(query, "s", box_id)) { + handle->closeDB(); + return 0; + } + + if (!handle->executeCommand()) { + handle->closeDB(); + return 0; + } + + int count = handle->getInt(0); + return count; +} diff --git a/src/API/web_provider_widget_info.h b/src/API/web_provider_widget_info.h new file mode 100755 index 0000000..8a64fda --- /dev/null +++ b/src/API/web_provider_widget_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_widget_info.h + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ +#ifndef WEB_PROVIDER_WIDGET_INFO_H +#define WEB_PROVIDER_WIDGET_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_widget_get_default_type(); +EXPORT_API char* web_provider_widget_get_box_type(const char* box_id); +EXPORT_API char* web_provider_widget_get_app_id(const char* box_id); +EXPORT_API int web_provider_widget_get_auto_launch(const char* box_id); +EXPORT_API int web_provider_widget_get_mouse_event(const char* box_id); +EXPORT_API bool web_provider_widget_get_gbar_fast_open(const char* box_id); +EXPORT_API int web_provider_widget_insert_box_info( + const char* box_id, + const char* app_id, + const char* box_type, + int auto_launch, + int mouse_event, + int gbar_fast_open); +EXPORT_API int web_provider_widget_delete_by_box_id(const char* box_id); +EXPORT_API int web_provider_widget_delete_by_app_id(const char* app_id); +EXPORT_API int web_provider_widget_delete_by_type(const char* type); + +EXPORT_API char** web_provider_widget_get_box_id_list(const char* app_id, int* count); +EXPORT_API void web_provider_widget_release_box_id_list(char** box_id_list, int count); +EXPORT_API bool web_provider_widget_check_box_installed(const char* box_id); + +#ifdef __cplusplus +} +#endif +#endif //WEB_PROVIDER_WIDGET_INFO_H \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..5959e47 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,44 @@ +# 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) + +SET(WEB_PROVIDER_STATIC_REQUIRES + dpl-efl +) + +PKG_CHECK_MODULES(WEB_PROVIDER_STATIC_DEP + ${WEB_PROVIDER_STATIC_REQUIRES} + REQUIRED +) + +INCLUDE_DIRECTORIES( + ${WEB_PROVIDER_STATIC_DEP_INCLUDE_DIRS} +) + +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/Core/Box.cpp b/src/Core/Box.cpp new file mode 100644 index 0000000..3568584 --- /dev/null +++ b/src/Core/Box.cpp @@ -0,0 +1,303 @@ +/* + * 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 +#include +#include +#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"); + if( boxInfo == NULL ){ + LogE("boxInfo is NULL"); + throw; + } + 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(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); + + m_currentTab = true; + m_paused = false; + + if (m_updateNeeded) { + m_updateNeeded = false; + m_updateTimer->start(); + m_renderView->update(); + } else { + m_renderView->resume(); + } + + m_showed = true; + SWITCH_BOX_STATE(); + return true; +} + +bool Box::needToUpdate() +{ + LogD("enter"); + + if (m_updateNeeded) { + return true; + } + + if (m_updateTimer && m_updateTimer->getPeriod() > 0) { + // check for need updateTimer + time_t currentTime = time(NULL); + float diffTime = static_cast(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 { + return true; + } + return false; + } + + if (!m_showed) { + 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::openGbar(int width, int height, int x, int y) +{ + LogD("enter"); + CHECK_BOX_STATE(m_state, permitOpenGbar); + + m_boxInfo->gbarWidth = width; + m_boxInfo->gbarHeight = height; + m_boxInfo->gbarX = x; + m_boxInfo->gbarY = y; + + try { + m_updateTimer->stop(); + m_renderView->openGbar(); + } catch (...) { + return false; + } + m_showed = true; + SWITCH_BOX_STATE(); + return true; +} + +bool Box::closeGbar() +{ + LogD("enter"); + CHECK_BOX_STATE(m_state, permitCloseGbar); + + try { + m_renderView->closeGbar(); + 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(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/Core/Box.h b/src/Core/Box.h new file mode 100644 index 0000000..22b7c5a --- /dev/null +++ b/src/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 +#include +#include +#include +#include +#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 openGbar(int width, int height, int x, int y); + bool closeGbar(); + 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/Core/BoxData.h b/src/Core/BoxData.h new file mode 100644 index 0000000..d5d2a48 --- /dev/null +++ b/src/Core/BoxData.h @@ -0,0 +1,84 @@ +/* + * 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 +#include + +struct BoxInfo +{ + std::string boxType; + std::string boxId; + std::string instanceId; + int boxWidth; + int boxHeight; + int gbarWidth; + int gbarHeight; + int gbarX; + int gbarY; + 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), + gbarWidth(0), + gbarHeight(0), + gbarX(0), + gbarY(0), + priority(0), + period(0), + contentInfo(), + appContentInfo() + { + }; + + BoxInfo() : + boxType(), + boxId(), + instanceId(), + boxWidth(0), + boxHeight(0), + gbarWidth(0), + gbarHeight(0), + gbarX(0), + gbarY(0), + priority(0), + period(0), + contentInfo(), + appContentInfo() + { + }; +}; + +typedef std::shared_ptr BoxInfoPtr; + +#endif // BOX_DATA_H diff --git a/src/Core/BoxLoadBalancer.cpp b/src/Core/BoxLoadBalancer.cpp new file mode 100755 index 0000000..3d1cc50 --- /dev/null +++ b/src/Core/BoxLoadBalancer.cpp @@ -0,0 +1,190 @@ +/* + * 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_boxAsyncCommandList.clear(); + m_boxLoadBalanceTimer = NULL; + m_updateTimeCount = 0.0f; +} + +BoxLoadBalancer::~BoxLoadBalancer() +{ + +} + +Eina_Bool BoxLoadBalancer::requestBoxLoadBalanceCallback(void* data) +{ + LogD("requestBoxLoadBalanceCallback"); + BoxLoadBalancer* This = static_cast(data); + + if (This->m_boxAsyncCommandList.empty()) { + LogD("m_boxAsyncCommandList.size() is empty"); + This->m_boxLoadBalanceTimer = NULL; + return ECORE_CALLBACK_CANCEL; + } + + BoxAsyncCommandInfoPtr boxCommandPtr = This->m_boxAsyncCommandList.front(); + IBoxPtr box = boxCommandPtr->getBoxPtr(); + if( box ){ + switch (boxCommandPtr->getType()) { + case BOX_AYNC_REQUEST_CMD_SHOW: + box->show(); + break; + case BOX_AYNC_REQUEST_CMD_RESUME: + box->resume(); + break; + case BOX_AYNC_REQUEST_CMD_UPDATE: + { + std::string contentInfo = boxCommandPtr->getAppContentInfo(); + box->update(contentInfo); + break; + } + default: + LogW("Wrong command %d", boxCommandPtr->getType()); + } + } + + This->m_boxAsyncCommandList.pop_front(); + + int commandListNumber = This->m_boxAsyncCommandList.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); + return ECORE_CALLBACK_CANCEL; + } + + if (commandListNumber > 0) { + LogD("m_boxAsyncCommandList.size() = %d", commandListNumber); + return ECORE_CALLBACK_RENEW; + } + + This->m_boxLoadBalanceTimer = NULL; + return ECORE_CALLBACK_CANCEL; +} + +void BoxLoadBalancer::eraseBoxAsyncCommandFromQueue(IBoxPtr boxPtr) +{ + if (m_boxAsyncCommandList.empty()) + return; + auto it = m_boxAsyncCommandList.begin(); + while( it != m_boxAsyncCommandList.end() ){ + BoxAsyncCommandInfoPtr boxCommandPtr = *it; + if ( boxCommandPtr->getBoxPtr() == boxPtr) { + auto deleteIt = it++; + m_boxAsyncCommandList.erase(deleteIt); + LogD("m_boxAsyncCommandList.erase"); + }else + ++it; + } +} + +void BoxLoadBalancer::pushBoxAsyncCommandIntoQueue(request_box_cmd_type cmdType, IBoxPtr boxPtr, BoxInfoPtr boxInfoPtr) +{ + BoxAsyncCommandInfoPtr boxAsyncInfo = BoxAsyncCommandInfoPtr(new BoxAsyncCommandInfo(cmdType, boxPtr, boxInfoPtr)); + + m_boxAsyncCommandList.push_back(boxAsyncInfo); + LogD("m_boxAsyncCommandList added = %d ",m_boxAsyncCommandList.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_boxAsyncCommandList.push_back(boxAsyncInfo); + LogD("m_boxAsyncCommandList added = %d ",m_boxAsyncCommandList.size()); + + if (!m_boxLoadBalanceTimer) { + // start timer for clearing existing snapshot in case of only gbar open + m_boxLoadBalanceTimer = ecore_timer_add(BOX_UPDATE_TIME, requestBoxLoadBalanceCallback, this); + m_updateTimeCount = BOX_UPDATE_TIME; + LogD("timer launched"); + } +} + +void BoxLoadBalancer::pushBoxAsyncCommandIntoTop(request_box_cmd_type cmdType, IBoxPtr boxPtr, BoxInfoPtr boxInfoPtr) +{ + BoxAsyncCommandInfoPtr boxAsyncInfo = BoxAsyncCommandInfoPtr(new BoxAsyncCommandInfo(cmdType, boxPtr, boxInfoPtr)); + m_boxAsyncCommandList.push_front(boxAsyncInfo); + LogD("m_boxAsyncCommandList added = %d ",m_boxAsyncCommandList.size()); + + if (!m_boxLoadBalanceTimer) { + // start timer for clearing existing snapshot in case of only gbar 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_boxAsyncCommandList.clear(); +} diff --git a/src/Core/BoxLoadBalancer.h b/src/Core/BoxLoadBalancer.h new file mode 100755 index 0000000..1881f39 --- /dev/null +++ b/src/Core/BoxLoadBalancer.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 BoxLoadBalancer.h + * @author Minhyung Ko (minhyung.ko@samsung.com) + */ +#ifndef BOX_LOAD_BALANCER_H +#define BOX_LOAD_BALANCER_H + +#include +#include +#include +#include +#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 +{ +private: + BoxAsyncCommandInfo() {}; +public: + 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 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::list m_boxAsyncCommandList; + float m_updateTimeCount; +}; +#endif // BOX_LOAD_BALANCER_H diff --git a/src/Core/BoxManager.cpp b/src/Core/BoxManager.cpp new file mode 100755 index 0000000..f36f0c6 --- /dev/null +++ b/src/Core/BoxManager.cpp @@ -0,0 +1,493 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include "Util/Log.h" +#include "Util/Util.h" +#include "IBox.h" +#include "Box.h" +#include "BoxData.h" + +namespace{ + static const std::string kDefaultBoxType("app"); +} + +BoxManager::BoxManager(IBoxPluginFactoryPtr factory) + : m_boxFactory(factory) + , m_boxLoadBalancer() +{ + LogD("enter"); +} + +BoxManager::~BoxManager() +{ + LogD("enter"); + + vconf_ignore_key_changed(VCONFKEY_NETWORK_PROXY,proxyChangedCallback); +} + +bool BoxManager::doCommand(const request_cmd_type type, const BoxInfoPtr& boxInfo) +{ + if( boxInfo == NULL ) + return false; + + 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()) { + result = requestRemoveBoxByInstanceId(boxInfo); + break; + } + if (!boxInfo->boxId.empty()) { + result = requestRemoveBoxByBoxId(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_GBAR: + result = requestOpenGbar(boxInfo->instanceId, + boxInfo->gbarWidth, boxInfo->gbarHeight, + boxInfo->gbarX, boxInfo->gbarY); + break; + case REQUEST_CMD_CLOSE_GBAR: + result = requestCloseGbar(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(); + break; + default: + LogD("not available request type"); + break; + } + + return result; +} + +bool BoxManager::requestAddBox(BoxInfoPtr boxInfo, EwkContextPtr ewkContext) +{ + LogD("enter"); + + if( boxInfo == NULL ){ + LogE("boxInfo is NULL"); + return false; + } + + 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; + } + m_boxMap.erase(instanceId); + + if (!box->hide()) { + return false; + } + return true; +} + +bool BoxManager::requestRemoveBoxByInstanceId(BoxInfoPtr boxInfo) +{ + LogD("enter"); + if( boxInfo == NULL ){ + LogE("boxInfo is NULL"); + return false; + } + + IBoxPtr box = searchBoxMap(boxInfo->instanceId); + if(box == NULL){ + LogE("Can't find box %s", boxInfo->instanceId.c_str()); + return false; + } + + m_boxLoadBalancer.eraseBoxAsyncCommandFromQueue(box); + requestRemoveBox(boxInfo->instanceId); + updateEwkContext(boxInfo->boxId); + return true; +} + +bool BoxManager::requestRemoveBoxByBoxId(BoxInfoPtr boxInfo) +{ + LogD("enter"); + if( boxInfo == NULL ){ + LogE("boxInfo is NULL"); + return false; + } + + bool found = false; + for (auto it = m_boxMap.begin(); it != m_boxMap.end(); ) { + if (it->first.find(boxInfo->boxId) == std::string::npos) { + ++it; + continue; + } + auto to_deleted = it++; + if( to_deleted->second && to_deleted->second->getBoxInfo() ) + requestRemoveBoxByInstanceId(to_deleted->second->getBoxInfo()); + found = true; + } + + return found; +} + +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::requestOpenGbar( + std::string& instanceId, + int width, int height, int x, int y) +{ + LogD("enter"); + IBoxPtr box = searchBoxMap(instanceId); + if (!box) { + return false; + } + + m_boxLoadBalancer.eraseBoxAsyncCommandFromQueue(box); + + return box->openGbar(width, height, x, y); +} + +bool BoxManager::requestCloseGbar(std::string& instanceId) +{ + LogD("enter"); + IBoxPtr box = searchBoxMap(instanceId); + if (!box) { + return false; + } + + return box->closeGbar(); +} + +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"); + + for (auto it = m_boxMap.begin(); it != m_boxMap.end(); ++it) { + if (it->first.find(boxId) == std::string::npos) { + continue; + } + IBoxPtr 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); + + m_boxLoadBalancer.stopLoadBalancer(); + + for (auto it = m_boxMap.begin(); it != m_boxMap.end(); ++it) { + if (it->second) { + IBoxPtr box = it->second; + box->setNeedToUpdate(); + + // I'll remove below if statement, + // because in box::update method, if box was pause state, actually does not execute update process, + // just mark to m_updateNeeded, so, later if box was resume, this box will updated. + //if (!box->isPaused()) + m_boxLoadBalancer.pushBoxAsyncCommandIntoQueue(BOX_AYNC_REQUEST_CMD_UPDATE, box, box->getBoxInfo()->appContentInfo); + } + } + return true; +} + +bool BoxManager::requestUpdateAppBox() +{ + LogD("enter"); + + for (auto it = m_boxMap.begin(); it != m_boxMap.end(); ++it) { + if (it->second) { + IBoxPtr box = it->second; + + if(box->getBoxInfo()->boxType.find(kDefaultBoxType) == std::string::npos) { + continue; + } + m_boxLoadBalancer.eraseBoxAsyncCommandFromQueue(box); + box->setNeedToUpdate(); + + // I'll remove below if statement, + // because in box::update method, if box was pause state, actually does not execute update process, + // just mark to m_updateNeeded, so, later if box was resume, this box will updated. + //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; + 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::proxyChangedCallback(keynode_t* /*keynode*/, void* data){ + LogD("enter"); + BoxManager *This = static_cast(data); + + // proxy server setting + char *proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY); + LogD("proxy address changed %s", proxy); + std::string dummyProxy("0.0.0.0"); + if (proxy && strlen(proxy) && (dummyProxy != proxy)) { + free(proxy); + proxy = NULL; + } + if( This->m_defaultContext.get() != NULL ) + ewk_context_proxy_uri_set(This->m_defaultContext.get(), proxy); + free(proxy); +} + +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); + } + vconf_notify_key_changed(VCONFKEY_NETWORK_PROXY,proxyChangedCallback,this); + + 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/Core/BoxManager.h b/src/Core/BoxManager.h new file mode 100755 index 0000000..1469a20 --- /dev/null +++ b/src/Core/BoxManager.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 BoxManager.h + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ +#ifndef BOX_MANAGER_H +#define BOX_MANAGER_H + +#include +#include +#include +#include +#include +#include +#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 requestOpenGbar( + std::string& instanceId, + int width, int height, int x, int y); + virtual bool requestCloseGbar(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(); + + 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(); + static void proxyChangedCallback(keynode_t* keynode, void* data); + + + typedef std::map BoxMap; + typedef std::pair BoxMapPair; + BoxMap m_boxMap; + IBoxPluginFactoryPtr m_boxFactory; + EwkContextPtr m_defaultContext; + + BoxLoadBalancer m_boxLoadBalancer; +}; + +#endif // BOX_MANAGER_H diff --git a/src/Core/BoxState.cpp b/src/Core/BoxState.cpp new file mode 100644 index 0000000..958f979 --- /dev/null +++ b/src/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::permitOpenGbar() +{ + return IBoxStatePtr(BoxOpenGbarState::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); +} + +// BoxOpenGbarState +IBoxStatePtr BoxOpenGbarState::permitCloseGbar() +{ + return IBoxStatePtr(BoxCloseGbarState::create(getContext())); +} + +// BoxCloseGbarState +IBoxStatePtr BoxCloseGbarState::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/Core/BoxState.h b/src/Core/BoxState.h new file mode 100644 index 0000000..e500d9b --- /dev/null +++ b/src/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 permitOpenGbar() { throw this; }; + virtual IBoxStatePtr permitCloseGbar() { 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 permitOpenGbar(); + 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 BoxOpenGbarState: public BoxState { + public: + static IBoxStatePtr create(IBoxContextPtr context) + { + return IBoxStatePtr(new BoxOpenGbarState(context)); + }; + virtual IBoxStatePtr permitCloseGbar(); + virtual ~BoxOpenGbarState() {}; + + private: + explicit BoxOpenGbarState(IBoxContextPtr context) : BoxState(context) {}; +}; + +class BoxCloseGbarState: public BoxState { + public: + static IBoxStatePtr create(IBoxContextPtr context) + { + return IBoxStatePtr(new BoxCloseGbarState(context)); + }; + virtual IBoxStatePtr permitShow(); + virtual ~BoxCloseGbarState() {}; + + private: + explicit BoxCloseGbarState(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/Core/BoxUpdateTimer.cpp b/src/Core/BoxUpdateTimer.cpp new file mode 100644 index 0000000..26f98db --- /dev/null +++ b/src/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 +#include +#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; + start(); +} diff --git a/src/Core/BoxUpdateTimer.h b/src/Core/BoxUpdateTimer.h new file mode 100644 index 0000000..1238cc0 --- /dev/null +++ b/src/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 +#include +#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/Core/Buffer/BoxRenderBuffer.cpp b/src/Core/Buffer/BoxRenderBuffer.cpp new file mode 100755 index 0000000..f13d10d --- /dev/null +++ b/src/Core/Buffer/BoxRenderBuffer.cpp @@ -0,0 +1,193 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include "RenderBuffer.h" +#include "BoxRenderBuffer.h" + +BoxRenderBuffer::BoxRenderBuffer(BoxInfoPtr boxInfo, TouchViewCallback touchCallback) + : m_boxId(boxInfo->boxId) + , m_instanceId(boxInfo->instanceId) + , m_contentInfo(boxInfo->contentInfo) + , m_width(boxInfo->boxWidth) + , m_height(boxInfo->boxHeight) + , m_touchCallback(touchCallback) +{ +} + +BoxRenderBuffer::~BoxRenderBuffer() +{ +} + +BufferInfoPtr BoxRenderBuffer::acquireBuffer() +{ + LogD("enter"); + + bool touchable = true; + char* type = web_provider_widget_get_box_type(m_boxId.c_str()); + const char* defaultType = web_provider_widget_get_default_type(); + if (type) { + touchable = web_provider_widget_get_mouse_event(m_boxId.c_str()) || + strcmp(type, defaultType); + } + + std::free(type); + + BufferInfoPtr bufferInfo = + widget_provider_buffer_create( + WIDGET_TYPE_WIDGET, + m_boxId.c_str(), + m_instanceId.c_str(), + 1, + touchable ? handleTouchEventCallback : NULL, + this); + + if( bufferInfo == NULL ) + return NULL; + + if (widget_provider_buffer_acquire( + bufferInfo, + m_width, + m_height, + sizeof(int))) { + widget_provider_buffer_destroy(bufferInfo); + bufferInfo = NULL; + } + + return bufferInfo; +} + +void BoxRenderBuffer::updateBuffer() +{ + widget_damage_region_s region; + region.x = 0; + region.y = 0; + region.w = m_width; + region.h = m_height; + + widget_provider_send_updated( + m_boxId.c_str(), + m_instanceId.c_str(), + WIDGET_PRIMARY_BUFFER, + ®ion, + 0, + NULL); +} + +int BoxRenderBuffer::handleTouchEventCallback( + BufferInfoPtr bufferInfo, + struct widget_buffer_event_data *evt, + void* data) +{ + LogD("enter"); + UNUSED_PARAM(bufferInfo); + + BoxRenderBuffer* This = static_cast(data); + if( This == NULL ) + return 0; + + char* boxType = web_provider_widget_get_box_type(This->m_boxId.c_str()); + TouchType type; + switch (evt->type) { + case WIDGET_BUFFER_EVENT_MOVE: + type = TOUCH_EVENT_MOVE; + break; + case WIDGET_BUFFER_EVENT_DOWN: + type = TOUCH_EVENT_DOWN; + break; + case WIDGET_BUFFER_EVENT_UP: + type = TOUCH_EVENT_UP; + break; + case WIDGET_BUFFER_EVENT_ON_HOLD: + type = TOUCH_EVENT_ON_HOLD; + break; + default: + type = TOUCH_EVENT_UNRECOGNIZED; + break; + } + + if (type == TOUCH_EVENT_UNRECOGNIZED) { + std::free(boxType); + return -1; + } + + if(boxType) { + This->didHandleTouchEvent(type, evt->timestamp, evt->info.pointer.x, evt->info.pointer.y); + } + + // call touch callback of renderView + This->m_touchCallback(evt->info.pointer.x, evt->info.pointer.y); + + std::free(boxType); + + return 0; +} + +void BoxRenderBuffer::didHandleTouchEvent( + TouchType type, double timestamp, int x, int y) +{ + UNUSED_PARAM(timestamp); + unsigned int flags; + + // 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, y, ecore_time_get() * 1000, NULL); + break; + case TOUCH_EVENT_DOWN: + LogD("down event"); + flags = evas_event_default_flags_get(getCanvas()); + flags &= ~EVAS_EVENT_FLAG_ON_SCROLL; + flags &= ~EVAS_EVENT_FLAG_ON_HOLD; + evas_event_default_flags_set(getCanvas(), (Evas_Event_Flags)flags); + + evas_event_feed_mouse_move( + getCanvas(), x, y, 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; + case TOUCH_EVENT_ON_HOLD: + LogD("onhold event"); + flags = (unsigned int)evas_event_default_flags_get(getCanvas()); + flags |= (unsigned int)EVAS_EVENT_FLAG_ON_HOLD; + evas_event_default_flags_set(getCanvas(), (Evas_Event_Flags)flags); + break; + default: + LogD("wrong event"); + break; + } +} diff --git a/src/Core/Buffer/BoxRenderBuffer.h b/src/Core/Buffer/BoxRenderBuffer.h new file mode 100644 index 0000000..f69cf07 --- /dev/null +++ b/src/Core/Buffer/BoxRenderBuffer.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 BoxRenderBuffer.h + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ +#ifndef BOX_RENDER_BUFFER_H +#define BOX_RENDER_BUFFER_H + +#include +#include +#include +#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, + TOUCH_EVENT_ON_HOLD + }; + + 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, int x, int 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, + struct widget_buffer_event_data *evt, + 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/Core/Buffer/CMakeLists.txt b/src/Core/Buffer/CMakeLists.txt new file mode 100644 index 0000000..c12825e --- /dev/null +++ b/src/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 + widget_provider + widget_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}/GbarRenderBuffer.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/Core/Buffer/GbarRenderBuffer.cpp b/src/Core/Buffer/GbarRenderBuffer.cpp new file mode 100755 index 0000000..8198ed2 --- /dev/null +++ b/src/Core/Buffer/GbarRenderBuffer.cpp @@ -0,0 +1,279 @@ +/* + * 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 GbarRenderBuffer.cpp + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ + +#include "GbarRenderBuffer.h" + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "RenderBuffer.h" + +GbarRenderBuffer::GbarRenderBuffer(BoxInfoPtr boxInfo, TouchViewCallback touchCallback) + : m_boxId(boxInfo->boxId) + , m_instanceId(boxInfo->instanceId) + , m_width(boxInfo->gbarWidth) + , m_height(boxInfo->gbarHeight) + , m_touchCallback(touchCallback) + , m_accessibiilty(false) +{ +} + +GbarRenderBuffer::~GbarRenderBuffer() +{ +} + +BufferInfoPtr GbarRenderBuffer::acquireBuffer() +{ + BufferInfoPtr bufferInfo = + widget_provider_buffer_create( + WIDGET_TYPE_GBAR, + m_boxId.c_str(), + m_instanceId.c_str(), + 1, + handleTouchEventCallback, + this); + + if( bufferInfo == NULL ) + return NULL; + + if (widget_provider_buffer_acquire( + bufferInfo, + m_width, + m_height, + sizeof(int))){ + widget_provider_buffer_destroy(bufferInfo); + bufferInfo = NULL; + } + + m_accessibiilty = false; + return bufferInfo; +} + +void GbarRenderBuffer::updateBuffer() +{ + LogD("enter"); + //TODO: check proper signature and arguments + /* + widget_provider_send_desc_updated( + m_boxId.c_str(), + m_instanceId.c_str(), + NULL); + */ +} + +int GbarRenderBuffer::handleTouchEventCallback( + BufferInfoPtr bufferInfo, + struct widget_buffer_event_data *evt, + void* data) +{ + LogD("enter"); + UNUSED_PARAM(bufferInfo); + + GbarRenderBuffer* This = static_cast(data); + + if( This == NULL ) + return 0; + + TouchType type; + +#if !ENABLE(WEBKIT_UPVERSION) + + Elm_Access_Action_Info ActionInfo; + + switch (evt->type) { + case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT: + case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_NEXT: + case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_PREV: + case WIDGET_BUFFER_EVENT_ACCESS_ACTIVATE: + case WIDGET_BUFFER_EVENT_ACCESS_ACTION_UP: + case WIDGET_BUFFER_EVENT_ACCESS_ACTION_DOWN: + case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_UP: + case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_MOVE: + case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_DOWN: + case WIDGET_BUFFER_EVENT_ACCESS_UNHIGHLIGHT: + { + LogD("handleTouchEventCallback event %d x,y %f,%f", evt->type, evt->info.pointer.x, evt->info.pointer.y); + 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 (evt->type) { + case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT: + { + ActionInfo.action_type = ELM_ACCESS_ACTION_HIGHLIGHT; + ActionInfo.action_by = ELM_ACCESS_ACTION_HIGHLIGHT; + if (pSmartData->api->screen_reader_action_execute(pSmartData, &ActionInfo)) { + widget_provider_send_access_status(This->m_boxId.c_str(), This->m_instanceId.c_str(), WIDGET_ACCESS_STATUS_DONE); + } else { + widget_provider_send_access_status(This->m_boxId.c_str(), This->m_instanceId.c_str(), WIDGET_ACCESS_STATUS_DONE); + } + ActionInfo.action_type = ELM_ACCESS_ACTION_READ; + break; + } + case WIDGET_BUFFER_EVENT_ACCESS_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)) { + widget_provider_send_access_status(This->m_boxId.c_str(), This->m_instanceId.c_str(), WIDGET_ACCESS_STATUS_DONE); + } else { + widget_provider_send_access_status(This->m_boxId.c_str(), This->m_instanceId.c_str(), WIDGET_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 WIDGET_BUFFER_EVENT_ACCESS_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)) { + widget_provider_send_access_status(This->m_boxId.c_str(), This->m_instanceId.c_str(), WIDGET_ACCESS_STATUS_DONE); + } else { + widget_provider_send_access_status(This->m_boxId.c_str(), This->m_instanceId.c_str(), WIDGET_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 WIDGET_BUFFER_EVENT_ACCESS_ACTIVATE: + ActionInfo.action_type = ELM_ACCESS_ACTION_ACTIVATE; + break; + case WIDGET_BUFFER_EVENT_ACCESS_UNHIGHLIGHT: + ActionInfo.action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT; + break; + case WIDGET_BUFFER_EVENT_ACCESS_ACTION_UP: + case WIDGET_BUFFER_EVENT_ACCESS_ACTION_DOWN: + case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_UP: + case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_MOVE: + case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_DOWN: + default: + break; + } + int xWebview,yWebview,w,h; + evas_object_geometry_get(This->getWebView(), &xWebview, &yWebview, &w, &h); + + ActionInfo.x = xWebview + static_cast(w*evt->info.pointer.x); + ActionInfo.y = yWebview + static_cast(h*evt->info.pointer.y); + + if (pSmartData->api->screen_reader_action_execute(pSmartData, &ActionInfo)) { + widget_provider_send_access_status(This->m_boxId.c_str(), This->m_instanceId.c_str(), WIDGET_ACCESS_STATUS_DONE); + } else { + widget_provider_send_access_status(This->m_boxId.c_str(), This->m_instanceId.c_str(), WIDGET_ACCESS_STATUS_LAST); + This->m_accessibiilty = false; + } + } + return 0; + default: + break; + } +#endif // WEBKIT_UPVERSION + + switch (evt->type) { + case WIDGET_BUFFER_EVENT_MOVE: + type = TOUCH_EVENT_MOVE; + break; + case WIDGET_BUFFER_EVENT_DOWN: + type = TOUCH_EVENT_DOWN; + break; + case WIDGET_BUFFER_EVENT_UP: + type = TOUCH_EVENT_UP; + break; + case WIDGET_BUFFER_EVENT_ON_HOLD: + type = TOUCH_EVENT_ON_HOLD; + break; + default: + type = TOUCH_EVENT_UNRECOGNIZED; + break; + } + + if (type == TOUCH_EVENT_UNRECOGNIZED) { + return -1; + } + + This->didHandleTouchEvent(type, evt->timestamp, evt->info.pointer.x, evt->info.pointer.y); + + // call touch callback of renderView + This->m_touchCallback(evt->info.pointer.x, evt->info.pointer.y); + + return 0; +} + +void GbarRenderBuffer::didHandleTouchEvent( + TouchType type, double timestamp, int x, int y) +{ + UNUSED_PARAM(timestamp); + unsigned int flags; + + // 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, y, ecore_time_get() * 1000, NULL); + break; + case TOUCH_EVENT_DOWN: + LogD("down event"); + flags = evas_event_default_flags_get(getCanvas()); + flags &= ~EVAS_EVENT_FLAG_ON_SCROLL; + flags &= ~EVAS_EVENT_FLAG_ON_HOLD; + evas_event_default_flags_set(getCanvas(), (Evas_Event_Flags)flags); + + evas_event_feed_mouse_move( + getCanvas(), x, y, 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; + case TOUCH_EVENT_ON_HOLD: + LogD("onhold event"); + flags = (unsigned int)evas_event_default_flags_get(getCanvas()); + flags |= (unsigned int)EVAS_EVENT_FLAG_ON_HOLD; + evas_event_default_flags_set(getCanvas(), (Evas_Event_Flags)flags); + break; + default: + LogD("wrong event"); + break; + } +} \ No newline at end of file diff --git a/src/Core/Buffer/GbarRenderBuffer.h b/src/Core/Buffer/GbarRenderBuffer.h new file mode 100755 index 0000000..fbc546f --- /dev/null +++ b/src/Core/Buffer/GbarRenderBuffer.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 GbarRenderBuffer.h + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ +#ifndef GBAR_RENDER_BUFFER_H +#define GBAR_RENDER_BUFFER_H + +#include +#include +#include +#include "IRenderBuffer.h" +#include "RenderBuffer.h" + +#define EXPORT_CLASS __attribute__ ((visibility("default"))) + +class EXPORT_CLASS GbarRenderBuffer: public RenderBuffer { + public: + enum TouchType { + TOUCH_EVENT_UNRECOGNIZED = -1, + TOUCH_EVENT_MOVE = 0, + TOUCH_EVENT_DOWN, + TOUCH_EVENT_UP, + TOUCH_EVENT_ON_HOLD + }; + + static IRenderBufferPtr create(BoxInfoPtr boxInfo, TouchViewCallback touchCallback) + { + return IRenderBufferPtr(new GbarRenderBuffer(boxInfo, touchCallback)); + }; + ~GbarRenderBuffer(); + + protected: + // this function may be overriden by derived class + virtual void didHandleTouchEvent( + TouchType type, double timestamp, int x, int y); + explicit GbarRenderBuffer(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, + struct widget_buffer_event_data *evt, + void* data); + + // members + std::string m_boxId; + std::string m_instanceId; + int m_width; + int m_height; + TouchViewCallback m_touchCallback; + bool m_accessibiilty; +}; + +#endif // GBAR_RENDER_BUFFER_H \ No newline at end of file diff --git a/src/Core/Buffer/IRenderBuffer.h b/src/Core/Buffer/IRenderBuffer.h new file mode 100644 index 0000000..ac28817 --- /dev/null +++ b/src/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 +#include +#include + +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 IRenderBufferPtr; + +#endif diff --git a/src/Core/Buffer/RenderBuffer.cpp b/src/Core/Buffer/RenderBuffer.cpp new file mode 100755 index 0000000..acc2ee1 --- /dev/null +++ b/src/Core/Buffer/RenderBuffer.cpp @@ -0,0 +1,436 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#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"); + free(); +} + +bool RenderBuffer::allocate(bool hwEnable) +{ + bool ret = false; + + LogD("enter"); + + m_hwEnable = hwEnable; + + if (m_bufferAddr) { + free(); + m_bufferAddr = NULL; + } + + if (hwEnable) { + ret = bufferAllocationForGLRendering(); + } else + ret = bufferAllocationForSWRendering(); + + if(ret) { + startCanvasUpdate(); + } + + return ret; +} + +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) +{ + LogD("enter"); + UNUSED_PARAM(eventInfo); + + RenderBuffer *buffer = static_cast(data); + + if ((buffer->m_hwEnable == true)) { + return; + } + + widget_provider_buffer_pre_render(buffer->m_bufferInfo); + //No need to re-draw after comment out evas_data_argb_unpremul function. + //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(data); + + if (buffer->m_hwEnable == true) { + buffer->updateBuffer(); + } else { + //To resolve font jaggies issue, comment out below line + //evas_data_argb_unpremul(static_cast(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); + } + LogD("/tmp/render-%dx%d.raw", buffer->getWidth(), buffer->getHeight()); + } +#endif + + if (!widget_provider_buffer_is_support_hw(buffer->m_bufferInfo)) { + widget_provider_buffer_sync(buffer->m_bufferInfo); + buffer->updateBuffer(); + } else { + widget_provider_buffer_post_render(buffer->m_bufferInfo); + buffer->updateBuffer(); + } + } +} + +void RenderBuffer::paintColor(unsigned int color) +{ + LogD("enter"); + + if (!widget_provider_buffer_is_support_hw(m_bufferInfo)) { + memset(m_bufferAddr, color, getWidth() * getHeight() * 4); + widget_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(data); + + if (buffer->m_bufferInfo) { + freeCallback(data, NULL); + } + + buffer->m_bufferInfo = buffer->acquireBuffer(); + if (!buffer->m_bufferInfo) { + return NULL; + } + + // set buffer address + if (!widget_provider_buffer_is_support_hw(buffer->m_bufferInfo)) { + LogD("s/w evas backend"); + buffer->m_bufferAddr = widget_provider_buffer_ref(buffer->m_bufferInfo); + } else { + LogD("h/w evas backend"); + int ret = widget_provider_buffer_create_hw(buffer->m_bufferInfo); + if (ret < 0) { + LogD("can't create hw pixmap"); + } + buffer->m_bufferAddr = widget_provider_buffer_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(data); + + // destroy buffer + if (!widget_provider_buffer_is_support_hw(buffer->m_bufferInfo)) { + widget_provider_buffer_unref(buffer->m_bufferAddr); + } else { + widget_provider_buffer_destroy_hw(buffer->m_bufferInfo); + } + + widget_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(tmpBuffer), + getWidth() * getHeight()); + evas_object_image_data_set(snapshot, tmpBuffer); + } else { + LogD("Failed to allocate buffer"); + } + + 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 false; + } + + if (!widget_provider_buffer_is_support_hw(m_bufferInfo)) { + LogD("s/w evas backend"); + m_bufferAddr = widget_provider_buffer_ref(m_bufferInfo); + } else { + LogD("h/w evas backend"); + int ret = widget_provider_buffer_create_hw(m_bufferInfo); + if (ret < 0) { + LogD("can't create hw pixmap"); + } + + m_bufferAddr = (void *)widget_provider_buffer_id(m_bufferInfo); + LogD("evas ecore widget_provider_buffer_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. + widget_provider_buffer_pre_render(m_bufferInfo); + ecore_evas_alpha_set(ee, EINA_TRUE); + widget_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); + + widget_provider_buffer_release(m_bufferInfo); + + m_bufferInfo = acquireBuffer(); + if (!m_bufferInfo) { + return; + } + + // set buffer address + if (!widget_provider_buffer_is_support_hw(m_bufferInfo)) { + LogD("s/w evas backend"); + m_bufferAddr = widget_provider_buffer_ref(m_bufferInfo); + } else { + LogD("h/w evas backend"); + int ret = widget_provider_buffer_create_hw(m_bufferInfo); + if (ret < 0) { + LogD("can't create hw pixmap"); + } + m_bufferAddr = (void *)widget_provider_buffer_id(m_bufferInfo); + LogD("evas ecore widget_provider_buffer_id m_bufferAddr %lu", (unsigned long)m_bufferAddr); + } +} + diff --git a/src/Core/Buffer/RenderBuffer.h b/src/Core/Buffer/RenderBuffer.h new file mode 100644 index 0000000..5f0a452 --- /dev/null +++ b/src/Core/Buffer/RenderBuffer.h @@ -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 RenderBuffer.h + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ +#ifndef RENDER_BUFFER_H +#define RENDER_BUFFER_H + +#include +#include +#include +#include "IRenderBuffer.h" + +// forward declaration +struct widget_buffer; + +// type definition +typedef struct widget_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/Core/CMakeLists.txt b/src/Core/CMakeLists.txt new file mode 100644 index 0000000..8846d76 --- /dev/null +++ b/src/Core/CMakeLists.txt @@ -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. +# +# @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 + ecore-evas + 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/Core/IBox.h b/src/Core/IBox.h new file mode 100644 index 0000000..0220bd7 --- /dev/null +++ b/src/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 +#include +#include +#include +#include + +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 openGbar(int width, int height, int x, int y) = 0; + virtual bool closeGbar() = 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 IBoxPtr; +typedef std::shared_ptr EwkContextPtr; + +#endif //I_BOX_H diff --git a/src/Core/IBoxContext.h b/src/Core/IBoxContext.h new file mode 100644 index 0000000..8dfa2a7 --- /dev/null +++ b/src/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 IBoxContextPtr; + +#endif // I_BOX_CONTEXT diff --git a/src/Core/IBoxManager.h b/src/Core/IBoxManager.h new file mode 100644 index 0000000..d441ed1 --- /dev/null +++ b/src/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 +#include +#include +#include "BoxData.h" + +class IBoxManager: Noncopyable { + public: + virtual bool doCommand(const request_cmd_type, const BoxInfoPtr&) = 0; + virtual ~IBoxManager() {}; +}; + +typedef std::shared_ptr IBoxManagerPtr; + +#endif // I_BOX_MANAGER_H diff --git a/src/Core/IBoxState.h b/src/Core/IBoxState.h new file mode 100644 index 0000000..fa632d8 --- /dev/null +++ b/src/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 + +class IBoxState; +typedef std::shared_ptr IBoxStatePtr; + +class IBoxState { + public: + virtual IBoxStatePtr permitShow() = 0; + virtual IBoxStatePtr permitHide() = 0; + virtual IBoxStatePtr permitResume() = 0; + virtual IBoxStatePtr permitPause() = 0; + virtual IBoxStatePtr permitOpenGbar() = 0; + virtual IBoxStatePtr permitCloseGbar() = 0; + virtual IBoxStatePtr permitShutdown() = 0; + virtual void switchState() = 0; + virtual ~IBoxState() {}; +}; + +#endif // I_BOX_STATE diff --git a/src/Core/Platform.h b/src/Core/Platform.h new file mode 100644 index 0000000..c7e5077 --- /dev/null +++ b/src/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 : +// +// Author : () - +// #define USE__ (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 : +// +// Author : () - +// #define ENABLE_ (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/Core/Util/CMakeLists.txt b/src/Core/Util/CMakeLists.txt new file mode 100644 index 0000000..11e14dc --- /dev/null +++ b/src/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/Core/Util/ITimer.h b/src/Core/Util/ITimer.h new file mode 100644 index 0000000..2db0dae --- /dev/null +++ b/src/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 + +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 ITimerPtr; + +#endif // I_TIMER_H diff --git a/src/Core/Util/Log.cpp b/src/Core/Util/Log.cpp new file mode 100644 index 0000000..34712ac --- /dev/null +++ b/src/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/Core/Util/Log.h b/src/Core/Util/Log.h new file mode 100644 index 0000000..ff649f7 --- /dev/null +++ b/src/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 +#include + +#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/Core/Util/Noncopyable.h b/src/Core/Util/Noncopyable.h new file mode 100644 index 0000000..accdd53 --- /dev/null +++ b/src/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/Core/Util/Util.h b/src/Core/Util/Util.h new file mode 100644 index 0000000..b2c310d --- /dev/null +++ b/src/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/Core/View/CMakeLists.txt b/src/Core/View/CMakeLists.txt new file mode 100644 index 0000000..8df7cce --- /dev/null +++ b/src/Core/View/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_VIEW}) +SET(TARGET_CORE_SERVICE web-provider-core-service) +SET(DEPS ${TARGET_NAME}_DEPS) + +PKG_CHECK_MODULES(${DEPS} + evas + eina + ewebkit2 + dlog + widget_provider # this should be removed! + REQUIRED +) +ADD_DEFINITIONS(${${DEPS}_CFLAGS}) + +SET(SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/GbarHelper.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(IGbarHelper.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME}) +INSTALL_FILE(GbarHelper.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/Core/View/GbarHelper.cpp b/src/Core/View/GbarHelper.cpp new file mode 100755 index 0000000..a0643eb --- /dev/null +++ b/src/Core/View/GbarHelper.cpp @@ -0,0 +1,146 @@ +/* + * 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 GbarHelper.cpp + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ +#include +#include +#include +#include +#include +#include "IRenderView.h" +#include "IGbarHelper.h" +#include "GbarHelper.h" + +GbarHelper::GbarHelper(RenderInfoPtr gbarRenderInfo, std::string gbarStartUrl) + : m_boxWebView() + , m_gbarWebView() + , m_gbarRenderInfo(gbarRenderInfo) + , m_startUrl(gbarStartUrl) + , m_opened(false) +{ +} + +GbarHelper::~GbarHelper() +{ +} + +void GbarHelper::startOpen() +{ + LogD("enter"); + if (!m_boxWebView) { + return; + } + + //make javascript string for gbar + std::string script = "var gbarWindow = window.open(\""; + script += validateUrl(m_startUrl); + script += "\", \"_blank\");"; + + // execute javascript for opening new webview for gbar + LogD("executed script: %s", script.c_str()); + ewk_view_script_execute( + m_boxWebView, script.c_str(), executeScriptCallback, this); +} + +void GbarHelper::finishOpen(Evas_Object* child) +{ + LogD("enter"); + + // gbar webview set and resize + m_gbarWebView = child; + evas_object_resize(m_gbarWebView, m_gbarRenderInfo->width, m_gbarRenderInfo->height); + m_opened = true; +} + +void GbarHelper::close() +{ + LogD("enter"); +} + +void GbarHelper::setBoxWebView(Evas_Object* webview) +{ + LogD("enter"); + m_boxWebView = webview; +} + +void GbarHelper::setGbarWebView(Evas_Object* webview) +{ + LogD("enter"); + m_gbarWebView = webview; +} + +Evas_Object* GbarHelper::getBoxWebView() const +{ + LogD("enter"); + return m_boxWebView; +} + +Evas_Object* GbarHelper::getGbarWebView() const +{ + LogD("enter"); + return m_gbarWebView; +} + +Evas* GbarHelper::getGbarCanvas() const +{ + LogD("enter"); + return evas_object_evas_get(m_gbarRenderInfo->window); +} + +bool GbarHelper::isGbarOpened() const +{ + LogD("enter"); + return m_opened; +} + +void GbarHelper::didExecuteScript(Evas_Object* webview, std::string& result) +{ + LogD("enter"); + UNUSED_PARAM(webview); + LogD("javascript execution result: %s", result.c_str()); +} + +std::string GbarHelper::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 GbarHelper::executeScriptCallback( + Evas_Object* webview, const char* result, void* data) +{ + LogD("enter"); + + GbarHelper* This = static_cast(data); + std::string resultStr(result ? result : "null"); + This->didExecuteScript(webview, resultStr); +} \ No newline at end of file diff --git a/src/Core/View/GbarHelper.h b/src/Core/View/GbarHelper.h new file mode 100755 index 0000000..0ef81a1 --- /dev/null +++ b/src/Core/View/GbarHelper.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 GbarHelper.h + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ + +#ifndef PD_HELPER_H +#define PD_HELPER_H + +#include +#include +#include "RenderView.h" +#include "IGbarHelper.h" + +#define EXPORT_CLASS __attribute__ ((visibility("default"))) + +class EXPORT_CLASS GbarHelper: public IGbarHelper { + public: + static IGbarHelperPtr create( + RenderInfoPtr gbarRenderInfo, + std::string gbarStartUrl) + { + return IGbarHelperPtr(new GbarHelper(gbarRenderInfo, gbarStartUrl)); + } + virtual void startOpen(); + virtual void finishOpen(Evas_Object* child); + virtual void close(); + virtual void setBoxWebView(Evas_Object* webview); + virtual void setGbarWebView(Evas_Object* webview); + virtual Evas_Object* getBoxWebView() const; + virtual Evas_Object* getGbarWebView() const; + virtual Evas* getGbarCanvas() const; + virtual bool isGbarOpened() const; + virtual ~GbarHelper(); + + 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); + + GbarHelper(RenderInfoPtr gbarRenderInfo, std::string gbarStartUrl); + + //members + Evas_Object* m_boxWebView; + Evas_Object* m_gbarWebView; + RenderInfoPtr m_gbarRenderInfo; + std::string m_startUrl; + bool m_opened; +}; + +#endif // PD_HELPER_H \ No newline at end of file diff --git a/src/Core/View/IGbarHelper.h b/src/Core/View/IGbarHelper.h new file mode 100755 index 0000000..bde1a75 --- /dev/null +++ b/src/Core/View/IGbarHelper.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 IGbarHelper.h + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ +#ifndef I_GBAR_HELPER_H +#define I_GBAR_HELPER_H + +#include +#include + +class IGbarHelper { + 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 setGbarWebView(Evas_Object* webview) = 0; + virtual Evas_Object* getBoxWebView() const = 0; + virtual Evas_Object* getGbarWebView() const = 0; + virtual Evas* getGbarCanvas() const = 0; + virtual bool isGbarOpened() const = 0; +}; + +typedef std::shared_ptr IGbarHelperPtr; + +#endif // I_GBAR_HELPER_H \ No newline at end of file diff --git a/src/Core/View/IJsInterface.h b/src/Core/View/IJsInterface.h new file mode 100644 index 0000000..6de0776 --- /dev/null +++ b/src/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 +#include + +class IJsInterface { + public: + virtual bool process(std::string& uri) = 0; + virtual ~IJsInterface() {}; +}; + +typedef std::shared_ptr IJsInterfacePtr; + +#endif //I_JS_INTERFACE_H diff --git a/src/Core/View/IRenderView.h b/src/Core/View/IRenderView.h new file mode 100644 index 0000000..a140a21 --- /dev/null +++ b/src/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 +#include +#include + +class IRenderView { + public: + enum UrlType { + URL_TYPE_BOX, + URL_TYPE_GBAR + }; + 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 openGbar() = 0; + virtual void closeGbar() = 0; + virtual Evas_Object* getBoxWebView() = 0; + virtual Evas_Object* getGbarWebView() = 0; + virtual ~IRenderView() {}; +}; + +typedef std::shared_ptr IRenderViewPtr; + +#endif // I_RENDER_VIEW_H diff --git a/src/Core/View/JsInterface.cpp b/src/Core/View/JsInterface.cpp new file mode 100755 index 0000000..dad9728 --- /dev/null +++ b/src/Core/View/JsInterface.cpp @@ -0,0 +1,250 @@ +/* + * 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 +#include +#include +#include +#include +#include "Service/AppControl.h" +#include "Service/PeriodChanger.h" +#include "Service/ScrollHolder.h" +#include "Service/MessageManager.h" +#include "JsInterface.h" + +using namespace Service; + +namespace { +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_GBAR("box://send-message-to-gbar"); +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"); + if( renderView == NULL ){ + LogE("render view is NULL"); + throw; + } +} + +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_GBAR.size(), + BOX_SCHEME_SEND_MESSAGE_TO_GBAR)) + { + std::string key("message"); + std::string message = parse(uri, key); + return handleSendMessage(MessageManager::TO_GBAR, 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_GBAR: + webview = m_renderView->getGbarWebView(); + 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; + } + std::string cur_key = query.substr(found, seperator - found); + unsigned next = query.find_first_of("&", seperator + 1); + + if (key == cur_key) { + LogD("key matched!\n"); + value = std::string(query, seperator + 1, next == std::string::npos ? std::string::npos : next - seperator - 1); + break; + } + if( next == std::string::npos ) + 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/Core/View/JsInterface.h b/src/Core/View/JsInterface.h new file mode 100755 index 0000000..187dac5 --- /dev/null +++ b/src/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 +#include +#include +#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 m_periodChanger; + std::shared_ptr m_messageManager; + RenderView* m_renderView; + BoxInfoPtr m_boxInfo; +}; + +#endif // JS_INTERFACE_H + diff --git a/src/Core/View/RenderView.cpp b/src/Core/View/RenderView.cpp new file mode 100644 index 0000000..a0dc7ee --- /dev/null +++ b/src/Core/View/RenderView.cpp @@ -0,0 +1,322 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "JsInterface.h" +#include + +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 renderTypeOpenGbar("gbaropen"); +static const std::string renderTypeUpdate("update"); + +RenderView::RenderView(BoxInfoPtr boxInfo, bool hwEnable) + : m_boxInfo(boxInfo) + , m_boxBuffer() + , m_gbarBuffer() + , 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_gbarBuffer) { + closeGbar(); + } + 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::openGbar() +{ + LogD("enter"); + + auto touchCallback = std::bind(RenderView::touchGbarCallback, _1, _2, this); + m_gbarBuffer = GbarRenderBuffer::create(m_boxInfo, touchCallback); + m_gbarBuffer->allocate(); + m_gbarBuffer->stopCanvasUpdate(); + showInternal(renderTypeOpenGbar); + ecore_idler_add(startUpdateRenderBufferIdlerCallback, m_gbarBuffer.get()); +} + +void RenderView::closeGbar() +{ + LogD("enter"); + if (m_gbarBuffer) { + m_gbarBuffer->stopCanvasUpdate(); + hideGbar(); + m_gbarBuffer->free(); + m_gbarBuffer.reset(); + } +} + +Evas_Object* RenderView::getBoxWebView() +{ + LogD("enter"); + // this will be implemented by derived class + return NULL; +} + +Evas_Object* RenderView::getGbarWebView() +{ + 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::showGbar(RenderInfoPtr gbarRenderInfo, RenderInfoPtr boxRenderInfo) +{ + LogD("enter"); + UNUSED_PARAM(gbarRenderInfo); + UNUSED_PARAM(boxRenderInfo); + // this will be implemented by derived class +} + +void RenderView::hideGbar() +{ + LogD("enter"); + // this will be implemented by derived class +} + +IRenderBufferPtr RenderView::getBoxBuffer() const +{ + return m_boxBuffer; +} + +IRenderBufferPtr RenderView::getGbarBuffer() const +{ + return m_gbarBuffer; +} + +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::didGbarTouched(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::touchGbarCallback(int x, int y, RenderView* This) +{ + This->didGbarTouched(x, y); +} + +Eina_Bool RenderView::startUpdateRenderBufferIdlerCallback(void* data) +{ + LogD("enter"); + RenderBuffer* buffer = static_cast(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_GBAR: + renderInfo->window = m_gbarBuffer->getWindow(); + renderInfo->width = m_boxInfo->gbarWidth; + renderInfo->height = m_boxInfo->gbarHeight; + break; + default: + LogD("error url type"); + return RenderInfoPtr(); + } + query << "&width=" << renderInfo->width << "&height=" << renderInfo->height; + + // if needed, set gbar information + if (renderType == renderTypeOpenGbar) { + // add position infomation of gbar + query << "&gbaropen-direction="; + if (m_boxInfo->gbarY == 0) { + query << "down"; + } else { + query << "up"; + } + + query << "&gbaropen-arrow-xpos="; + query << static_cast((m_boxInfo->gbarX) * (m_boxInfo->gbarWidth)); + + // 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 == renderTypeOpenGbar) { + RenderInfoPtr gbarRenderInfo = makeRenderInfo(renderType, URL_TYPE_GBAR); + RenderInfoPtr boxRenderInfo = makeRenderInfo(renderType, URL_TYPE_BOX); + showGbar(gbarRenderInfo, 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/Core/View/RenderView.h b/src/Core/View/RenderView.h new file mode 100644 index 0000000..c33eca5 --- /dev/null +++ b/src/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 +#include +#include +#include +#include +#include +#include "IJsInterface.h" +#include "IRenderView.h" + +#define EXPORT_CLASS __attribute__ ((visibility("default"))) + +typedef std::function TouchViewCallback; + +struct RenderInfo { + int width; + int height; + Evas_Object* window; + std::string defaultUrlParams; +}; + +typedef std::shared_ptr 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 openGbar(); + void closeGbar(); + virtual Evas_Object* getBoxWebView(); + virtual Evas_Object* getGbarWebView(); + virtual ~RenderView(); + + protected: + virtual void showBox(RenderInfoPtr boxRenderInfo); + virtual void hideBox(); + virtual void pauseBox(); + virtual void resumeBox(); + virtual void showGbar(RenderInfoPtr gbarRenderInfo, RenderInfoPtr boxRenderInfo); + virtual void hideGbar(); + virtual void didBoxTouched(int x, int y); + virtual void didGbarTouched(int x, int y); + + // To be used by derived class + bool processBoxScheme(std::string& uri); + IRenderBufferPtr getBoxBuffer() const; + IRenderBufferPtr getGbarBuffer() 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 touchGbarCallback(int x, int y, RenderView* This); + static Eina_Bool startUpdateRenderBufferIdlerCallback(void* data); + + // members + BoxInfoPtr m_boxInfo; + IRenderBufferPtr m_boxBuffer; + IRenderBufferPtr m_gbarBuffer; + IJsInterfacePtr m_jsInterface; + // timestamp for last time of showing box. + time_t m_lastShowBoxTime; + + friend class BoxRenderBuffer; + friend class GbarRenderBuffer; +}; + +#endif // RENDER_VIEW_H diff --git a/src/Core/View/Service/AppControl.cpp b/src/Core/View/Service/AppControl.cpp new file mode 100644 index 0000000..af851e1 --- /dev/null +++ b/src/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 +#include +#include +#include "AppControl.h" + +namespace Service { +namespace AppControl { + +bool launchBrowser(std::string& url) +{ + LogD("enter"); + + app_control_h handle = NULL; + int ret = APP_CONTROL_ERROR_NONE; + + ret = app_control_create(&handle); + if (ret != APP_CONTROL_ERROR_NONE) { + LogD("failed to create app_control"); + return false; + } + + ret = app_control_set_operation(handle, APP_CONTROL_OPERATION_VIEW); + if (ret != APP_CONTROL_ERROR_NONE) { + LogD("failed to set operation"); + app_control_destroy(handle); + return false; + } + + ret = app_control_set_uri(handle, url.c_str()); + if (ret != APP_CONTROL_ERROR_NONE) { + LogD("failed to set url"); + app_control_destroy(handle); + return false; + } + + ret = app_control_send_launch_request(handle, NULL, NULL); + if (ret != APP_CONTROL_ERROR_NONE) { + LogD("failed to request launch"); + app_control_destroy(handle); + return false; + } + + LogD("success to launch browser: %s", url.c_str()); + app_control_destroy(handle); + + return true; +} + +bool launchDownloader(std::string& url, std::string& cookie) +{ + LogD("enter"); + + app_control_h handle = NULL; + int ret = APP_CONTROL_ERROR_NONE; + + if (url.empty()) { + LogD("invalid arguments"); + return false; + } + + ret = app_control_create(&handle); + if (ret != APP_CONTROL_ERROR_NONE) { + LogD("failed to create app_control"); + return false; + } + + ret = app_control_set_operation(handle, APP_CONTROL_OPERATION_DOWNLOAD); + if (ret != APP_CONTROL_ERROR_NONE) { + LogD("failed to set operation"); + app_control_destroy(handle); + return false; + } + + ret = app_control_set_uri(handle, url.c_str()); + if (ret != APP_CONTROL_ERROR_NONE) { + LogD("failed to set url"); + app_control_destroy(handle); + return false; + } + + if (!cookie.empty()) { + ret = app_control_add_extra_data(handle, "cookie", cookie.c_str()); + if (ret != APP_CONTROL_ERROR_NONE) { + LogD("failed to set cookie"); + app_control_destroy(handle); + return false; + } + } + + ret = app_control_send_launch_request(handle, NULL, NULL); + if (ret != APP_CONTROL_ERROR_NONE) { + LogD("failed to request launch"); + app_control_destroy(handle); + return false; + } + + LogD("success to launch downloader"); + app_control_destroy(handle); + + return true; +} + +} // AppControl +} // Service diff --git a/src/Core/View/Service/AppControl.h b/src/Core/View/Service/AppControl.h new file mode 100644 index 0000000..5693873 --- /dev/null +++ b/src/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 + +namespace Service { +namespace AppControl { + +bool launchBrowser(std::string& url); +bool launchDownloader(std::string& url, std::string& cookie); + +} +} // Service diff --git a/src/Core/View/Service/CMakeLists.txt b/src/Core/View/Service/CMakeLists.txt new file mode 100755 index 0000000..4b002d4 --- /dev/null +++ b/src/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 + widget_service + evas + eina + ecore-x + elementary + efl-assist + widget_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/Core/View/Service/MessageManager.cpp b/src/Core/View/Service/MessageManager.cpp new file mode 100755 index 0000000..ba6fa41 --- /dev/null +++ b/src/Core/View/Service/MessageManager.cpp @@ -0,0 +1,93 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include "MessageManager.h" + +namespace Service { + +static const std::string jsFireWindowEventFunction("webprovider.fireAppWidgetEvent"); +static const std::string jsGbarMessageEvent("gbarmessage"); +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 = jsGbarMessageEvent; + break; + case TO_GBAR: + 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/Core/View/Service/MessageManager.h b/src/Core/View/Service/MessageManager.h new file mode 100644 index 0000000..c053fd0 --- /dev/null +++ b/src/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 +#include +#include + +namespace Service { + +class MessageManager; +typedef std::shared_ptr MessageManagerPtr; + +class MessageManager { + public: + enum ReceiverType { + TO_BOX, + TO_GBAR + }; + + 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/Core/View/Service/PeriodChanger.cpp b/src/Core/View/Service/PeriodChanger.cpp new file mode 100755 index 0000000..d1259c9 --- /dev/null +++ b/src/Core/View/Service/PeriodChanger.cpp @@ -0,0 +1,277 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#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/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); + const char* popup_type = elm_object_widget_type_get(popup); + if (type && popup_type && !strcmp(type, popup_type)) { + 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 = widget_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(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(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(data); + This->destroyPeriodPopup(obj); +} + +Eina_Bool PeriodChanger::popupDestroyIdlerCallback(void *data) +{ + LogD("enter"); + PopupListData* popupData = static_cast(data); + popupData->periodChanger->destroyPeriodPopup(popupData->radio); + return ECORE_CALLBACK_CANCEL; +} +} // Service diff --git a/src/Core/View/Service/PeriodChanger.h b/src/Core/View/Service/PeriodChanger.h new file mode 100755 index 0000000..b8902b0 --- /dev/null +++ b/src/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 +#include +#include + +namespace Service { +class PeriodChanger; +typedef std::shared_ptr 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/Core/View/Service/ScrollHolder.cpp b/src/Core/View/Service/ScrollHolder.cpp new file mode 100644 index 0000000..aa3216d --- /dev/null +++ b/src/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 +#include +#include + +namespace Service { +namespace ScrollHolder { + +void holdHorizontalScroll(std::string& boxId, std::string& instanceId, bool start) +{ + LogD("enter"); + + if (start) { + LogD("scroll start"); + widget_provider_send_hold_scroll(boxId.c_str(), instanceId.c_str(), 1); + } else { + LogD("scroll stop"); + widget_provider_send_hold_scroll(boxId.c_str(), instanceId.c_str(), 0); + } +} + +} // AppControl +} // Service diff --git a/src/Core/View/Service/ScrollHolder.h b/src/Core/View/Service/ScrollHolder.h new file mode 100644 index 0000000..a7373b7 --- /dev/null +++ b/src/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 + +namespace Service { +namespace ScrollHolder { + +void holdHorizontalScroll(std::string& boxId, std::string& instanceId, bool start); + +} +} // Service diff --git a/src/Core/View/injection.js b/src/Core/View/injection.js new file mode 100644 index 0000000..1a2a80c --- /dev/null +++ b/src/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.sendMessageToGbar = 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("gbarmessage"); +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/Core/config.h b/src/Core/config.h new file mode 100644 index 0000000..52d0d61 --- /dev/null +++ b/src/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 + +/*** define list **/ +#define WEB_PROVIDER_INSPECTOR_PORT_NUMBER 9980 +#define WEB_PROVIDER_INSPECTOR_FILE_PATH "/tmp/inspector" diff --git a/src/Daemon/BoxDaemon.cpp b/src/Daemon/BoxDaemon.cpp new file mode 100644 index 0000000..f0a3d4c --- /dev/null +++ b/src/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 +#include +#include "BoxDaemon.h" +#include "BoxDaemonImpl.h" + +BoxDaemon::BoxDaemon() + : m_impl(new BoxDaemonImpl()) +{ +} + +BoxDaemon::~BoxDaemon() +{ +} + +bool BoxDaemon::start(std::string& name, app_control_h app_control) +{ + return m_impl->start(name, app_control); +} + +bool BoxDaemon::stop() +{ + return m_impl->stop(); +} + +bool BoxDaemon::handleAppControl(app_control_h app_control) +{ + return m_impl->handleAppControl(app_control); +} diff --git a/src/Daemon/BoxDaemon.h b/src/Daemon/BoxDaemon.h new file mode 100644 index 0000000..f01a838 --- /dev/null +++ b/src/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 +#include +#include +#include + +class BoxDaemonImpl; + +class BoxDaemon: Noncopyable { + public: + bool start(std::string& name, app_control_h app_control); + bool stop(); + bool handleAppControl(app_control_h app_control); + + explicit BoxDaemon(); + ~BoxDaemon(); + + private: + std::shared_ptr m_impl; +}; + +#endif //BOX_DAEMON_H diff --git a/src/Daemon/BoxDaemonImpl.cpp b/src/Daemon/BoxDaemonImpl.cpp new file mode 100755 index 0000000..d174b59 --- /dev/null +++ b/src/Daemon/BoxDaemonImpl.cpp @@ -0,0 +1,923 @@ +/* + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "BoxDaemonUtil.h" +#include "BoxDaemonImpl.h" + +#define MASTER_PROVIDER_PING_TIME 120.0f +#define CONF_DEFAULT_ABI "c" +#define SW_ACCEL "use-sw" + +BoxDaemonImpl::BoxDaemonImpl() + : m_pluginConnector(BoxPluginConnector::create()) +{ + appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, requestUpdateLangCallback, this); + appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, requestLowMemoryCallback, this); + appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, requestUpdateLangCallback, 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, app_control_h app_control) +{ + LogD("enter"); + + // initialize existing plugins for web widget + if (!m_pluginConnector->initialize()) { + LogD("failed to initialize plugins"); + return false; + } + + // set name + m_daemonName = name; + + char *secured = NULL; + int ret = app_control_get_extra_data(app_control, "secured", &secured); + if (ret != APP_CONTROL_ERROR_NONE || !secured) { + LogD("Secured is not valid\n"); + return false; + } + + char *hwAcceleration = NULL; + ret = app_control_get_extra_data(app_control, "hw-acceleration", &hwAcceleration); + if (ret != APP_CONTROL_ERROR_NONE) { + LogD("Unable to get option for hw-acceleration\n"); + hwAcceleration = strdup(SW_ACCEL); + /* Go ahead */ + } + char *abi = NULL; + ret = app_control_get_extra_data(app_control, "abi", &abi); + if (ret != APP_CONTROL_ERROR_NONE) { + LogD("Unable to get option for hw-acceleration\n"); + abi = strdup(CONF_DEFAULT_ABI); + /* Go ahead */ + } + // provider init + ProviderCallbacks callbacks; + setProviderCallbacks(callbacks); + + ret = widget_provider_prepare_init(abi, + hwAcceleration, + ((!strcasecmp(secured, "true"))? true : false)); + if (abi) + free(abi); + if (hwAcceleration) + free(hwAcceleration); + if (secured) + free(secured); + + if (ret < 0) { + LogD("failed to prepare provider"); + return false; + } + + ret = widget_provider_init(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 existing plugins for web widget + if (!m_pluginConnector->shutdown()) { + LogD("failed to shutdown plugins"); + return false; + } + + // deinitialize provider + widget_provider_fini(); + + return true; +} + +bool BoxDaemonImpl::handleAppControl(app_control_h app_control) +{ + LogD("enter"); + bool result = false; + char* operation = NULL; + + // app_control_get_operation allocates memory using malloc() to operation + if (app_control_get_operation(app_control, &operation) != APP_CONTROL_ERROR_NONE) { + LogD("App Control error"); + return false; + } + + // checks for scenario when APP_CONTROL_ERROR_NONE returned but operation is NULL + if (!operation) { + LogD("no operation"); + return false; + } + + if (!strcmp(APP_CONTROL_OPERATION_BOX_UPDATE, operation)) { + BoxInfoPtr info = handleOperationUpdate(app_control); + if (info) { + JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_BOX, info, this); + if (ecore_job_add(requestBoxJobCallback, jobInfo)) { + result = true; + } else { + delete jobInfo; + } + } + } else if (!strcmp(APP_CONTROL_OPERATION_BOX_REMOVE, operation)) { + std::vector container = handleOperationRemove(app_control); + 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 = NULL; + app_control_get_extra_data(app_control, APP_CONTROL_REMOVE_APPID_KEY, &appId); + web_provider_service_wakeup_installer(appId); + result = true; + free(appId); + } else { + LogD("unknown operation: %s", operation); + } + + free(operation); + operation = NULL; + + return result; +} + +int BoxDaemonImpl::connectedCallback(ProviderEventArgPtr arg, void* data) +{ + LogD("enter"); + UNUSED_PARAM(arg); + + BoxDaemonImpl* This = static_cast(data); + if (!widget_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(data); + if( This == NULL ) + return -1; + + BoxInfoPtr info = This->initializeBoxInfo(arg); + if (!info) { + return -1; + } + + if ((arg->info.widget_create.width == 0) || (arg->info.widget_create.height == 0)) { + widget_service_get_size(WIDGET_SIZE_TYPE_1x1, width, height); + } else { + *width = arg->info.widget_create.width; + *height = arg->info.widget_create.height; + } + + info->boxWidth = *width; + info->boxHeight = *height; + info->priority = 1.0f; + info->period = arg->info.widget_create.period; + if (arg->info.widget_create.content && strlen(arg->info.widget_create.content)) { + info->contentInfo = std::string(arg->info.widget_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(data); + if( This == NULL ) + return -1; + + BoxInfoPtr info = This->initializeBoxInfo(arg); + if (!info) { + return -1; + } + + if ((arg->info.widget_recreate.width == 0) || (arg->info.widget_recreate.height == 0)) { + widget_service_get_size(WIDGET_SIZE_TYPE_1x1, + &arg->info.widget_recreate.width, + &arg->info.widget_recreate.height); + } + + info->boxWidth = arg->info.widget_recreate.width; + info->boxHeight = arg->info.widget_recreate.height; + info->priority = 1.0f; + info->period = arg->info.widget_recreate.period; + if (arg->info.widget_recreate.content) { + info->contentInfo = std::string(arg->info.widget_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(data); + if( This == NULL ) + return -1; + + 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::gbarCreateCallback(ProviderEventArgPtr arg, void* data) +{ + LogD("enter"); + + BoxDaemonImpl* This = static_cast(data); + if( This == NULL ) + return -1; + + BoxInfoPtr info = This->initializeBoxInfo(arg); + if (!info) { + return -1; + } + if (arg->info.gbar_create.w == 0 || arg->info.gbar_create.h == 0) { + return -1; + } + + //Use the screen width to fix the device width + ecore_x_window_size_get(0, &info->gbarWidth, NULL); + info->gbarHeight = arg->info.gbar_create.h; + info->gbarX = arg->info.gbar_create.x; + info->gbarY = arg->info.gbar_create.y; + + LogD("--------------------------------------------"); + LogD("boxId: %s", info->boxId.c_str()); + LogD("InstanceId: %s", info->instanceId.c_str()); + LogD("width: %d", info->gbarWidth); + LogD("height: %d", info->gbarHeight); + LogD("x: %f", info->gbarX); + LogD("y: %f", info->gbarY); + LogD("--------------------------------------------"); + + JobInfo* jobInfo = new JobInfo(REQUEST_CMD_OPEN_GBAR, info, This); + Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo); + + if (!ret) { + delete jobInfo; + } + + return ret ? 0 : -1; +} + +int BoxDaemonImpl::gbarDestroyCallback(ProviderEventArgPtr arg, void* data) +{ + LogD("enter"); + + BoxDaemonImpl* This = static_cast(data); + if( This == NULL ) + return -1; + + 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_GBAR, info, This); + Ecore_Job* ret = ecore_job_add(requestBoxJobCallback, jobInfo); + + if (!ret) { + delete jobInfo; + } + + return ret ? 0 : -1; +} + +int BoxDaemonImpl::clickedCallback(ProviderEventArgPtr arg, void* data) +{ + LogD("enter"); + + BoxDaemonImpl* This = static_cast(data); + if( This == NULL ) + return -1; + + BoxInfoPtr info = This->initializeBoxInfo(arg); + if (!info) { + return -1; + } + + int flag = web_provider_widget_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(data); + if( This == NULL ) + return -1; + + 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); + + if (!ret) { + delete jobInfo; + } + + return ret ? 0 : -1; +} + +int BoxDaemonImpl::boxPauseCallback(ProviderEventArgPtr arg, void* data) +{ + LogD("enter"); + + BoxDaemonImpl* This = static_cast(data); + if( This == NULL ) + return -1; + + 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); + + if (!ret) { + delete jobInfo; + } + + return ret ? 0 : -1; +} + +int BoxDaemonImpl::boxResumeCallback(ProviderEventArgPtr arg, void* data) +{ + LogD("enter"); + + BoxDaemonImpl* This = static_cast(data); + if( This == NULL ) + return -1; + + 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); + + if (!ret) { + delete jobInfo; + } + + return ret ? 0 : -1; +} + +int BoxDaemonImpl::pauseCallback(ProviderEventArgPtr arg, void* data) +{ + LogD("enter"); + UNUSED_PARAM(arg); + + BoxDaemonImpl* This = static_cast(data); + if( This == NULL ) + return -1; + + 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); + + if (!ret) { + delete jobInfo; + } + + return ret ? 0 : -1; +} + +int BoxDaemonImpl::resumeCallback(ProviderEventArgPtr arg, void* data) +{ + LogD("enter"); + UNUSED_PARAM(arg); + + BoxDaemonImpl* This = static_cast(data); + if( This == NULL ) + return -1; + + 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); + + if (!ret) { + delete jobInfo; + } + + return ret ? 0 : -1; +} + +int BoxDaemonImpl::boxPeriodChangeCallback(ProviderEventArgPtr arg, void* data) +{ + LogD("enter"); + BoxDaemonImpl* This = static_cast(data); + if( This == NULL ) + return -1; + + 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); + + if (!ret) { + delete jobInfo; + } + + return ret ? 0 : -1; +} + +int BoxDaemonImpl::boxUpdateCallback(ProviderEventArgPtr arg, void* data) +{ + LogD("enter"); + + BoxDaemonImpl* This = static_cast(data); + if( This == NULL ) + return -1; + + 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); + + if (!ret) { + delete 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.widget_create = BoxDaemonImpl::boxCreateCallback; + callbacks.widget_recreate = BoxDaemonImpl::boxReCreateCallback; + callbacks.widget_destroy = BoxDaemonImpl::boxDestroyCallback; + callbacks.widget_pause = BoxDaemonImpl::boxPauseCallback; + callbacks.widget_resume = BoxDaemonImpl::boxResumeCallback; + callbacks.gbar_create = BoxDaemonImpl::gbarCreateCallback; + callbacks.gbar_destroy = BoxDaemonImpl::gbarDestroyCallback; + 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(); + } + + char* type = web_provider_widget_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(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::getBoxIdFromAppControl(app_control_h app_control) +{ + LogD("enter"); + + int ret; + char* appControlUri = NULL; + ret = app_control_get_uri(app_control, &appControlUri); + if (ret != APP_CONTROL_ERROR_NONE) { + LogD("no box uri"); + return std::string(); + } + + std::string uri(appControlUri); + free(appControlUri); + + if(uri.compare(0, strlen(APP_CONTROL_BOX_SERVICE_SCHEME), APP_CONTROL_BOX_SERVICE_SCHEME)) { + // uri is not box-service scheme + return std::string(); + } + + std::string boxId = uri.substr(strlen(APP_CONTROL_BOX_SERVICE_SCHEME)); + return boxId; +} + +bool BoxDaemonImpl::isAppControlCallerBoxOwner(app_control_h app_control) +{ + LogD("enter"); + + int ret; + + std::string boxId = getBoxIdFromAppControl(app_control); + if (boxId.empty()) { + LogD("error box-id"); + return false; + } + + // check if caller is owner of this widget + char* appId = web_provider_widget_get_app_id(boxId.c_str()); + if (!appId) { + return false; + } + std::string ownerAppId(appId); + free(appId); + + char* caller = NULL; + ret = app_control_get_caller(app_control, &caller); + if (ret != APP_CONTROL_ERROR_NONE) { + ret = app_control_get_extra_data( + app_control, APP_CONTROL_ALARM_CALLER_KEY, &caller); + if (ret != APP_CONTROL_ERROR_NONE) { + LogD("failed to get caller's appid from app_control"); + return false; + } + } + std::string callerAppId(caller); + + // release strings + free(caller); + + if (ownerAppId != callerAppId) { + LogD("caller is not matched with owner of requested box"); + return false; + } + + return true; +} + +BoxInfoPtr BoxDaemonImpl::handleOperationUpdate(app_control_h app_control) +{ + LogD("enter"); + + if (!isAppControlCallerBoxOwner(app_control)) { + return BoxInfoPtr(); + } + + std::string boxId = getBoxIdFromAppControl(app_control); + if (boxId.empty()) { + LogD("error box-id"); + return BoxInfoPtr(); + } + + char* appContentInfo = NULL; + app_control_get_extra_data(app_control, APP_CONTROL_CONTENT_INFO_KEY, &appContentInfo); + + std::string type(getBoxType(boxId.c_str())); + if (type.empty()) { + LogD("no type for this box"); + free(appContentInfo); + return BoxInfoPtr(); + } + + BoxInfoPtr info = BoxInfoPtr(new BoxInfo(type, boxId, "")); + if (appContentInfo) { + LogD("app_control content info: %s", appContentInfo); + info->appContentInfo = std::string(appContentInfo); + } + + // release string + free(appContentInfo); + + return info; +} + +int BoxDaemonImpl::requestUpdateAll(void) +{ + LogD("enter"); + + BoxInfoPtr info = BoxInfoPtr(new BoxInfo()); + JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_ALL, info, this); + + if (!ecore_job_add(requestBoxJobCallback, jobInfo)) { + delete jobInfo; + } + return 0; +} + +std::vector BoxDaemonImpl::handleOperationRemove(app_control_h app_control) +{ + LogD("enter"); + + char* appId = NULL; + app_control_get_extra_data(app_control, APP_CONTROL_REMOVE_APPID_KEY, &appId); + LogD("request appid: %s", appId); + + // check if this appId has widget + int boxCount = 0; + char** boxIdList = web_provider_widget_get_box_id_list(appId, &boxCount); + free(appId); + if (!boxIdList) { + return std::vector(); + } + + std::vector 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); + } + + web_provider_widget_release_box_id_list(boxIdList, boxCount); + return boxInfoPtrContainer; +} + +Eina_Bool BoxDaemonImpl::pingToMasterCallback(void* data) +{ + LogD("enter"); + UNUSED_PARAM(data); + + widget_provider_send_ping(); + + return ECORE_CALLBACK_RENEW; +} + +void BoxDaemonImpl::requestBoxJobCallback(void* data) +{ + JobInfo* jobInfo = static_cast(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::requestUpdateLangCallback(void* /*eventInfo*/, void* data) +{ + LogD("enter"); + BoxDaemonImpl* This = static_cast(data); + return This->requestUpdateAll(); +} + +int BoxDaemonImpl::requestLowMemoryCallback(void* data, void* /* tmp */) +{ + 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(data); + if( This == NULL ) + return; + This->requestUpdateAll(); +} + +void BoxDaemonImpl::requestUpdateAppBoxCallback(keynode_t* key, void* data) +{ + LogD("enter"); + UNUSED_PARAM(key); + + BoxDaemonImpl* This = static_cast(data); + if( This == NULL ) + return; + BoxInfoPtr info = BoxInfoPtr(new BoxInfo()); + JobInfo* jobInfo = new JobInfo(REQUEST_CMD_UPDATE_APPBOX, info, This); + + if (!ecore_job_add(requestBoxJobCallback, jobInfo)) { + delete jobInfo; + } +} diff --git a/src/Daemon/BoxDaemonImpl.h b/src/Daemon/BoxDaemonImpl.h new file mode 100755 index 0000000..0fe4808 --- /dev/null +++ b/src/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 +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +// forward declaration +class IBoxManager; +class IBoxPluginConnector; + +class BoxDaemonImpl { + public: + bool start(std::string& name, app_control_h app_control); + bool stop(); + bool handleAppControl(app_control_h app_control); + + public: + explicit BoxDaemonImpl(); + ~BoxDaemonImpl(); + + private: + // type definition + typedef struct widget_event_arg ProviderEventArg; + typedef ProviderEventArg* ProviderEventArgPtr; + typedef struct widget_event_table ProviderCallbacks; + typedef ProviderCallbacks* ProviderCallbacksPtr; + + // widget'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 gbarCreateCallback(ProviderEventArgPtr arg, void* data); + static int gbarDestroyCallback(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 requestUpdateLangCallback(void* data, void* tmp); + static int requestLowMemoryCallback(void* data, void* tmp); + // 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 getBoxIdFromAppControl(app_control_h app_control); + bool isAppControlCallerBoxOwner(app_control_h app_control); + BoxInfoPtr handleOperationUpdate(app_control_h app_control); + std::vector handleOperationRemove(app_control_h app_control); + + // 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 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/Daemon/BoxDaemonUtil.cpp b/src/Daemon/BoxDaemonUtil.cpp new file mode 100644 index 0000000..8934d59 --- /dev/null +++ b/src/Daemon/BoxDaemonUtil.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 BoxDaemonUtil.cpp + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ +#include +#include +#include +#include +#include +#include +#include +#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"); + + char* appId = web_provider_widget_get_app_id(boxId.c_str()); + if (!appId) { + LogD("no appid of %s", boxId.c_str()); + return false; + } + + app_control_h handle = NULL; + int ret = APP_CONTROL_ERROR_NONE; + + ret = app_control_create(&handle); + if (ret != APP_CONTROL_ERROR_NONE && !handle) { + LogD("failed to create app_control"); + free(appId); + return false; + } + + ret = app_control_set_app_id(handle, appId); + free(appId); + if (ret != APP_CONTROL_ERROR_NONE) { + LogD("failed to set package"); + app_control_destroy(handle); + return false; + } + + app_control_add_extra_data(handle, boxIdKey.c_str(), boxId.c_str()); + app_control_add_extra_data(handle, instanceIdKey.c_str(), instanceId.c_str()); + + ret = app_control_send_launch_request(handle, NULL, NULL); + if (ret != APP_CONTROL_ERROR_NONE) { + LogD("failed to launch package"); + app_control_destroy(handle); + return false; + } + + app_control_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/Daemon/BoxDaemonUtil.h b/src/Daemon/BoxDaemonUtil.h new file mode 100644 index 0000000..3d58396 --- /dev/null +++ b/src/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 + +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/Daemon/CMakeLists.txt b/src/Daemon/CMakeLists.txt new file mode 100644 index 0000000..f14fdac --- /dev/null +++ b/src/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 + widget_provider + widget_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/widget.${PROJECT_NAME}/bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE +) diff --git a/src/Daemon/main.cpp b/src/Daemon/main.cpp new file mode 100755 index 0000000..92f5e59 --- /dev/null +++ b/src/Daemon/main.cpp @@ -0,0 +1,171 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#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(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 appControlCallback(app_control_h app_control, void *data) +{ + LogD("app control"); + + int ret; + char* name = NULL; + + BoxDaemon *boxDaemon = static_cast(data); + ret = app_control_get_extra_data(app_control, "name", &name); + + // check if web-provider is launched, or not + if (ret == APP_CONTROL_ERROR_NONE) { + std::string daemonName(name); + if(!(boxDaemon->start(daemonName, app_control))) { + LogD("daemon failed to start"); + elm_exit(); + } + atexit(atExitCallback); + free(name); + return; + } + + boxDaemon->handleAppControl(app_control); + free(name); +} + +static bool grantProcessCapability() +{ + cap_user_header_t header; + cap_user_data_t data; + + header = static_cast(malloc(sizeof(*header))); + if (!header) { + return false; + } + + data = static_cast(calloc(sizeof(*data), _LINUX_CAPABILITY_U32S_3)); + if (!data) { + free(header); + return false; + } + + 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 + ui_app_lifecycle_callback_s ops; + memset(&ops, 0x00, sizeof(ui_app_lifecycle_callback_s)); + ops.create = appCreateCallback; + ops.terminate = appTerminateCallback; + ops.pause = appPauseCallback; + ops.resume = appResumeCallback; + ops.app_control = appControlCallback; + + // start appcore + int ret = ui_app_main(argc, argv, &ops, &boxDaemon); + return ret; +} diff --git a/src/Plugin/AppBoxPlugin/AppBoxGbarHelper.cpp b/src/Plugin/AppBoxPlugin/AppBoxGbarHelper.cpp new file mode 100755 index 0000000..d69e271 --- /dev/null +++ b/src/Plugin/AppBoxPlugin/AppBoxGbarHelper.cpp @@ -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 AppBoxGbarHelper.cpp + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ +#include +#include +#include +#include +#include +#include "AppBoxGbarHelper.h" + +AppBoxGbarHelper::AppBoxGbarHelper(Evas_Object* gbarWin) + : m_win(gbarWin) + , m_boxWebView() + , m_GbarWebView() + , m_opened(false) +{ +} + +AppBoxGbarHelper::~AppBoxGbarHelper() +{ +} + +void AppBoxGbarHelper::startOpen() +{ + LogD("enter"); +} + +void AppBoxGbarHelper::finishOpen(Evas_Object* child) +{ + LogD("enter"); + m_opened = true; + setGbarWebView(child); +} + +void AppBoxGbarHelper::close() +{ + LogD("enter"); +} + +void AppBoxGbarHelper::setBoxWebView(Evas_Object* webview) +{ + LogD("enter"); + m_boxWebView = webview; +} + +void AppBoxGbarHelper::setGbarWebView(Evas_Object* webview) +{ + LogD("enter"); + m_GbarWebView = webview; +} + +Evas_Object* AppBoxGbarHelper::getBoxWebView() const +{ + LogD("enter"); + return m_boxWebView; +} + +Evas_Object* AppBoxGbarHelper::getGbarWebView() const +{ + LogD("enter"); + return m_GbarWebView; +} + +Evas* AppBoxGbarHelper::getGbarCanvas() const +{ + LogD("enter"); + return evas_object_evas_get(m_win); +} + +bool AppBoxGbarHelper::isGbarOpened() const +{ + LogD("enter"); + return m_opened; +} \ No newline at end of file diff --git a/src/Plugin/AppBoxPlugin/AppBoxGbarHelper.h b/src/Plugin/AppBoxPlugin/AppBoxGbarHelper.h new file mode 100755 index 0000000..9134f49 --- /dev/null +++ b/src/Plugin/AppBoxPlugin/AppBoxGbarHelper.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 AppBoxGbarHelper.h + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ + +#ifndef APP_BOX_GBAR_HELPER_H +#define APP_BOX_GBAR_HELPER_H + +#include +#include +#include + +class AppBoxGbarHelper: public IGbarHelper { + public: + static IGbarHelperPtr create(Evas_Object* gbarWin) + { + return IGbarHelperPtr(new AppBoxGbarHelper(gbarWin)); + } + virtual void startOpen(); + virtual void finishOpen(Evas_Object* child); + virtual void close(); + virtual void setBoxWebView(Evas_Object* webview); + virtual void setGbarWebView(Evas_Object* webview); + virtual Evas_Object* getBoxWebView() const; + virtual Evas_Object* getGbarWebView() const; + virtual Evas* getGbarCanvas() const; + virtual bool isGbarOpened() const; + virtual ~AppBoxGbarHelper(); + + private: + AppBoxGbarHelper(Evas_Object* gbarWin); + + //members + Evas_Object* m_win; + Evas_Object* m_boxWebView; + Evas_Object* m_GbarWebView; + bool m_opened; +}; + +#endif // APP_BOX_GBAR_HELPER_H \ No newline at end of file diff --git a/src/Plugin/AppBoxPlugin/AppBoxManager.cpp b/src/Plugin/AppBoxPlugin/AppBoxManager.cpp new file mode 100755 index 0000000..fecb4b3 --- /dev/null +++ b/src/Plugin/AppBoxPlugin/AppBoxManager.cpp @@ -0,0 +1,213 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 + } + + vconf_notify_key_changed(VCONFKEY_NETWORK_PROXY,proxyChangedCallback,this); +} + +AppBoxManager::~AppBoxManager() +{ + vconf_ignore_key_changed(VCONFKEY_NETWORK_PROXY,proxyChangedCallback); +} + +bool AppBoxManager::requestAddBox(BoxInfoPtr boxInfo, EwkContextPtr ewkContext) +{ + char* appId = + web_provider_widget_get_app_id(boxInfo->boxId.c_str()); + + if (!appId) { + LogD("no appid of %s", boxInfo->boxId.c_str()); + return false; + } + + std::string appIdStr(appId); + free(appId); + + auto it = m_ewkContextMap.find(appIdStr); + if (it == m_ewkContextMap.end()) { + ewkContext = getAvailableEwkContext(appIdStr); + if( ewkContext == NULL ){ + LogE("Can't create ewkContext (not allowed appid)"); + return false; + } + insertContextMap(appIdStr, ewkContext); + } else { + ewkContext = it->second; + } + + if (!BoxManager::requestAddBox(boxInfo, ewkContext)) { + return false; + } + + return true; +} + +void AppBoxManager::updateEwkContext(std::string& boxId) +{ + LogD("enter"); + char* appId = web_provider_widget_get_app_id(boxId.c_str()); + if (!appId) { + LogD("no appid of %s", boxId.c_str()); + return; + } + + std::string appIdStr(appId); + free(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()); + + //find package root path + std::string pkgpath = baseExecutablePath.substr(0, baseExecutablePath.rfind("/bin/")); + pkgpath = pkgpath + "/data/.webkit/localStorage/"; + //setting for localStorage database path to share with webapp + ewk_context_web_storage_path_set(newEwkContext.get(), pkgpath.c_str()); + + // proxy server setting + char *proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY); + LogD("proxy address changed %s", proxy); + std::string dummyProxy("0.0.0.0"); + if (proxy && strlen(proxy) && (dummyProxy != proxy)) { + free(proxy); + proxy = NULL; + } + ewk_context_proxy_uri_set(newEwkContext.get(), proxy); + + // We can't unset due to Webprocess was forked in other thread. + // 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) +{ + pkgmgrinfo_appinfo_h handle = NULL; + char* retStr = NULL; + + int ret = pkgmgrinfo_appinfo_get_appinfo(appId.c_str(), &handle); + if (ret != PMINFO_R_OK) { + LogE("pkgmgrinfo_appinfo_get_appinfo failed"); + return std::string(); + } + + ret = pkgmgrinfo_appinfo_get_exec(handle, &retStr); + if (ret != PMINFO_R_OK || !retStr) { + LogE("pkgmgrinfo_appinfo_get_exec failed"); + + ret = pkgmgrinfo_appinfo_destroy_appinfo(handle); + if (ret != PMINFO_R_OK) { + LogE("pkgmgrinfo_appinfo_destroy_appinfo failed"); + } + return std::string(); + } else { + std::string basePath(retStr); + + ret = pkgmgrinfo_appinfo_destroy_appinfo(handle); + if (ret != PMINFO_R_OK) { + LogE("pkgmgrinfo_appinfo_destroy_appinfo failed"); + return std::string(); + } + return basePath; + } +} + + +void AppBoxManager::proxyChangedCallback(keynode_t* /* keynode */, void* data){ + LogD("enter"); + AppBoxManager *This = static_cast(data); + if( This == NULL ) + return; + + // proxy server setting + char *proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY); + LogD("proxy address changed %s", proxy); + std::string dummyProxy("0.0.0.0"); + if (proxy && strlen(proxy) && (dummyProxy != proxy)) { + free(proxy); + proxy = NULL; + } + for( auto it = This->m_ewkContextMap.begin(); it != This->m_ewkContextMap.end(); ++it){ + ewk_context_proxy_uri_set(it->second.get(), proxy); + } + free(proxy); +} diff --git a/src/Plugin/AppBoxPlugin/AppBoxManager.h b/src/Plugin/AppBoxPlugin/AppBoxManager.h new file mode 100644 index 0000000..147519c --- /dev/null +++ b/src/Plugin/AppBoxPlugin/AppBoxManager.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 AppBoxManager.h + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ +#ifndef APP_BOX_MANAGER_H +#define APP_BOX_MANAGER_H + +#include + +#include +#include +#include +#include +#include + + +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); + static void proxyChangedCallback(keynode_t* keynode, void* data); + + // members + typedef std::map EwkContextMap; + typedef std::pair EwkContextMapPair; + EwkContextMap m_ewkContextMap; +}; + + +#endif // APP_BOX_MANAGER_H diff --git a/src/Plugin/AppBoxPlugin/AppBoxPluginFactory.cpp b/src/Plugin/AppBoxPlugin/AppBoxPluginFactory.cpp new file mode 100644 index 0000000..58f149c --- /dev/null +++ b/src/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 +#include +#include +#include +#include "AppBoxRenderView.h" +#include "AppBoxPluginFactory.h" + +IRenderViewPtr AppBoxPluginFactory::createRenderView( + std::shared_ptr boxInfo, + std::shared_ptr ewkContext) +{ + return AppBoxRenderView::create(boxInfo, ewkContext); +} diff --git a/src/Plugin/AppBoxPlugin/AppBoxPluginFactory.h b/src/Plugin/AppBoxPlugin/AppBoxPluginFactory.h new file mode 100644 index 0000000..b01a4a5 --- /dev/null +++ b/src/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 +#include +#include +#include +#include +#include +#include +#include + +// forward declaration +struct BoxInfo; + +class AppBoxPluginFactory: public IBoxPluginFactory { + public: + IRenderViewPtr createRenderView( + std::shared_ptr boxInfo, + std::shared_ptr ewkContext); + + AppBoxPluginFactory() {}; + ~AppBoxPluginFactory() {}; +}; + +#endif //APP_BOX_PLUGIN_FACTORY_H diff --git a/src/Plugin/AppBoxPlugin/AppBoxRenderView.cpp b/src/Plugin/AppBoxPlugin/AppBoxRenderView.cpp new file mode 100755 index 0000000..63ef18d --- /dev/null +++ b/src/Plugin/AppBoxPlugin/AppBoxRenderView.cpp @@ -0,0 +1,998 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "AppBoxGbarHelper.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 30.0 +#define WEB_WIDGET_OBJ_MOVE_TO_OUTSIDE_POINT_VALUE -10000 + +namespace{ +// injection javascript file regarding creating js object used by box and gbar +static const std::string kInjectionFile("/usr/share/web-provider/injection.js"); +static const std::string kConsoleMessageLogTag("ConsoleMessage"); +static const std::string kJsRegisterBoxInfoFunction( + "webprovider.registerAppWidgetContextInfo"); +} + +AppBoxRenderView::AppBoxRenderView( + BoxInfoPtr boxInfo, + EwkContextPtr ewkContext) + : RenderView(boxInfo, false) + , m_appId() + , m_boxId() + , m_instanceId() + , m_contentInfo() + , m_blockedURI() + , m_ewkContext(ewkContext) + , m_boxRenderInfo() + , m_boxWrt() + , m_gbarWrt() + , m_boxRenderBuffer() + , m_gbarRenderBuffer() + , m_boxSnapshot() + , m_boxRenderTimer() + , m_boxTouchTimer() + , m_boxRemoveSnapShotTimer() + , m_gbarHelper() + , m_boxIcon() + , m_gbarFastOpen(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"); + + if( boxInfo == NULL ){ + LogE("boxInfo is NULL!"); + throw; + } + + // 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 ENABLE(SHOW_PRE_ICON) + if (!m_showIcon) { + pkgmgrinfo_appinfo_h handle; + int ret; + char *icon; + + ret = pkgmgrinfo_appinfo_get_appinfo(m_appId.c_str(), &handle); + if (ret != PMINFO_R_OK) { + LogE("[%s] DB_FAILED(0x) : failed to get the app-info", __FUNCTION__); + } else { + ret = pkgmgrinfo_appinfo_get_icon(handle, &icon); + if (ret != PMINFO_R_OK) { + LogE("pkgmgrinfo_appinfo_get_icon failed"); + } else { + showIcon(icon, boxInfo->boxWidth, boxInfo->boxHeight); + } + ret = pkgmgrinfo_appinfo_destroy_appinfo(handle); + if (ret != PMINFO_R_OK) { + LogE("pkgmgrinfo_appinfo_get_icon failed"); + } + } + } +#endif + + // use fastopen to default + // m_gbarFastOpen = web_provider_widget_get_gbar_fast_open(m_boxId.c_str()) ? true : false; + m_gbarFastOpen = true; + m_isTouchableBox = + web_provider_widget_get_mouse_event(m_boxId.c_str()) ? true : false; +} + +AppBoxRenderView::~AppBoxRenderView() +{ + LogD("enter"); + + destroyWrtCore(m_boxWrt); + destroyWrtCore(m_gbarWrt); +} + +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 gbar open + if (m_gbarHelper) { + m_gbarHelper->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_WIDGET_OBJ_MOVE_TO_OUTSIDE_POINT_VALUE, WEB_WIDGET_OBJ_MOVE_TO_OUTSIDE_POINT_VALUE); + + m_boxWrt->Show(); + m_boxRenderInfo = boxRenderInfo; + + // start timer for clearing existing snapshot in case of only gabr 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::finishGbarLoadCallback, 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); + cbs->blockedUrlPolicyCallback = std::bind(&AppBoxRenderView::blockedUrlPolicy, this, _1); + 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::destroyGbarWrtCore() +{ + LogD("enter"); + + destroyWrtCore(m_gbarWrt); + m_gbarWrt.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::showGbar(RenderInfoPtr gbarRenderInfo, RenderInfoPtr boxRenderInfo) +{ + LogD("enter"); + + std::string gbarStartUrl = getStartUrl(URL_TYPE_GBAR, gbarRenderInfo->defaultUrlParams); + if (m_gbarFastOpen) { + destroyGbarWrtCore(); + m_gbarWrt = createWrtCore(URL_TYPE_GBAR, gbarStartUrl, gbarRenderInfo->window, m_ewkContext); + if (!m_gbarWrt) { + LogD("no wrt core instance"); + return; + } + m_gbarHelper = AppBoxGbarHelper::create(gbarRenderInfo->window); + + // resize webview fitted to width, height of gbar + evas_object_resize( + m_gbarWrt->GetCurrentWebview(), + gbarRenderInfo->width, + gbarRenderInfo->height); + // show gbar + m_gbarWrt->Show(); + m_gbarHelper->finishOpen(m_gbarWrt->GetCurrentWebview()); + } else { + m_gbarHelper = GbarHelper::create(gbarRenderInfo, gbarStartUrl); + } + + // show gbar window + evas_object_show(gbarRenderInfo->window); + + // need to create new snapshot when m_napshot is empty + if (!m_boxSnapshot) { + evas_object_show(getCurrentSnapShot()); + } + getGbarBuffer()->setWebView(m_gbarWrt->GetCurrentWebview()); + // show box + showBox(boxRenderInfo); + + // start timer for clearing existing snapshot in case of only gbar open + addTimer(&m_boxRemoveSnapShotTimer, SNAPSHOT_REMOVE_TIME, removeBoxSnapShotTimerCallback); +} + +void AppBoxRenderView::hideGbar() +{ + LogD("enter"); + + if (m_gbarFastOpen) { + destroyGbarWrtCore(); + } + m_gbarHelper->close(); + m_gbarHelper.reset(); + + // start timer for clearing existing snapshot in case of only gbar 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::didGbarTouched(int x, int y) +{ + LogD("x : %d, y: %d", x, y); +} + +Evas_Object* AppBoxRenderView::getBoxWebView() +{ + if (!m_gbarHelper) { + 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 GBAR's webview. + return m_gbarHelper->getBoxWebView(); + } +} + +Evas_Object* AppBoxRenderView::getGbarWebView() +{ + if (!m_gbarHelper) { + return NULL; + } + + return m_gbarHelper->getGbarWebView(); +} + +std::string AppBoxRenderView::getAppId(std::string& boxId) +{ + LogD("enter"); + + char* appId = web_provider_widget_get_app_id(boxId.c_str()); + if (!appId) { + LogD("no appid of %s", boxId.c_str()); + return std::string(); + } + + std::string ret = std::string(appId); + free(appId); + return ret; +} + +std::string AppBoxRenderView::getStartUrl(UrlType type, std::string& defaultParams) +{ + char* path = NULL; + switch (type) { + case URL_TYPE_BOX: + path = widget_service_get_widget_script_path(m_boxId.c_str()); + break; + case URL_TYPE_GBAR: + path = widget_service_get_gbar_script_path(m_boxId.c_str()); + break; + default: + LogD("no available type"); + } + + std::string startUrl; + if (path) { + LogD("path : %s", path); + startUrl = path; + free(path); + path = NULL; + } 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 == NULL ) + return; + if (*timer) { + deleteTimer(timer); + } + + *timer = ecore_timer_add(interval, callback, this); +} + +void AppBoxRenderView::deleteTimer(Ecore_Timer** timer) +{ + LogD("enter"); + if( timer == NULL ) + return; + 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; + } +#if !ENABLE(WEBKIT_UPVERSION) + Ewk_Settings* setting = ewk_view_settings_get(webview); + // disable shadow effect on scrolling + 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, 0); + + // 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, kConsoleMessageLogTag.c_str(), format, args); + break; + case DLOG_WARN: + ALOG_VA(LOG_WARN, kConsoleMessageLogTag.c_str(), format, args); + break; + case DLOG_ERROR: + ALOG_VA(LOG_ERROR, kConsoleMessageLogTag.c_str(), format, args); + break; + default: + ALOG_VA(LOG_DEBUG, kConsoleMessageLogTag.c_str(), format, args); + break; + } + va_end(args); +} + +Eina_Bool AppBoxRenderView::fireBoxRenderTimerCallback(void* data) +{ + LogD("enter"); + + AppBoxRenderView* This = static_cast(data); + if( This == NULL) + return ECORE_CALLBACK_CANCEL; + + This->m_boxRenderTimer = NULL; + This->stopRenderBox(); + + return ECORE_CALLBACK_CANCEL; +} + +Eina_Bool AppBoxRenderView::fireBoxTouchTimerCallback(void* data) +{ + + LogD("enter"); + AppBoxRenderView* This = static_cast(data); + if( This == NULL) + return ECORE_CALLBACK_CANCEL; + + 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(data); + if( This == NULL) + return ECORE_CALLBACK_CANCEL; + + 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::openGbarIdlerCallback(void* data) +{ + LogD("enter"); + AppBoxRenderView* This = static_cast(data); + if (This && This->m_gbarHelper) { + This->m_gbarHelper->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(kInjectionFile); + std::string jsString((std::istreambuf_iterator(jsFile)), + std::istreambuf_iterator()); + + std::ostringstream script; + script << jsString; + + // add javascripts for operation of synchronous call + script << kJsRegisterBoxInfoFunction << "('box-id', '" << m_boxId << "');"; + script << kJsRegisterBoxInfoFunction << "('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; + } + + if (!m_gbarHelper) { + // 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_gbarFastOpen) { + if (!(m_gbarHelper->isGbarOpened()) && + webview == m_gbarHelper->getBoxWebView()) + { + // open gbar + ecore_idler_add(openGbarIdlerCallback, this); + } + } + } + + // set flag + m_boxFinishLoad = true; +} + +void AppBoxRenderView::finishGbarLoadCallback(Evas_Object* webview, void* eventInfo) +{ + LogD("enter"); + UNUSED_PARAM(eventInfo); + if (!webview) { + return; + } +} + +void AppBoxRenderView::createWindowBeforeCallback(Evas** canvas, Evas_Object* parent) +{ + LogD("enter"); + + if (m_gbarHelper) { + if (!(m_gbarHelper->isGbarOpened()) && + parent == m_gbarHelper->getBoxWebView()) + { + LogD("gbar canvas is used"); + *canvas = m_gbarHelper->getGbarCanvas(); + 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_gbarHelper) { + 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 + evas_object_show(parent); + m_gbarHelper->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); +} + +bool AppBoxRenderView::decideNavigationCallback(Evas_Object* webview, void* eventInfo) +{ + LogD("enter"); + UNUSED_PARAM(webview); + + Ewk_Policy_Decision* policyDecision = static_cast(eventInfo); + const char* url = ewk_policy_decision_url_get(policyDecision); + if (!url || !*url) { + LogE("url is empty"); + return false; + } + std::string uri(url); + if(m_blockedURI == uri) { + LogE("url is blocked by policy: %s ", url); + return false; + } + + // navigation of box scheme should be ignored + processBoxScheme(uri); + return true; +} + +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(data); + + if( This == NULL ) + return; + + // 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(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()); +} + +bool AppBoxRenderView::blockedUrlPolicy (const std::string& blockedUrl) +{ + LogD("Request was blocked : %s \n", blockedUrl.c_str() ); + m_blockedURI = blockedUrl; + return true; +} + +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(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); + + widget_damage_region_s region; + region.x = 0; + region.y = 0; + region.w = width; + region.h = height; + + widget_provider_send_updated( + m_boxId.c_str(), + m_instanceId.c_str(), + WIDGET_PRIMARY_BUFFER, + ®ion, + 0, + NULL); + + m_boxIcon = snapshot; + m_showIcon = true; +} diff --git a/src/Plugin/AppBoxPlugin/AppBoxRenderView.h b/src/Plugin/AppBoxPlugin/AppBoxRenderView.h new file mode 100755 index 0000000..d6af57f --- /dev/null +++ b/src/Plugin/AppBoxPlugin/AppBoxRenderView.h @@ -0,0 +1,146 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class AppBoxRenderBuffer; + +class AppBoxRenderView: public RenderView { + public: + typedef std::shared_ptr 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 showGbar(RenderInfoPtr gbarRenderInfo, RenderInfoPtr boxRenderInfo); + virtual void hideGbar(); + virtual void didBoxTouched(int x, int y); + virtual void didGbarTouched(int x, int y); + virtual ~AppBoxRenderView(); + + private: + // type definition + typedef std::shared_ptr WrtCorePtr; + enum UrlType { + URL_TYPE_BOX, + URL_TYPE_GBAR + }; + + WrtCorePtr createWrtCore( + UrlType type, std::string& startUrl, + Evas_Object* win, EwkContextPtr ewkContext); + void setWebViewBasicSetting(Evas_Object* webview); + void destroyWrtCore(WrtCorePtr wrt); + void destroyBoxWrtCore(); + void destroyGbarWrtCore(); + Evas_Object* getBoxWebView(); + Evas_Object* getGbarWebView(); + 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 openGbarIdlerCallback(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 finishGbarLoadCallback(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); + bool decideNavigationCallback(Evas_Object* webview, void* eventInfo); + void crashWebProcessCallback(Evas_Object* webview, void* eventInfo); + void consoleMessageCallback(Evas_Object* webview, void* eventInfo); + bool blockedUrlPolicy (const std::string& blockedUrl); + + // constructor + explicit AppBoxRenderView(BoxInfoPtr boxInfo, EwkContextPtr ewkContext); + + // members + std::string m_appId; + std::string m_boxId; + std::string m_instanceId; + std::string m_contentInfo; + std::string m_blockedURI; + EwkContextPtr m_ewkContext; + RenderInfoPtr m_boxRenderInfo; + WrtCorePtr m_boxWrt; + WrtCorePtr m_gbarWrt; + IRenderBufferPtr m_boxRenderBuffer; + IRenderBufferPtr m_gbarRenderBuffer; + Evas_Object* m_boxSnapshot; + Ecore_Timer* m_boxRenderTimer; + Ecore_Timer* m_boxTouchTimer; + Ecore_Timer* m_boxRemoveSnapShotTimer; + IGbarHelperPtr m_gbarHelper; + Evas_Object* m_boxIcon; + + // for check status of webview + bool m_gbarFastOpen; + 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/Plugin/AppBoxPlugin/CMakeLists.txt b/src/Plugin/AppBoxPlugin/CMakeLists.txt new file mode 100644 index 0000000..63b38e9 --- /dev/null +++ b/src/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 + dlog + widget_service + widget_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}/AppBoxGbarHelper.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/Plugin/AppBoxPlugin/app.json b/src/Plugin/AppBoxPlugin/app.json new file mode 100644 index 0000000..6388702 --- /dev/null +++ b/src/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/Plugin/AppBoxPlugin/box_plugin_interface.cpp b/src/Plugin/AppBoxPlugin/box_plugin_interface.cpp new file mode 100644 index 0000000..ca5e65e --- /dev/null +++ b/src/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 +#include +#include +#include +#include "AppBoxManager.h" +#include "AppBoxPluginFactory.h" + +static std::shared_ptr 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/Plugin/BoxPluginConnector.cpp b/src/Plugin/BoxPluginConnector.cpp new file mode 100755 index 0000000..6d0aa0d --- /dev/null +++ b/src/Plugin/BoxPluginConnector.cpp @@ -0,0 +1,188 @@ +/* + * 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 +#include +#include +#include +#include +#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 widget plugins"); + web_provider_plugin_release_installed_list(pluginList, count); + 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 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( + dlsym(handle, WEB_PROVIDER_PLUGIN_INTERFACE_SYM_INITIALIZE)); + pluginInfo->command = + reinterpret_cast( + dlsym(handle, WEB_PROVIDER_PLUGIN_INTERFACE_SYM_COMMAND)); + pluginInfo->shutdown = + reinterpret_cast( + 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 = m_pluginMap[boxInfo->boxType]; + if (!plugin) { + LogD("not available widget 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/Plugin/BoxPluginConnector.h b/src/Plugin/BoxPluginConnector.h new file mode 100644 index 0000000..5ada8db --- /dev/null +++ b/src/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 +#include +#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 > pluginMap; + + pluginMap m_pluginMap; + +}; + +#endif // BOX_PLUGIN_CONNECTOR_H diff --git a/src/Plugin/CMakeLists.txt b/src/Plugin/CMakeLists.txt new file mode 100644 index 0000000..952d980 --- /dev/null +++ b/src/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 widget +ADD_SUBDIRECTORY(AppBoxPlugin) diff --git a/src/Plugin/IBoxPluginConnector.h b/src/Plugin/IBoxPluginConnector.h new file mode 100644 index 0000000..3e94fb8 --- /dev/null +++ b/src/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 +#include +#include +#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 IBoxPluginConnectorPtr; + +#endif // I_BOX_PLUGIN_CONNECTOR_H diff --git a/src/Plugin/IBoxPluginFactory.h b/src/Plugin/IBoxPluginFactory.h new file mode 100644 index 0000000..170d6a7 --- /dev/null +++ b/src/Plugin/IBoxPluginFactory.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 IBoxPluginFactory.h + * @author Yunchan Cho (yunchan.cho@samsung.com) + */ +#ifndef I_BOX_PLUGIN_FACTORY_H +#define I_BOX_PLUGIN_FACTORY_H + +#include +#include +#include +#include +#include + +// forward declaration +class IRenderView; +struct BoxInfo; + +class IBoxPluginFactory { + public: + virtual std::shared_ptr createRenderView( + std::shared_ptr boxInfo, + std::shared_ptr ewkContext) = 0; + virtual ~IBoxPluginFactory() {}; +}; + +typedef std::shared_ptr IBoxPluginFactoryPtr; + +#endif //I_BOX_PLUGIN_FACTORY_H diff --git a/src/Plugin/box_plugin_interface.h b/src/Plugin/box_plugin_interface.h new file mode 100755 index 0000000..5b503bc --- /dev/null +++ b/src/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 +#include + +#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_GBAR, + REQUEST_CMD_CLOSE_GBAR, + 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\)"` diff --git a/widget.web-provider.efl b/widget.web-provider.efl new file mode 100644 index 0000000..5a1afb8 --- /dev/null +++ b/widget.web-provider.efl @@ -0,0 +1,44 @@ +com.samsung.w-home widget.web-provider x----- ------ +widget.web-provider widget.web-provider::db rwxat- ------ +widget.web-provider system::vconf_setting rwxat- ------ +widget.web-provider system::vconf_network rwxat- ------ +widget.web-provider system::vconf_system rwxat- ------ +widget.web-provider system::vconf rwxat- ------ +widget.web-provider system::vconf_inhouse rwxat- ------ +widget.web-provider system::vconf_multimedia rwxat- ------ +widget.web-provider system::vconf_misc rwxat- ------ +widget.web-provider system::homedir rwxat- ------ +widget.web-provider system::use_internet rwxat- ------ +widget.web-provider system::media rwxat- ------ +widget.web-provider system::share rwxat- ------ +widget.web-provider device::app_logging rwxat- ------ +widget.web-provider data-provider-master rwxat- ------ +widget.web-provider data-provider-master::share rwxat- ------ +widget.web-provider data-provider-master::data rwxat- ------ +widget.web-provider data-provider-master::db rwxat- ------ +widget.web-provider data-provider-master::provider rwxat- ------ +widget.web-provider wrt-security-daemon::db rwxat- ------ +widget.web-provider wrt-security-daemon rwxat- ------ +widget.web-provider cert-svc rwxat- ------ +widget.web-provider wrt-commons::db_wrt rwxat- ------ +widget.web-provider syslogd rwxat- ------ +widget.web-provider xorg rwxat- ------ +widget.web-provider isf rwxat- ------ +widget.web-provider dbus rwxat- ------ +widget.web-provider e17 rwxat- ------ +widget.web-provider pulseaudio rwxat- ------ +widget.web-provider ail::db rwxat- ------ +widget.web-provider sys-assert::core rwxat- ------ +widget.web-provider webkit2-efl rwxat- ------ +widget.web-provider app-svc rwxat- ------ +widget.web-provider app-svc::db rwxat- ------ +widget.web-provider svi-data rwxat- ------ +widget.web-provider sound_server rwxat- ------ +widget.web-provider pkgmgr::db rwxat- ------ +widget.web-provider privacy-manager::db rwxat- ------ +widget.web-provider media-data::db rwxat- ------ +widget.web-provider immvibed rwxat- ------ +system::use_internet widget.web-provider rwxat- ------ +widget.web-provider aul::launch rwxat- ------ +widget.web-provider aul::terminate rwxat- ------ +widget.web-provider tts-server rwxat- ------ diff --git a/widget.web-provider.manifest b/widget.web-provider.manifest new file mode 100755 index 0000000..54a17be --- /dev/null +++ b/widget.web-provider.manifest @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + diff --git a/widget.web-provider.xml b/widget.web-provider.xml new file mode 100644 index 0000000..b4ac6e6 --- /dev/null +++ b/widget.web-provider.xml @@ -0,0 +1,18 @@ + + + + Yunchan Cho + Web Widget Provider Executable + + widget.web-provider.png + + + + + + + + + + + -- 2.7.4