From: jk7744.park Date: Tue, 8 Sep 2015 16:33:11 +0000 (+0900) Subject: tizen 2.3.1 release X-Git-Tag: submit/tizen_2.3.1/20150915.091042 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=885cca9fd4a072fc19ca73ac09bf9a7e01c690b7;p=framework%2Fweb%2Fwearable%2Fwrt.git tizen 2.3.1 release --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4911e5b --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +Build-arm +Build-i586 + +# FIXME: It should be considered to moving into build directory. +data/Wrt.edj +data/generic_popup.edj +data/generic_popup_horizontal.edj +debugfiles.list +debuglinks.list +debugsources.list +pkgconfig/wrt-core.pc diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..e6b59ad --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,254 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @author Pawel Sikorski (p.sikorski@samsung.com) +# @version 1.0 +# @brief +# + +# Check minimum CMake version +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +# Project name +PROJECT(wrt) + +INCLUDE(FindPkgConfig) + +STRING(REGEX MATCH "([^.]*)" PROJECT_API_VERSION "${PROJECT_VERSION}") +ADD_DEFINITIONS("-DPROJECT_API_VERSION=\"$(PROJECT_API_VERSION)\"") +MESSAGE(STATUS "Version from changelog: ${PROJECT_VERSION}") +#ADD_DEFINITIONS("-DWRT_SMACK_ENABLED") + +############################# +# Build type +IF(NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE "Release") +ENDIF(NOT CMAKE_BUILD_TYPE) + +OPTION(DPL_LOG "DPL logs status" ON) +SET(LOG_TAG "WRT") +OPTION(WITH_TESTS "Build tests" OFF) +OPTION(CSP_SUPPORT "Support for csp policy" ON) +OPTION(ALLOW_NAVIGATION_SUPPORT "Support for allow-navigation" ON) +OPTION(APP_SCHEME_SUPPORT "Support for app:// scheme" OFF) +OPTION(CORS_WHITELISTING_SUPPORT "CORS white listing for access positions" OFF) +OPTION(ORIENTATION_SUPPORT "Support for screen orientation" OFF) +OPTION(JOURNAL_LOG_SUPPORT "Enable journal log" ON) + +IF(JOURNAL_LOG_SUPPORT) + ADD_DEFINITIONS("-DJOURNAL_LOG_SUPPORT") +ENDIF(JOURNAL_LOG_SUPPORT) + +IF(CSP_SUPPORT) + ADD_DEFINITIONS("-DCSP_ENABLED") +ENDIF(CSP_SUPPORT) +IF(ALLOW_NAVIGATION_SUPPORT) + ADD_DEFINITIONS("-DALLOW_NAVIGATION_ENABLED") +ENDIF(ALLOW_NAVIGATION_SUPPORT) +IF(APP_SCHEME_SUPPORT) + ADD_DEFINITIONS("-DAPP_SCHEME_ENABLED") +ENDIF(APP_SCHEME_SUPPORT) +IF(CORS_WHITELISTING_SUPPORT) + ADD_DEFINITIONS("-DCORS_WHITELISTING_ENABLED") +ENDIF(CORS_WHITELISTING_SUPPORT) +IF(ORIENTATION_SUPPORT) + ADD_DEFINITIONS("-DORIENTATION_ENABLED") +ENDIF(ORIENTATION_SUPPORT) + +# logs can be only enabled in debug mode +IF(CMAKE_BUILD_TYPE MATCHES "Profiling" AND DPL_LOG) + MESSAGE(STATUS "Logging disabled for DPL") +ELSE(CMAKE_BUILD_TYPE MATCHES "Profiling" AND DPL_LOG) + ADD_DEFINITIONS("-DDPL_LOGS_ENABLED") + MESSAGE(STATUS "Logging enabled for DPL") +ENDIF(CMAKE_BUILD_TYPE MATCHES "Profiling" AND DPL_LOG) + +MESSAGE(STATUS "WITH_TESTS: " ${WITH_TESTS}) +MESSAGE(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") +OPTION(PROFILING "Profiling status" OFF) +IF(CMAKE_BUILD_TYPE MATCHES "Profiling") + MESSAGE(STATUS "PROFILING: ENABLED") + ADD_DEFINITIONS("-DPROFILING_ENABLED") + SET(PROFILING ON) +ELSE(CMAKE_BUILD_TYPE MATCHES "Profiling") + MESSAGE(STATUS "PROFILING: DISABLED") +ENDIF(CMAKE_BUILD_TYPE MATCHES "Profiling") + +SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/build") +INCLUDE(Options) + +# Compiler flags +SET(CMAKE_C_FLAGS_PROFILING "-O2") +SET(CMAKE_CXX_FLAGS_PROFILING "-O2 -std=c++0x") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -std=c++0x -g") +SET(CMAKE_C_FLAGS_RELEASE "-Os") +SET(CMAKE_CXX_FLAGS_RELEASE "-Os -std=c++0x -fvisibility-inlines-hidden") +SET(CMAKE_CXX_FLAGS_CCOV "-O0 -std=c++0x -g --coverage") + +ADD_DEFINITIONS("-fPIC") # If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table. This option makes a difference on the m68k, PowerPC and SPARC. (BJ: our ARM too?) +#ADD_DEFINITIONS("-fvisibility=hidden") # Set the default ELF image symbol visibility to hidden - all symbols will be marked with this unless overridden within the code. + +# Set compiler warning flags +#ADD_DEFINITIONS("-Werror") # Make all warnings into errors. +ADD_DEFINITIONS("-Wall") # Generate all warnings +ADD_DEFINITIONS("-Wextra") # Generate even more extra warnings +ADD_DEFINITIONS("-Wno-variadic-macros") # Inhibit variadic macros warnings (needed for ORM) +#ADD_DEFINITIONS("-ansi") # Accept only ANSI code +#ADD_DEFINITIONS("-pedantic") # Accept only pedantic code +#ADD_DEFINITIONS("-Weffc++") # Accept only effective C++ code +#ADD_DEFINITIONS("-Wwrite-strings") # Do not accept writing to contant string memory +#ADD_DEFINITIONS("-Winit-self") # Do not accept initializing variable with itself +#ADD_DEFINITIONS("-Wcast-align") # Do not accept misaligning with casting +#ADD_DEFINITIONS("-Wcast-qual") # Do not accept removing qualifiers with casting +#ADD_DEFINITIONS("-Wold-style-cast") # Do not accept old style casting +#ADD_DEFINITIONS("-Wpointer-arith") # Warn about void pointer arthimetic +#ADD_DEFINITIONS("-Wstrict-aliasing") # Ensure strict aliasing +#ADD_DEFINITIONS("-Wuninitialized") # Do not accept uninitialized variables +#ADD_DEFINITIONS("-Wmissing-declarations") # Warn about global and non-accesible functions +#ADD_DEFINITIONS("-Woverloaded-virtual") # Warn about incidental overiding non-virtual base methods +#ADD_DEFINITIONS("-Wnon-virtual-dtor") # Warn about non-virtual destructor +#ADD_DEFINITIONS("-Wctor-dtor-privacy") # Warn about useless and non-constructible classes +#ADD_DEFINITIONS("-Wlong-long") # Do not allow using long long +#ADD_DEFINITIONS("-Wunreachable-code") # Warn about unreachable code +#ADD_DEFINITIONS("-Wfloat-equal") # Do not accept comparing floating points with equal operator +#ADD_DEFINITIONS("-Wabi") # Warn about possible ABI problems +#ADD_DEFINITIONS("-Wswitch-enum") # Check switch enumeration +#ADD_DEFINITIONS("-Wformat=2") # Check printf formatting +#ADD_DEFINITIONS("-Wundef") # Warn if an undefined identifier is evaluated in an @if directive. +#ADD_DEFINITIONS("-Wshadow") # Warn whenever a local variable shadows another local variable, parameter or global variable or whenever a built-in function is shadowed +#ADD_DEFINITIONS("-Wconversion") # Warn for implicit conversions that may alter a value +#ADD_DEFINITIONS("-Wlogical-op") # Warn about suspicious uses of logical operators in expressions +#ADD_DEFINITIONS("-Waggregate-return") # Warn if any functions that return structures or unions are defined or called. +#ADD_DEFINITIONS("-Wmissing-field-initializers") # Warn if a structure's initializer has some fields missing. +#ADD_DEFINITIONS("-Wredundant-decls") # Warn if anything is declared more than once in the same scope, even in cases where multiple declaration is valid and changes nothing. +#ADD_DEFINITIONS("-Wmissing-include-dirs") # Warn if a user-supplied include directory does not exist. +#ADD_DEFINITIONS("-Wswitch-default") # Warn whenever a switch statement does not have a default case. +#ADD_DEFINITIONS("-Wsync-nand") # Warn when __sync_fetch_and_nand and __sync_nand_and_fetch built-in functions are used. These functions changed semantics in GCC 4.4. +#ADD_DEFINITIONS("-Wunused") # All the above -Wunused options combined. +#ADD_DEFINITIONS("-Wstrict-overflow=5") # Also warn about cases where the compiler reduces the magnitude of a constant involved in a comparison. +#ADD_DEFINITIONS("-Wunsafe-loop-optimizations") # Warn if the loop cannot be optimized because the compiler could not assume anything on the bounds of the loop indices. With -funsafe-loop-optimizations warn if the compiler made such assumptions. +#ADD_DEFINITIONS("-Wmissing-format-attribute") # Warn about function pointers which might be candidates for format attributes. +#ADD_DEFINITIONS("-Wpadded") # Warn if padding is included in a structure, either to align an element of the structure or to align the whole structure. +#ADD_DEFINITIONS("-Winline") # Warn if a function can not be inlined and it was declared as inline. +#ADD_DEFINITIONS("-Wdisabled-optimization") # Warn if a requested optimization pass is disabled. +ADD_DEFINITIONS("-Wno-deprecated") # No warnings about deprecated features + +############################# +# Targets names +SET(TARGET_WRT_ENGINE_STATIC "wrt-engine-static") +SET(TARGET_TESTS_COMMON_LIB "wrt-engine-tests-lib") #tests only +SET(TARGET_PROFILING_LIB "wrt-profiling") +SET(TARGET_PLUGIN_MODULE_LIB "wrt-plugin-module") +SET(TARGET_VIEW_MODULE_LIB "wrt-view-module") +SET(TARGET_VIEW_COMMON_LIB_STATIC "wrt-view-common") +SET(TARGET_CORE_MODULE_LIB "wrt-core-module") +SET(TARGET_INJECTED_BUNDLE_LIB "wrt-injected-bundle") +SET(PROF_LIB "") +IF(PROFILING) + SET(PROF_LIB ${TARGET_PROFILING_LIB}) +ENDIF(PROFILING) + +############################# +# definitions +ADD_DEFINITIONS("-DWRT_EDJ_PATH=\"/usr/share/edje/wrt/Wrt.edj\"") + +############################# +# edc build +ADD_CUSTOM_COMMAND( + OUTPUT ${PROJECT_SOURCE_DIR}/data/Wrt.edj + COMMAND edje_cc + ARGS ${PROJECT_SOURCE_DIR}/data/Wrt.edc + ${PROJECT_SOURCE_DIR}/data/Wrt.edj + DEPENDS ${PROJECT_SOURCE_DIR}/data/Wrt.edc +) +ADD_CUSTOM_TARGET(WRT_EDJE ALL + DEPENDS ${PROJECT_SOURCE_DIR}/data/Wrt.edj +) + +ADD_CUSTOM_COMMAND( + OUTPUT ${PROJECT_SOURCE_DIR}/data/generic_popup.edj + COMMAND edje_cc + ARGS ${PROJECT_SOURCE_DIR}/data/generic_popup.edc + ${PROJECT_SOURCE_DIR}/data/generic_popup.edj + DEPENDS ${PROJECT_SOURCE_DIR}/data/generic_popup.edc +) +ADD_CUSTOM_TARGET(WRT_GENERIC_POPUP_EDJE ALL + DEPENDS ${PROJECT_SOURCE_DIR}/data/generic_popup.edj +) + +ADD_CUSTOM_COMMAND( + OUTPUT ${PROJECT_SOURCE_DIR}/data/generic_popup_horizontal.edj + COMMAND edje_cc + ARGS ${PROJECT_SOURCE_DIR}/data/generic_popup_horizontal.edc + ${PROJECT_SOURCE_DIR}/data/generic_popup_horizontal.edj + DEPENDS ${PROJECT_SOURCE_DIR}/data/generic_popup_horizontal.edc +) +ADD_CUSTOM_TARGET(WRT_GENERIC_POPUP_HORIZONTAL_EDJE ALL + DEPENDS ${PROJECT_SOURCE_DIR}/data/generic_popup_horizontal.edj +) + +############################# +# install +INSTALL(FILES + ${PROJECT_SOURCE_DIR}/wrt_reset_db.sh + ${PROJECT_SOURCE_DIR}/wrt_reset_all.sh + DESTINATION /usr/bin/ +) +INSTALL(FILES + ${PROJECT_SOURCE_DIR}/data/Wrt.edj + DESTINATION share/edje/wrt/ +) +INSTALL(FILES + ${PROJECT_SOURCE_DIR}/data/generic_popup.edj + ${PROJECT_SOURCE_DIR}/data/generic_popup_horizontal.edj + DESTINATION share/edje/ace/ +) + +############################# +# install launchpad files +INSTALL(FILES ${CMAKE_SOURCE_DIR}/wrt_env.sh + DESTINATION /etc/profile.d/ +) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/wrt_launchpad_daemon.efl + DESTINATION /etc/smack/accesses.d/ +) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/wrt-launcher.efl + DESTINATION /etc/smack/accesses.d/ +) +INSTALL(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/systemd/wrt_launchpad_daemon.service + DESTINATION /usr/lib/systemd/system/ +) + +ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(po) + +SET(WRT_API_NEW_INCLUDES + "${PROJECT_SOURCE_DIR}/src/api_new/" + "${PROJECT_SOURCE_DIR}/src/domain/" + "${PROJECT_SOURCE_DIR}/src/view/") + +SET(PKGCONFIG_DIR ${PROJECT_SOURCE_DIR}/pkgconfig) + +CONFIGURE_FILE(${PKGCONFIG_DIR}/wrt-core.pc.in + ${PKGCONFIG_DIR}/wrt-core.pc @ONLY) +INSTALL(FILES ${PKGCONFIG_DIR}/wrt-core.pc DESTINATION lib/pkgconfig) + +IF(WITH_TESTS) + add_subdirectory(tests) +ENDIF(WITH_TESTS) diff --git a/DESCRIPTION b/DESCRIPTION new file mode 100644 index 0000000..68aa8f4 --- /dev/null +++ b/DESCRIPTION @@ -0,0 +1 @@ +Main package folder diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100644 index 0000000..247c97d --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,203 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + 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. + + 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, + 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 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 in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) 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 + + (d) 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. + + 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 Apache License to your work. + + To apply the Apache 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 Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT 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/LICENSE.Flora b/LICENSE.Flora new file mode 100644 index 0000000..4a0af40 --- /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/NOTICE b/NOTICE new file mode 100644 index 0000000..ded3804 --- /dev/null +++ b/NOTICE @@ -0,0 +1 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. \ No newline at end of file diff --git a/README b/README new file mode 100755 index 0000000..cc937dc --- /dev/null +++ b/README @@ -0,0 +1,39 @@ +README file for WARP PATENT ISSUE + +The files below have been implemented in compliance with W3C WARP SPEC. + +src/domain/efl/view_logic.cpp +src/domain/warp_iri.cpp +src/domain/widget_data_types.h +tests/warp_tests/TestCases.cpp +tests/warp_tests/WarpIriTestBase.cpp + +There are some patent issue between W3C WARP SPEC and APPPLE. +If you want to use this files, refer to the W3C Notices. + +[W3C Notice] +http://www.w3.org/2010/12/cfpa +refer to the WARP_Widgets_Access Request Policy_PAG Report_49839.pdf in root directory or http://www.w3.org/2009/11/widgets-pag/pagreport + + +W3C's Disclaimer +-------------------------------------------------------------------------------------------------------------------------------------- +Although portions of this PAG analysis were drafted by attorneys following review of the facts, +none of the authors is your attorney. No part of this report is intended as legal advice either to W3C or to its members. +It is intended merely as a summary of what the PAG has learned to date. +Rely on this report entirely at your own risk. However, nothing should prevent even +an attorney from expressing his or her personal opinions, and so this analysis includes the personal opinions of the authors. + +With respect to W3C, the publication of the WARP Candidate Recommendation would not, by itself, be patent infringement +of any patents owned by Apple or anyone else. Implementers and distributors of software products, +though, are encouraged to read the analysis below, consult with their own attorneys, and form their own conclusions. + +THESE RECOMMENDATIONS OF THE PATENT ADVISORY GROUP ARE NOT LEGAL ADVICE. +NEITHER W3C NOR ANY OF THE PARTICIPANTS OF THE WIDGET UPDATES PATENT ADVISORY GROUP +OR THEIR RESPECTIVE EMPLOYERS TAKES ANY RESPONSIBILITY FOR THE ACCURACY, LEGAL CORRECTNESS +OR OTHER FITNESS FOR ANY PURPOSE OF THE INFORMATION PROVIDED IN THIS REPORT. ESPECIALLY, +NEITHER W3C NOR ANY OF THE PARTICIPANTS OF THE WIDGET UPDATES PATENT ADVISORY GROUP +OR ANY OF THEIR RESPECTIVE EMPLOYERS MAKE ANY REPRESENTATION THAT FOLLOWING THE RECOMMENDATIONS +HERE WILL AVOID AN INFRINGEMENT OF THE US PATENT NR. 7,743,336 OR ANY OTHER PATENT MENTIONED + IN THE REPORT OR THE PAGE ON PRIOR ART. +-------------------------------------------------------------------------------------------------------------------------------------- diff --git a/WARP_Widgets_Access Request Policy_PAG Report_49839.pdf b/WARP_Widgets_Access Request Policy_PAG Report_49839.pdf new file mode 100644 index 0000000..c38b56b Binary files /dev/null and b/WARP_Widgets_Access Request Policy_PAG Report_49839.pdf differ diff --git a/build/Options.cmake b/build/Options.cmake new file mode 100644 index 0000000..a230b29 --- /dev/null +++ b/build/Options.cmake @@ -0,0 +1,42 @@ +# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 Options.cmake +# @author Jihoon Chung (jihoon.chung@samsung.com) +# + +# Macro declaration +# - WRT_OPTION() : Wrapper omitting description argument from OPTION() command. +MACRO(WRT_OPTION feature_name on_off) + OPTION(${feature_name} "" ${on_off}) +ENDMACRO(WRT_OPTION) + +# Use Feature +# Use a particular optional platform service or third-party library +# +# Description : +# +# Author : () - +# WRT_OPTION(_USE_ ON/OFF) +#WRT_OPTION(WRT_USE_WEBKIT_UPVERSION OFF) + +# Enable Feature +# Turn on a specific feature of WRT +# +# Description : +# +# Author : () - +# WRT_OPTION(_ENABLE_ ON/OFF) + diff --git a/data/DESCRIPTION b/data/DESCRIPTION new file mode 100644 index 0000000..daacea4 --- /dev/null +++ b/data/DESCRIPTION @@ -0,0 +1,8 @@ +!!!options!!! stop +Data files (edc, icons, certificates, UAP) +Various data files: + - edc layouts + - icons etc + - certificates + - User Agent Profile data (XML) + diff --git a/data/Wrt.edc b/data/Wrt.edc new file mode 100644 index 0000000..9cd48a9 --- /dev/null +++ b/data/Wrt.edc @@ -0,0 +1,445 @@ +collections { + group { + name: "web-application"; + parts { + part { + name: "base"; + scale: 1; + type: RECT; + description { + state: "default" 0.0; + fixed: 1 1; + rel1 { relative: 0 0; offset: 0 0; } + rel2 { relative: 1 1; offset: -1 -1; } + color: 0 0 0 255; + } + description { + state: "transparent" 0.0; + inherit: "default" 0.0; + color: 0 0 0 0; + } + } + part { + name: "elm.swallow.content"; + scale: 1; + type: SWALLOW; + description { + state: "default" 0.0; + fixed: 1 1; + rel1 { relative: 0.0 0.0; to: base; } + rel2 { relative: 1.0 1.0; to: base; } + align: 0.0 0.0; + } + /* ratio 1x1 (only for gear3) */ + description { + state: "ratio1x1" 0.0; + fixed: 1 1; + aspect: 1 1; + aspect_preference: BOTH; + align: 0.5 0.5; + } + } + part { + name: "elm.swallow.progress"; + scale: 1; + type: SWALLOW; + description { + state: "default" 0.0; + visible: 0; + fixed: 0 1; + rel1 { relative: 0.0 0.0; } + rel2 { relative: 1.0 0.0; } + align: 0.5 0.0; + } + description { + state: "visible" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + }//end of parts + programs { + program { name: "show,progress"; + signal: "show,progress,signal"; + action: STATE_SET "visible" 0.0; + target: "elm.swallow.progress"; + } + program { name: "hide,progress"; + signal: "hide,progress,signal"; + action: STATE_SET "default" 0.0; + target: "elm.swallow.progress"; + } + program { name: "show,transparent"; + signal: "show,transparent,signal"; + action: STATE_SET "transparent" 0.0; + target: "base"; + } + program { name: "hide,transparent"; + signal: "hide,transparent,signal"; + action: STATE_SET "default" 0.0; + target: "base"; + } + /* Webview ratio control (for gear3) */ + program { name: "1x1,ratio"; + signal: "1x1,ratio,signal"; + action: STATE_SET "ratio1x1" 0.0; + target: "elm.swallow.content"; + } + program { name: "natural,ratio"; + signal: "natural,ratio,signal"; + action: STATE_SET "default" 0.0; + target: "elm.swallow.content"; + } + }//end of programs + }//end of group + + group { + name: "popupWithCheck"; + parts { + part { + name: "pad_t"; + type: SPACER; + scale: 1; + description { + state: "default" 0.0; + align: 0.5 0.0; + min: 16 0; + fixed: 0 1; + rel1 { relative: 1.0 0.0;to_x: "pad_l"; } + rel2 { relative: 0.0 0.0;to_x: "pad_r"; } + } + } + part { + name: "pad_l"; + type: SPACER; + scale: 1; + description { + state: "default" 0.0; + min: 16 0; + max: 16 0; + fixed: 1 0; + rel1 { relative: 0.0 0.0; } + rel2 { relative: 0.0 1.0; } + align: 0.0 0.0; + } + } + part { + name: "pad_r"; + type: SPACER; + scale: 1; + description { + state: "default" 0.0; + min: 16 0; + max: 16 0; + fixed: 1 0; + rel1 { relative: 1.0 0.0; } + rel2 { relative: 1.0 1.0; } + align: 1.0 0.0; + } + } + part { + name:"elm.swallow.label"; + type: SWALLOW; + scale : 1; + description { + state: "default" 0.0; + fixed: 1 0; + rel1 { + relative: 1.0 1.0; + to_x: "pad_l"; + to_y: "pad_t"; + } + rel2 { + relative: 0.0 0.0; + to_x: "pad_r"; + to_y: "pad_b"; + } + } + } + part { + name: "bottom_pad"; + type: SPACER; + scale: 1; + description { + state: "default" 0.0; + align: 0.0 1.0; + min: 0 16; + fixed: 0 1; + rel1 { relative: 1.0 1.0; to_x: "pad_l"; } + rel2 { relative: 0.0 1.0; to_x: "pad_r"; } + } + } + part { + name: "pad_b"; + type: SPACER; + scale: 1; + description { + state: "default" 0.0; + align: 0.0 1.0; + min: 0 44; + fixed: 0 1; + rel1 { relative: 0.0 0.0; to: "bottom_pad"; } + rel2 { relative: 1.0 0.0; to: "bottom_pad"; } + } + } + part { + name: "end_field"; + type: SPACER; + scale: 1; + description { + state: "default" 0.0; + align: 0.0 1.0; + min: 0 40; + fixed: 0 1; + rel1 { relative: 0.0 1.0; to: "pad_b"; } + rel2 { relative: 1.0 1.0; to: "pad_b"; } + } + } + part { + name: "elm.swallow.checkbox"; + type: SWALLOW; + scale: 1; + description { + state: "default" 0.0; + fixed: 1 1; + align: 0.0 0.5; + rel1.to: "end_field"; + rel2.to: "end_field"; + } + } + } //end of parts + } //end of group + + group { + name: "authRequestPopup"; + parts { + part { + name: "pad_t"; + type: SPACER; + scale: 1; + description { + state: "default" 0.0; + align: 0.5 0.0; + min: 0 32; + fixed: 0 1; + rel1 { relative: 1.0 0.0;to_x: "pad_l"; } + rel2 { relative: 0.0 0.0;to_x: "pad_r"; } + } + } + part { + name: "pad_l"; + type: SPACER; + scale: 1; + description { + state: "default" 0.0; + min: 26 0; + max: 26 0; + fixed: 1 0; + rel1 { relative: 0.0 0.0; } + rel2 { relative: 0.0 1.0; } + align: 0.0 0.0; + } + } + part { + name: "pad_r"; + type: SPACER; + scale: 1; + description { + state: "default" 0.0; + min: 26 0; + max: 26 0; + fixed: 1 0; + rel1 { relative: 1.0 0.0; } + rel2 { relative: 1.0 1.0; } + align: 1.0 0.0; + } + } + part { + name:"elm.swallow.label"; + type: SWALLOW; + scale : 1; + description { + state: "default" 0.0; + fixed: 1 0; + rel1 { + relative: 1.0 1.0; + to_x: "pad_l"; + to_y: "pad_t"; + } + rel2 { + relative: 0.0 0.0; + to_x: "pad_r"; + to_y: "pad_b"; + } + } + } + part { + name: "bottom_pad"; + type: SPACER; + scale: 1; + description { + state: "default" 0.0; + align: 0.0 1.0; + min: 0 32; + fixed: 0 1; + rel1 { relative: 1.0 1.0; to_x: "pad_l"; } + rel2 { relative: 0.0 1.0; to_x: "pad_r"; } + } + } + part { + name: "pad_b"; + type: SPACER; + scale: 1; + description { + state: "default" 0.0; + align: 0.0 1.0; + min: 0 200; + fixed: 0 1; + rel1 { relative: 0.0 0.1; to: "bottom_pad"; } + rel2 { relative: 1.0 0.1; to: "bottom_pad"; } + } + } + part { + name: "pad_m1"; + type: SPACER; + scale: 1; + description { + state: "default" 0.0; + align: 0.0 1.0; + min: 0 32; + fixed: 0 1; + rel1 { relative: 0.0 0.0; to: "pad_b"; } + rel2 { relative: 1.0 0.0; to: "pad_b"; } + } + } + part{ + name:"elm.swallow.idtext"; + type: TEXT; + scale : 1; + description { + state: "default" 0.0; + color: 168 168 168 255; + text { + font: "Tizen:style=Medium"; + size: 35; + align: 0.0 0.5; + } + align: 0.0 0.0; + min: 0 40; + fixed: 0 1; + rel1 { relative: 0.0 1.0; to: "pad_m1"; } + rel2 { relative: 1.0 1.0; to: "pad_m1"; } + } + } + part { + name: "elm.swallow.idfield"; + type: SWALLOW; + scale: 1; + description { + state: "default" 0.0; + align: 0.0 0.0; + min: 0 63; + fixed: 0 1; + rel1 { relative: 0.0 1.0; to: "elm.swallow.idtext"; } + rel2 { relative: 1.0 1.0; to: "elm.swallow.idtext"; } + } + } + part { + name: "pad_m2"; + type: SPACER; + scale: 1; + description { + state: "default" 0.0; + align: 0.0 1.0; + min: 0 32; + fixed: 0 1; + rel1 { relative: 0.0 1.0; to: "elm.swallow.idfield"; } + rel2 { relative: 1.0 1.0; to: "elm.swallow.idfield"; } + } + } + part{ + name:"elm.swallow.pwtext"; + type: TEXT; + scale : 1; + description { + state: "default" 0.0; + color: 168 168 168 255; + text { + font: "Tizen:style=Medium"; + size: 35; + align: 0.0 0.5; + } + align: 0.0 0.0; + min: 0 40; + fixed: 0 1; + rel1 { relative: 0.0 1.0; to: "pad_m2"; } + rel2 { relative: 1.0 1.0; to: "pad_m2"; } + } + } + part { + name: "elm.swallow.pwfield"; + type: SWALLOW; + scale: 1; + description { + state: "default" 0.0; + align: 0.0 0.0; + min: 0 63; + fixed: 0 1; + rel1 { relative: 0.0 1.0; to: "elm.swallow.pwtext"; } + rel2 { relative: 1.0 1.0; to: "elm.swallow.pwtext"; } + } + } + } //end of parts + } //end of group + + group { name: "elm/button/base/wrt"; + #define BUTTON_HEIGHT 78.0 + parts { + part { name: "bg"; + type: RECT; + scale: 1; + description { state: "default" 0.0; + color: 0 0 0 0; + min: 0 BUTTON_HEIGHT; + } + } + part { name: "elm.text"; + type: TEXTBLOCK; + mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + text { + min: 0 1; + style: "button_general_text_normal"; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + text.style: "button_general_text_dim"; + } + description { state: "pressed" 0.0; + inherit: "default" 0.0; + text.style: "button_general_text_press"; + } + } + part { name: "elm.swallow.content"; + clip_to: "elm.swallow.content.clip"; + type: SWALLOW; + scale: 1; + description { state: "default" 0.0; } + } + part { name: "elm.swallow.content.clip"; + type: RECT; + scale: 1; + description { state: "default" 0.0; + color_class: "F022L1i"; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + color_class: "F022L1iD"; + } + } + }//end of part + }//end of group + +}//end of collection diff --git a/data/generic_popup.edc b/data/generic_popup.edc new file mode 100644 index 0000000..23d56e1 --- /dev/null +++ b/data/generic_popup.edc @@ -0,0 +1,181 @@ +#define MAIN_W 470 +#define MAIN_H 800 + +#define TITLE_START_Y 72 +#define TITLE_H 90 + +#define FULL_TRANS 0 0 0 0 +#define TXT_SIZE 14 +#define FONT_NAME "system_content" + +images { +} + +collections +group { + + name: "popup_layout1"; + parts { + part { + name: "pad_t"; + scale : 1; + mouse_events: 0; + repeat_events: 1; + + description { + state: "default" 0.0; + align: 0.5 0.0; + min: 0 2; + fixed: 0 1; + rel1 { relative: 1.0 0.0; to_x: "pad_l"; } + rel2 { relative: 0.0 0.0; to_x: "pad_r"; } + } + } + part { + name: "pad_l"; + scale: 1; + + description { + state: "default" 0.0; + min : 10 0; + fixed: 1 0; + rel1 { relative: 0.0 0.0; } + rel2 { relative: 0.0 1.0; } + align: 0.0 0.0; + } + } + part { + name: "pad_r"; + scale: 1; + + description { + state: "default" 0.0; + min : 10 0; + fixed: 1 0; + rel1 { relative: 1.0 0.0; } + rel2 { relative: 1.0 1.0; } + align: 1.0 0.0; + } + } + part { + name:"0"; + type: SWALLOW; + scale : 1; + + description { + state: "default" 0.0; + min: 380 0; + align: 0.5 0.5; + fixed: 1 0; + rel1 { relative: 0.5 1.0; to: "pad_t"; } + rel2 { relative: 0.5 0.0; to: "pad_b"; } + } + } + part { + name: "pad_b"; + scale : 1; + mouse_events: 0; + repeat_events: 1; + + description { + state: "default" 0.0; + align: 0.5 1.0; + min: 0 2; + fixed: 0 1; + rel1 { relative: 1.0 1.0;to_x: "pad_l"; } + rel2 { relative: 0.0 1.0;to_x: "pad_r"; } + } + } + } +} + +group { + name: "popup_layout2"; + parts { + part { + name: "pad_t"; + scale : 1; + mouse_events: 0; + repeat_events: 1; + + description { + state: "default" 0.0; + align: 0.5 0.0; + min: 0 14; + fixed: 0 1; + rel1 { relative: 1.0 0.0; to_x: "pad_l"; } + rel2 { relative: 0.0 0.0; to_x: "pad_r"; } + } + } + part { + name: "pad_l"; + scale: 1; + + description { + state: "default" 0.0; + min : 10 0; + fixed: 1 0; + rel1 { relative: 0.0 0.0; } + rel2 { relative: 0.0 1.0; } + align: 0.0 0.0; + } + } + part { + name: "pad_r"; + scale: 1; + + description { + state: "default" 0.0; + min : 10 0; + fixed: 1 0; + rel1 { relative: 1.0 0.0; } + rel2 { relative: 1.0 1.0; } + align: 1.0 0.0; + } + } + part { + name:"0"; + type: SWALLOW; + scale : 1; + + description { + state: "default" 0.0; + min: 380 0; + align: 0.5 0.5; + fixed: 1 0; + rel1 { relative: 0.5 1.0; to: "pad_t"; } + rel2 { relative: 0.5 0.0; to: "pad_b"; } + } + } + part { + name: "pad_b"; + scale : 1; + mouse_events: 0; + repeat_events: 1; + + description { + state: "default" 0.0; + align: 0.5 1.0; + min: 0 66; + fixed: 0 1; + rel1 { relative: 1.0 1.0; to_x: "pad_l"; } + rel2 { relative: 0.0 1.0; to_x: "pad_r"; } + } + } + part { + name: "1"; + type: SWALLOW; + scale : 1; + mouse_events: 1; + repeat_events: 1; + + description { + state: "default" 0.0; + align: 0.5 0.5; + fixed: 1 1; + rel1 { relative: 0.0 0.0; to: "pad_b"; } + rel2 { relative: 1.0 1.0; to: "pad_b"; } + } + } + } // parts +} // group diff --git a/data/generic_popup_horizontal.edc b/data/generic_popup_horizontal.edc new file mode 100644 index 0000000..801eef0 --- /dev/null +++ b/data/generic_popup_horizontal.edc @@ -0,0 +1,52 @@ +#define MAIN_W 470 +#define MAIN_H 800 + +#define TITLE_START_Y 72 +#define TITLE_H 90 + +#define FULL_TRANS 0 0 0 0 +#define TXT_SIZE 14 +#define FONT_NAME "system_content" + +images { +} + +collections + group { + name: "popup_h"; + + #define BUTTON_WIDTH 200.0 + #define BUTTON_HEIGHT 78.0 + #define BUTTON_GAP 50.0 + #define PART_MAX 5000 + parts{ + part { + name: "0"; + type: SWALLOW; + scale: 1; + + description { + state: "default" 0.0; + + fixed: 1 1; + rel1 { relative: 0.1 0.0; } + rel2 { relative: 0.5 0.9; } + } + } + + part { + name: "1"; + type: SWALLOW; + scale: 1; + + description { + + fixed: 1 1; + rel1 { relative: 0.5 0.0; } + rel2 { relative: 0.9 0.9; } + } + } + } + } + +} diff --git a/dir-struct.py b/dir-struct.py new file mode 100755 index 0000000..910f153 --- /dev/null +++ b/dir-struct.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import os +import re + + +def countLines(path): + with open(path) as f: + return len(f.readlines()) + +# RETURNS: ( +# short description (string or None) +# long decsription (array of strings or None) +# options: stop +def parseDescr(lines): + if len(lines) == 0: + return (None, None, False) + linesRest = None + if re.match( r"!!!options!!!", lines[0] ): + optStop = True + linesRest = lines[1:] + else: + optStop = False + linesRest = lines + if len(linesRest) == 0: + return(None,None,optStop) + short = linesRest[0].rstrip() + long = [] + for l in linesRest[1:]: + ll = l.rstrip() + if re.search( r"\S", ll ): + long.append( ll ) + if len(long) == 0: + long = None + + return (short, long, optStop) + +# RETURNS a tree with nodes like: ( +# path (string) +# short description (string or None) +# long decsription (array of strings or None) +# LOC (integer) +# list of subdirs (child nodes like this one) +def parseDir(path): + short = None + long = None + optStop = False + try: + with open( path+'/DESCRIPTION' ) as f: + short, long, optStop = parseDescr( f.readlines() ) + except IOError: + pass + dirs = [] + cntLines = 0 + for fname in os.listdir(path): + if fname != '.git' and os.path.isdir(path+'/'+fname): + subdir = parseDir(path+'/'+fname) + if optStop == False: + dirs.append(subdir) + (dummy0, dummy1, dummy2, subLines, dummy4) = subdir + cntLines += subLines + + if os.path.isfile(path+'/'+fname) \ + and not os.path.islink(path+'/'+fname): + cntLines += countLines(path+'/'+fname) + + return path, short, long, cntLines, dirs + + +### ##### PRINT AS TEXT +### +### def printTextSub(path,indent,withLongDesc): +### short, long, dirs, loc = parseDir(path) +### if short == None: +### p = re.sub(r"^\./", '', path) +### print '%s%s -- ' % (indent, p) +### else: +### p = re.sub(r"^\./", '', path) +### print '%s%s -- %s' % (indent, p, short) +### if withLongDesc: +### if long != None: +### print '' +### for line in long: +### print '%s%s' % (indent+' ',line) +### print '' +### for dir in dirs: +### printTextSub(path+'/'+dir, indent+' ', withLongDesc) +### +### def printText(path,withLongDesc): +### printTextSub(path,'',withLongDesc) +### +### def printTextWoMain(path,withLongDesc): +### short, long, dirs, loc = parseDir(path) +### for dir in dirs: +### printTextSub(path+'/'+dir, '', withLongDesc) +### + +##### PRINT AS a sort of CSV delimited by '|' + +# indent is a number (0..) +def printTabSub(tree,indent): + path, short, long, loc, subdirs = tree + p = re.sub(r"^\./", '', path) + m = re.search(r"/([^/]*$)", p) + if m != None: p = m.groups()[0] + if short == None: + print '%s%s|%d|' % (" "*indent, p, loc) + else: + print '%s%s|%d|%s' % (" "*indent, p, loc, short) + for dir in subdirs: + printTabSub(dir, indent+1) + +def printTab(tree): + printTabSub(tree,0) + +def printTabWoMain(tree): + path, short, long, loc, dirs = tree + for dir in dirs: + printTabSub(dir, 0) + + +##### MAIN + +tree = parseDir('.') +printTabWoMain(tree) + diff --git a/doxyfile b/doxyfile new file mode 100644 index 0000000..f7d6c5d --- /dev/null +++ b/doxyfile @@ -0,0 +1,1600 @@ +# Doxyfile 1.6.2 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = WRT-Engine + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.0 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = ./Documentation + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = YES + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it parses. +# With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this tag. +# The format is ext=language, where ext is a file extension, and language is one of +# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, +# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. Note that for custom extensions you also need to set +# FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ./src/ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.vhd \ + *.vhdl + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = NO + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. +# For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvances is that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = YES + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/packaging/wrt.spec b/packaging/wrt.spec new file mode 100644 index 0000000..dcfc974 --- /dev/null +++ b/packaging/wrt.spec @@ -0,0 +1,199 @@ +#git:framework/web/wrt +Name: wrt +Summary: web runtime +Version: 0.8.325_w21 +Release: 1 +Group: Development/Libraries +License: Apache-2.0 and Flora-1.1 +URL: N/A +Source0: %{name}-%{version}.tar.gz + +BuildRequires: cmake +BuildRequires: edje-tools +BuildRequires: gettext +BuildRequires: libcap-devel +BuildRequires: libss-client-devel +BuildRequires: pkgconfig(aul) +BuildRequires: pkgconfig(appsvc) +BuildRequires: pkgconfig(capi-appfw-app-manager) +BuildRequires: pkgconfig(capi-appfw-application) +BuildRequires: pkgconfig(capi-appfw-watch-application) +BuildRequires: pkgconfig(appcore-watch) +BuildRequires: pkgconfig(capi-system-device) +BuildRequires: pkgconfig(capi-system-system-settings) +BuildRequires: pkgconfig(cert-svc) +BuildRequires: pkgconfig(cert-svc-vcore) +BuildRequires: pkgconfig(deviced) +BuildRequires: pkgconfig(dpl-efl) +BuildRequires: pkgconfig(ecore) +BuildRequires: pkgconfig(efl-assist) +BuildRequires: pkgconfig(eina) +BuildRequires: pkgconfig(ewebkit2) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(json-glib-1.0) +BuildRequires: pkgconfig(libcurl) +BuildRequires: pkgconfig(libiri) +BuildRequires: pkgconfig(libpcrecpp) +BuildRequires: pkgconfig(libprivilege-control) +BuildRequires: pkgconfig(libsmack) +BuildRequires: pkgconfig(libsoup-2.4) +BuildRequires: pkgconfig(notification) +BuildRequires: pkgconfig(openssl) +BuildRequires: pkgconfig(pkgmgr) +BuildRequires: pkgconfig(pkgmgr-info) +BuildRequires: pkgconfig(secure-storage) +BuildRequires: pkgconfig(security-client) +BuildRequires: pkgconfig(security-core) +BuildRequires: pkgconfig(utilX) +BuildRequires: pkgconfig(wrt-plugin-loading) +BuildRequires: pkgconfig(wrt-plugin-js-overlay) +BuildRequires: pkgconfig(wrt-plugins-ipc-message) +BuildRequires: pkgconfig(wrt-popup-wrt-runner) +BuildRequires: pkgconfig(wrt-popup-ace-runner) +BuildRequires: pkgconfig(journal) +BuildRequires: pkgconfig(efl-extension) +BuildRequires: pkgconfig(privacy-manager-client) +BuildRequires: libss-client-devel +BuildRequires: gettext +BuildRequires: edje-tools +Requires: libss-client + +### NETWORK TRACE ############################################################# +BuildRequires: pkgconfig(libresourced) +############################################################################### + +## wrt-launchpad-daemon ####################################################### +BuildRequires: pkgconfig(app-checker) +BuildRequires: pkgconfig(bundle) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(dbus-glib-1) +BuildRequires: pkgconfig(libsmack) +BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(x11) +BuildRequires: pkgconfig(aul) +BuildRequires: pkgconfig(libsystemd-daemon) +%{?systemd_requires} + +#Use these macro to avoid hard-coded path +#After upgrading systemd to v204 or higher macro can be deleted +%define _unitdir /usr/lib/systemd/system +############################################################################### + +%description +web runtime + +%package devel +Summary: Wrt header files for external modules +Group: Development/Libraries +Requires: %{name} = %{version} +Requires: pkgconfig(ewebkit2) + +%description devel +wrt library development headers + +%prep +%setup -q + +%define with_tests 0 +%if "%{WITH_TESTS}" == "ON" || "%{WITH_TESTS}" == "Y" || "%{WITH_TESTS}" == "YES" || "%{WITH_TESTS}" == "TRUE" || "%{WITH_TESTS}" == "1" + %define with_tests 1 +%endif + +%build +export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" +export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" +export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" + +export CFLAGS="$CFLAGS -DTIZEN_RELEASE_TYPE_ENG" +export CXXFLAGS="$CXXFLAGS -DTIZEN_RELEASE_TYPE_ENG" +export FFLAGS="$FFLAGS -DTIZEN_RELEASE_TYPE_ENG" + +export LDFLAGS+="-Wl,--rpath=/usr/lib" + +%ifarch %{arm} +%define build_dir Build-arm +%else +%define build_dir Build-i586 +%endif + +mkdir -p %{build_dir} +cd %{build_dir} + +cmake .. -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + -DDPL_LOG="ON" \ + -DPROJECT_VERSION=%{version} \ + -DCMAKE_BUILD_TYPE=%{?build_type:%build_type} \ + %{?WITH_TESTS:-DWITH_TESTS=%WITH_TESTS} +make %{?jobs:-j%jobs} + +%install +mkdir -p %{buildroot}/usr/share/license +cp LICENSE.APLv2 %{buildroot}/usr/share/license/%{name} +cp LICENSE.Flora %{buildroot}/usr/share/license/%{name} + +cd %{build_dir} +%make_install +mkdir -p %{buildroot}%{app_data} + +mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants +ln -s %{_unitdir}/wrt_launchpad_daemon.service %{buildroot}%{_unitdir}/multi-user.target.wants/wrt_launchpad_daemon.service + +%pre +if [ $1 -eq 2 ] ; then + systemctl stop wrt_launchpad_daemon.service +fi + +%preun +if [ $1 -eq 0 ] ; then + systemctl stop wrt_launchpad_daemon.service +fi + +%clean +rm -rf %{buildroot} + +%post +chmod +s /usr/bin/wrt-launcher + +mkdir -p %{_sysconfdir}/systemd/default-extra-dependencies/ignore-units.d/ +ln -s %{_libdir}/systemd/system/wrt_launchpad_daemon.service %{_sysconfdir}/systemd/default-extra-dependencies/ignore-units.d/ + +/sbin/ldconfig +systemctl daemon-reload +if [ $1 -eq 2 ] ; then + systemctl start wrt_launchpad_daemon.service +fi + +%postun +systemctl daemon-reload + +%files +%manifest wrt.manifest +%{_libdir}/*.so +%{_libdir}/*.so.* +%attr(755,root,root) %{_bindir}/wrt-client +%attr(755,root,root) %{_bindir}/wrt-launcher +%attr(755,root,root) %{_bindir}/wrt_reset_all.sh +%attr(755,root,root) %{_bindir}/wrt_reset_db.sh +%{_datadir}/locale/* +%{_datadir}/license/%{name} +%attr(644,root,root) %{_datadir}/edje/wrt/* +%attr(644,root,root) %{_datadir}/edje/ace/* +%if %{with_tests} + %attr(755,root,root) %{_bindir}/wrt-tests-general + /opt/share/widget/tests/general/* +%endif +%attr(755,root,root) %{_sysconfdir}/profile.d/wrt_env.sh + +## wrt-launchpad-daemon ####################################################### +%attr(755,root,root) %{_bindir}/wrt_launchpad_daemon +/usr/share/aul/preload_list_wrt.txt +/etc/smack/accesses.d/wrt_launchpad_daemon.efl +/etc/smack/accesses.d/wrt-launcher.efl +#systemd +%{_unitdir}/multi-user.target.wants/wrt_launchpad_daemon.service +%{_unitdir}/wrt_launchpad_daemon.service +############################################################################### + +%files devel +%{_includedir}/* +%{_libdir}/pkgconfig/* diff --git a/pkgconfig/wrt-core.pc.in b/pkgconfig/wrt-core.pc.in new file mode 100644 index 0000000..8436f7e --- /dev/null +++ b/pkgconfig/wrt-core.pc.in @@ -0,0 +1,12 @@ +prefix=/usr +project_name=@CMAKE_PROJECT_NAME@ +exec_prefix=${prefix} +libdir=${prefix}/lib/ +includedir=${prefix}/include/${project_name} + +Name: WebRuntime wrt core module +Description: WebRuntime core module +Version: @CMAKE_PROJECT_VERSION@ +Requires: +Libs: -L${libdir} -lwrt-core-module +Cflags: -I${includedir} diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt new file mode 100644 index 0000000..863f2ce --- /dev/null +++ b/po/CMakeLists.txt @@ -0,0 +1,43 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# 78 language(*.po) +SET(POFILES +ar.po as.po az.po bg.po bn.po ca.po cs.po da.po de.po el_GR.po en.po en_PH.po en_US.po es_ES.po es_US.po et.po eu.po fa.po fi.po fr.po fr_CA.po +ga.po gl.po gu.po he.po hi.po hr.po hu.po hy.po id.po is.po it_IT.po ja_JP.po ka.po kk.po km.po kn.po ko_KR.po ky_KG.po lo.po lt.po lv.po mk.po +ml.po mn_MN.po mr.po ms.po my.po nb.po ne.po nl.po or.po pa.po pl.po pt_BR.po pt_PT.po ro.po ru_RU.po si.po sk.po sl.po sq.po sr.po sv.po ta.po +te.po tg_TJ.po th.po tk_TM.po tl.po tr_TR.po uk.po ur.po uz.po vi.po zh_CN.po zh_HK.po zh_TW.po +) + +SET(MSGFMT "/usr/bin/msgfmt") +SET(LOCALE_DIR "/usr/share/locale/") + +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..fe94652 --- /dev/null +++ b/po/ar.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "يوجد طلب من %1$s (%2$s) للحصول على إذن من أجل استخدام الكاميرا" + +msgid "IDS_BR_SK_OK" +msgstr "موافق" + +msgid "IDS_BR_SK_YES" +msgstr "نعم" + +msgid "IDS_BR_SK_NO" +msgstr "لا" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "تسجيل الدخول" + +msgid "IDS_BR_SK_CANCEL" +msgstr "إلغاء" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "السماح" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "يوجد طلب من %1$s (%2$s) للحصول على إذن من أجل عرض الإخطارات" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "يوجد طلب من %1$s (%2$s) للحصول على إذن من أجل الوصول إلى موقعك" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "توجد محاولة من %1$s (%2$s) لتخزين كمية كبيرة من البيانات على جهازك للاستخدام عند عدم الاتصال بالإنترنت" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "يوجد طلب من ‎%1$s (%2$s)‎ للحصول على إذن من أجل تخزين بيانات على جهازك للاستخدام عند عدم الاتصال بالإنترنت" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "جاري بدء التنزيل..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "توجد مشاكل في شهادة الأمان الخاصة بهذا الموقع." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "مطلوب التوثيق." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "كلمة المرور" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "اسم المستخدم" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "تذكر الأفضلية." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "إلغاء تحديد إعدادات التطبيق الافتراضية من خلال الانتقال إلى الضبط > عام > إدارة التطبيقات > الكل." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "جاري التحميل ..." + +msgid "IDS_KA_BODY_DENY" +msgstr "رفض" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "السماح باستخدام تسجيل الوسائط؟" + diff --git a/po/as.po b/po/as.po new file mode 100755 index 0000000..c56decb --- /dev/null +++ b/po/as.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s)-এ আপোনাৰ কেমেৰা ব্যৱহাৰ কৰিবলৈ অনুমতি বিচাৰি অনুৰোধ জনাইছে৷" + +msgid "IDS_BR_SK_OK" +msgstr "ঠিক" + +msgid "IDS_BR_SK_YES" +msgstr "হয়" + +msgid "IDS_BR_SK_NO" +msgstr "নহয়" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "লগইন" + +msgid "IDS_BR_SK_CANCEL" +msgstr "বাতিল" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "অনুমতি দিয়ক" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s)-এ অধিসূচনাসমূহ দেখুৱাবলৈ অনুৰোধ জনাইছে৷" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s)-এ আপোনাৰ অৱস্থানলৈ প্ৰৱেশৰ অনুমতি বিচাৰি অনুৰোধ জনাইছে৷" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s)-এ অফলাইনত ব্যৱহাৰ কৰিবৰ বাবে এক বৃহৎ পৰিমাণৰ ডাটা আপোনাৰ ডিভাইচত সংৰক্ষণ কৰিবলৈ চেষ্টা কৰিছে৷" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s)-এ অফলাইনত ব্যৱহাৰ কৰিবৰ বাবে ডাটা সংগ্ৰহ কৰি ৰাখিবলৈ অনুমতি বিচাৰি অনুৰোধ জনাইছে৷" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "ডাউনলোড আৰম্ভ কৰি থকা হৈছে..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "এই ছাইটৰ প্ৰতিৰক্ষা প্ৰমাণ পত্ৰৰ সৈতে সমস্যা আছে৷" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "প্ৰামাণিকৰণৰ প্ৰয়োজন৷" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "পাছৱৰ্ড" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "ব্যৱহাৰকৰ্তাৰ নাম" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "অগ্ৰাধিকাৰ মনত ৰাখক৷" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "ছেটিংছ > সাধাৰণ > এপ্লিকেশ্বন প্ৰৱন্ধন কৰক > সকলো লৈ গৈ ডি'ফল্ট এপ ছেটিংছ পৰিষ্কাৰ কৰক৷" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "লোড হৈ আছে..." + +msgid "IDS_KA_BODY_DENY" +msgstr "অবৰোধিত" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "মিডিয়া ৰেকৰ্ডিং ব্যৱহাৰ কৰিবলৈ অনুমতি দিবনে?" + diff --git a/po/az.po b/po/az.po new file mode 100755 index 0000000..4f3d0c1 --- /dev/null +++ b/po/az.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) kameranızdan istifadə etmək üçün icazə istəyir." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Bəli" + +msgid "IDS_BR_SK_NO" +msgstr "Xeyr" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Sistemə giriş" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Ləğv et" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "İcazə ver" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) bildirişləri göstərmək üçün icazə istəyir." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) yerinizə daxil olmaq üçün icazə istəyir." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) sizin cihazınızda oflayn istifadə üçün böyük həcmdə məlumat saxlamağa cəhd edir." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) cihazınızda oflayn istifadə üçün məlumat saxlamağa icazə istəyir." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Yükləmə başladılır..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Bu saytın təhlükəsizlik sertifikatı ilə bağlı problemlər var." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Kimliyin müəyyən edilməsi tələb olunur." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Şifrə" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "İstifadəçinin adı" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Secimi yadda saxla." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Parametrlər > Ümumi > Proqramları İdarə et > Hamısı seçməklə defolt proqram parametrlərini silin." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Yüklənir..." + +msgid "IDS_KA_BODY_DENY" +msgstr "İmtina et" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Mediya qeydindən istifadəyə icazə verilsin?" + diff --git a/po/bg.po b/po/bg.po new file mode 100755 index 0000000..0f9d1ad --- /dev/null +++ b/po/bg.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) иска разрешение за използване на вашата камера." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Да" + +msgid "IDS_BR_SK_NO" +msgstr "Не" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Вход" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Отмени" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Разрешаване" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) иска разрешение за показване на известия." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) иска разрешение за достъп до вашето местоположение." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) се опитва да съхранява голямо количество данни на вашето устройство за използване офлайн." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) иска разрешение за съхраняване на данни на вашето устройство за използване офлайн." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Начало на изтеглянето..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Има проблеми със сертификата за защита за този сайт." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Изисква се удостоверяване." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Парола" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Потребителско име" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Запомни предпочитанията" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Изчистете настройките за приложение по подразбиране, като отидете в Настройки > Общи > Управление на приложения > Всички." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Зареждане" + +msgid "IDS_KA_BODY_DENY" +msgstr "Отхвърли" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Позволяване на запис на медии?" + diff --git a/po/bn.po b/po/bn.po new file mode 100755 index 0000000..6a8a70e --- /dev/null +++ b/po/bn.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) আপনার ক্যামেরা ব্যবহারের জন্য অনুমতি অনুরোধ করছে।" + +msgid "IDS_BR_SK_OK" +msgstr "ওকে" + +msgid "IDS_BR_SK_YES" +msgstr "হ্যাঁ" + +msgid "IDS_BR_SK_NO" +msgstr "না" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "লগইন" + +msgid "IDS_BR_SK_CANCEL" +msgstr "বাতিল" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "অনুমতি" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) বিজ্ঞপ্তি দেখানোর জন্য অনুমতি অনুরোধ করছে।" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) আপনার অবস্থান অ্যাক্সেসের জন্য অনুমতি অনুরোধ করছে।" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) অফলাইনে ব্যবহারের জন্য আপনার ডিভাইসে বড় পরিমাণ তথ্য সঞ্চয় করার প্রয়াস করছে।" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) অফলাইন ব্যবহারের জন্য আপনার ডিভাইসে তথ্য সঞ্চয় করার অনুমতি অনুরোধ করছে।" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "ডাউনলোড আরম্ভ হচ্ছে..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "এই সাইটের সুরক্ষা শংসাপত্র-এ কিছু সমস্যা আছে।" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "প্রামাণিকরণ দরকার।" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "পাসওয়ার্ড" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "ব্যবহারকারীর নাম" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "অগ্রাধিকার মনে রাখা।" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "এখানে গিয়ে ডিফল্ট অ্যাপ সেটিংস পরিষ্কার করুন সেটিংস > সাধারণ > অ্যাপ্লিকেশনগুলি পরিচালনা করুন > সমস্ত।" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "লোড হচ্ছে..." + +msgid "IDS_KA_BODY_DENY" +msgstr "অস্বীকার" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "মিডিয়া রেকর্ডিং ব্যবহার করার অনুমতি দেওয়া হবে কি ?" + diff --git a/po/ca.po b/po/ca.po new file mode 100755 index 0000000..78636a2 --- /dev/null +++ b/po/ca.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) està demanant permís per utilitzar la seva càmera" + +msgid "IDS_BR_SK_OK" +msgstr "Acceptar" + +msgid "IDS_BR_SK_YES" +msgstr "Sí" + +msgid "IDS_BR_SK_NO" +msgstr "No" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Iniciar sessió" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Cancel" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Permetre" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) està demanant permís per mostrar notificacions" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) està demanant permís per accedir a la seva ubicació" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) està intentant emmagatzemar una gran quantitat de dades al seu dispositiu per a ús fora de línia" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) està demanant permís per emmagatzemar dades al seu dispositiu per a ús fora de línia" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "S'està iniciant la descàrrega..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Hi ha problemes amb el certificat de seguretat d'aquest lloc" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Es requereix autenticació" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Contrasenya" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Nom d'usuari" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Recordar preferència" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Esborri els ajustaments d'aplicacions predeterminades anant a Ajustaments > General > Administrar aplicacions > Totes" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Carregant..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Denegar" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Permetre utilitzar gravació multimèdia?" + diff --git a/po/cs.po b/po/cs.po new file mode 100755 index 0000000..e4ce41f --- /dev/null +++ b/po/cs.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) žádá o povolení použít fotoaparát." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Ano" + +msgid "IDS_BR_SK_NO" +msgstr "Ne" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Přihlášení" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Zrušit" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Povolit" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) žádá o povolení zobrazit oznámení." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) žádá o povolení přístupu k informacím o vaší poloze." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) se pokouší uložit do zařízení velké množství dat pro použití offline." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) žádá o povolení uložit do zařízení data pro použití offline." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Spouští se stahování..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Došlo k potížím s certifikátem zabezpečení pro tento server." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Je vyžadováno ověření." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Heslo" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Uživatelské jméno" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Zapamatovat preference." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Vymažte výchozí nastavení aplikací pomocí Nastavení > Obecné > Správa aplikací > Vše." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Nahrávám..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Odmítnout" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Povolit nahrávání médií?" + diff --git a/po/da.po b/po/da.po new file mode 100755 index 0000000..f7f6548 --- /dev/null +++ b/po/da.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) anmoder om tilladelse til at bruge dit kamera." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Ja" + +msgid "IDS_BR_SK_NO" +msgstr "Nej" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Log på" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Annullér" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Tillad" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) anmoder om tilladelse til at vise meddelelser." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) anmoder om tilladelse til at få adgang til din placering." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) forsøger at gemme en stor mængde data på din enhed til offline-brug." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) anmoder om tilladelse til at gemme en stor mængde data på din enhed til offline-brug." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Starter download..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Der er problemer med sikkerhedscertifikatet for dette websted." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Godkendelse påkrævet." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Adgangskode" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Brugernavn" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Husk præference." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Ryd standardindstillinger for program ved at gå til Indstillinger > Generelt > Administrér programmer > Alle." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Indlæser data ..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Afvis" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Vil du tillade brug af medieoptagelse?" + diff --git a/po/de.po b/po/de.po new file mode 100755 index 0000000..893a082 --- /dev/null +++ b/po/de.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) möchte die Berechtigung erhalten, Ihre Kamera zu benutzen." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Ja" + +msgid "IDS_BR_SK_NO" +msgstr "Nein" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Anmeldung" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Abbrechen" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Zulassen" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) möchte die Berechtigung erhalten, Benachrichtigungen anzuzeigen." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) möchte die Berechtigung erhalten, um auf Ihren Standort zuzugreifen." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) versucht, eine große Datenmenge für die Offline-Verwendung auf Ihrem Gerät zu speichern." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) möchte die Berechtigung erhalten, Daten für die Offline-Verwendung auf Ihrem Gerät zu speichern." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Download wird gestartet..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Probleme mit dem Sicherheitszertifikat für diese Site" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Authentifizierung erforderlich" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Passwort" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Benutzername" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Voreinstellung merken" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Löschen Sie App-Standardeinstellungen unter „Einstellungen > Allgemein > Anwendungsmanager > Alle“." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Lädt..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Ablehnen" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Verwenden der Medienaufnahme erlauben?" + diff --git a/po/el_GR.po b/po/el_GR.po new file mode 100755 index 0000000..7a3adc5 --- /dev/null +++ b/po/el_GR.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "Η ιστοσελίδα %1$s (%2$s) ζητά δικαίωμα για τη χρήση της κάμεράς σας." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Ναι" + +msgid "IDS_BR_SK_NO" +msgstr "Όχι" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Σύνδεση" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Άκυρο" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Να επιτρέπεται" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "Η ιστοσελίδα %1$s (%2$s) ζητά δικαίωμα για την εμφάνιση ειδοποιήσεων." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "Η ιστοσελίδα %1$s (%2$s) ζητά δικαίωμα πρόσβασης στα δεδομένα θέσης σας." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "Η ιστοσελίδα %1$s (%2$s) επιχειρεί να αποθηκεύσει ένα μεγάλο όγκο δεδομένων στη συσκευή σας για χρήση εκτός σύνδεσης." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "Η ιστοσελίδα %1$s (%2$s) ζητά δικαίωμα για την αποθήκευση δεδομένων στη συσκευή σας για χρήση εκτός σύνδεσης." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Ξεκινά η λήψη..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Υπάρχουν προβλήματα με το πιστοποιητικό ασφαλείας αυτής της τοποθεσίας." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Απαιτείται έλεγχος ταυτότητας." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Κωδικός πρόσβασης" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Όνομα χρήστη" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Απομνημόνευση προτίμησης." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Εκκαθαρίστε τις ρυθμίσεις προεπιλεγμένης εφαρμογής μεταβαίνοντας στις Ρυθμίσεις > Γενικά > Διαχείριση εφαρμογών > Όλα." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Φόρτωση..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Απόρριψη" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Να επιτραπεί η χρήση εγγραφής μέσου;" + diff --git a/po/en.po b/po/en.po new file mode 100755 index 0000000..a5ee120 --- /dev/null +++ b/po/en.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) is requesting permission to use your camera." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Yes" + +msgid "IDS_BR_SK_NO" +msgstr "No" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Login" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Cancel" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Allow" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) is requesting permission to show notifications." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) is requesting permission to access your location." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) is attempting to store a large amount of data on your device for offline use." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) is requesting permission to store data on your device for offline use." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Starting download..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "There are problems with the security certificate for this site." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Authentication required." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Password" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Username" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Remember preference." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Clear default app settings by going to Settings > General > Manage applications > All." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Loading..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Deny" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Allow to use media recording?" + diff --git a/po/en_PH.po b/po/en_PH.po new file mode 100755 index 0000000..5689c35 --- /dev/null +++ b/po/en_PH.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) is requesting permission to use your camera." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Yes" + +msgid "IDS_BR_SK_NO" +msgstr "No" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Log-in" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Cancel" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Allow" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) is requesting permission to show notifications." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) is requesting permission to access your location." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) is attempting to store a large amount of data on your device for offline use." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) is requesting permission to store data on your device for offline use." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Starting download..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "There are problems with the security certificate for this site." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Authentication required." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Password" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Username" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Remember preference." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Clear default app settings by going to Settings > General > Manage applications > All." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Loading..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Deny" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Allow to use media recording?" + diff --git a/po/en_US.po b/po/en_US.po new file mode 100755 index 0000000..a5ee120 --- /dev/null +++ b/po/en_US.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) is requesting permission to use your camera." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Yes" + +msgid "IDS_BR_SK_NO" +msgstr "No" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Login" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Cancel" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Allow" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) is requesting permission to show notifications." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) is requesting permission to access your location." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) is attempting to store a large amount of data on your device for offline use." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) is requesting permission to store data on your device for offline use." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Starting download..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "There are problems with the security certificate for this site." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Authentication required." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Password" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Username" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Remember preference." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Clear default app settings by going to Settings > General > Manage applications > All." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Loading..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Deny" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Allow to use media recording?" + diff --git a/po/es_ES.po b/po/es_ES.po new file mode 100755 index 0000000..23a7fda --- /dev/null +++ b/po/es_ES.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) está solicitando permiso para usar su cámara" + +msgid "IDS_BR_SK_OK" +msgstr "Aceptar" + +msgid "IDS_BR_SK_YES" +msgstr "Sí" + +msgid "IDS_BR_SK_NO" +msgstr "No" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Conectar" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Cancelar" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Permitir" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) está solicitando permiso para mostrar notificaciones" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) está solicitando permiso para acceder a su ubicación" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) está intentando almacenar una gran cantidad de datos en su dispositivo para su uso fuera de línea" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) está solicitando permiso para almacenar datos en su dispositivo para su uso fuera de línea" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Iniciando descarga..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Hay problemas con el certificado de seguridad de este sitio" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Autenticación necesaria" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Contraseña" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Nombre de usuario" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Recordar preferencias" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Borre ajustes de aplicaciones predeterminados en Ajustes > General > Gestionar aplicaciones > Todas" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Cargando..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Rechazar" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "¿Permitir uso de grabación multimedia?" + diff --git a/po/es_US.po b/po/es_US.po new file mode 100755 index 0000000..a136423 --- /dev/null +++ b/po/es_US.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) está solicitando permiso para usar Cámara." + +msgid "IDS_BR_SK_OK" +msgstr "Aceptar" + +msgid "IDS_BR_SK_YES" +msgstr "Sí" + +msgid "IDS_BR_SK_NO" +msgstr "No" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Conectar" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Cancelar" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Permitir" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) está solicitando permiso para mostrar notificaciones." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) está solicitando permiso para acceder a su ubicación." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) está intentado almacenar una gran cantidad de datos en su dispositivo para el uso sin conexión." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) está solicitando permiso para almacenar datos en su dispositivo para el uso sin conexión." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Iniciando descarga..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Hay problemas con el certificado de seguridad de este sitio." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Autenticación necesaria." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Contraseña" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Nombre de usuario" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Preferencias de recordatorio." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Elimine la configuración predeterminada de la aplicación en Configuración > General > Administrar aplicaciones > Todo." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Cargando..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Rechazar" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "¿Permitir uso de grabación multimedia?" + diff --git a/po/et.po b/po/et.po new file mode 100755 index 0000000..2ed5413 --- /dev/null +++ b/po/et.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) taotleb luba kasutada teie kaamerat." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Jah" + +msgid "IDS_BR_SK_NO" +msgstr "Ei" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Sisselogimine" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Tühista" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Luba" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) taotleb luba naidata teavitusi." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) taotleb luba juurdepaasuks teie asukohale." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) proovib teie seadmesse salvestada suurt hulka andmeid, et kasutada neid vorguuhenduseta." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) taotleb luba salvestada teie seadmesse andmeid, et kasutada neid vorguuhenduseta." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Allalaadimise alustamine..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Selle saidi turvasertifikaadiga tekkis probleeme." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Autentimine on kohustuslik." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Parool" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Kasutajanimi" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Maleta eelistusi." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Tuhistage vaikerakenduse seaded menuus Seaded > Uldine > Halda rakendusi > Koik." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Laadimine..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Keeldu" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Kas lubada meediumisalvestus?" + diff --git a/po/eu.po b/po/eu.po new file mode 100755 index 0000000..30c7068 --- /dev/null +++ b/po/eu.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) baimena eskatzen ari zaizu zure kamera erabiltzeko" + +msgid "IDS_BR_SK_OK" +msgstr "Ados" + +msgid "IDS_BR_SK_YES" +msgstr "Bai" + +msgid "IDS_BR_SK_NO" +msgstr "Ez" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Saioa hasi" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Ezeztatu" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Onartu" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) baimena eskatzen ari zaizu jakinarazpenak erakusteko" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) baimena eskatzen ari zaizu zure kokapenera sartzeko" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) datu kopuru handia gordetzen saiatzen ari da zure gailua lineaz kanpo erabiltzeko" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) baimena eskatzen ari zaizu datu kopuru handia gordetzeko zure gailuan lineaz kanpoko erabilerarako" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Deskarga hasten..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Arazoak daude gune honen segurtasun ziurtagiriarekin" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Autentikazioa beharrezkoa" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Pasahitza" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Erabiltzaile izena" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Gogoratu hobespenak" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Garbitu lehenetsitako aplikazio ezarpenak Ezarpenak > Orokorra > Kudeatu aplikazioak > Denak aukerara joanda" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Kargatzen..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Ukatu" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Media grabaketa erabiltzea onartu?" + diff --git a/po/fa.po b/po/fa.po new file mode 100755 index 0000000..cea26d3 --- /dev/null +++ b/po/fa.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) درخواست مجوز برای استفاده از دوربین شما را دارد" + +msgid "IDS_BR_SK_OK" +msgstr "تاييد" + +msgid "IDS_BR_SK_YES" +msgstr "بلی" + +msgid "IDS_BR_SK_NO" +msgstr "خير" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "ورود به سیستم" + +msgid "IDS_BR_SK_CANCEL" +msgstr "خیر" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "اجازه" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) درخواست مجوز برای نشان دادن اعلان ها را دارد" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) درخواست مجوز برای دسترسی به مکان شما را دارد" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) سعی می کند مقدار زیادی داده در دستگاه شما برای استفاده آفلاین ذخیره کند" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) درخواست مجوز برای ذخیره داده در دستگاه شما برای استفاده آفلاین دارد" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "شروع بارگیری..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "مشکلاتی در مجوز امنیتی برای این سایت وجود دارد." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "تأیید اعتبار لازم است." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "رمز" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "اسم کاربر" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "مورد ترجیحی را یادآوری کنید." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "با رفتن به تنظیمات > عمومی > مدیریت برنامه‌ها > همه، تنظیمات پیش‌فرض برنامه را پاک کنید." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "در حال دانلود..." + +msgid "IDS_KA_BODY_DENY" +msgstr "رد کردن" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "اجازه می دهید از ضبط رسانه استفاده شود؟" + diff --git a/po/fi.po b/po/fi.po new file mode 100755 index 0000000..3c0c0d6 --- /dev/null +++ b/po/fi.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) pyytää lupaa kamerasi käyttämiseen." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Kyllä" + +msgid "IDS_BR_SK_NO" +msgstr "Ei" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Kirjaudu" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Peruuta" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Salli" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) pyytää lupaa ilmoitusten näyttämiseen." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) pyytää lupaa sijaintisi käyttämiseen." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) yrittää tallentaa suuren määrän tietoja laitteeseen offline-tilassa tapahtuvaa käyttöä varten." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) pyytää lupaa tietojen tallentamiseen laitteeseen offline-tilassa tapahtuvaa käyttöä varten." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Lataus käynnistetään..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Sivuston suojausvarmenteen kanssa on ongelmia." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Todennus vaaditaan." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Salasana" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Käyttäjän nimi" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Muista ensisijainen asetus." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Poista sovelluksen oletusasetukset käytöstä valitsemalla Asetukset > Yleistä > Sovellusten hallinta > Kaikki." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Ladataan..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Kieltäydy" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Sallitaanko median tallennus?" + diff --git a/po/fr.po b/po/fr.po new file mode 100755 index 0000000..f497350 --- /dev/null +++ b/po/fr.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) demande l'autorisation d'utiliser votre appareil photo." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Oui" + +msgid "IDS_BR_SK_NO" +msgstr "Non" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Connexion" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Annuler" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Autoriser" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) demande l'autorisation de consulter les notifications." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) demande l'autorisation de se connecter pour connaître votre position." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) tente d'enregistrer une grande quantité de données sur votre appareil pour une utilisation hors-ligne." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) demande l'autorisation d'enregistrer des données sur votre appareil pour une utilisation hors-ligne." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Début du téléchargement..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Problèmes avec le certificat de sécurité de ce site" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Authentification obligatoire" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Mot de passe" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Nom d'utilisateur" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Mémoriser la préférence." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Effacez les paramètres par défaut des applications en accédant à Paramètres > Général > Gérer les applications > Toutes." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Chargement en cours." + +msgid "IDS_KA_BODY_DENY" +msgstr "Refuser" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Autoriser l'enregistrement de médias ?" + diff --git a/po/fr_CA.po b/po/fr_CA.po new file mode 100755 index 0000000..3884ec7 --- /dev/null +++ b/po/fr_CA.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) demande l'autorisation d'utiliser votre appareil photo." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Oui" + +msgid "IDS_BR_SK_NO" +msgstr "Non" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Connexion" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Annuler" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Autoriser" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) demande l'autorisation de consulter les notifications." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) demande l'autorisation de se connecter pour connaitre votre position." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) tente d'enregistrer une grande quantité de données sur votre appareil pour une utilisation hors-ligne." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) demande l'autorisation d'enregistrer des données sur votre appareil pour une utilisation hors-ligne." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Début du téléchargement..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Problèmes avec le certificat de sécurité de ce site" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Authentification requise" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Mot de passe" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Nom d'utilisateur" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Mémoriser la préférence." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Effacez les paramètres par défaut des applications en accédant à Paramètres > Général > Gérer les applications > Toutes." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Chargement..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Refuser" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Autoriser l'enregistrement de médias?" + diff --git a/po/ga.po b/po/ga.po new file mode 100755 index 0000000..1ccf135 --- /dev/null +++ b/po/ga.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "Tá %1$s (%2$s) ag iarraidh ceada le do cheamara a úsáid" + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Déan é" + +msgid "IDS_BR_SK_NO" +msgstr "Ná déan é" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Logáil isteach" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Cuir ar ceal" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Ceadaigh" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "Tá %1$s (%2$s) ag iarraidh ceada le fógraí a thaispeáint" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "Tá %1$s (%2$s) ag iarraidh ceada le do shuíomh a rochtain" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "Tá %1$s (%2$s) ag iarraidh líon mór sonraí a stóráil ar do ghléas le húsáid as líne" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "Tá %1$s (%2$s) ag iarraidh ceada le sonraí a stóráil ar do ghléas le húsáid as líne" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Ag tosú ar íoslódáil..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Tá fadhbanna leis an deimhniú slándála don láithreán seo" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Fíordheimhniú de dhíth." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Pasfhocal" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Ainm úsáideora" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Cuimhnigh ar mo shainrogha" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Glan réamhshocruithe feidhmchláir trí ghabháil chuig Socruithe > Ginearálta > Bainistigh feidhmchláir > Gach" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Ag lódáil..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Séan air" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Ceadaigh taifeadadh meán a úsáid?" + diff --git a/po/gl.po b/po/gl.po new file mode 100755 index 0000000..a8761f7 --- /dev/null +++ b/po/gl.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) está solicitando permiso para usar a túa cámara" + +msgid "IDS_BR_SK_OK" +msgstr "Aceptar" + +msgid "IDS_BR_SK_YES" +msgstr "Si" + +msgid "IDS_BR_SK_NO" +msgstr "Non" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Conectar" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Cancelar" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Permitir" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) está solicitando permiso para amosar notificacións" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) está solicitando permiso para ter acceso á túa situación" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) está tentando almacenar unha grande cantidade de datos no teu dispositivo para utilizalos fóra de liña" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) está solicitando permiso para almacenar datos no teu dispositivo para utilizalos fóra de liña" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Iniciando descarga..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Existen problemas co certificado de seguridade deste sitio" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Autenticación requirida" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Contrasinal" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Nome de usuario" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Lembrar preferencia" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Borra os axustes predeterminados das aplicacións en Axustes > Xeral > Xestionar aplicacións > Todo" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Cargando..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Denegar" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Permitir usar a gravación multimedia?" + diff --git a/po/gu.po b/po/gu.po new file mode 100755 index 0000000..c161b89 --- /dev/null +++ b/po/gu.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) તમારા સ્થાનનો ઉપયોગ કરવાની પરવાનગીની વિનંતી કરી રહ્યાં છે." + +msgid "IDS_BR_SK_OK" +msgstr "ઓકે" + +msgid "IDS_BR_SK_YES" +msgstr "હા" + +msgid "IDS_BR_SK_NO" +msgstr "ના" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "લોગિન" + +msgid "IDS_BR_SK_CANCEL" +msgstr "રદ કરો" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "છૂટ આપો" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) એ સૂચનાઓ બતાવવાની પરવાનગીની વિનંતી કરી રહ્યાં છે." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) તમારા સ્થાનને પ્રવેશ કરવાની પરવાનગીની વિનંતી કરી રહ્યાં છે." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) ઓફલાઇન ઉપયોગ માટે તમારા ઉપકરણ પર વધુ પ્રમાણમાં ડેટાનો સંગ્રહ કરવાનો પ્રયાસ કરી રહ્યાં છો." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) એ ઓફલાઇન ઉપયોગ માટે તમારા ઉપકરણ પર ડેટા સંગ્રહિત કરવા માટેની પરવાનગીની વિનંતી કરી રહ્યાં છે." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "ડાઉનલોડ પ્રારંભ કરે છે..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "આ સાઇટ માટેનાં સુરક્ષા પ્રમાણપત્રમાં સમસ્યાઓ છે." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "પ્રમાણીકરણ જરૂરી." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "પાસવર્ડ" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "ઉપયોગકર્તાનું નામ" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "પ્રાથમિકતા યાદ રાખો." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "સેટિંગ્સ > સામાન્ય > એપ્લિકેશનોનું સંચાલન કરો > બધું પર જઈને મૂળભૂત એપ્લિકેશનો સેટિંગ્સને સાફ કરો." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "લોડિંગ..." + +msgid "IDS_KA_BODY_DENY" +msgstr "નકારો" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "મીડિયા રેકોર્ડિંગ વાપરવાની છૂટ?" + diff --git a/po/he.po b/po/he.po new file mode 100755 index 0000000..34583de --- /dev/null +++ b/po/he.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) מבקש אישור לשימוש במצלמה שלך" + +msgid "IDS_BR_SK_OK" +msgstr "אישור" + +msgid "IDS_BR_SK_YES" +msgstr "כן" + +msgid "IDS_BR_SK_NO" +msgstr "לא" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "כניסה" + +msgid "IDS_BR_SK_CANCEL" +msgstr "ביטול" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "אפשר" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) מבקש אישור להציג התראות" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) מבקש אישור לגשת למיקום שלך" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) מנסה לאחסן כמות נתונים גדולה במכשיר שלך לצורך שימוש לא מקוון" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) מבקש הרשאה לאחסון נתונים במכשיר שלך לצורך שימוש לא מקוון" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "ההורדה מתחילה..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "יש בעיות באישור האבטחה של אתר זה." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "אימות דרוש." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "סיסמה" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "שם משתמש" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "זכור העדפה." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "נקה את הגדרות היישום שנקבעו כברירת מחדל דרך הגדרות > כללי > נהל יישומים > הכל." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "טוען..." + +msgid "IDS_KA_BODY_DENY" +msgstr "דחה" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "לאפשר שימוש בהקלטת מדיה?" + diff --git a/po/hi.po b/po/hi.po new file mode 100755 index 0000000..1b214f0 --- /dev/null +++ b/po/hi.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) आपके कैमरा उपयोग करने की अनुमति का अनुरोध कर रहा है" + +msgid "IDS_BR_SK_OK" +msgstr "ओके" + +msgid "IDS_BR_SK_YES" +msgstr "हाँ" + +msgid "IDS_BR_SK_NO" +msgstr "नहीं" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "लॉगिन" + +msgid "IDS_BR_SK_CANCEL" +msgstr "रद्द" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "अनुमति दें" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) अधिसूचना दिखाने की अनुमति का अनुरोध कर रहा है" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) आपके स्थान को ऐक्सेस करने की अनुमति का अनुरोध कर रहा है" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) आपके डिवाइस पर ऑफ़लाइन उपयोग करने के लिए बड़ी मात्रा में डाटा स्टोर करने का प्रयास कर रहा है" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) आपके डिवाइस पर ऑफ़लाइन उपयोग करने के लिए डाटा स्टोर करने हेतु अनुरोध कर रहा है" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "डाउनलोड शुरू कर रहे है..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "इस साइट के सुरक्षा प्रमाणपत्र के साथ समस्‍याएँ है" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "प्रमाणीकरण आवश्यक है" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "पासवर्ड" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "उपभोक्ता नाम" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "प्राथमिकता याद रखें" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "सेटिंग्स > सामान्य > ऐप्लिकेशंस प्रबंधित करें > सभी पर जाकर डिफ़ॉल्ट ऐप सेटिंग्स साफ करें" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "लोड हो रहा है..." + +msgid "IDS_KA_BODY_DENY" +msgstr "अस्वीकृत करें" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "मीडिया रिकॉर्डिंग उपयोग की अनुमति दें?" + diff --git a/po/hr.po b/po/hr.po new file mode 100755 index 0000000..6c25be2 --- /dev/null +++ b/po/hr.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) traži dopuštenje da koristi vašu kameru." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Da" + +msgid "IDS_BR_SK_NO" +msgstr "Ne" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Prijava" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Prekid" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Dopusti" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) traži dopuštenje da prikaže obavijesti." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) traži dopuštenje da pristupi vašoj lokaciji." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) pokušava pohraniti veću količinu podataka na vaš uređaj za korištenje izvan mreže." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) traži dopuštenje da pohrani veću količinu podataka na vaš uređaj za korištenje izvan mreže." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Pokretanje skidanja..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Greška sigurnosne potvrde za ovu stranicu." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Provjera potrebna." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Šifra" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Korisničko ime" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Spremi postavke." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Obrišite zadane postavke aplikacija tako da odete na Postavke > Općenito > Upravljanje aplikacijama > Sve." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Učitavanje..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Odbijeno" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Dopustiti snimanje medija?" + diff --git a/po/hu.po b/po/hu.po new file mode 100755 index 0000000..4a061d1 --- /dev/null +++ b/po/hu.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) engedélyt kér a fényképező használatára." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Igen" + +msgid "IDS_BR_SK_NO" +msgstr "Nem" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Bejelentkezés" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Mégse" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Engedélyezés" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) engedélyt kér értesítések megjelenítésére." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) engedélyt kér az Ön helyadataihoz való hozzáféréshez." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) nagymennyiségű adatot próbál az eszközön tárolni offline használatra." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) engedélyt kér nagymennyiségű adat tárolására az eszközön offline használatra." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Letöltés indítása..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Probléma merült fel a webhely biztonsági tanúsítványával kapcsolatban." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Hitelesítés szükséges." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Jelszó" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Felhasználónév" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Beállítások megjegyzése" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "A Beállítások > Általános > Alkalmazások kezelése > Összes pontban törölheti az alapértelmezett alkalmazásbeállításokat." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Betöltés..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Elutasítás" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Engedélyezi a médiarögzítést?" + diff --git a/po/hy.po b/po/hy.po new file mode 100755 index 0000000..5b5a31e --- /dev/null +++ b/po/hy.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) հարցնում է Ձեր խցիկն օգտագործելու թույլտվություն:" + +msgid "IDS_BR_SK_OK" +msgstr "Ընդունել" + +msgid "IDS_BR_SK_YES" +msgstr "Այո" + +msgid "IDS_BR_SK_NO" +msgstr "Ոչ" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Մուտք գործել" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Չեղարկել" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Թույլատրել" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) հարցնում է ծանուցումները ցույց տալու թույլտվություն:" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) հարցնում է Ձեր գտնվելու տեղը մուտք գործելու թույլտվություն:" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) փորձում է ցանցից դուրս օգտագործման համար մեծ քանակությամբ տվյալներ պահել Ձեր սարքում:" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) հարցնում է ցանցից դուրս օգտագործման համար Ձեր սարքում տվյալներ պահելու թույլտվություն:" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Ներբեռնման մեկնարկում..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Այս կայքն ունի անվտանգության վկայագրերի խնդիր:" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Պահանջվում է վավերականացում:" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Գաղտնաբառ" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Օգտվողի անուն" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Հիշել նախապատվությունը:" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Մաքրեք կանխադրված ծրագրի դրվածքները՝ գնալով Դրվածքներ > Ընդհանուր > Կառավարել ծրագրերը > Բոլոր:" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Բեռնում է..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Մերժել" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Թույլատրե՞լ մեդիա ձայնագրություններ" + diff --git a/po/id.po b/po/id.po new file mode 100755 index 0000000..a2a08bf --- /dev/null +++ b/po/id.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) meminta izin untuk menggunakan kamera Anda." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Ya" + +msgid "IDS_BR_SK_NO" +msgstr "Tidak" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Masuk" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Batal" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Bolehkan" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) meminta izin memperlihatkan notifikasi." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) meminta izin untuk mengakses lokasi Anda." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) mencoba menyimpan jumlah data yang besar di perangkat untuk penggunaan offline." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) meminta izin menyimpan data di perangkat Anda untuk penggunaan offline." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Mulai mendownload..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Sertifikat keamanan situs ini bermasalah." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Autentikasi diperlukan." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Kata sandi" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Nama pemakai" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Ingat preferensi." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Hapus pengaturan aplikasi default dengan masuk ke Pengaturan > Umum > Kelola aplikasi > Semua." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Meloading…" + +msgid "IDS_KA_BODY_DENY" +msgstr "Deny" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Bolehkan menggunakan rekaman media?" + diff --git a/po/is.po b/po/is.po new file mode 100755 index 0000000..5d258af --- /dev/null +++ b/po/is.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) biður um leyfi til að nota myndavélina þína." + +msgid "IDS_BR_SK_OK" +msgstr "Í lagi" + +msgid "IDS_BR_SK_YES" +msgstr "Já" + +msgid "IDS_BR_SK_NO" +msgstr "Nei" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Innskráning" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Hætta við" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Leyfa" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) biður um leyfi til að sýna tilkynningar." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) biður um leyfi til að fá aðgang að staðsetningunni þinni." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) er að reyna að geyma mikið magn gagna í tækinu til notkunar án nettengingar." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) biður um leyfi til að geyma mikið magn gagna í tækinu til notkunar án nettengingar." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Ræsi niðurhal..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Það komu upp vandamál með öryggisvottorðið fyrir þetta svæði." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Sannprófun er nauðsynleg." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Aðgangsorð" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Notandanafn" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Muna stillingu." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Hreinsaðu sjálfgefnar forritastillingar með því að fara í Stillingar > Almennt > Stjórna forritum > Allt." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Hleð..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Hafna" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Leyfa efnisupptöku?" + diff --git a/po/it_IT.po b/po/it_IT.po new file mode 100755 index 0000000..b3b1b2d --- /dev/null +++ b/po/it_IT.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) sta chiedendo il permesso di utilizzare la fotocamera." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Sì" + +msgid "IDS_BR_SK_NO" +msgstr "No" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Accesso" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Annulla" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Consenti" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) sta chiedendo il permesso di mostrare le notifiche." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) sta chiedendo il permesso di accedere alla posizione dell'utente." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) sta tentando di archiviare una grande quantità di dati sul dispositivo in uso per l'utilizzo offline." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) sta chiedendo il permesso di archiviare i dati sul dispositivo in uso per l'utilizzo offline." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Inizio download..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Problemi con il certificato di sicurezza di questo sito." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Autenticazione richiesta." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Password" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Nome utente" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Ricorda preferenza." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Cancellate le impostazioni predefinite delle applicazioni andando in Impostazioni > Generali > Gestisci applicazioni > Tutte." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Caricamento..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Rifiuta" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Consentire l'uso della registrazione multimediale?" + diff --git a/po/ja_JP.po b/po/ja_JP.po new file mode 100755 index 0000000..3c76ee2 --- /dev/null +++ b/po/ja_JP.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s(%2$s)がカメラを使用する権限を要求しています。" + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "はい" + +msgid "IDS_BR_SK_NO" +msgstr "いいえ" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "ログイン" + +msgid "IDS_BR_SK_CANCEL" +msgstr "キャンセル" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "許可する" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s(%2$s)が通知を表示する権限を要求しています。" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s(%2$s)が現在地情報にアクセスする権限を要求しています。" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s(%2$s)がオフラインで使用するために、端末に容量の大きなデータを保存しようとしています。" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s(%2$s)がオフラインで使用するために、端末にデータを保存する権限を要求しています。" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "ダウンロード開始..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "このサイトのセキュリティ証明書に問題があります。" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "認証が必要です。" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "パスワード" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "ユーザー名" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "設定を保存" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "標準アプリ設定を解除するには、[設定] > [一般] > [アプリケーション管理] > [全て]に移動してください。" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "読み込み中..." + +msgid "IDS_KA_BODY_DENY" +msgstr "拒否" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "メディア​録音​の​使用​を​許可​しますか?" + diff --git a/po/ka.po b/po/ka.po new file mode 100755 index 0000000..41838e4 --- /dev/null +++ b/po/ka.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) ითხოვს თქვენი კამერის გამოყენების ნებართვას." + +msgid "IDS_BR_SK_OK" +msgstr "კი" + +msgid "IDS_BR_SK_YES" +msgstr "კი" + +msgid "IDS_BR_SK_NO" +msgstr "არა" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "შესვლა" + +msgid "IDS_BR_SK_CANCEL" +msgstr "გაუქმება" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "დართე ნება" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) ითხოვს შეტყობინებების ჩვენების ნებართვას." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) ითხოვს თქვენს ლოკაციაზე წვდომის ნებართვას." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) ცდილობს შეინახოს დიდი მოცულობის მონაცემები თქვენს მოწყობილობაში, ინტერნეტში გამოსაყენებლად." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) ითხოვს მონაცემების თქვენს მოწყობილობაში შენახვის ნებართვას, ინტერნეტში მათ გამოსაყენებლად." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "იწყება ჩამოტვირთვა..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "ამ საიტს აქვს უსაფრთხოების სერთიფიკატთან დაკავშირებული პრობლემა." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "ავტორიზაცია აუცილებელია." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "პაროლი" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "მომხმარებლის სახელი" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "უპირატესობის დამახსოვრება." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "პროგრამის ნაგულისხმევი პარამეტრების წასაშლელად, გახსენით პარამეტრები > ზოგადი > პროგრამების მართვა > ყველა." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "იტვირთება..." + +msgid "IDS_KA_BODY_DENY" +msgstr "უარყოფა" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "დართავთ მედია ჩანაწერის გამოყენების ნებას?" + diff --git a/po/kk.po b/po/kk.po new file mode 100755 index 0000000..d7c84bd --- /dev/null +++ b/po/kk.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) камераңызды пайдалану рұқсатын сұрауда." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Иә" + +msgid "IDS_BR_SK_NO" +msgstr "Жоқ" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Жүйеге кіру" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Тоқтату" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Рұқсат" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) хабарландыруларды көрсетуге рұқсат сұрауда." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) орналасқан орныңызға кіру рұқсатын сұрауда." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) үлкен көлемдегі деректерді құрылғыңызда желіден тыс пайдалану үшін сақтауда." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) желіден тыс пайдалану үшін деректерді құрылғыда сақтау рұқсатын сұрауда." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Жүктеу басталуда..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Осы сайтқа арналған қауіпсіздік куәлігінде қателер пайда болады." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Түпнұсқаны тексеру қажет." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Кілтсөз" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Тұтынушы аты" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Басымдығын еске сақтау." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Әдепкі бағдарлама параметрлерін Параметрлер > Жалпы > Бағдарламаларды басқару > Барлығы мәзіріне өту арқылы өшіріңіз." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Жазылуда..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Бас тарту" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Мультимедиялық жазуды пайдалануға рұқсат беру керек пе?" + diff --git a/po/km.po b/po/km.po new file mode 100755 index 0000000..fc9a229 --- /dev/null +++ b/po/km.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) កំពុង​ស្នើ​ការអនុញ្ញាត​ប្រើ​កាមេរ៉ា​របស់​អ្នក។" + +msgid "IDS_BR_SK_OK" +msgstr "ព្រម" + +msgid "IDS_BR_SK_YES" +msgstr "ព្រម" + +msgid "IDS_BR_SK_NO" +msgstr "ទេ" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "ចុះ​ឈ្មោះ​ចូល" + +msgid "IDS_BR_SK_CANCEL" +msgstr "ចោល" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "អនុញ្ញាត" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) កំពុង​ស្នើ​ការអនុញ្ញាត​បង្ហាញ​ការជូនដំណឹង។" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) កំពុង​ស្នើ​ការអនុញ្ញាត​ចូលប្រើ​ទីកន្លែង​របស់​អ្នក។" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) កំពុង​ព្យាយាម​រក្សាទុក​បរិមាណ​ទិន្នន័យ​ជាច្រើន​លើ​ឧបករណ៍​របស់​អ្នក​សម្រាប់​ការប្រើ​ក្រៅ​បណ្ដាញ។" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) កំពុង​ស្នើ​ការអនុញ្ញាត​រក្សាទុក​ទិន្នន័យ​លើ​ឧបករណ៍​របស់​អ្នក​សម្រាប់​ការប្រើ​ក្រៅ​បណ្ដាញ។" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "កំពុង​ចាប់​ផ្ដើម​ទាញ​យក..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "មាន​បញ្ហា​ជាមួយ​វិញ្ញាបនបត្រ​សន្តិសុខ​សម្រាប់​វិបសៃ​នេះ។" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "ត្រូវការ​ការផ្ទៀងផ្ទាត់​ភាពពិត។" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "ពាក្យ​សម្ងាត់" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "ឈ្មោះ​អ្នកប្រើ" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "ចងចាំ​ចំណូលចិត្ត។" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "ជម្រះ​ការកំណត់​កម្មវិធី​លំនាំដើម ដោយ​ការចូលទៅ ការកំណត់ > ទូទៅ > គ្រប់គ្រង​កម្មវិធី > ទាំងអស់។" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "កំពុង​ផ្ទុក..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Deny" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "អនុញ្ញាត​ឲ្យ​ប្រើ​ការថត​មេឌៀ?" + diff --git a/po/kn.po b/po/kn.po new file mode 100755 index 0000000..390a6dd --- /dev/null +++ b/po/kn.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "ನಿಮ್ಮ ಕ್ಯಾಮರಾ ಬಳಸಲು ಅನುಮತಿಯನ್ನು %1$s (%2$s) ವಿನಂತಿಸುತ್ತಿದೆ." + +msgid "IDS_BR_SK_OK" +msgstr "ಸರಿ" + +msgid "IDS_BR_SK_YES" +msgstr "ಹೌದು" + +msgid "IDS_BR_SK_NO" +msgstr "ಇಲ್ಲ" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "ಲಾಗಿನ್" + +msgid "IDS_BR_SK_CANCEL" +msgstr "ರದ್ದು" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "ಅನುಮತಿಸು" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "ಪ್ರಕಟಣೆಗಳನ್ನು ತೋರಿಸಲು ಅನುಮತಿಯನ್ನು %1$s (%2$s) ವಿನಂತಿಸುತ್ತಿದೆ." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಲು %1$s (%2$s) ವಿನಂತಿಸುತ್ತಿದೆ." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "ಆಫ್‌ಲೈನ್ ಬಳಕೆಗಾಗಿ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ದೊಡ್ಡ ಪ್ರಮಾಣದ ಡೇಟಾವನ್ನು ಸಂಗ್ರಹಿಸಲು %1$s (%2$s) ಪ್ರಯತ್ನಿಸುತ್ತಿದೆ." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "ಆಫ್‌ಲೈನ್ ಬಳಕೆಗಾಗಿ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಡೇಟಾ ಸಂಗ್ರಹಿಸಲು ಅನುಮತಿಯನ್ನು %1$s (%2$s) ವಿನಂತಿಸುತ್ತಿದೆ." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "ಡೌನ್‌ಲೋಡ್ ಆರಂಭಿಸುತ್ತಿದೆ..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "ಈ ಸೈಟಿನ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರದ ಜೊತೆ ಸಮಸ್ಯೆಗಳಿವೆ." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "ಪ್ರಮಾಣೀಕರಣ ಅಗತ್ಯವಿದೆ." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "ಪಾಸ್‌ವರ್ಡ್" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "ಬಳಕೆದಾರರಹೆಸರು" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "ಇಚ್ಛೆ ನೆನಪಿಡಿ." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "ಸಂಯೋಜನೆ‌ಗಳು > ಸಾಮಾನ್ಯ > ಅನ್ವಹಿಸುವಿಕೆಗಳನ್ನು ನಿರ್ವಹಿಸು > ಎಲ್ಲಾ ಇಲ್ಲಿಗೆ ಹೋಗುವ ಮೂಲಕ ಡೀಫಾಲ್ಟ್ ಅನ್ವಹಿಸುವಿಕೆ ಸಂಯೋಜನೆಗಳನ್ನು ತೆರವುಗೊಳಿಸಿ." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "ಲೋಡಿಂಗ್..." + +msgid "IDS_KA_BODY_DENY" +msgstr "ನಿರಾಕರಿಸು" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "ಮಿಡಿಯಾ ರೆಕಾರ್ಡಿಂಗ್ ಉಪಯೋಗಿಸಲು ಅನುಮತಿ ನೀಡಲೆ?" + diff --git a/po/ko_KR.po b/po/ko_KR.po new file mode 100755 index 0000000..ed1d96b --- /dev/null +++ b/po/ko_KR.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s(%2$s)에서 카메라 사용 권한을 요청합니다." + +msgid "IDS_BR_SK_OK" +msgstr "확인" + +msgid "IDS_BR_SK_YES" +msgstr "예" + +msgid "IDS_BR_SK_NO" +msgstr "아니요" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "로그인" + +msgid "IDS_BR_SK_CANCEL" +msgstr "취소" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "허용" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s(%2$s)에서 알림 표시 권한을 요청합니다." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s(%2$s)에서 내 위치정보 접근 권한을 요청합니다." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s(%2$s)에서 오프라인에서 사용하기 위해 용량이 큰 데이터를 내 디바이스에 저장하려고 합니다." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s(%2$s)에서 오프라인 사용을 위해 내 디바이스에 데이터를 저장할 권한을 요청합니다." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "다운로드를 시작하는 중..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "URL을 검색하거나 입력하세요" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "인증이 필요합니다." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "비밀번호" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "사용자 이름" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "설정을 기억합니다." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "[설정] > [일반] > [애플리케이션 관리] > [전체]에서 기본 애플리케이션 설정을 삭제하세요." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "불러오는 중..." + +msgid "IDS_KA_BODY_DENY" +msgstr "거부" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "미디어 레코딩을 사용하도록 허용할까요?" + diff --git a/po/ky_KG.po b/po/ky_KG.po new file mode 100755 index 0000000..8b38edf --- /dev/null +++ b/po/ky_KG.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) is requesting permission to use your camera." + +msgid "IDS_BR_SK_OK" +msgstr "ОК" + +msgid "IDS_BR_SK_YES" +msgstr "Ооба" + +msgid "IDS_BR_SK_NO" +msgstr "Жок" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Кирүү" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Артка" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Уруксат бер" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) is requesting permission to show notifications." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) is requesting permission to access your location." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) is attempting to store a large amount of data on your device for offline use." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) is requesting permission to store data on your device for offline use." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Жүктөөнү баштоодо..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Бул сайттын коопсуздук тастыктамасы менен көйгөй бар." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Authentication required." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Сырсөз" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Колдонуучу аты" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Артык көрүүнү эстеп калуу" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Clear default app settings by going to Settings > General > Manage applications > All." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Жүктөлүүдө..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Четке кагуу" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Allow to use media recording?" + diff --git a/po/lo.po b/po/lo.po new file mode 100755 index 0000000..062b1c1 --- /dev/null +++ b/po/lo.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) ກໍາລັງຂໍການອະນຸຍາດໃຊ້ກ້ອງຂອງທ່ານ." + +msgid "IDS_BR_SK_OK" +msgstr "ຕົກລົງ" + +msgid "IDS_BR_SK_YES" +msgstr "ແມ່ນ" + +msgid "IDS_BR_SK_NO" +msgstr "ບໍ່" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "ລົງຊື່ເຂົ້າໃຊ້" + +msgid "IDS_BR_SK_CANCEL" +msgstr "ຍົກເລີກ" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "ອະນຸຍາດ" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) ກໍາລັງຂໍການອະນຸຍາດສະແດງການແຈ້ງເຕືອນ." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) ກໍາລັງຂໍການອະນຸຍາດເຂົ້າຫາທີ່ຕັ້ງຂອງທ່ານ." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) ກໍາລັງພະຍາຍາມບັນທຶກປະລິມານຂໍ້ມູນຂະໜາດໃຫຍ່ຢູ່ໃນເຄື່ອງຂອງທ່ານ ເພື່ອໄວ້ໃຊ້ເວລາອອບໄລນ໌." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) ກໍາລັງຂໍອະນຸຍາດເກັບຮັກສາຂໍ້ມູນໄວ້ຢູ່ໃນເຄື່ອງຂອງທ່ານ ເພື່ອໄວ້ໃຊ້ເວລາອອບໄລນ໌." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "ເລີ່ມການດາວໂຫຼດ..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "ມີບັນຫາກັບໃບຢັ້ງຢືນຄວາມປອດໄພສໍາລັບເວັບໄຊທ໌ນີ້." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Authentication required." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "ລະຫັດຜ່ານ" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "ຊື່ຜູ້ໃຊ້" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "ຈື່ສິ່ງທີ່ມັກໄວ້." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "ລຶບການຕັ້ງຄ່າແອັບມາດຕະຖານໂດຍໄປທີ່ ການຕັ້ງຄ່າ > ທົ່ວໄປ > ຈັດການແອພພລິເຄຊັນ > ທັງໝົດ." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "ກຳລັງໂຫຼດ..." + +msgid "IDS_KA_BODY_DENY" +msgstr "ປະຕິເສດ" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "ອະນຸຍາດໃຫ້ໃຊ້ໃນການບັນທຶກສື່?" + diff --git a/po/lt.po b/po/lt.po new file mode 100755 index 0000000..6fd67cf --- /dev/null +++ b/po/lt.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) prašo leidimo naudoti jūsų fotoaparatą." + +msgid "IDS_BR_SK_OK" +msgstr "Gerai" + +msgid "IDS_BR_SK_YES" +msgstr "Taip" + +msgid "IDS_BR_SK_NO" +msgstr "Ne" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Prisijungimas" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Atšaukti" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Leisti" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) prašo leidimo parodyti pranešimus." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) prašo leidimo nustatyti jūsų vietą." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) bando išsaugoti didelį duomenų kiekį jūsų įrenginyje, kad galėtų jais naudotis atsijungus." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) prašo leidimo išsaugoti duomenis jūsų įrenginyje ir naudotis jais atsijungus." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Pradeda siųsti..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Iškilo problemų dėl šios svetainės apsaugos sertifikato." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Reikalinga patvirtinti autentiškumą." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Slaptažodis" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Naudotojo vardas" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Įsiminti nuostatą." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Eidami į Nustatymai > Bendrieji nustatymai > Tvarkyti programas > Visos, išvalykite numatytuosius programos nustatymus." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Įkeliama..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Atmesti" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Leisti naudotis medijos įrašymo funkcija?" + diff --git a/po/lv.po b/po/lv.po new file mode 100755 index 0000000..c43fda1 --- /dev/null +++ b/po/lv.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) pieprasa atļauju izmantot jūsu kameru." + +msgid "IDS_BR_SK_OK" +msgstr "Labi" + +msgid "IDS_BR_SK_YES" +msgstr "Jā" + +msgid "IDS_BR_SK_NO" +msgstr "Nē" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Pieteikšanās" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Atcelt" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Atļaut" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) pieprasa atļauju rādīt paziņojumus." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) pieprasa atļauju piekļūt jūsu atrašanās vietai." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) mēģina jūsu ierīcē saglabāt lielu datu apjomu lietošanai bezsaistē." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) pieprasa atļauju jūsu ierīcē saglabāt datus lietošanai bezsaistē." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Sāk lejupielādi..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Šai vietnei ir radušās problēmas ar drošības sertifikātu." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Nepieciešama autentifikācija." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Parole" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Lietotājvārds" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Atcerēties preferenci." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Lai notīrītu noklusējuma programmu iestatījumus, izvēlieties Iestatījumi > Vispārīgi > Pārvaldīt programmas > Visas." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Ielādē..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Atteikt" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Vai atļaut lietot multivides ierakstīšanu?" + diff --git a/po/mk.po b/po/mk.po new file mode 100755 index 0000000..e4eaacb --- /dev/null +++ b/po/mk.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) бара дозвола да ја користи Вашата камера." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Да" + +msgid "IDS_BR_SK_NO" +msgstr "Не" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Најава" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Откажи" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Дозволи" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) бара дозвола да покажува известувања." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) бара дозвола да пристапи кон Вашата локација." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) се обидува да сочува големо количество податоци на уредот за користење без интернет." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) бара дозвола да зачувува податоци на уредот за користење без интернет." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Почнува преземање..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Има проблеми со безбедносниот сертификат на сајтот." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Се бара препознавање." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Лозинка" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Корисничко име" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Запомни преференци." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Избришете ги основните опции за апликациите во Опции > Општо > Управување со апликации > Сите." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Активирање..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Отфрли" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Дозволи користење снимање медиуми?" + diff --git a/po/ml.po b/po/ml.po new file mode 100755 index 0000000..e9e750d --- /dev/null +++ b/po/ml.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "നിങ്ങളുടെ ക്യാമറ ആക്സസ്സ് ചെയ്യുന്നതിനുള്ള അനുമതി %1$s (%2$s) അഭ്യര്‍ത്ഥിക്കുന്നു." + +msgid "IDS_BR_SK_OK" +msgstr "ശരി" + +msgid "IDS_BR_SK_YES" +msgstr "അതെ" + +msgid "IDS_BR_SK_NO" +msgstr "ഇല്ല" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "ലോഗിന്‍ ചെയ്യുക" + +msgid "IDS_BR_SK_CANCEL" +msgstr "റദ്ദാക്കു." + +msgid "IDS_BR_OPT_ALLOW" +msgstr "അനുവദിക്കൂ" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "അറിയിപ്പുകള്‍ കാണിക്കുന്നതിനുള്ള അനുമതി %1$s (%2$s) അഭ്യര്‍ത്ഥിക്കുന്നു." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "നിങ്ങളുടെ ലൊക്കേഷന്‍ ആക്സസ്സ് ചെയ്യുന്നതിനുള്ള അനുമതി %1$s (%2$s) അഭ്യര്‍ത്ഥിക്കുന്നു." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "ഓഫ്‌ലൈന്‍ ഉപയോഗത്തിനായി വലിയ തോതിലുള്ള ഡാറ്റ നിങ്ങളുടെ ഉപകരണത്തില്‍ സംഭരിക്കുന്നതിനായി %1$s (%2$s) ശ്രമിക്കുന്നു." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "ഓഫ്‌ലൈന്‍ ഉപയോഗത്തിനായി നിങ്ങളുടെ ഉപകരണത്തില്‍ ഡാറ്റ സംഭരിക്കുന്നതിനുള്ള അനുമതി %1$s (%2$s) അഭ്യര്‍ത്ഥിക്കുന്നു." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "ഡൌണ്‍ലോഡ് ആരംഭിക്കുന്നു..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "ഈ സൈറ്റിനായുള്ള സുരക്ഷാ സര്‍ട്ടിഫിക്കറ്റില്‍ പ്രശ്നങ്ങളുണ്ട്." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "ആധാരീകരിക്കല്‍ ആവശ്യമാണ്." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "പാസ്‌വേഡ്" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "ഉപയോക്തൃ നാമം" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "മുന്‍ഗണന ഓര്‍ക്കുക." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "ക്രമീകരണങ്ങൾ > പൊതുവായവ > ആപ്ലിക്കേഷനുകൾ മാനേജ് ചെയ്യുക > എല്ലാം തുടങ്ങിയവയിലേക്ക് പോയി ഡിഫോൾട്ട് ആപ്ലിക്കേഷൻ ക്രമീകരണങ്ങൾ മായ്ക്കുക." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "ലോഡ്‌ ചെയ്യുന്നു..." + +msgid "IDS_KA_BODY_DENY" +msgstr "നിരസിക്കുക" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "മീഡിയ റെക്കോഡിംഗ് ഉപയോഗിക്കാന്‍ അനുവദിക്കണോ?" + diff --git a/po/mn_MN.po b/po/mn_MN.po new file mode 100755 index 0000000..bfa3c7c --- /dev/null +++ b/po/mn_MN.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) таны камерыг ашиглах зөвшөөрөл хүсэж байна" + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Тийм" + +msgid "IDS_BR_SK_NO" +msgstr "Үгүй" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Нэвтрэх" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Цуцлах" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Зөвшөөрөх" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) мэдэгдлүүд харуулах зөвшөөрөл хүсэж байна" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) таны байрлалд хандах зөвшөөрөл хүсэж байна" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) сүлжээнд холбоогүй ашиглах их хэмжээний өгөгдөл таны төхөөрөмж дээр хадгалахыг оролдож байна" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) сүлжээнд холбоогүй ашиглах өгөгдөл таны төхөөрөмж дээр хадгалах зөвшөөрөл хүсэж байна" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Татан авалтыг эхлүүлж байна..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Энэ сайтын хамгаалалтын гэрчилгээ асуудалтай байна" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Баталгаажуулалт шаардагдана." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Нууц үг" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Хэрэглэгчийн нэр" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Сонголт санах" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Тохиргоо > Ерөнхий > Програмууд удирдах > Бүгд рүү очиж өгөгдмөл програмын тохиргоог арилга" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Ачаалж байна..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Татгалзах" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Медиа бичлэг ашиглахыг зөвшөөрөх үү?" + diff --git a/po/mr.po b/po/mr.po new file mode 100755 index 0000000..d11f30f --- /dev/null +++ b/po/mr.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) आपला कॅमेरा वापरण्‍याकरिता परवानगीसाठी विनंती करत आहे." + +msgid "IDS_BR_SK_OK" +msgstr "ठीक" + +msgid "IDS_BR_SK_YES" +msgstr "होय" + +msgid "IDS_BR_SK_NO" +msgstr "नाही" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "लॉगिन" + +msgid "IDS_BR_SK_CANCEL" +msgstr "रद्द" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "अनुमती द्या" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) अधिसूचना दर्शविण्‍याकरिता परवानगीची विनंती करत आहे." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) आपले स्‍थान ऍक्‍सेस करण्‍याकरिता परवानगीसाठी विनंती करत आहे." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) ऑफलाइन वापरासाठी आपल्‍या उपकरणवर डेटाची मोठी राशी संग्रहित करण्‍याचा प्रयत्‍न करत आहे." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) ऑफलाइन वापरासाठी आपल्‍या उपकरणवर डेटा संग्रहित करण्‍याकरिता परवानगीची विनंती करत आहे." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "डाऊनलोड सुरू करीत आहे..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "या संकेतस्थळाच्या सुरक्षा प्रमाणपत्रा बाबत समस्या आहेत." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "प्रमाणीकरण आवश्यक." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "पासवर्ड" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "वापरकर्त्याचे नाव" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "प्राधान्य लक्षात ठेवा." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "सेटिंग्स > सामान्‍य > अनुप्रयोग व्यवस्थापित करा > सर्व वर जाऊन डीफॉल्ट अनुप्रयोग सेटिंग्स साफ करा." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "लोड होत आहे..." + +msgid "IDS_KA_BODY_DENY" +msgstr "नकार द्या" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "मीडिया रेकॉर्डिंग वापरायला मान्य आहे?" + diff --git a/po/ms.po b/po/ms.po new file mode 100755 index 0000000..a1a19fe --- /dev/null +++ b/po/ms.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) meminta kebenaran menggunakan kamera anda." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Ya" + +msgid "IDS_BR_SK_NO" +msgstr "Tidak" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Log masuk" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Batal" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Benarkan" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) meminta kebenaran menunjukkan pemberitahuan." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) meminta kebenaran mencapai lokasi anda." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) cuba menyimpan sejumlah besar data pada peranti anda untuk kegunaan luar talian." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) meminta kebenaran menyimpan data pada peranti anda untuk kegunaan luar talian." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Memulakan muat turun..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Terdapat masalah dengan sijil keselamatan untuk tapak ini." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Pengesahan Diperlukan." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Kata laluan" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Nama pengguna" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Ingat keutamaan." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Kosongkan aturan aplikasi lalai dengan pergi ke Aturan > Am > Uruskan aplikasi > Semua." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Memuat…" + +msgid "IDS_KA_BODY_DENY" +msgstr "Nafi" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Benarkan untuk mengguna media untuk merakam?" + diff --git a/po/my.po b/po/my.po new file mode 100755 index 0000000..b216a3a --- /dev/null +++ b/po/my.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "သင့္ ကင္မရာသံုးရန္ %1$s (%2$s) က အခြင့္ေတာင္းခံေနသည္။" + +msgid "IDS_BR_SK_OK" +msgstr "အုိေက" + +msgid "IDS_BR_SK_YES" +msgstr "ဟုတ္ကဲ့" + +msgid "IDS_BR_SK_NO" +msgstr "မဟုတ္" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "ေလာ့အင္" + +msgid "IDS_BR_SK_CANCEL" +msgstr "ပယ္ဖ်က္" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "ခြင့္ျပဳပါ" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "အသိေပးခ်က္မ်ား ျပရန္ %1$s (%2$s) က အခြင့္ေတာင္းခံေနသည္။" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "သင့္တည္ေနရာကို ဝင္ေရာက္ရန္ %1$s (%2$s) က အခြင့္ေတာင္းခံေနသည္။" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "အြန္လိုင္းသံုးရန္ သင့္ကိရိယာေပၚတြင္ %1$s (%2$s) က ေဒတာ အေျမာက္အမ်ား သိုေလွာင္ရန္ ၾကိဳးပမ္းေနသည္။" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "ေအာ့ဖ္လိုင္း သံုးရန္ သင့္ကိရိယာေပၚ ေဒတာသိုေလွာင္ရန္ %1$s (%2$s) က အခြင့္ေတာင္းခံေနသည္။" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "လႊဲေျပာင္းကူးယူမႈစတင္ေနပါသည္.." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "ဤဆိုက္အတြက္ လံုျခံဳေရး ေအာင္လက္မွတ္ႏွင့္ပတ္သက္၍ ျပသာနာမ်ား ရွိေနပါသည္။" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Authentication required." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "စကား၀ွက္" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "သုံးစြဲသူ အမည္" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "ပိုမိုႏွစ္သက္မႈမ်ားကို မွတ္ထားပါ" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "ဆက္တင္မ်ား > အေထြေထြ > အပလီေကးရွင္းမ်ား စီမံပါ > အားလံုး သို႔သြားျပီး အသင့္သြင္းထားသည့္ အက္ပ္ဆက္တင္မ်ား ရွင္းပါ။" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "အခ်က္အလက္ျဖည့္သြင္းေနပါသည္…" + +msgid "IDS_KA_BODY_DENY" +msgstr "ျငင္းဆိုပါ" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "မီဒီယာျဖင့္ မွတ္တမ္းတင္ျခင္းကုိ ခြင့္ျပဳလုိပါသလား?" + diff --git a/po/nb.po b/po/nb.po new file mode 100755 index 0000000..aaf30c8 --- /dev/null +++ b/po/nb.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) ber om tillatelse til å bruke kameraet ditt." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Ja" + +msgid "IDS_BR_SK_NO" +msgstr "Nei" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Logg inn" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Avbryt" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Tillat" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) ber om tillatelse til å vise varsler." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) ber om tillatelse til å få tilgang til posisjonen din." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) forsøker å lagre store mengder data på enheten din for bruk i frakoblet modus." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) ber om tillatelse til å lagre data på enheten din for bruk i frakoblet modus." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Starter nedlasting..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Det er problemer med sikkerhetssertifikatet for dette området." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Krever godkjenning." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Passord" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Brukernavn" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Husk preferanse." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Fjern standard appinnstillinger ved å gå til Innstillinger > Generelt > Administrer apper > Alle." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Åpner..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Avslå" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Tillate å bruke mediaopptak?" + diff --git a/po/ne.po b/po/ne.po new file mode 100755 index 0000000..f2f7913 --- /dev/null +++ b/po/ne.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) तपाईको क्यामराको प्रयोग गर्न अनुमतिको लागि अनुरोध गर्दैछ।" + +msgid "IDS_BR_SK_OK" +msgstr "ठीक छ" + +msgid "IDS_BR_SK_YES" +msgstr "हो" + +msgid "IDS_BR_SK_NO" +msgstr "होइन" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "लग-इन" + +msgid "IDS_BR_SK_CANCEL" +msgstr "रद्द" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "अनुमति दिनुहोस्" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) सूचनाहरू देखाउन अनुमतिको लागि अनुरोध गर्दैछ।" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) तपाईको स्थान एक्सेस गर्नको लागि अनुमति को अनुरोध गर्दैछ।" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) अफलाइन प्रयोगको लागि तपाईको यन्त्रमा डाटाको ठूलो मात्रामा भण्डार गर्ने प्रयास गर्दैछ।" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) अफलाइन प्रयोगको लागि तपाईंको यन्त्रमा डाटा भण्डार गर्न अनुमति को अनुरोध गर्दैछ।" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "डाउनलोड शुरू भयो..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "यस साइटका लागि सुरक्षा प्रमाणपत्रसंग केही समस्याहरू छन्।" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "प्रमाणीकरण आवश्यक हुन्छ।" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "पासवर्ड" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "प्रयोगकर्ता नाम" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "प्राथमिकता सम्झनुहोस्।" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "सेटिङ्हरू > सामान्य > अनुप्रयोगहरू व्यवस्थापन गर्नुहोस् > सबै मा गएर पूर्वनिर्धारित एप सेटिङहरू खाली गर्नुहोस्।" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "लोड हुँदै छ..." + +msgid "IDS_KA_BODY_DENY" +msgstr "नकार" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "मिडिया रेकर्डिङ प्रयोग गर्न दिऊँ?" + diff --git a/po/nl.po b/po/nl.po new file mode 100755 index 0000000..fd3e823 --- /dev/null +++ b/po/nl.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) vraagt toestemming om uw camera te gebruiken." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Ja" + +msgid "IDS_BR_SK_NO" +msgstr "Nee" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Inloggen" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Annuleren" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Toestaan" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) vraagt toestemming voor het weergeven van meldingen." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) vraagt toestemming voor toegang tot uw locatie." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) probeert een grote hoeveelheid gegevens op uw apparaat op te slaan voor offline gebruik." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) vraagt toestemming om gegevens op uw apparaat op te slaan voor offline gebruik." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Downloaden starten..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Er zijn problemen met het beveiligingscertificaat voor deze site." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Verificatie vereist." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Wachtwoord" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Gebruikersnaam" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Voorkeur onthouden" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Wis standaard app-instellingen via Instellingen > Algemeen > Applicaties beheren > Alle." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Laden..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Afwijzen" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Media opnemen toestaan?" + diff --git a/po/or.po b/po/or.po new file mode 100755 index 0000000..4a6bec0 --- /dev/null +++ b/po/or.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "ଆପଣଙ୍କ କ୍ୟାମେରା ବ୍ୟବହାର କରିବାକୁ %1$s (%2$s) ଅନୁମତି ଅନୁରୋଧ କରୁଛି।" + +msgid "IDS_BR_SK_OK" +msgstr "ଓକେ" + +msgid "IDS_BR_SK_YES" +msgstr "ହଁ" + +msgid "IDS_BR_SK_NO" +msgstr "ନା" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "ଲଗ୍ଇନ୍" + +msgid "IDS_BR_SK_CANCEL" +msgstr "ବାତିଲ୍" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "ଅନୁମତି" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "ବିଜ୍ଞପ୍ତି ଦେଖାଇବାକୁ %1$s (%2$s) ଅନୁମତି ଅନୁରୋଧ କରୁଛି।" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "ଆପଣଙ୍କ ଅବସ୍ଥାନ ପ୍ରବେଶ କରିବାକୁ %1$s (%2$s) ଅନୁମତି ଅନୁରୋଧ କରୁଛି।" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "ଅଫ୍‌ଲାଇନ୍ ବ୍ୟବହାର ପାଇଁ %1$s (%2$s) ଆପଣଙ୍କ ଡିଭାଇସ୍‌ରେ ଏକ ବୃହତ୍ ପରିମାଣର ଡାଟା ଷ୍ଟୋର୍ କରିବାକୁ ଉଦ୍ୟମ କରୁଛି।" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "ଅଫ୍‌ଲାଇନ୍ ବ୍ୟବହାର ପାଇଁ %1$s (%2$s) ଆପଣଙ୍କ ଡିଭାଇସ୍‌ରେ ଡାଟା ଷ୍ଟୋର୍ କରିବାକୁ ଅନୁରୋଧ କରୁଛି।" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "ଡାଉନ୍‌ଲୋଡ୍‌ ଆରମ୍ଭ କରୁଛି..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "ଏହି ସାଇଟ୍ ପାଇଁ ସୁରକ୍ଷା ସାର୍ଟିଫିକେଟ୍ ସହିତ ଅସୁବିଧା ଅଛି।" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "ପ୍ରାମାଣିକରଣ ଆବଶ୍ୟକ।" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "ପାସ୍‌ୱାର୍ଡ୍" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "ଉପଭୋକ୍ତାନାମ" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "ଅଗ୍ରାଧିକାର ମନେ ରଖନ୍ତୁ।" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "ସେଟିଂ > ସାଧାରଣ > ଆପ୍ଲିକେସନ୍‌ଗୁଡିକ ପରିଚାଳନା > ସମସ୍ତକୁ ଯାଇ ଡିଫଲ୍ଟ୍ ଆପ୍ଲିକେସନ୍ ସେଟିଂ ଖାଲି କରନ୍ତୁ।" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "ଲୋଡ୍ କରୁଛି..." + +msgid "IDS_KA_BODY_DENY" +msgstr "ଅଗ୍ରାହ୍ୟ" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "ମିଡିଆ ରେକର୍ଡିଂ ବ୍ୟବହାର କରିବାକୁ ଅନୁମତି କରନ୍ତୁ?" + diff --git a/po/pa.po b/po/pa.po new file mode 100755 index 0000000..5bce279 --- /dev/null +++ b/po/pa.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) ਤੁਹਾਡੇ ਕੈਮਰੇ ਦਾ ਉਪਯੋਗ ਕਰਨ ਦੀ ਆਗਿਆ ਲੈਣ ਲਈ ਬੇਨਤੀ ਕਰ ਰਿਹਾ ਹੈ।" + +msgid "IDS_BR_SK_OK" +msgstr "ਓਕੇ" + +msgid "IDS_BR_SK_YES" +msgstr "ਹਾਂ" + +msgid "IDS_BR_SK_NO" +msgstr "ਨਹੀਂ" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "ਲੌਗਇਨ" + +msgid "IDS_BR_SK_CANCEL" +msgstr "ਰੱਦ ਕਰੋ" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "ਆਗਿਆ ਦਿਉ" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) ਸੂਚਨਾਵਾਂ ਦਿਖਾਉਣ ਦੀ ਆਗਿਆ ਲੈਣ ਲਈ ਬੇਨਤੀ ਕਰ ਰਿਹਾ ਹੈ।" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) ਤੁਹਾਡੀ ਸਥਿਤੀ 'ਤੇ ਐਕਸੈੱਸ ਕਰਨ ਦੀ ਆਗਿਆ ਲੈਣ ਲਈ ਬੇਨਤੀ ਕਰ ਰਿਹਾ ਹੈ।" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) ਔਫਲਾਈਨ ਉਪਯੋਗ ਲਈ ਤੁਹਾਡੇ ਡਿਵਾਈਸ 'ਤੇ ਵੱਡੀ ਮਾਤਰਾ ਵਿੱਚ ਡੈਟਾ ਸੰਭਾਲਣ ਦਾ ਯਤਨ ਕਰ ਰਿਹਾ ਹੈ।" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) ਔਫਲਾਈਨ ਉਪਯੋਗ ਵਾਸਤੇ ਤੁਹਾਡੇ ਡਿਵਾਈਸ 'ਤੇ ਡੈਟਾ ਸੰਭਾਲਣ ਦੀ ਆਗਿਆ ਲੈਣ ਲਈ ਬੇਨਤੀ ਕਰ ਰਿਹਾ ਹੈ।" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "ਡਾਉਨਲੋਡ ਸ਼ੁਰੂ ਹੋ ਰਿਹਾ ਹੈ..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "ਇਸ ਸਾਈਟ ਦੇ ਲਈ ਸੁਰੱਖਿਆ ਸਰਟੀਫੀਕੇਟ ਵਿੱਚ ਸਮੱਸਿਆਵਾਂ ਹਨ।" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "ਪ੍ਰਮਾਣੀਕਰਨ ਦੀ ਲੋੜ ਹੈ।" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "ਪਾਸਵਰਡ" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "ਉਪਯੋਗਕਰਤਾ ਦਾ ਨਾਂ" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "ਤਰਜੀਹ ਨੂੰ ਯਾਦ ਰੱਖੋ।" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "ਸੈੱਟਿੰਗਸ > ਸਧਾਰਨ > ਅਨੁਪ੍ਰਯੋਗ ਪ੍ਰਬੰਧਕ > ਸਾਰੇ ਤੇ ਜਾ ਕੇ ਡਿਫਾੱਲਟ ਅਨੁਪ੍ਰਯੋਗ ਸੈੱਟਿੰਗਸ ਨੂੰ ਹਟਾਓ।" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "ਲੋਡ ਹੋ ਰਿਹਾ ਹੈ..." + +msgid "IDS_KA_BODY_DENY" +msgstr "ਅਸਵੀਕਾਰ" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "ਉਪਭੋਗਤਾ ਨੂੰ ਮੀਡਿਆ ਰਿਕਾਰਡਿੰਗ ਵਰਤਣ ਦੀ ਅਨੁਮਤੀ ਦਿਓ?" + diff --git a/po/pl.po b/po/pl.po new file mode 100755 index 0000000..c6585a1 --- /dev/null +++ b/po/pl.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) żąda zezwolenia na korzystanie z Twojego aparatu." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Tak" + +msgid "IDS_BR_SK_NO" +msgstr "Nie" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Logowanie" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Anuluj" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Zezwalaj" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) żąda zezwolenia na pokazanie powiadomień." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) żąda zezwolenia na dostęp do Twojej lokalizacji." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) próbuje zapisać dużą ilość danych na Twoim urządzeniu do korzystania offline." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) żąda zezwolenia na zapisanie danych na Twoim urządzeniu do korzystania offline." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Rozpoczynanie pobierania..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Wystąpiły problemy z certyfikatem zabezpieczeń dla tej witryny." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Wymagane uwierzytelnianie." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Hasło" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Nazwa użytkownika" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Zapamiętaj preferencje." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Wyczyść domyślne ustawienia aplikacji, przechodząc do opcji Ustawienia > Ogólne > Zarządzaj aplikacjami > Wszystkie." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Ładuję..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Odrzuć" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Zezwalać na nagrywanie multimediów?" + diff --git a/po/pt_BR.po b/po/pt_BR.po new file mode 100755 index 0000000..d9bda4a --- /dev/null +++ b/po/pt_BR.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) está solicitando permissão para usar a câmera." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Sim" + +msgid "IDS_BR_SK_NO" +msgstr "Não" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Início de sessão" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Cancelar" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Permitir" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) está solicitando permissão para exibir notificações." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) está solicitando permissão para acessar sua localização." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) está tentando armazenar uma grande quantidade de dados no seu dispositivo para uso offline." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) está solicitando permissão para armazenar dados no seu dispositivo para uso offline." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Iniciando download..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Existem problemas com o certificado de segurança para este site." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Autenticação solicitada." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Senha" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Usuário" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Lembrar preferência." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Apagar as configurações padrão do aplicativo indo para Configurações > Gerais > Gerenciar aplicativos > Todos." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Carregando..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Declinar" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Permitir a utilização de gravação multimídia?" + diff --git a/po/pt_PT.po b/po/pt_PT.po new file mode 100755 index 0000000..da54185 --- /dev/null +++ b/po/pt_PT.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) está a pedir permissão para utilizar a sua câmara." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Sim" + +msgid "IDS_BR_SK_NO" +msgstr "Não" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Início de sessão" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Cancelar" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Permitir" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) está a pedir permissão para mostrar notificações." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) está a pedir permissão para aceder à sua localização." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) está a tentar guardar uma grande quantidade de dados no seu dispositivo para utilização offline." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) está a pedir permissão para guardar uma grande quantidade de dados no seu dispositivo para utilização offline." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "A iniciar transferência..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Existem problemas com o certificado de segurança para este site." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Autenticação requerida." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Palavra-passe" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Nome de utilizador" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Lembrar preferência." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Limpe as predefinições das aplicações acedendo a Definições > Geral > Gestor de aplicações > Tudo." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "A carregar..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Declinar" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Permitir a utilização de gravação multimédia?" + diff --git a/po/ro.po b/po/ro.po new file mode 100755 index 0000000..dd80622 --- /dev/null +++ b/po/ro.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) solicită permisiunea de a vă utiliza camera foto." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Da" + +msgid "IDS_BR_SK_NO" +msgstr "Nu" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Conectare" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Anulare" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Se permite" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) solicită permisiunea de a afişa notificări." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) solicită permisiunea de a vă accesa locaţia." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) încearcă să salveze un volum mare de date pe dispozitivul dvs. pentru utilizarea offline." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) solicită permisiunea de a salva date pe dispozitivul dvs. pentru utilizarea offline." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Se începe descărcarea..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Au apărut probleme privind certificatul de securitate pentru acest site." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Se solicită autentificare." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Parolă" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Nume utilizator" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Reţinere preferinţe" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Ştergeţi setările implicite ale aplicaţiei accesând Setări > General >Gestionare aplicaţii > Toate." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Încărcare..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Refuzare" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Permiteţi utilizarea înregistrării media?" + diff --git a/po/ru_RU.po b/po/ru_RU.po new file mode 100755 index 0000000..86d6361 --- /dev/null +++ b/po/ru_RU.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) запрашивает разрешение на использование камеры." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Да" + +msgid "IDS_BR_SK_NO" +msgstr "Нет" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Вход" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Отмена" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Разрешить" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) запрашивает разрешение на отображение уведомлений." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) запрашивает разрешение на доступ к местоположению." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) пытается сохранить большой объем данных на устройстве для использования в автономном режиме." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) запрашивает разрешение на хранение данных на устройстве для использования в автономном режиме." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Начало загрузки..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Проблемы с сертификатом безопасности этого сайта." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Требуется проверка подлинности." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Пароль" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Имя пользователя" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Запомнить настройки." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Чтобы больше не использовать приложение по умолчанию, удалите его назначение в меню “Параметры” > “Общие” > “Управление приложениями” > “Все”." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Загрузка..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Запретить" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Разрешить мультимедийную запись?" + diff --git a/po/si.po b/po/si.po new file mode 100755 index 0000000..4e26294 --- /dev/null +++ b/po/si.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) ඔබගේ කැමරාව භාවිතා කිරීමට අවසරය ඉල්ලමින් සිටී." + +msgid "IDS_BR_SK_OK" +msgstr "හරි" + +msgid "IDS_BR_SK_YES" +msgstr "ඔවි" + +msgid "IDS_BR_SK_NO" +msgstr "නැත" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "ඇතුළු වන්න" + +msgid "IDS_BR_SK_CANCEL" +msgstr "අව. කර" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "ඉඩ දෙන්න" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) දැනුම්දීම් පෙන්වීමට අවසර ඉල්ලමින් සිටී." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) ඔබගේ පිහිටීම වෙත ප්‍රවේශ වීමට අවසර ඉල්ලමින් සිටී." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) නොබැඳි භාවිතය සඳහා ඔබගේ උපාංගය මත විශාල දත්ත ප්‍රමාණයක් ගබඩා කිරීමට උත්සාහ කරමින් සිටී." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) නොබැඳි භාවිතය සඳහා ඔබගේ උපාංගය මත දත්ත ගබඩා කිරීමට අවසරය ඉල්ලමින් සිටී." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "බාගැනුම අරඹමින්..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "මෙම අඩවිය සඳහා ආරක්ෂණ සහතිකයේ ප්‍රශ්න පවතී." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "සත්‍යාපනය අවශ්‍යයයි." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "මුරපදය" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "භාවිතා කරනනාගේ නම" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "කැමැත්ත මතක තබා ගන්න." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "සැකසුම් > සාමාන්‍ය > යෙදුම් කළමනාකරණය කරන්න > සියලු වෙත යාමෙන් පෙරනිමි යෙදුම් සැකසුම් හිස් කරන්න." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "පූරණය කරමින්..." + +msgid "IDS_KA_BODY_DENY" +msgstr "ප්‍රතික්ෂේප කරන්න" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "මාධ්‍ය පටිගත කිරීම භාවිතයට ඉඩ දෙන්නද?" + diff --git a/po/sk.po b/po/sk.po new file mode 100755 index 0000000..a5b4266 --- /dev/null +++ b/po/sk.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) žiada o povolenie používať váš fotoaparát." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Áno" + +msgid "IDS_BR_SK_NO" +msgstr "Nie" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Prihlásenie" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Zrušiť" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Povoliť" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) žiada o povolenie zobrazovať oznámenia." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) žiada o povolenie na prístup k vášmu umiestneniu." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) sa pokúša uložiť veľké množstvo údajov do vášho zariadenia na používanie v režime offline." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) žiada o povolenie uložiť údaje do vášho zariadenia na používanie v režime offline." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Spúšťa sa sťahovanie..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Vyskytli sa problémy s bezpečnostným certifikátom pre túto lokalitu." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Vyžaduje sa overenie." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Heslo" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Užívateľské meno" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Zapamätať predvoľbu" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Vymažte predvolené nastavenia aplikácie v menu Nastavenia > Všeobecné > Spravovať aplikácie > Všetky." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Načítava sa..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Odmietnuť" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Povoliť nahrávanie médií?" + diff --git a/po/sl.po b/po/sl.po new file mode 100755 index 0000000..ce0b019 --- /dev/null +++ b/po/sl.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) zahteva dovoljenje za uporabo kamere." + +msgid "IDS_BR_SK_OK" +msgstr "V redu" + +msgid "IDS_BR_SK_YES" +msgstr "Da" + +msgid "IDS_BR_SK_NO" +msgstr "Ne" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Prijava" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Prekliči" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Dovoli" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) zahteva dovoljenje za prikaz obvestil." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) zahteva dovoljenje za dostop do vaše lokacije." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) poskuša shraniti veliko količino podatkov v vašo napravo za uporabo brez povezave." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) zahteva dovoljenje za shranjevanje podatkov v vašo napravo za uporabo brez povezave." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Začenjam prenos ..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Za to spletno mesto obstajajo težave z varnostnim certifikatom." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Potrebno je overjanje." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Geslo" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Uporabniško ime" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Zapomni si prednostne nastavitve." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Izbrišite privzete nastavitve aplikacije v meniju Nastavitve > Splošno > Upravljanje aplikacij > Vse." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Nalaganje..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Zavrnjeno" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Dovolim uporabo snemanja medijev?" + diff --git a/po/sq.po b/po/sq.po new file mode 100755 index 0000000..4735ed5 --- /dev/null +++ b/po/sq.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) po kërkon leje për të përdorur kamerën." + +msgid "IDS_BR_SK_OK" +msgstr "Ok" + +msgid "IDS_BR_SK_YES" +msgstr "Po" + +msgid "IDS_BR_SK_NO" +msgstr "Jo" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Login" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Anullo" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Lejo" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) po kërkon leje për të shfaqur njoftime." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) po kërkon leje për t'u aksesuar në vendndodhjen tënde." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) po përpiqet të ruajë një sasi të madhe të dhënash në pajisjen tënde për përdorim jashtë linje." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) po kërkon leje për të ruajtur të dhëna në pajisjen tënde për përdorim jashtë linje." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Duke filluar shkarkimin..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Ka probleme me certifikatën e sigurshmërisë për këtë site." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Kërkohet autentikim." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Fjalëkalimi" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Emri i përdoruesit" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Mbaj mend preferencën." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Pastro cilësimet e parazgjedhura të aplikacioneve duke shkuar te Cilësimet > Të përgjithshme > Menaxho aplikacionet > Të gjitha." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Duke ngarkuar..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Refuzo" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Ta lejoj të përdorë regjistrim në media?" + diff --git a/po/sr.po b/po/sr.po new file mode 100755 index 0000000..1c68541 --- /dev/null +++ b/po/sr.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) traži dozvolu za korišćenje tvoje kamere." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Da" + +msgid "IDS_BR_SK_NO" +msgstr "Ne" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Prijava" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Otkaži" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Dozvoli" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) traži dozvolu za prikazivanje obaveštenja." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) traži dozvolu za pristup tvojoj lokaciji." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) pokušava da sačuva veliku količinu podataka na tvoj uređaj za offline korišćenje." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) traži dozvolu da sačuva podatke na tvoj uređaj za offline korišćenje." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Počinje preuzimanje..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Postoje problemi sa bezbednosnim sertifikatom za ovaj sajt." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Potrebna je autentikacija." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Lozinka" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Korisničko ime" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Zapamti željenu vrednost." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Obriši podrazumevana podešavanja aplikacije u okviru Podešavanja > Opšte > Upravljanje aplikacijama > Sve." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Učitavanje..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Odbijeno" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Dozvoli korišćenje medijskih snimaka?" + diff --git a/po/sv.po b/po/sv.po new file mode 100755 index 0000000..ba86e7b --- /dev/null +++ b/po/sv.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) begär tillstånd för att använda kameran." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Ja" + +msgid "IDS_BR_SK_NO" +msgstr "Nej" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Inloggning" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Avbryt" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Tillåt" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) begär tillstånd för att visa meddelanden." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) begär tillstånd om åtkomst till din plats." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) försöker att lagra en stor mängd data på din enhet för användning offline." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) begär tillstånd för att lagra en stor mängd data på din enhet för användning offline." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Startar hämtning..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Det är problem med säkerhetscertifikatet för denna plats." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Verifiering krävs." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Lösenord" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Användarnamn" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Kom ihåg preferens." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Rensa standardprograminställningarna genom att gå till Inställningar > Allmänt > Hantera program > Alla." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Laddar..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Avvisa" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Tillåt mediainspelning?" + diff --git a/po/ta.po b/po/ta.po new file mode 100755 index 0000000..bfd10b5 --- /dev/null +++ b/po/ta.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) உங்கள் கேமராவை உபயோகிக்க அனுமதி கோருகிறது." + +msgid "IDS_BR_SK_OK" +msgstr "சரி" + +msgid "IDS_BR_SK_YES" +msgstr "ஆம்" + +msgid "IDS_BR_SK_NO" +msgstr "இல்லை" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "உள்நுழை" + +msgid "IDS_BR_SK_CANCEL" +msgstr "ரத்து" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "அனுமதி" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) அறிவிக்கைகளைக் காட்டுவதற்கு அனுமதி கோருகிறது." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) உங்கள் இருப்பிடத்தை அணுக அனுமதி கோருகிறது." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) ஆஃப்லைன் உபயோகத்திற்காக உங்கள் சாதனத்தில் அதிகளவு தரவுகளைச் சேமிக்க முயற்சிக்கிறது." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) ஆஃப்லைன் உபயோகத்திற்காக உங்கள் சாதனத்தில் தரவுகளைச் சேமிக்க அனுமதி கோருகிறது." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "பதிவிறக்கம் துவங்குகிறது..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "இந்த இணையதளத்திற்கான பாதுகாப்பு சான்றிதழில் சில சிக்கல்கள் உள்ளன." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "அங்கீகரிப்பு தேவை." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "கடவுச்சொல்" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "பயனர் பெயர்" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "முன்னுரிமையை நினைவுகொள்." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "அமைவுகள் > பொது > பயன்பாடுகளை நிர்வகி > அனைத்துக்குச் சென்று இயல்புநிலை பயன்பாடு அமைவுகளை அழிக்கவும்." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "லோடிங்..." + +msgid "IDS_KA_BODY_DENY" +msgstr "மறுக்கவும்" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "ஊடக பதிதல் பயன்படுத்த அனுமதிக்கவா?" + diff --git a/po/te.po b/po/te.po new file mode 100755 index 0000000..eec5116 --- /dev/null +++ b/po/te.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) మీ కెమెరాని ఉపయోగించడానికి అనుమతిని అభ్యర్థిస్తోంది." + +msgid "IDS_BR_SK_OK" +msgstr "సరే" + +msgid "IDS_BR_SK_YES" +msgstr "అవును" + +msgid "IDS_BR_SK_NO" +msgstr "కాదు" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "లాగిన్" + +msgid "IDS_BR_SK_CANCEL" +msgstr "రద్దు" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "అనుమతించు" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) నోటిఫికేషన్‌లను చూపడానికి అనుమతిని అభ్యర్థిస్తోంది." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) మీ స్థానాన్ని యాక్సెస్ చేయడానికి అనుమతిని అభ్యర్థిస్తోంది." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) మీ పరికరంలో ఆఫ్‌లైన్ ఉపయోగం కోసం అధిక మొత్తంలో డేటాని నిల్వ చేయడానికి ప్రయత్నిస్తోంది." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) మీ పరికరంలో ఆఫ్‌లైన్ ఉపయోగం కోసం డేటాని నిల్వ చేయడానికి అనుమతిని అభ్యర్థిస్తోంది." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "డౌన్లోడ్ ప్రారంభమవుతోంది..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "ఈ సైట్ కు సెక్యూరిటీ సర్టిఫికెట్లనుండి సమస్యలు ఉన్నాయి." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "ప్రమాణీకరణ అవసరం." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "పాస్వర్డ్" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "యూజర్ పేరు" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "ప్రాధాన్యతను గుర్తుపెట్టుకోండి." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "సెట్టింగ్‌లు > సాధారణం > అప్లికేషన్‌లను నిర్వహించు > అన్నీకి వెళ్లడం ద్వారా డిఫాల్ట్ అప్లికేషన్ సెట్టింగ్‌లను క్లియర్ చేయండి." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "లోడ్ అవుతోంది..." + +msgid "IDS_KA_BODY_DENY" +msgstr "నిరాకరించు" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "మీడియా రికార్డింగ్‌ను ఉపయోగించేందుకు అనుమతించాలా?" + diff --git a/po/tg_TJ.po b/po/tg_TJ.po new file mode 100755 index 0000000..f7bc0a7 --- /dev/null +++ b/po/tg_TJ.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) барои истифодаи камераи шумо иҷозатро дархост карда истодааст." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Ҳа" + +msgid "IDS_BR_SK_NO" +msgstr "Не" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Ворид шудан" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Бекор кардан" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Иҷозат додан" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) барои намоиши огоҳиҳо иҷозатро дархост карда истодааст." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) барои пайдо кардани дастрасӣ ба ҷойгиршавии шумо иҷозатро дархост карда истодааст." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) мехоҳад, ки иттилоотро бо ҳаҷми бузург барои истифодаи онлайн ба дастгоҳи шумо захира кунад." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) барои захира кардани иттилоот ба дастгоҳи шумо барои истифодаи онлайн иҷозатро дархост карда истодааст." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Оғозкунии боргирӣ..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Шаҳодатномаи амнияти ин сомона мушкилиҳое дорад." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "санҷиши ҳаққоният лозим аст." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Парол" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Номи корбар" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Ба ёд гирифтани афзалият." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Ба Танзимот > Умумӣ > Идоракунии барномаҳо > Ҳама гузашта, танзимоти пешфарзи барномаҳоро тоза кунед." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Боркунӣ..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Рад кардан" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Сабткунии видеоро иҷозат медиҳед?" + diff --git a/po/th.po b/po/th.po new file mode 100755 index 0000000..146541f --- /dev/null +++ b/po/th.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) กำลังขออนุญาต เพื่อใช้กล้องของคุณ" + +msgid "IDS_BR_SK_OK" +msgstr "ตกลง" + +msgid "IDS_BR_SK_YES" +msgstr "ใช่" + +msgid "IDS_BR_SK_NO" +msgstr "ไม่" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Login" + +msgid "IDS_BR_SK_CANCEL" +msgstr "ยกเลิก" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "อนุญาต" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) กำลังขออนุญาตให้แสดง การแจ้งเตือน" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) กำลังขออนุญาต เพื่อเข้าถึงตำแหน่งของคุณ" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) กำลังพยายามจัดเก็บข้อมูลจำนวนมาก ลงในอุปกรณ์ของคุณสำหรับใช้งานแบบออฟไลน์" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) กำลังขออนุญาตให้จัดเก็บข้อมูล ลงบนอุปกรณ์ของคุณ สำหรับใช้งานแบบออฟไลน์" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "กำลัง​เริ่ม​ดาวน์​โหลด..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "มี​ปัญหา​การ​รับรอง​ความ​ปลอดภัย​สำ​หรับ​ไซ​ต์​นี้" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "ต้อง​การ​การ​รับรอง" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "รหัสผ่าน" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "ชื่อ​ผู้​ใช้" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "จดจำค่าที่เตรียมไว้" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "ล้างการตั้งค่าแอพพื้น​ฐาน​โดยไปที่ การตั้งค่า > ทั่วไป > จัดการแอพพลิเคชั่น > ทั้งหมด" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "โหลด..." + +msgid "IDS_KA_BODY_DENY" +msgstr "ปฏิเสธ" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "อนุญาต​ให้​ใช้​การ​บัน​ทึก​มี​เดีย?" + diff --git a/po/tk_TM.po b/po/tk_TM.po new file mode 100755 index 0000000..996dbcf --- /dev/null +++ b/po/tk_TM.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) siziň kameraňyzy ulanmak üçin rugsat soraýar." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Hawa" + +msgid "IDS_BR_SK_NO" +msgstr "Ýok" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Hasaba giriş" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Ýatyr" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Rugsat etmek" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) habarnamalary görkezmäge rugsat soraýar." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) siziň ýerleşiş maglumatlaryňyza giriş rugsady soraýar." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) siziň enjamyňyzda awtonom ulanyş üçin uly mukdarda maglumat saklamaga synanyşýar." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) siziň enjamyňyzda awtonom ulanyş üçin maglumat saklamaga rugsat soraýar." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Ýüklemäni başlamak..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Bu saýt üçin howpsuzlyk sertifikaty babatyndan bökdençlikler bar." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Hakykylyk barlagy gerek." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Parol" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Ulanyjynyň ady" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Ileri tutulanlary ýatda sakla" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Sazlamalar > Umumy > Goýmalary dolandyr > Ählä baryp, standart goýma sazlamalaryny öçüriň." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Ýükleýär..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Deni" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Multimedia ýazga geçirmegi ulanmaga rugsat bermelimi?" + diff --git a/po/tl.po b/po/tl.po new file mode 100755 index 0000000..fc6a251 --- /dev/null +++ b/po/tl.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "Si %1$s (%2$s) ay humihiling ng pahintulot na gamitin ang iyong camera." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Oo" + +msgid "IDS_BR_SK_NO" +msgstr "Hindi" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Mag-log in" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Ikansela" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Payagan" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "Si %1$s (%2$s) ay humihiling ng pahintulot na magpakita ng mga notification." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "Si %1$s (%2$s) ay humihiling ng pahintulot na ma-access ang iyong lokasyon." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "Sinusubukan ni %1$s (%2$s) na mag-store ng malaking halaga ng data sa iyong device para sa paggamit offline." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "Si %1$s (%2$s) ay humihiling ng pahintulot na mag-store ng data sa iyong device para sa paggamit offline." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Sinisimulan ang pag-download..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Mayroong mga problema sa katibayan sa seguridad para sa site na ito." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Kailangan ng pagpapatunay" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Password" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Username" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Tandaan ang preferences." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "I-clear ang default na mga setting ng app sa pamamagitan ng pagpunta sa Mga Setting > Pangkalahatan > Pamahalaan ang mga application > Lahat." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Naglo-load..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Tanggihan" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Payagang gumamit ng media recording?" + diff --git a/po/tr_TR.po b/po/tr_TR.po new file mode 100755 index 0000000..37c465e --- /dev/null +++ b/po/tr_TR.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) kameranızı kullanmak için izin istiyor" + +msgid "IDS_BR_SK_OK" +msgstr "Tamam" + +msgid "IDS_BR_SK_YES" +msgstr "Evet" + +msgid "IDS_BR_SK_NO" +msgstr "Hayır" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Oturum aç" + +msgid "IDS_BR_SK_CANCEL" +msgstr "İptal" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "İzin ver" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) bildirimleri göstermek için izin istiyor" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) konumunuza erişmek için izin istiyor" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) çevrim dışı kullanım için cihazınıza büyük miktarda veri saklamayı deniyor" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) çevrim dışı kullanım için cihazınıza veri depolamak üzere izin istiyor" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "İndirme başlıyor..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Bu siteyle ilgili güvenlik sertifikasında sorunlar var." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Kimlik denetimi gerekli." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Şifre" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Kullanıcı adı" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Tercihi hatırla." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Ayarlar > Genel > Uygulamaları yönet > Tümü seçeneğine giderek varsayılan uygulama ayarlarını silin." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Yükleniyor..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Geri çevir" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Ortam kaydını kullanmaya izin verilsin mi?" + diff --git a/po/uk.po b/po/uk.po new file mode 100755 index 0000000..cef146c --- /dev/null +++ b/po/uk.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) запитує дозвіл на використання камери." + +msgid "IDS_BR_SK_OK" +msgstr "ОК" + +msgid "IDS_BR_SK_YES" +msgstr "Так" + +msgid "IDS_BR_SK_NO" +msgstr "Ні" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Логін" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Скасувати" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Дозволити" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) запитує дозвіл на відображення сповіщень." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) запитує дозвіл на отримання доступу до вашого розташування." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) намагається зберегти великий об'єм даних на пристрої для автономного використання." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) запитує дозвіл на збереження даних на пристрої для автономного використання." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Початок завантаження..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Проблеми із сертифікатом безпеки для цього сайту." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Потрібна аутентифікація." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Пароль" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Ім'я користувача" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Запам’ятати параметр." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Щоб очистити стандартні установки програм, перейдіть до розділу «Установки» > «Загальні» > «Керування програмами» > «Усі»." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Завантаження..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Відмовити" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Дозволити використання записування медіаданих?" + diff --git a/po/ur.po b/po/ur.po new file mode 100755 index 0000000..1c83e18 --- /dev/null +++ b/po/ur.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) آپ کا کیمرہ استعمال کرنے کی اجازت کی درخواست کررہا ہے" + +msgid "IDS_BR_SK_OK" +msgstr "ٹھیک ہے" + +msgid "IDS_BR_SK_YES" +msgstr "ہاں" + +msgid "IDS_BR_SK_NO" +msgstr "نہیں" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "لاگ ان" + +msgid "IDS_BR_SK_CANCEL" +msgstr "منسوخ" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "اجازت دیں" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) اعلانات دکھانے کی اجازت کی درخواست کررہا ہے" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) آپ کے محل وقوع پر رسائی کرنے کی اجازت کی درخواست کررہا ہے" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) آف لائن استعمال کے لئے آپ کے آلہ پر ڈیٹا کی ایک بڑی مقدار ذخیرہ کرنے کی کوشش کررہا ہے" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) آف لائن استعمال کے لئے آپ کے آلہ پر ڈیٹا ذخیرہ کرنے کی اجازت کی درخواست کررہا ہے" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "ڈاؤن لوڈ شروع کررہا ہے..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "اس سائٹ کے لئے سلامتی کی سند میں مسائل ہیں" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "اتھینٹیکیشن ضروری۔" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "پاس ورڈ" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "استمعال کنندہ کا نام" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "ترجیح یاد رکھیں" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "طے شدہ ایپلیکیشن سیٹنگز کو یہاں جا کر صاف کریں سیٹنگز > عمومی > ایپلیکیشنز بندوبست کریں > تمام" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "لوڈنگ..." + +msgid "IDS_KA_BODY_DENY" +msgstr "انکار کریں" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "میڈیا ریکارڈنگ استعمال کرنے کی اجازت دیں؟" + diff --git a/po/uz.po b/po/uz.po new file mode 100755 index 0000000..e144c69 --- /dev/null +++ b/po/uz.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) kamerangizdan foydalanish uchun ruxsat so‘ramoqda." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "Ha" + +msgid "IDS_BR_SK_NO" +msgstr "Yo‘q" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Kirish" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Bekor qilish" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Ruxsat" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) bildirishnomalarni ko‘rsatish uchun ruxsat so‘ramoqda." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) joylashuvingizga kirish uchun ruxsat so‘ramoqda." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) qurilmangizga offlayn foydalanish uchun katta hajmdagi ma’lumotni saqlashga urinmoqda." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) qurilmangizga offlayn foydalanish uchun ma’lumotni saqlashga ruxsat so‘ramoqda." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Yuklab olish boshlanmoqda..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Ushbu sayt sertifikati bilan bog‘liq muammolar mavjud." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Haqiqiylik tekshiruvi talab qilinadi." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Parol" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Foydalanuvchi nomi" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Eslab qolish afzalligi." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Parametrlar > Umumiy > Ilovalarni boshqarish > Barchasiga o‘tish orqali birlamchi ilova parametrlarini tozalang." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Yuklanmoqda..." + +msgid "IDS_KA_BODY_DENY" +msgstr "Rad etish" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Mediani yozib olishdan foydalanish uchun ruxsat berilsinmi?" + diff --git a/po/vi.po b/po/vi.po new file mode 100755 index 0000000..25b0cd8 --- /dev/null +++ b/po/vi.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) đang yêu cầu quyền sử dụng máy ảnh của bạn." + +msgid "IDS_BR_SK_OK" +msgstr "OK" + +msgid "IDS_BR_SK_YES" +msgstr "OK" + +msgid "IDS_BR_SK_NO" +msgstr "Không" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "Đăng nhập" + +msgid "IDS_BR_SK_CANCEL" +msgstr "Hủy" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "Cho phép" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) đang yêu cầu quyền hiển thị thông báo." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) đang yêu cầu quyền truy cập vị trí của bạn." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) đang cố gắng lưu trữ một lượng lớn dữ liệu vào thiết bị để sử dụng offline." + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) đang yêu cầu lưu trữ dữ liệu trên thiết bị của bạn để dùng offline." + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "Đang bắt đầu tải về..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "Có vấn đề về chứng chỉ bảo mật cho site này." + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "Yêu cầu xác thực." + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "Mật mã" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "Tên người dùng" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "Nhớ Cài đặt sở thích." + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "Xóa cài đặt ứng dụng mặc định bằng cách vào Cài đặt > Cài đặt chung > Quản lý ứng dụng > Tất cả." + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "Đang tải…" + +msgid "IDS_KA_BODY_DENY" +msgstr "Từ chối" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "Cho phép sử dụng ghi media?" + diff --git a/po/zh_CN.po b/po/zh_CN.po new file mode 100755 index 0000000..7071c75 --- /dev/null +++ b/po/zh_CN.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) 正在请求许可使用您的相机。" + +msgid "IDS_BR_SK_OK" +msgstr "确定" + +msgid "IDS_BR_SK_YES" +msgstr "是" + +msgid "IDS_BR_SK_NO" +msgstr "否" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "登录" + +msgid "IDS_BR_SK_CANCEL" +msgstr "取消" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "允许" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) 正在请求许可显示通知。" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) 正在请求许可访问您的位置。" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) 正在尝试在您的设备上存储大量数据用于离线使用。" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) 正在请求许可在您的设备上存储数据用于离线使用。" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "正在开始下载..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "此站点的安全证书存在问题。" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "需要认证" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "密码" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "用户名" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "记住首选项。" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "通过进入设定 > 一般 > 管理应用程序 > 全部清除默认应用程序设置。" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "载入中…" + +msgid "IDS_KA_BODY_DENY" +msgstr "拒绝" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "允许使用媒体录制?" + diff --git a/po/zh_HK.po b/po/zh_HK.po new file mode 100755 index 0000000..849ad53 --- /dev/null +++ b/po/zh_HK.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) 正在請求授權以使用您的相機。" + +msgid "IDS_BR_SK_OK" +msgstr "確定" + +msgid "IDS_BR_SK_YES" +msgstr "是" + +msgid "IDS_BR_SK_NO" +msgstr "否" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "登入" + +msgid "IDS_BR_SK_CANCEL" +msgstr "取消" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "允許" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) 正在請求授權以顯示通知。" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) 正在請求授權以存取您的位置。" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) 正嘗試在您的裝置上儲存大容量數據作為離線使用。" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) 正在請求權限以於您的裝置上儲存數據作為離線使用。" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "正在開始下載..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "此網站的安全性證書存在問題。" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "需要認證" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "密碼" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "用戶名稱" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "記住偏好。" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "通過前往設定 > 一般 > 管理應用程式 > 全部,清除預設的應用程式設定。" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "正在載入..." + +msgid "IDS_KA_BODY_DENY" +msgstr "拒絕" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "允許使用媒體錄製嗎?" + diff --git a/po/zh_TW.po b/po/zh_TW.po new file mode 100755 index 0000000..384a543 --- /dev/null +++ b/po/zh_TW.po @@ -0,0 +1,63 @@ +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA" +msgstr "%1$s (%2$s) 正在請求授權以使用您的相機。" + +msgid "IDS_BR_SK_OK" +msgstr "確定" + +msgid "IDS_BR_SK_YES" +msgstr "是" + +msgid "IDS_BR_SK_NO" +msgstr "否" + +msgid "IDS_BR_BODY_LOGIN" +msgstr "登入" + +msgid "IDS_BR_SK_CANCEL" +msgstr "取消" + +msgid "IDS_BR_OPT_ALLOW" +msgstr "允許" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS" +msgstr "%1$s (%2$s) 正在請求授權以顯示通知。" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION" +msgstr "%1$s (%2$s) 正在請求授權以存取您的位置。" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) 正嘗試在您的裝置上儲存大容量資料作為離線使用。" + +msgid "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE" +msgstr "%1$s (%2$s) 正在請求權限以於您的裝置上儲存資料作為離線使用。" + +msgid "IDS_BR_POP_STARTING_DOWNLOAD_ING" +msgstr "正在開始下載..." + +msgid "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG" +msgstr "此網站的安全憑證有問題。" + +msgid "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED" +msgstr "需要驗證" + +msgid "IDS_BR_BODY_PASSWORD" +msgstr "密碼" + +msgid "IDS_BR_BODY_AUTHUSERNAME" +msgstr "使用者名稱" + +msgid "IDS_BR_BODY_REMEMBER_PREFERENCE" +msgstr "記住偏好。" + +msgid "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL" +msgstr "前往設定 > 一般 > 管理應用程式來清除預設的應用程式設定。" + +msgid "IDS_BR_BODY_LOADING_ING" +msgstr "正在載入..." + +msgid "IDS_KA_BODY_DENY" +msgstr "拒絕" + +msgid "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q" +msgstr "允許使用媒體錄製?" + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..0b41ec3 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,182 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# @file CMakeLists.txt +# @author Lukasz Wrzosek (l.wrzosek@samsung.com) +# @version 1.0 +# + +ADD_DEFINITIONS("-DWRT_LOG") + +# "smack-labeling-support-static" static library ------------------------------- +SET(SMACK_LABELING_SUPPORT_STATIC "smack-labeling-support-static") +PKG_CHECK_MODULES(SMACK_LABELING_SUPPORT_DEPS + dpl-efl + libsmack + REQUIRED +) +SET(SMACK_LABELING_SUPPORT_SOURCES + ${PROJECT_SOURCE_DIR}/src/wrt-client/process_pool/smack_labeling_support.cpp + ) +SET(SMACK_LABELING_SUPPORT_INCLUDES + ${PROJECT_SOURCE_DIR}/src/wrt-client/process_pool/ + ) +INCLUDE_DIRECTORIES( + ${SMACK_LABELING_SUPPORT_INCLUDES} + ${SMACK_LABELING_SUPPORT_DEPS_INCLUDE_DIRS} + ) +ADD_LIBRARY(${SMACK_LABELING_SUPPORT_STATIC} STATIC + ${SMACK_LABELING_SUPPORT_SOURCES} + ) +TARGET_LINK_LIBRARIES(${SMACK_LABELING_SUPPORT_STATIC} + ${SMACK_LABELING_SUPPORT_DEPS_LIBRARIES} + ) +SET_TARGET_PROPERTIES(${SMACK_LABELING_SUPPORT_STATIC} PROPERTIES + COMPILE_DEFINITIONS LOG_TAG="${LOG_TAG}") + +# ------------------------------------------------------------------------------ + +#it is here, so no INCLUDE_DIRS and DEFINITIONS are passed there + +SET(WRT_SRC_DIR + ${PROJECT_SOURCE_DIR}/src + ) + +SET(WRT_CORE_BASE_SOURCES + ${WRT_SRC_DIR}/domain/application_data.cpp + ${WRT_SRC_DIR}/domain/localization_setting.cpp + ${WRT_SRC_DIR}/domain/main_thread.cpp + ${WRT_SRC_DIR}/domain/permission_popup_manager.cpp + ${WRT_SRC_DIR}/domain/widget_data_types.cpp + ${WRT_SRC_DIR}/domain/widget_deserialize_model.cpp + ${WRT_SRC_DIR}/domain/widget_model.cpp + ) + +SET(WRT_CORE_INCLUDES + ${WRT_SRC_DIR}/plugin-service + ${WRT_SRC_DIR}/domain + ${WRT_SRC_DIR}/profiling + ${WRT_SRC_DIR}/view + ) + +SET(WRT_PLUGIN_LOADING_DIR + ${WRT_SRC_DIR}/plugin-service/plugin-loading/ + ) + + +SET(PLUGIN_LOADING_INCLUDES + ${WRT_PLUGIN_LOADING_DIR} +) + +SET(WRT_BASIC_DEP + dpl-efl + dpl-dbus-efl + dpl-event-efl + dpl-utils-efl + wrt-popup-ace-runner + security-core + security-client +) + + +SET(SYS_WRT_BASIC_DEP + openssl + libpcrecpp + glib-2.0 + gthread-2.0 + libsoup-2.4 + libiri + appsvc + cert-svc-vcore + edje + ecore + ecore-x + evas + eina + ewebkit2 + elementary + vconf + cert-svc + secure-storage + capi-appfw-app-manager + efl-extension +) + +IF(SMACK_ENABLED) + LIST(APPEND SYS_WRT_BASIC_DEP libprivilege-control) +ENDIF(SMACK_ENABLED) + + + +PKG_CHECK_MODULES(SYS_WRT_ENGINE_DEPS + ${SYS_WRT_BASIC_DEP} + REQUIRED +) + +PKG_CHECK_MODULES(WRT_ENGINE_DEPS + ${WRT_BASIC_DEP} + REQUIRED +) + +SET(WRT_ENGINE_INCLUDE_DIRS + ${WRT_CORE_INCLUDES} + ${PLUGIN_LOADING_INCLUDES} + ${WRT_ENGINE_DEPS_INCLUDE_DIRS} +) + +#wrt-engine-static +ADD_DEFINITIONS(${SYS_WRT_ENGINE_DEPS_CFLAGS}) +ADD_DEFINITIONS(${SYS_WRT_ENGINE_DEPS_CFLAGS_OTHER}) +ADD_DEFINITIONS(${WRT_ENGINE_DEPS_CFLAGS}) +ADD_DEFINITIONS(${WRT_ENGINE_DEPS_CFLAGS_OTHER}) + +INCLUDE_DIRECTORIES(SYSTEM ${SYS_WRT_ENGINE_DEPS_INCLUDE_DIRS}) +INCLUDE_DIRECTORIES(${WRT_ENGINE_INCLUDE_DIRS}) + +ADD_LIBRARY(${TARGET_WRT_ENGINE_STATIC} STATIC + ${WRT_CORE_BASE_SOURCES} +) + +SET_TARGET_PROPERTIES(${TARGET_WRT_ENGINE_STATIC} PROPERTIES + COMPILE_DEFINITIONS LOG_TAG="${LOG_TAG}") + +SET_TARGET_PROPERTIES(${TARGET_WRT_ENGINE_STATIC} PROPERTIES + SOVERSION ${PROJECT_API_VERSION} + VERSION ${PROJECT_VERSION}) + +SET_TARGET_PROPERTIES(${TARGET_WRT_ENGINE_STATIC} PROPERTIES + COMPILE_FLAGS -fPIC) +SET_TARGET_PROPERTIES(${TARGET_WRT_ENGINE_STATIC} PROPERTIES + COMPILE_FLAGS "-include profiling_util.h") + +INSTALL(FILES + ${WRT_SRC_DIR}/domain/widget_model.h + DESTINATION include/${PROJECT_NAME} +) + +INSTALL(FILES + ${WRT_SRC_DIR}/domain/widget_data_types.h + DESTINATION include/${PROJECT_NAME} +) + +ADD_SUBDIRECTORY(view) +ADD_SUBDIRECTORY(api_new) +ADD_SUBDIRECTORY(wrt-client) +ADD_SUBDIRECTORY(wrt-launcher) +ADD_SUBDIRECTORY(plugin-service) +IF(PROFILING) + ADD_SUBDIRECTORY(profiling) +ENDIF(PROFILING) +ADD_SUBDIRECTORY(wrt-launchpad-daemon) diff --git a/src/DESCRIPTION b/src/DESCRIPTION new file mode 100644 index 0000000..bc2b1d7 --- /dev/null +++ b/src/DESCRIPTION @@ -0,0 +1 @@ +Main source folder diff --git a/src/api_new/CMakeLists.txt b/src/api_new/CMakeLists.txt new file mode 100644 index 0000000..f9b1417 --- /dev/null +++ b/src/api_new/CMakeLists.txt @@ -0,0 +1,89 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +ADD_LIBRARY(${TARGET_CORE_MODULE_LIB} SHARED + ${PROJECT_SOURCE_DIR}/src/api_new/core_module.cpp + ${PROJECT_SOURCE_DIR}/src/api_new/runnable_widget_object.cpp + ${PROJECT_SOURCE_DIR}/src/api_new/runnable_widget_object_state.cpp + ${PROJECT_SOURCE_DIR}/src/api_new/client_security_support.cpp +) + +SET_TARGET_PROPERTIES(${TARGET_CORE_MODULE_LIB} PROPERTIES + COMPILE_DEFINITIONS LOG_TAG="${LOG_TAG}") + +SET_TARGET_PROPERTIES(${TARGET_CORE_MODULE_LIB} PROPERTIES +# COMPILE_FLAGS "-include profiling_util.h" + OUTPUT_NAME ${TARGET_CORE_MODULE_LIB} +) + +PKG_CHECK_MODULES(CORE_MODULE_DEP + dpl-efl + wrt-popup-wrt-runner + REQUIRED +) + +PKG_CHECK_MODULES(SYS_CORE_MODULE_DEP + libprivilege-control + cert-svc + REQUIRED +) + +INCLUDE_DIRECTORIES( + ${CORE_MODULE_DEP_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} +) + +INCLUDE_DIRECTORIES( SYSTEM ${SYS_CORE_MODULE_DEP_INCLUDE_DIRS}) + + +# +#Set libraries that should be linked to the file that is linking wrt-core-module +#Do not set any static libraries as it will be included in wrt-core-module +# +SET(WRT_CORE_MODULE_INTERFACE_LIBRARIES + ${WRT_ENGINE_DEPS_LIBRARIES} + ${SYS_WRT_ENGINE_DEPS_LIBRARIES} + ${CORE_MODULE_DEP_LIBRARIES} + ${SYS_CORE_MODULE_DEP_LIBRARIES} +) + +TARGET_LINK_LIBRARIES(${TARGET_CORE_MODULE_LIB} +# include all symbols that could be used by wrt-client or other binaries + "-Wl,--whole-archive" + ${TARGET_WRT_ENGINE_STATIC} + ${TARGET_VIEW_COMMON_LIB_STATIC} + "-Wl,--no-whole-archive" + ${TARGET_VIEW_MODULE_LIB} + ${WRT_CORE_MODULE_INTERFACE_LIBRARIES} +) + +SET_TARGET_PROPERTIES(${TARGET_CORE_MODULE_LIB} + PROPERTIES + LINK_INTERFACE_LIBRARIES "${WRT_CORE_MODULE_INTERFACE_LIBRARIES}" +) + +INSTALL(TARGETS ${TARGET_CORE_MODULE_LIB} + DESTINATION lib/ + PERMISSIONS OWNER_READ OWNER_WRITE + GROUP_READ GROUP_EXECUTE WORLD_READ +) + +INSTALL(FILES + ${PROJECT_SOURCE_DIR}/src/api_new/core_module.h + ${PROJECT_SOURCE_DIR}/src/api_new/i_runnable_widget_object.h + ${PROJECT_SOURCE_DIR}/src/api_new/user_delegates.h + ${PROJECT_SOURCE_DIR}/src/api_new/client_security_support.h + DESTINATION include/${PROJECT_NAME} +) diff --git a/src/api_new/client_security_support.cpp b/src/api_new/client_security_support.cpp new file mode 100755 index 0000000..bf91f2d --- /dev/null +++ b/src/api_new/client_security_support.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 client_security_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ + +#include "client_security_support.h" + +#include + +#include +#include + +#include +#include + +namespace ClientModule { +namespace { +class Exception +{ +public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, GetAppInfoFailed) + DECLARE_EXCEPTION_TYPE(Base, GetPkgInfoFailed) + DECLARE_EXCEPTION_TYPE(Base, GetAppInfoStrFailed) + DECLARE_EXCEPTION_TYPE(Base, SetPrivilegeFailed) +}; + +// Function declare +void destroyAppInfoHandle(pkgmgrinfo_appinfo_h handle); +void getAppInfo(const std::string& tizenAppId, pkgmgrinfo_appinfo_h* handle); +void getPkgInfo(const char * tizenPkgId, pkgmgrinfo_pkginfo_h *handle); +char* getExePath(pkgmgrinfo_appinfo_h handle); +char* getPackageId(pkgmgrinfo_appinfo_h handle); +char* getPackageType(const char* pkgId); + +void destroyAppInfoHandle(pkgmgrinfo_appinfo_h handle) +{ + if (handle != NULL) { + int ret = pkgmgrinfo_appinfo_destroy_appinfo(handle); + if (ret != PMINFO_R_OK) { + _E("pkgmgrinfo_appinfo_destroy_appinfo failed"); + } + } +} + +void destroyPkgInfoHandle(pkgmgrinfo_pkginfo_h handle) +{ + if (handle != NULL) { + int ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + if (ret != PMINFO_R_OK) { + _E("pkgmgrinfo_pkginfo_destroy_pkginfo failed"); + } + } +} + +void getAppInfo(const std::string& tizenAppId, pkgmgrinfo_appinfo_h* handle) +{ + int ret = pkgmgrinfo_appinfo_get_appinfo(tizenAppId.c_str(), handle); + if (ret != PMINFO_R_OK) { + _E("error pkgmgrinfo_appinfo_get_appinfo(%s) : %d", tizenAppId.c_str(), ret); + Throw(Exception::GetAppInfoFailed); + } +} + +void getPkgInfo(const char * tizenPkgId, pkgmgrinfo_pkginfo_h *handle){ + int ret = pkgmgrinfo_pkginfo_get_pkginfo(tizenPkgId, handle); + if( ret != PMINFO_R_OK ){ + _E("error pkgmgrinfo_pkginfo_get_pkginfo(%s) : %d", tizenPkgId, ret); + Throw(Exception::GetPkgInfoFailed); + } +} + +char* getExePath(pkgmgrinfo_appinfo_h handle) +{ + char* str = NULL; + int ret = pkgmgrinfo_appinfo_get_exec(handle, &str); + if (ret != PMINFO_R_OK) { + _E("error pkgmgrinfo_appinfo_get_exec(%s) : %d", PMINFO_APPINFO_PROP_APP_EXEC, ret); + Throw(Exception::GetAppInfoStrFailed); + } + return str; +} + +char* getPackageId(pkgmgrinfo_appinfo_h handle) +{ + char* str = NULL; + int ret = pkgmgrinfo_appinfo_get_pkgid(handle, &str); + if (ret != PMINFO_R_OK) { + _E("error pkgmgrinfo_appinfo_get_pkgid(%s) : %d", PMINFO_PKGINFO_PROP_PACKAGE_ID, ret); + Throw(Exception::GetAppInfoStrFailed); + } + return str; +} + +char* getPackageType(pkgmgrinfo_pkginfo_h handle) +{ + char* str = NULL; + int ret = pkgmgrinfo_pkginfo_get_type(handle, &str); + if (ret != PMINFO_R_OK) { + _E("error pkgmgrinfo_pkginfo_get_type(%s) : %d", PMINFO_PKGINFO_PROP_PACKAGE_TYPE, ret); + Throw(Exception::GetAppInfoStrFailed); + } + return str; +} + +} // namespace anonymous + +bool SecuritySupport::setAppPrivilege(const std::string& tizenAppId) +{ + pkgmgrinfo_appinfo_h handle = NULL; + pkgmgrinfo_pkginfo_h pkg_handle = NULL; + Try + { + getAppInfo(tizenAppId, &handle); + char* path = getExePath(handle); + char* pkgId = getPackageId(handle); + getPkgInfo(pkgId,&pkg_handle); + char* type = getPackageType(pkg_handle); + + _D("Package ID : %s", pkgId); + _D("Package TYPE : %s", type); + _D("Package PATH : %s", path); + + int ret = perm_app_set_privilege(pkgId, type, path); + if (ret != PC_OPERATION_SUCCESS) { + _E("error perm_app_set_privilege : (%d)", ret); + Throw(Exception::SetPrivilegeFailed); + } + } + Catch(Exception::Base) + { + destroyAppInfoHandle(handle); + destroyPkgInfoHandle(pkg_handle); + return false; + } + + destroyAppInfoHandle(handle); + destroyPkgInfoHandle(pkg_handle); + return true; +} + +std::string SecuritySupport::getPluginProcessSoftLinkPath(const std::string& tzAppId) +{ + const std::string npruntimePostfix = ".npruntime"; + + pkgmgrinfo_appinfo_h handle = NULL; + std::string appBinPath; + + Try + { + getAppInfo(tzAppId, &handle); + char* path = getExePath(handle); + appBinPath = path; + } + Catch(Exception::Base) + { + destroyAppInfoHandle(handle); + return ""; + } + + destroyAppInfoHandle(handle); + return appBinPath + npruntimePostfix; +} +} // ClientModule diff --git a/src/api_new/client_security_support.h b/src/api_new/client_security_support.h new file mode 100644 index 0000000..e62cf4f --- /dev/null +++ b/src/api_new/client_security_support.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 client_security_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ +#ifndef CLIENT_SECURITY_SUPPORT_H_ +#define CLIENT_SECURITY_SUPPORT_H_ + +#include + +namespace ClientModule { +namespace SecuritySupport { +bool setAppPrivilege(const std::string& tizenAppId); +std::string getPluginProcessSoftLinkPath(const std::string& tzAppId); +} // namespace SecuritySupport +} // namespace ClientModule +#endif // CLIENT_SECURITY_SUPPORT_H_ \ No newline at end of file diff --git a/src/api_new/core_module.cpp b/src/api_new/core_module.cpp new file mode 100644 index 0000000..12cea3a --- /dev/null +++ b/src/api_new/core_module.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 core_module.cpp + * @author Przemyslaw Ciezkowski (p.ciezkowski@samsung.com) + * @author Andrzej Surdej (a.surdej@samsung.com) + * @version 1.0 + * @brief File contains definitions of wrt core module. + */ + +#include "core_module.h" +#include "runnable_widget_object.h" +#include +#include +#include +#include +#include +#include +#include +#include "localization_setting.h" +#include +#include +#include +#include + +IMPLEMENT_SINGLETON(WRT::CoreModule) + +namespace { +const char* const TEXT_DOMAIN = "wrt"; +const char* const TEXT_LOCALE_PATH = "/usr/share/locale"; + +std::string cutOffFileName(const std::string& path) +{ + size_t found = path.find_last_of("/"); + if (found == std::string::npos) { + return path; + } else { + return path.substr(0, found); + } +} + +bool isDir(const std::string& path) +{ + struct stat st; + if (0 == stat(path.c_str(), &st) && S_ISDIR(st.st_mode)) { + return true; + } + LogError("Cannot access directory [ " << path << " ]"); + return false; +} + +bool checkPaths() +{ + using namespace WrtDB; + using namespace WrtDB::GlobalConfig; + + bool if_ok = true; + if_ok &= (isDir(cutOffFileName(GetWrtDatabaseFilePath()))); + if_ok &= (isDir(GetDevicePluginPath())); + if_ok &= (isDir(GetUserInstalledWidgetPath())); + return if_ok; +} +} // namespace anonymous + +namespace WRT { +class CoreModuleImpl +{ + public: + + CoreModuleImpl() : m_initialized(false) + { + LogDebug("enter"); + } + + ~CoreModuleImpl() + { + LogDebug("Core module implementation destroyed"); + } + + bool Init() + { + if (!m_initialized) { + ADD_PROFILING_POINT("CoreModule::Init", "point"); + DPL::Log::LogSystemSingleton::Instance().SetTag("WRT"); + LogDebug("Initialize"); + if (!checkPaths()) { + LogError("Required path does not exist"); + return false; + } + Try + { + ADD_PROFILING_POINT("attach databases", "start"); + MainThreadSingleton::Instance().AttachDatabases(); + ADD_PROFILING_POINT("attach databases", "stop"); + LogDebug("Initialize finished"); + } catch (const DPL::Exception& ex) { + LogError("Internal Error during screen preparation:"); + DPL::Exception::DisplayKnownException(ex); + /* TODO: + * Do deinitialization: check on which step exception occured + * and deinitialize only initialized parts. + */ + return false; + } + bindtextdomain(TEXT_DOMAIN, TEXT_LOCALE_PATH); + m_initialized = true; + } + return true; + } + + void Terminate() + { + MainThreadSingleton::Instance().DetachDatabases(); + m_initialized = false; + } + + RunnableWidgetObjectPtr getRunnableWidgetObject( + const std::string& tizenId) + { + try { + RunnableWidgetObjectPtr runnable; + WidgetModelPtr model = + Domain::deserializeWidgetModel(tizenId); + if (!!model) { + runnable.reset(new RunnableWidgetObject(model)); + } + return runnable; + } catch (WrtDB::WidgetDAOReadOnly::Exception::WidgetNotExist) { + LogError("Widget not found."); + return NULL; + } catch (DPL::Exception) { + LogError("Error creating runnable object"); + return NULL; + } + } + + private: + bool m_initialized; +}; + +CoreModule::CoreModule() : m_impl(new CoreModuleImpl()) +{} + +CoreModule::~CoreModule() +{} + +bool CoreModule::Init() +{ + return m_impl->Init(); +} + +void CoreModule::Terminate() +{ + return m_impl->Terminate(); +} + +RunnableWidgetObjectPtr CoreModule::getRunnableWidgetObject( + const std::string& tizenId) +{ + return m_impl->getRunnableWidgetObject(tizenId); +} + +} /* namespace WRT */ diff --git a/src/api_new/core_module.h b/src/api_new/core_module.h new file mode 100644 index 0000000..ba884dd --- /dev/null +++ b/src/api_new/core_module.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 core_module.cpp + * @author Przemyslaw Ciezkowski (p.ciezkowski@samsung.com) + * @authir Andrzej Surdej (a.surdej@gmail.com) + * @version 1.0 + * @brief File contains declarations of wrt core module. + */ + +#ifndef CORE_MODULE_H_ +#define CORE_MODULE_H_ + +#include +#include "i_runnable_widget_object.h" +#include +#include +#include + +namespace WRT { +class CoreModuleImpl; // forward declaration + +class CoreModule +{ + public: + /** + * Initialize needed by WRT components (database etc). + * Will not throw exception. elm_init() is NOT called in this function. + * You MUST call it before running widget. + * @return true on success, false when it fails + */ + bool Init(); + /** + * Deinitialize CoreModule. If it called without Init() some internal + * asserts will fail. + */ + void Terminate(); + /** + * Create model with given package name. + * Init must be called earlier. You MUST destroy all + * RunnableWidgetObjectPtr before calling Terminate. + * @param packageName + * @return NULL on fail + */ + RunnableWidgetObjectPtr getRunnableWidgetObject( + const std::string& tizenId); + + private: + CoreModule(); + ~CoreModule(); + std::unique_ptr m_impl; + + friend class DPL::Singleton; +}; + +typedef DPL::Singleton CoreModuleSingleton; +} /* namespace WRT */ +#endif /* CORE_MODULE_H_ */ \ No newline at end of file diff --git a/src/api_new/i_runnable_widget_object.h b/src/api_new/i_runnable_widget_object.h new file mode 100644 index 0000000..c263261 --- /dev/null +++ b/src/api_new/i_runnable_widget_object.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 i_runnable_widget_object.h + * @author Przemyslaw Ciezkowski (p.ciezkowski@samsung.com) + * @version 1.0 + * @brief File contains declaration of IRunnableWidgetObject interface. + */ + +#ifndef RUNNABLE_WIDGET_OBJECT_INTERFACE_H_ +#define RUNNABLE_WIDGET_OBJECT_INTERFACE_H_ + +#include +#include +#include +#include + +#include + +namespace WRT { + +/** + * @brief The IRunnableWidgetObject class Runnable object interface + * + * Interface for managing WRT widgets runnable object. + * Methods should be called in approopriatte order. Check graph below. + * + * /----------->(INITIAL) + * | | + * | | PrepareView() + * | V + * | (PREPARED) + * | | + * | Reset() | CheckBeforeLaunch() + * | V + * | (SECCHECKED) + * | | + * | | Show() + * | V + * | (SHOWED) + * | / ^ + * | Suspend() | | Resume() + * | V / + * | (SUSPENDED) + * | + * | + * | (any state besides INITIAL) + * | | + * | | Hide() + * | V + * \-------------(HIDDEN) + * + */ +class IRunnableWidgetObject +{ + public: + // IRunnableWidgetObject base exception + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + + // Throwed by any method if it is called in wrong state + DECLARE_EXCEPTION_TYPE(Base, MethodInvocationForbidden) + + /** + * Runs OCSPCheck + * @return false when widget is already running or + * when security check fails + */ + virtual bool CheckBeforeLaunch() = 0; + /** + * Prepares view to launch. You MUST call elm_init before calling + * this method. + * @param window + * @param callbacks passed to viewLogic + */ + virtual bool PrepareView(const std::string &startUrl, + Evas_Object *window, + Ewk_Context* ewkContext = NULL, + int category = 0) = 0; + /** + * Shows widget asynchronously. Callback will be called when + * webkit generates website. + * @param callback + */ + virtual void Show() = 0; + /** + * Hides widget. To show it again Reset must be called. + */ + virtual void Hide() = 0; + /** + * Stops widget's javascript. If widget has set background_enabled + * then this method has no effect. To resume use Resume(); + */ + virtual void Suspend() = 0; + /** + * Resumes widget's javascript after calling Suspend(). Resumes only if + * widget is in suspend state. + */ + virtual void Resume() = 0; + /** + * Resets widgets after calling Hide(). + */ + virtual void Reset() = 0; + /** + * Send Custom Event with epoch time + */ + virtual void TimeTick(long time) = 0; + /** + * Send Custom Event with epoch time on the ambient mode + */ + virtual void AmbientTick(long time) = 0; + /** + * Send Custom Event to notify ambient mode changed + */ + virtual void AmbientModeChanged(bool ambient_mode) = 0; + /** + * Reload start page on widget. + */ + virtual void ReloadStartPage() = 0; + /** + * Retrieve widget's top level webview + * @return Evas_Object* + */ + virtual Evas_Object* GetCurrentWebview() = 0; + /** + * Register widget's delegates + */ + virtual void SetUserDelegates(const UserDelegatesPtr& cbs) = 0; + /** + * Call goBack() on webkit + */ + virtual void Backward() = 0; + /** + * fire custom javascript event + */ + virtual void FireJavascriptEvent(int event, void* data) = 0; + + virtual ~IRunnableWidgetObject() {} +}; + +typedef std::shared_ptr RunnableWidgetObjectPtr; +} +#endif /* RUNNABLE_WIDGET_OBJECT_INTERFACE_H_ */ + diff --git a/src/api_new/runnable_widget_object.cpp b/src/api_new/runnable_widget_object.cpp new file mode 100644 index 0000000..27c5752 --- /dev/null +++ b/src/api_new/runnable_widget_object.cpp @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 runnable_widget_object.cpp + * @author Przemyslaw Ciezkowski (p.ciezkowski@samsung.com) + * @version 1.0 + * @brief File contains defitinions of RunnableWidgetObject implementation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { //Anonymous +const unsigned int UID_ROOT = 0; +const char* const MESSAGE_NAME_INITIALIZE = "ToInjectedBundle::INIT"; +const char* const MESSAGE_NAME_SHUTDOWN = "ToInjectedBundle::SHUTDOWN"; +} // namespace anonymous + +namespace WRT { +RunnableWidgetObject::RunnableWidgetObject(WidgetModelPtr &model) : + m_widgetModel(model), + m_view(ViewModule::createView()), + m_contextManagerFactoryMethod(ViewModule::makeContextManagerFactoryMethod()) +{ + //set initial state of runnable object + m_guardstate = std::shared_ptr( + new State::InitialState(*this)); + // If current uid is 'root', change privilege to apps + if (UID_ROOT == getuid()) { + // Set privilege by tizen id + // this code prevent that widget launch with "root" permission, + // when developers launch by command in the shell + + if (!ClientModule::SecuritySupport::setAppPrivilege( + DPL::ToUTF8String(m_widgetModel->TizenId))) { + Throw(IRunnableWidgetObject::Base); + } + } +} + +bool RunnableWidgetObject::CheckBeforeLaunch() +{ + State::StateChange change = m_guardstate->allowCheckBeforeLaunch(); + Assert(m_widgetModel); + +#ifdef WRT_SMACK_ENABLED + // TODO - this should be in the very first line of the process's main() + // for security reasons; but for now it is easier to place here because + // here the pkg name is already known; we don't struggle to move it + // near the start of main() because we don't know yet if this will + // stay in this process at all: it may be moved to AUL altogether + set_process_config(DPL::ToUTF8String(widgetModel->TizenId).c_str()); +#endif + + change.commit(); + return true; +} + +bool RunnableWidgetObject::PrepareView(const std::string &startUrl, + Evas_Object *window, Ewk_Context* ewkContext, int category) +{ + State::StateChange change = m_guardstate->allowPrepareView(); + if (!window) { + return false; + } + + std::string appId = DPL::ToUTF8String(m_widgetModel->TizenId); + Try { + if(!m_ewkContextManager) { + m_ewkContextManager = m_contextManagerFactoryMethod(appId, ewkContext, m_view); + } else { + if (ewkContext && + ewkContext != m_ewkContextManager->getEwkContext()) + { + m_ewkContextManager = m_contextManagerFactoryMethod(appId, ewkContext, m_view); + } + } + } Catch (DPL::Exception) { + LogError("Internal Error during create or initialize Ewk Context"); + return false; + } + + ADD_PROFILING_POINT("view_logic_init", "start"); + Ewk_Context* context = m_ewkContextManager->getEwkContext(); + + // plugin init + ewk_context_message_post_to_injected_bundle( + context, + MESSAGE_NAME_INITIALIZE, + DPL::ToUTF8String(m_widgetModel->TizenId).c_str()); + + // view init + if(!m_view->createView(context, window)) { + return false; + } + m_view->prepareView(m_widgetModel.get(), startUrl, category); + ADD_PROFILING_POINT("view_logic_init", "stop"); + + change.commit(); + return true; +} + +void RunnableWidgetObject::Show() +{ + State::StateChange change = m_guardstate->allowShow(); + + m_view->showWidget(); + + change.commit(); +} + +void RunnableWidgetObject::Hide() +{ + State::StateChange change = m_guardstate->allowHide(); + + m_view->hideWidget(); + + change.commit(); +} + +void RunnableWidgetObject::Suspend() +{ + LogDebug("Suspending widget"); + State::StateChange change = m_guardstate->allowSuspend(); + m_view->suspendWidget(); + + change.commit(); +} + +void RunnableWidgetObject::Resume() +{ + LogDebug("Resuming widget"); + State::StateChange change = m_guardstate->allowResume(); + m_view->resumeWidget(); + + change.commit(); +} + +void RunnableWidgetObject::Reset() +{ + LogDebug("Reseting widget"); + State::StateChange change = m_guardstate->allowReset(); + if (m_guardstate->toString() == "SUSPENDED") { + m_view->resetWidgetFromSuspend(); + } else { + // PREPARED, SECURITY_CHECKED, SHOWED + m_view->resetWidgetFromResume(); + } + + change.commit(); +} + +void RunnableWidgetObject::TimeTick(long time) +{ + LogDebug("TimeTick called"); + // TODO: how to handle state guard????? + m_view->TimeTick(time); +} + +void RunnableWidgetObject::AmbientTick(long time) +{ + LogDebug("AmbientTick called"); + m_view->AmbientTick(time); +} + +void RunnableWidgetObject::AmbientModeChanged(bool ambient_mode) +{ + LogDebug("AmbientModeChanged called"); + m_view->AmbientModeChanged(ambient_mode); +} + +void RunnableWidgetObject::ReloadStartPage() +{ + m_view->reloadStartPage(); +} + +Evas_Object* RunnableWidgetObject::GetCurrentWebview() +{ + State::StateChange change = m_guardstate->allowGetCurrentWebview(); + + Evas_Object* cww = m_view->getCurrentWebview(); + + change.commit(); + return cww; +} + +void RunnableWidgetObject::SetUserDelegates(const UserDelegatesPtr& cbs) +{ + State::StateChange change = m_guardstate->allowSetUserDelegates(); + m_view->setUserCallbacks(cbs); + change.commit(); +} + +void RunnableWidgetObject::Backward() +{ + State::StateChange change = m_guardstate->allowBackward(); + m_view->backward(); + + change.commit(); +} + +void RunnableWidgetObject::FireJavascriptEvent(int event, void* data) +{ + State::StateChange change = m_guardstate->allowFireJavascriptEvent(); + m_view->fireJavascriptEvent(event, data); + + change.commit(); +} + +void RunnableWidgetObject::setViewModule(ViewModule::IViewModulePtr ptr) +{ + LogDebug("Setting ViewModule"); + m_view = ptr; +} + +void RunnableWidgetObject::setContextManagerFactoryMethod( + ViewModule::ContextManagerFactoryMethod method) +{ + LogDebug("Setting ContextManagerFactoryMethod"); + m_contextManagerFactoryMethod = method; +} + +void RunnableWidgetObject::setNewState( + std::shared_ptr sptr) +{ + LogDebug("RunnableWidgetObject changes state to: " << sptr->toString()); + m_guardstate = sptr; +} + +RunnableWidgetObject::~RunnableWidgetObject() +{ + LogDebug(""); + if(m_ewkContextManager) + { + ewk_context_message_post_to_injected_bundle( + m_ewkContextManager->getEwkContext(), + MESSAGE_NAME_SHUTDOWN, + DPL::ToUTF8String(m_widgetModel->TizenId).c_str()); + } + else + { + LogError("ewk context manager is null"); + } +} +} /* namespace WRT */ diff --git a/src/api_new/runnable_widget_object.h b/src/api_new/runnable_widget_object.h new file mode 100644 index 0000000..ee8ac6c --- /dev/null +++ b/src/api_new/runnable_widget_object.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 core_module.cpp + * @author Przemyslaw Ciezkowski (p.ciezkowski@samsung.com) + * @version 1.0 + * @brief File contains defitinions of RunnableWidgetObject implementation. + */ + +#ifndef RUNNABLE_WIDGET_OBJECT_H_ +#define RUNNABLE_WIDGET_OBJECT_H_ + +//forward declaration +namespace WRT { +namespace State { +class RunnableWidgetObjectState; +class StateChange; +} +} + +#include "i_runnable_widget_object.h" + +#include +#include + +#include +#include +#include +#include + +namespace WRT { +class RunnableWidgetObject : public IRunnableWidgetObject +{ +public: + RunnableWidgetObject(WidgetModelPtr &model); + virtual ~RunnableWidgetObject(); + + bool CheckBeforeLaunch(); + bool PrepareView(const std::string &startUrl, + Evas_Object *window, Ewk_Context* ewkContext = NULL, int category = 0); + void Show(); //asynchronous function + void Hide(); + void Suspend(); + void Resume(); + void Reset(); + void TimeTick(long time); + void AmbientTick(long time); + void AmbientModeChanged(bool ambient_mode); + void ReloadStartPage(); + Evas_Object* GetCurrentWebview(); + void SetUserDelegates(const UserDelegatesPtr& cbs); + void Backward(); + void FireJavascriptEvent(int event, void* data); + + void setViewModule(ViewModule::IViewModulePtr ptr); + void setContextManagerFactoryMethod(ViewModule::ContextManagerFactoryMethod method); + private: + + bool CheckWACTestCertififedWidget(); + void setNewState(std::shared_ptr sptr); + + WidgetModelPtr m_widgetModel; + ViewModule::IViewModulePtr m_view; + std::shared_ptr m_guardstate; + ViewModule::ContextManagerPtr m_ewkContextManager; + + //factor method to be used for creation of context manager when needed + ViewModule::ContextManagerFactoryMethod m_contextManagerFactoryMethod; + + friend class State::StateChange; +}; +} /* namespace WRT */ +#endif /* RUNNABLE_WIDGET_OBJECT_H_ */ diff --git a/src/api_new/runnable_widget_object_state.cpp b/src/api_new/runnable_widget_object_state.cpp new file mode 100644 index 0000000..6eeedba --- /dev/null +++ b/src/api_new/runnable_widget_object_state.cpp @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 core_module.cpp + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @version 1.0 + * @brief State classes for runnable object + */ + +#include "runnable_widget_object_state.h" + +#include + +#include "runnable_widget_object.h" + +namespace WRT { +namespace State { +const StateChange StateChange::NoChange = StateChange(); + +StateChange::StateChange() +{} + +StateChange::StateChange(RunnableWidgetObjectStatePtr sptr) : + m_sptr(sptr) +{} + +void StateChange::commit() +{ + if (m_sptr) { + m_sptr->getObject().setNewState(m_sptr); + } +} + +RunnableWidgetObjectState::RunnableWidgetObjectState( + RunnableWidgetObject & object) : + m_object(object) +{} + +RunnableWidgetObjectState::~RunnableWidgetObjectState() +{} + +RunnableWidgetObject & RunnableWidgetObjectState::getObject() const +{ + return m_object; +} + +StateChange RunnableWidgetObjectState::allowCheckBeforeLaunch() +{ + ThrowMsg(IRunnableWidgetObject::MethodInvocationForbidden, + "CheckBeforeLaunch cannot be called in current state" << toString()); +} + +StateChange RunnableWidgetObjectState::allowPrepareView() +{ + ThrowMsg(IRunnableWidgetObject::MethodInvocationForbidden, + "PrepareView cannot be called in current state" << toString()); +} + +StateChange RunnableWidgetObjectState::allowShow() +{ + ThrowMsg(IRunnableWidgetObject::MethodInvocationForbidden, + "Show cannot be called in current state" << toString()); +} + +StateChange RunnableWidgetObjectState::allowHide() +{ + return StateChange(RunnableWidgetObjectStatePtr(new HiddenState(m_object))); +} + +StateChange RunnableWidgetObjectState::allowSuspend() +{ + ThrowMsg(IRunnableWidgetObject::MethodInvocationForbidden, + "Hide cannot be called in current state" << toString()); +} + +StateChange RunnableWidgetObjectState::allowResume() +{ + ThrowMsg(IRunnableWidgetObject::MethodInvocationForbidden, + "Resume cannot be called in current state" << toString()); +} + +StateChange RunnableWidgetObjectState::allowReset() +{ + ThrowMsg(IRunnableWidgetObject::MethodInvocationForbidden, + "Cannot reset in curretn state"); +} + +StateChange RunnableWidgetObjectState::allowGetCurrentWebview() +{ + return StateChange::NoChange; +} + +StateChange RunnableWidgetObjectState::allowSetUserDelegates() +{ + ThrowMsg(IRunnableWidgetObject::MethodInvocationForbidden, + "SetUserCallbacks cannot be called in current state"); +} + +StateChange RunnableWidgetObjectState::allowBackward() +{ + ThrowMsg(IRunnableWidgetObject::MethodInvocationForbidden, + "Backward cannot be called in current state "); +} + +StateChange RunnableWidgetObjectState::allowForward() +{ + ThrowMsg(IRunnableWidgetObject::MethodInvocationForbidden, + "Foreward cannot be called in current state "); +} + +StateChange RunnableWidgetObjectState::allowReload() +{ + ThrowMsg(IRunnableWidgetObject::MethodInvocationForbidden, + "Reload cannot be called in current state "); +} + +StateChange RunnableWidgetObjectState::allowFireJavascriptEvent() +{ + ThrowMsg(IRunnableWidgetObject::MethodInvocationForbidden, + "FireJavascriptEvent cannot be called in current state "); +} + +InitialState::InitialState(RunnableWidgetObject & object) : + RunnableWidgetObjectState(object) +{} + +std::string InitialState::toString() const +{ + return "INITIAL"; +} + +StateChange InitialState::allowPrepareView() +{ + return StateChange(RunnableWidgetObjectStatePtr(new PreparedState(m_object))); +} + +StateChange InitialState::allowHide() +{ + ThrowMsg(IRunnableWidgetObject::MethodInvocationForbidden, + "Cannot hide before RunnableWidgetObject initialization"); +} + +StateChange InitialState::allowGetCurrentWebview() +{ + ThrowMsg( + IRunnableWidgetObject::MethodInvocationForbidden, + "Cannot call GetCurrentWebview before RunnableWidgetObject initialization"); +} + +PreparedState::PreparedState(RunnableWidgetObject & object) : + RunnableWidgetObjectState(object) +{} + +StateChange PreparedState::allowCheckBeforeLaunch() +{ + return StateChange(RunnableWidgetObjectStatePtr(new SecurityCheckedState( + m_object))); +} + +std::string PreparedState::toString() const +{ + return "PREPARED"; +} + +SecurityCheckedState::SecurityCheckedState(RunnableWidgetObject & object) : + RunnableWidgetObjectState(object) +{} + +std::string SecurityCheckedState::toString() const +{ + return "SECURITY_CHECKED"; +} + +StateChange SecurityCheckedState::allowShow() +{ + return StateChange(RunnableWidgetObjectStatePtr(new ShowedState(m_object))); +} + +StateChange SecurityCheckedState::allowSetUserDelegates() +{ + return StateChange::NoChange; +} + +ShowedState::ShowedState(RunnableWidgetObject & object) : + RunnableWidgetObjectState(object) +{} + +std::string ShowedState::toString() const +{ + return "SHOWED"; +} + +StateChange ShowedState::allowSuspend() +{ + return StateChange(RunnableWidgetObjectStatePtr(new SuspendedState(m_object))); +} + +StateChange ShowedState::allowBackward() +{ + return StateChange::NoChange; +} + +StateChange ShowedState::allowForward() +{ + return StateChange::NoChange; +} + +StateChange ShowedState::allowReload() +{ + return StateChange::NoChange; +} + +StateChange ShowedState::allowReset() +{ + return StateChange::NoChange; +} + +StateChange ShowedState::allowFireJavascriptEvent() +{ + return StateChange::NoChange; +} + +SuspendedState::SuspendedState(RunnableWidgetObject & object) : + RunnableWidgetObjectState(object) +{} + +std::string SuspendedState::toString() const +{ + return "SUSPENDED"; +} + +StateChange SuspendedState::allowResume() +{ + return StateChange(RunnableWidgetObjectStatePtr(new ShowedState(m_object))); +} + +StateChange SuspendedState::allowReset() +{ + return StateChange(RunnableWidgetObjectStatePtr(new ShowedState(m_object))); +} + +HiddenState::HiddenState(RunnableWidgetObject & object) : + RunnableWidgetObjectState(object) +{} + +std::string HiddenState::toString() const +{ + return "HIDEN"; +} + +StateChange HiddenState::allowHide() +{ + ThrowMsg(IRunnableWidgetObject::MethodInvocationForbidden, + "Hide cannot be called in current state" << toString()); +} +} +} diff --git a/src/api_new/runnable_widget_object_state.h b/src/api_new/runnable_widget_object_state.h new file mode 100644 index 0000000..fe9ea13 --- /dev/null +++ b/src/api_new/runnable_widget_object_state.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 core_module.cpp + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @version 1.0 + * @brief State classes for runnable object + */ +#ifndef RUNNABLE_WIDGET_OBJECT_STATE_H +#define RUNNABLE_WIDGET_OBJECT_STATE_H + +//forward declarations +namespace WRT { +class RunnableWidgetObject; + +namespace State { +class RunnableWidgetObjectState; +} +} + +#include + +#include + +namespace WRT { +namespace State { +typedef std::shared_ptr RunnableWidgetObjectStatePtr; + +/** + * @brief The StateChange class + * + * RunnableWidgetObject state change abstraction + */ +class StateChange +{ + public: + static const StateChange NoChange; + + StateChange(); + explicit StateChange(RunnableWidgetObjectStatePtr sptr); + + /** + * @brief commit actually performs change of state + */ + void commit(); + + private: + RunnableWidgetObjectStatePtr m_sptr; +}; + +/** + * @brief The RunnableWidgetObjectState class + * + * Base class for all runnable object states + * + * Allow methods should be called if referenced method are actually + * going to be called effectively. They return next state object. + * Call commit on this object to make change of state of RunnableWidgetObject + */ +class RunnableWidgetObjectState +{ + public: + explicit RunnableWidgetObjectState(RunnableWidgetObject & object); + virtual ~RunnableWidgetObjectState(); + + virtual StateChange allowCheckBeforeLaunch(); + virtual StateChange allowPrepareView(); + virtual StateChange allowShow(); + virtual StateChange allowHide(); + virtual StateChange allowSuspend(); + virtual StateChange allowResume(); + virtual StateChange allowReset(); + virtual StateChange allowGetCurrentWebview(); + virtual StateChange allowSetUserDelegates(); + virtual StateChange allowBackward(); + virtual StateChange allowForward(); + virtual StateChange allowReload(); + virtual StateChange allowFireJavascriptEvent(); + + virtual std::string toString() const = 0; + virtual RunnableWidgetObject & getObject() const; + + protected: + RunnableWidgetObject & m_object; +}; + +/** + * INITIAL STATE + */ +class InitialState : public RunnableWidgetObjectState +{ + public: + explicit InitialState(RunnableWidgetObject & object); + std::string toString() const; + + StateChange allowPrepareView(); + StateChange allowHide(); + StateChange allowGetCurrentWebview(); +}; + +/** + * PREPARED STATE + */ +class PreparedState : public RunnableWidgetObjectState +{ + public: + explicit PreparedState(RunnableWidgetObject & object); + std::string toString() const; + + StateChange allowCheckBeforeLaunch(); +}; + +/** + * SECURITY CHECKED STATE + */ +class SecurityCheckedState : public RunnableWidgetObjectState +{ + public: + explicit SecurityCheckedState(RunnableWidgetObject & object); + std::string toString() const; + + StateChange allowShow(); + StateChange allowSetUserDelegates(); +}; + +/** + * SHOWED STATE + */ +class ShowedState : public RunnableWidgetObjectState +{ + public: + explicit ShowedState(RunnableWidgetObject & object); + std::string toString() const; + + StateChange allowSuspend(); + StateChange allowBackward(); + StateChange allowForward(); + StateChange allowReload(); + StateChange allowReset(); + StateChange allowFireJavascriptEvent(); +}; + +/** + * SUSPENDED STATE + */ +class SuspendedState : public RunnableWidgetObjectState +{ + public: + explicit SuspendedState(RunnableWidgetObject & object); + std::string toString() const; + + StateChange allowResume(); + StateChange allowReset(); +}; + +/** + * HIDDEN STATE + */ +class HiddenState : public RunnableWidgetObjectState +{ + public: + explicit HiddenState(RunnableWidgetObject & object); + std::string toString() const; + + StateChange allowHide(); +}; +} +} + +#endif // RUNNABLE_WIDGET_OBJECT_STATE_H diff --git a/src/api_new/user_delegates.h b/src/api_new/user_delegates.h new file mode 100755 index 0000000..936d582 --- /dev/null +++ b/src/api_new/user_delegates.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 user_delegates.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief user delegates + */ +#ifndef USER_DELEGATES_H +#define USER_DELEGATES_H + +#include +#include +#include + +#include + +namespace WRT { +typedef std::function SetWebviewCallback; +typedef std::function UnsetWebviewCallback; +typedef std::function LoadProgressStartedCallback; +typedef std::function LoadProgressCallback; +typedef std::function LoadProgressFinishedCallback; +typedef std::function LoadStartedCallback; +typedef std::function LoadFinishedCallback; +typedef std::function ProcessCrashedCallback; +typedef std::function PolicyNavigationDecideCallback; +typedef std::function ProcessExitCallback; +typedef std::function EnterFullscreenCallback; +typedef std::function ExitFullscreenCallback; +typedef std::function OrientationLockCallback; +typedef std::function KeyCallback; +typedef std::function ConsoleMessageCallback; +typedef std::function RotatePreparedCallback; +typedef std::function EnableVideoHwOverlayCallback; +typedef std::function DisableVideoHwOverlaycallback; +typedef std::function PopupReplyWaitStartCallback; +typedef std::function PopupReplyWaitFinishCallback; +typedef std::function FrameRenderedCallback; +typedef std::function BlockedUrlPolicyCallback; + +struct UserDelegates { + SetWebviewCallback setWebviewCallback; + UnsetWebviewCallback unsetWebviewCallback; + LoadProgressStartedCallback loadProgressStartedCallback; + LoadProgressCallback loadProgressCallback; + LoadProgressFinishedCallback loadProgressFinishedCallback; + LoadStartedCallback loadStartedCallback; + LoadFinishedCallback loadFinishedCallback; + ProcessCrashedCallback processCrashedCallback; + PolicyNavigationDecideCallback policyNavigationDecideCallback; + ProcessExitCallback processExitCallback; + EnterFullscreenCallback enterFullscreenCallback; + ExitFullscreenCallback exitFullscreenCallback; + OrientationLockCallback orientationLockCallback; + KeyCallback keyCallback; + ConsoleMessageCallback consoleMessageCallback; + RotatePreparedCallback rotatePreparedCallback; + EnableVideoHwOverlayCallback enableVideoHwOverlayCallback; + DisableVideoHwOverlaycallback disableVideoHwOverlayCallback; + PopupReplyWaitStartCallback popupReplyWaitStartCallback; + PopupReplyWaitFinishCallback popupReplyWaitFinishCallback; + FrameRenderedCallback frameRenderedCallback; + BlockedUrlPolicyCallback blockedUrlPolicyCallback; +}; + +typedef std::shared_ptr UserDelegatesPtr; +} + +#endif // USER_DELEGATES_H diff --git a/src/domain/DESCRIPTION b/src/domain/DESCRIPTION new file mode 100644 index 0000000..2f8c08b --- /dev/null +++ b/src/domain/DESCRIPTION @@ -0,0 +1 @@ +Collective folder for a number of modules diff --git a/src/domain/application_data.cpp b/src/domain/application_data.cpp new file mode 100644 index 0000000..e6fa8c7 --- /dev/null +++ b/src/domain/application_data.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 application_data.cpp + * @author Yunchan Cho (yunchan.cho@samsung.com) + * @version 1.0 + * @brief implementation file for application_data.h + */ + +#include "application_data.h" +#include +#include +#include + +IMPLEMENT_SAFE_SINGLETON(ApplicationData) + +ApplicationData::ApplicationData() : + m_originBundle(NULL), + m_encodedBundle(NULL) +{} + +ApplicationData::~ApplicationData() +{} + +bundle* ApplicationData::getBundle() const +{ + return m_originBundle; +} + +const char* ApplicationData::getEncodedBundle() const +{ + return (const char *)m_encodedBundle; +} + +bool ApplicationData::setBundle(bundle *originBundle) +{ + if (!originBundle) { + LogError("Bundle is empty!"); + return false; + } + + freeBundle(); + + m_originBundle = originBundle; + return true; +} + +bool ApplicationData::setEncodedBundle(bundle* originBundle) +{ + int len, ret; + if (!originBundle) { + LogError("Bundle is empty!"); + return false; + } + + freeEncodedBundle(); + + ret = bundle_encode(originBundle, &m_encodedBundle, &len); + if (ret == -1) { + LogError("Failed to encode bundle data"); + return false; + } + + LogDebug("Encoded Bundle : " << m_encodedBundle); + return true; +} + +void ApplicationData::freeBundle() +{ + if (!m_originBundle) { + return; + } + + if (!bundle_free(m_originBundle)) { + LogDebug("Bundle data freed for new bundle data"); + m_originBundle = NULL; + } +} + +void ApplicationData::freeEncodedBundle() +{ + if (!m_encodedBundle) { + return; + } + + if (m_encodedBundle) { + if (!bundle_free_encoded_rawdata( + &m_encodedBundle)) + { + LogDebug("Bundle data freed for new bundle data"); + m_encodedBundle = NULL; + } + } +} + diff --git a/src/domain/application_data.h b/src/domain/application_data.h new file mode 100644 index 0000000..7d183ce --- /dev/null +++ b/src/domain/application_data.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 application_data.h + * @author Yunchan Cho (yunchan.cho@samsung.com) + * @version 1.0 + * @brief Header file for application_data.h + */ + +#ifndef APPLICATION_DATA_H_ +#define APPLICATION_DATA_H_ + +#include +#include +#include + +class ApplicationData +{ + public: + bundle* getBundle() const; + const char* getEncodedBundle() const; + bool setBundle(bundle *originBundle); + bool setEncodedBundle(bundle* originBundle); + void freeBundle(); + void freeEncodedBundle(); + + private: + ApplicationData(); + ~ApplicationData(); + + bundle* m_originBundle; + bundle_raw* m_encodedBundle; + + friend class DPL::Singleton; +}; + +typedef DPL::Singleton ApplicationDataSingleton; + +#endif /*APPLICATION_DATA_H_*/ diff --git a/src/domain/iana_record_types.h b/src/domain/iana_record_types.h new file mode 100644 index 0000000..8f3bb6d --- /dev/null +++ b/src/domain/iana_record_types.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 iana_record_types.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + */ + +enum iana_record_types_e +{ + RECORD_TYPE_LANGUAGE, + RECORD_TYPE_SCRIPT, + RECORD_TYPE_REGION, + RECORD_TYPE_VARIANT, + RECORD_TYPE_GRANDFATHERED, + RECORD_TYPE_REDUNDANT, + RECORD_TYPE_EXTLANG +}; diff --git a/src/domain/localization_setting.cpp b/src/domain/localization_setting.cpp new file mode 100644 index 0000000..79aae9e --- /dev/null +++ b/src/domain/localization_setting.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 localization_setting.cpp + * @author Soyoung Kim (sy037.kim@samsung.com) + * @version 1.0 + * @brief Localization setting implementation + */ + +#include "localization_setting.h" +#include + +#include + +namespace LocalizationSetting { +void SetLanguageChangedCallback(LanguageChangedCallback cb, void *data) +{ + LogDebug("Set language changed callback"); + + appcore_set_event_callback( + APPCORE_EVENT_LANG_CHANGE, + cb, data); +} +} //Namespace LocalizationSetting diff --git a/src/domain/localization_setting.h b/src/domain/localization_setting.h new file mode 100644 index 0000000..7a32544 --- /dev/null +++ b/src/domain/localization_setting.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 localization_setting.h + * @author Soyoung Kim (sy037.kim@samsung.com) + * @version 1.0 + * @brief localization setting implementation + */ +#ifndef LOCALIZATION_SETTING_H_ +#define LOCALIZATION_SETTING_H_ + +namespace LocalizationSetting { +typedef int (*LanguageChangedCallback)(void *data, void *tmp); + +void SetLanguageChangedCallback(LanguageChangedCallback cb, void *data); +} //LocalizationSetting + +#endif // ifndef LOCALIZATION_SETTING_H_ + diff --git a/src/domain/main_thread.cpp b/src/domain/main_thread.cpp new file mode 100644 index 0000000..4f6afa4 --- /dev/null +++ b/src/domain/main_thread.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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_thread.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#include "main_thread.h" +#include +#include +#include +#include +#include +#include +IMPLEMENT_SINGLETON(MainThread) + +using namespace WrtDB; + +MainThread::MainThread() : m_attached(false) {} + +MainThread::~MainThread() +{ + if (m_attached) { + LogError("Destroyed without detach"); + } +} + +void MainThread::AttachDatabases() +{ + Assert(!m_attached); + // Attach databases + ace_return_t ret = ace_client_initialize(Wrt::Popup::run_popup); + Assert(ACE_OK == ret); + WrtDB::WrtDatabase::attachToThreadRO(); + m_attached = true; +} + +void MainThread::DetachDatabases() +{ + Assert(m_attached); + m_attached = false; + // Detach databases + ace_return_t ret = ace_client_shutdown(); + Assert(ACE_OK == ret); + WrtDB::WrtDatabase::detachFromThread(); +} diff --git a/src/domain/main_thread.h b/src/domain/main_thread.h new file mode 100644 index 0000000..df00289 --- /dev/null +++ b/src/domain/main_thread.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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_thread.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#ifndef WRT_SRC_DOMAIN_MAINTHREAD_H_ +#define WRT_SRC_DOMAIN_MAINTHREAD_H_ + +#include + +class MainThread +{ + public: + void AttachDatabases(); + void DetachDatabases(); + + private: + friend class DPL::Singleton; + + MainThread(); + virtual ~MainThread(); + + bool m_attached; +}; + +typedef DPL::Singleton MainThreadSingleton; + +#endif /* WRT_SRC_DOMAIN_MAINTHREAD_H_ */ diff --git a/src/domain/permission_popup_manager.cpp b/src/domain/permission_popup_manager.cpp new file mode 100644 index 0000000..6b4ec85 --- /dev/null +++ b/src/domain/permission_popup_manager.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 permission_popup_manager.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ + +#include "permission_popup_manager.h" + +#include +#include +#include +#include +#include + +IMPLEMENT_SAFE_SINGLETON(PermissionPopupManager) + +PermissionPopupManager::PermissionPopupManager() +{} + +PermissionPopupManager::~PermissionPopupManager() +{} + +void PermissionPopupManager::registerPopup(Evas_Object* webview, Evas_Object* popup) +{ + _D("register %p %p", webview, popup); + + if (!webview || !popup) + { + _W("Wrong input argument"); + return; + } + addWebview(webview); + addPopup(popup); + m_pairList.push_back(Pair(webview, popup)); +} + +void PermissionPopupManager::unregisterWebview(Evas_Object* webview) +{ + _D("unegister webview[%p]", webview); + + FOREACH(it, m_pairList) + { + if (it->first == webview) + { + removePopup(it->second); + evas_object_del(it->second); + + // erase iterator + PairList::iterator next = it; + ++next; + m_pairList.erase(it); + it = next; + } + } + removeWebview(webview); +} + +void PermissionPopupManager::unregisterPopup(Evas_Object* popup) +{ + _D("unegister popup[%p]", popup); + + Evas_Object* webview = NULL; + + FOREACH(it, m_pairList) + { + if (it->second == popup) + { + webview = it->first; + removePopup(it->second); + + // erase iterator + PairList::iterator next = it; + ++next; + m_pairList.erase(it); + it = next; + } + } + + if (webview) + { + FOREACH(it, m_pairList) + { + if (it->first == webview) + { + // PairList still has webview usage. + // Do not clean-up webview data. + return; + } + } + removeWebview(webview); + } +} + +void PermissionPopupManager::addWebview(Evas_Object* webview) +{ + evas_object_event_callback_add(webview, EVAS_CALLBACK_DEL, deleteWebviewCallback, this); +} + +void PermissionPopupManager::addPopup(Evas_Object* popup) +{ + evas_object_event_callback_add(popup, EVAS_CALLBACK_DEL, deletePopupCallback, this); +} + +void PermissionPopupManager::removeWebview(Evas_Object* webview) +{ + evas_object_event_callback_del(webview, EVAS_CALLBACK_DEL, deleteWebviewCallback); +} + +void PermissionPopupManager::removePopup(Evas_Object* popup) +{ + evas_object_event_callback_del(popup, EVAS_CALLBACK_DEL, deletePopupCallback); +} + +void PermissionPopupManager::deleteWebviewCallback(void* data, Evas* e, Evas_Object* obj, void* eventInfo) +{ + Assert(data); + Assert(obj); + + DPL_UNUSED_PARAM(e); + DPL_UNUSED_PARAM(eventInfo); + + PermissionPopupManager* This = static_cast(data); + This->unregisterWebview(obj); +} + +void PermissionPopupManager::deletePopupCallback(void* data, Evas* e, Evas_Object* obj, void* eventInfo) +{ + Assert(data); + Assert(obj); + + DPL_UNUSED_PARAM(e); + DPL_UNUSED_PARAM(eventInfo); + + PermissionPopupManager* This = static_cast(data); + This->unregisterPopup(obj); +} + diff --git a/src/domain/permission_popup_manager.h b/src/domain/permission_popup_manager.h new file mode 100644 index 0000000..68cead1 --- /dev/null +++ b/src/domain/permission_popup_manager.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 permission_popup_manager.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ + +#ifndef PERMISSION_POPUP_MANAGER_H_ +#define PERMISSION_POPUP_MANAGER_H_ + +#include +#include + +#include +#include + +class PermissionPopupManager +{ + public: + void registerPopup(Evas_Object* webview, Evas_Object* popup); + + private: + PermissionPopupManager(); + ~PermissionPopupManager(); + + void unregisterPopup(Evas_Object* popup); + void unregisterWebview(Evas_Object* webview); + + void addWebview(Evas_Object* webview); + void addPopup(Evas_Object* popup); + void removeWebview(Evas_Object* webview); + void removePopup(Evas_Object* popup); + + static void deleteWebviewCallback(void* data, Evas* e, Evas_Object* obj, void* eventInfo); + static void deletePopupCallback(void* data, Evas* e, Evas_Object* obj, void* eventInfo); + + typedef std::pair Pair; // std::pair + typedef std::list PairList; + PairList m_pairList; + + friend class DPL::Singleton; +}; + +typedef DPL::Singleton PermissionPopupManagerSingleton; + +#endif // PERMISSION_POPUP_MANAGER_H_ diff --git a/src/domain/widget_data_types.cpp b/src/domain/widget_data_types.cpp new file mode 100755 index 0000000..908f436 --- /dev/null +++ b/src/domain/widget_data_types.cpp @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file have been implemented in compliance with W3C WARP SPEC. + * but there are some patent issue between W3C WARP SPEC and APPLE. + * so if you want to use this file, refer to the README file in root directory + */ +/** + * @file widget_data_types.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @author Tomasz Iwanek (t.iwanek@samsung.com) (implementation moved to + * cpp) + * @version 0.1 + * @brief + */ + +#include + +#include + +#include +#include + +namespace { +const char* const WRT_WIDGET_DATA_TYPES_LOG_ENABLE = + "WRT_WIDGET_DATA_TYPES_LOG_ENABLE"; +} + +WidgetAccessList::WidgetAccessList() : m_isAccessAll(false) +{} + +WidgetAccessList::WidgetAccessList( + const WrtDB::WidgetAccessInfoList &widgetAccessInfoList) : + m_isAccessAll(false) +{ + FOREACH(it, widgetAccessInfoList) + { + if (DPL::FromUTF32String(L"*") == it->strIRI) { + m_isAccessAll = true; + m_warpIriList.clear(); + return; + } + + WarpIRI warpIri; + + warpIri.set(DPL::ToUTF8String(it->strIRI).c_str(), + it->bSubDomains); + + if (warpIri.isAccessDefinition()) { + m_warpIriList.push_back(warpIri); + } + } +} + +bool WidgetAccessList::getIsAccessAll() const +{ + return m_isAccessAll; +} + +const WarpIRIList* WidgetAccessList::getWarpIRIList() const +{ + return &m_warpIriList; +} + +bool WidgetAccessList::isRequiredIRI(const DPL::String &iri) const +{ + if (m_isAccessAll) { + return true; + } + + WarpIRI requestIri; + requestIri.set(iri.c_str(), false); + + FOREACH(it, m_warpIriList) + { + if (it->isSubDomain(requestIri)) { + return true; + } + } + + return false; +} + +bool WidgetAccessList::operator ==(const WidgetAccessList& other) const +{ + return m_warpIriList == other.m_warpIriList && + m_isAccessAll == other.m_isAccessAll; +} + +WidgetSettingList::WidgetSettingList() : + m_RotationLock(Screen_Portrait), + m_IndicatorPresence(Indicator_Enable), + m_BackButtonPresence(BackButton_Disable), + m_ContextMenu(ContextMenu_Enable), + m_Encryption(Encryption_Disable), + m_BackgroundSupport(BackgroundSupport_Disable), + m_ProgressbarPresence(ProgressBar_Disable), + m_HWkeyEvent(HWkeyEvent_Enable), + m_Accessibility(Accessibility_Enable), + m_SoundMode(SoundMode_Shared), + m_BackgroundVibration(BackgroundVibration_Disable) +{ + m_logEnable = (getenv(WRT_WIDGET_DATA_TYPES_LOG_ENABLE) != NULL); +} + +WidgetSettingList::WidgetSettingList(WrtDB::WidgetSettings &widgetSettings) +{ + using namespace TizenSetting::Name; + using namespace TizenSetting::Value; + + m_logEnable = (getenv(WRT_WIDGET_DATA_TYPES_LOG_ENABLE) != NULL); + + m_RotationLock = Screen_Portrait; + m_IndicatorPresence = Indicator_Enable; + m_BackButtonPresence = BackButton_Disable; + m_ContextMenu = ContextMenu_Enable; + m_Encryption = Encryption_Disable; + m_BackgroundSupport = BackgroundSupport_Disable; + m_ProgressbarPresence = ProgressBar_Disable; + m_HWkeyEvent = HWkeyEvent_Enable; + m_Accessibility = Accessibility_Enable; + m_SoundMode = SoundMode_Shared; + m_BackgroundVibration = BackgroundVibration_Disable; + + FOREACH(it, widgetSettings) { + DPL::String name = it->settingName; + DPL::String value = it->settingValue; + + if (name == SCREEN_ORIENTATION) { + if (value == SCREEN_ORIENTATION_PORTRAIT) { + m_RotationLock = Screen_Portrait; + } else if (value == SCREEN_ORIENTATION_LANDSCAPE) { + m_RotationLock = Screen_Landscape; + } else if (value == SCREEN_ORIENTATION_AUTO_ROTATION) { + m_RotationLock = Screen_AutoRotation; + } else { + displayError(name, value); + m_RotationLock = Screen_Portrait; + } + } else if (name == INDICATOR_PRESENCE) { + if (value == INDICATOR_PRESENCE_ENALBE) { + m_IndicatorPresence = Indicator_Enable; + } else if (value == INDICATOR_PRESENCE_DISABLE) { + m_IndicatorPresence = Indicator_Disable; + } else { + displayError(name, value); + m_IndicatorPresence = Indicator_Enable; + } + } else if (name == BACKBUTTON_PRESENCE) { + if (value == BACKBUTTON_PRESENCE_ENALBE) { + m_BackButtonPresence = BackButton_Enable; + } else if (value == BACKBUTTON_PRESENCE_DISABLE) { + m_BackButtonPresence = BackButton_Disable; + } else { + displayError(name, value); + m_BackButtonPresence = BackButton_Disable; + } + } else if (name == CONTEXT_MENU) { + if (value == CONTEXT_MENU_ENABLE) { + m_ContextMenu = ContextMenu_Enable; + } else if (value == CONTEXT_MENU_DISABLE) { + m_ContextMenu = ContextMenu_Disable; + } else { + displayError(name, value); + m_ContextMenu = ContextMenu_Enable; + } + } else if (name == ENCRYPTION) { + if (value == ENCRYPTION_ENABLE) { + m_Encryption = Encryption_Enable; + } else if (value == ENCRYPTION_DISABLE) { + m_Encryption = Encryption_Disable; + } else { + displayError(name, value); + m_Encryption = Encryption_Disable; + } + } else if (name == BACKGROUND_SUPPORT) { + if (value == ENABLE) { + m_BackgroundSupport = BackgroundSupport_Enable; + } else if (value == DISABLE) { + m_BackgroundSupport = BackgroundSupport_Disable; + } else { + displayError(name, value); + m_BackgroundSupport = BackgroundSupport_Disable; + } + } +#if ENABLE(CUSTOM_USER_AGENT_SUPPORT) + else if (name == USER_AGENT) { + DPL::OptionalString userAgent = value; + if (!!userAgent) { + m_UserAgent = DPL::ToUTF8String(*userAgent); + } + } +#endif // ENABLE(CUSTOM_USER_AGENT_SUPPORT) + else if (name == PROGRESSBAR_PRESENCE) { + if (value == PROGRESSBAR_PRESENCE_ENABLE) { + m_ProgressbarPresence = ProgressBar_Enable; + } else if (value == PROGRESSBAR_PRESENCE_DISABLE) { + m_ProgressbarPresence = ProgressBar_Disable; + } else { + displayError(name, value); + m_ProgressbarPresence = ProgressBar_Disable; + } + } else if (name == HWKEY_EVENT) { + if (value == HWKEY_EVENT_ENABLE) { + m_HWkeyEvent = HWkeyEvent_Enable; + } else if (value == HWKEY_EVENT_DISABLE) { + m_HWkeyEvent = HWkeyEvent_Disable; + } else { + displayError(name, value); + m_HWkeyEvent = HWkeyEvent_Enable; + } + } else if (name == ACCESSIBILITY) { + if (value == ACCESSIBILITY_ENABLE) { + m_Accessibility = Accessibility_Enable; + } else if (value == ACCESSIBILITY_DISABLE) { + m_Accessibility = Accessibility_Disable; + } else { + displayError(name, value); + m_Accessibility = Accessibility_Enable; + } + } else if (name == SOUND_MODE) { + if (value == SOUND_MODE_SAHRED) { + m_SoundMode = SoundMode_Shared; + } else if (value == SOUND_MODE_EXCLUSIVE) { + m_SoundMode = SoundMode_Exclusive; + } else { + displayError(name, value); + m_SoundMode = SoundMode_Shared; + } + } else if (name == BACKGROUND_VIBRATION) { + if (value == ENABLE) { + m_BackgroundVibration = BackgroundVibration_Enable; + } else if (value == DISABLE) { + m_BackgroundVibration = BackgroundVibration_Disable; + } else { + displayError(name, value); + m_BackgroundVibration = BackgroundVibration_Disable; + } + } else { + displayError(name, value); + } + } +} + +WidgetSettingScreenLock WidgetSettingList::getRotationValue() const +{ + if (m_logEnable) {_D("m_RotationLock: %d", m_RotationLock);} + return m_RotationLock; +} + +WidgetSettingIndicatorPresence WidgetSettingList::getIndicatorPresence() const +{ + if (m_logEnable) {_D("m_IndicatorPresence: %d", m_IndicatorPresence);} + return m_IndicatorPresence; +} + +WidgetSettingBackButtonPresence WidgetSettingList::getBackButtonPresence() +const +{ + if (m_logEnable) {_D("m_BackButtonPresence: %d", m_BackButtonPresence);} + return m_BackButtonPresence; +} + +WidgetSettingContextMenu WidgetSettingList::getContextMenu() const +{ + if (m_logEnable) {_D("m_ContextMenu: %d", m_ContextMenu);} + return m_ContextMenu; +} + +WidgetSettingEncryption WidgetSettingList::getEncryption() const +{ + if (m_logEnable) {_D("m_Encryption: %d", m_Encryption);} + return m_Encryption; +} + +WidgetSettingBackgroundSupport WidgetSettingList::getBackgroundSupport() const +{ + if (m_logEnable) {_D("m_BackgroundSupport: %d", m_BackgroundSupport);} + return m_BackgroundSupport; +} + +#if ENABLE(CUSTOM_USER_AGENT_SUPPORT) +std::string WidgetSettingList::getUserAgent() const +{ + if (m_logEnable) {_D("m_UserAgent: %s", m_UserAgent.c_str());} + return m_UserAgent; +} +#endif // ENABLE(CUSTOM_USER_AGENT_SUPPORT) + +WidgetSettingProgressBarPresence WidgetSettingList::getProgressBarPresence() const +{ + if (m_logEnable) {_D("m_ProgressbarPresence: %d", m_ProgressbarPresence);} + return m_ProgressbarPresence; +} + +WidgetSettingHWkeyEventPresence WidgetSettingList::getHWkeyEvent() const +{ + if (m_logEnable) {_D("m_HWkeyEvent: %d", m_HWkeyEvent);} + return m_HWkeyEvent; +} + +WidgetSettingAccessibility WidgetSettingList::getAccessibility() const +{ + if (m_logEnable) {_D("m_Accessibility: %d", m_Accessibility);} + return m_Accessibility; +} + +WidgetSettingSoundMode WidgetSettingList::getSoundMode() const +{ + if (m_logEnable) {_D("m_SoundMode: %d", m_SoundMode);} + return m_SoundMode; +} + +WidgetSettingBackgroundVibration WidgetSettingList::getBackgroundVibration() const +{ + if (m_logEnable) {_D("m_BackgroundVibration: %d", m_BackgroundVibration);} + return m_BackgroundVibration; +} + +bool WidgetSettingList::operator ==(const WidgetSettingList& other) const +{ + return m_RotationLock == other.m_RotationLock && + m_IndicatorPresence == other.m_IndicatorPresence && + m_BackButtonPresence == other.m_BackButtonPresence && + m_ContextMenu == other.m_ContextMenu && + m_Encryption == other.m_Encryption && + m_BackgroundSupport == other.m_BackgroundSupport && +#if ENABLE(CUSTOM_USER_AGENT_SUPPORT) + m_UserAgent == other.m_UserAgent && +#endif // ENABLE(CUSTOM_USER_AGENT_SUPPORT) + m_ProgressbarPresence == other.m_ProgressbarPresence && + m_HWkeyEvent == other.m_HWkeyEvent && + m_Accessibility == other.m_Accessibility && + m_SoundMode == other.m_SoundMode && + m_BackgroundVibration== other.m_BackgroundVibration; +} + +void WidgetSettingList::displayError(const DPL::String& name, + const DPL::String& value) +{ + _W("Invalid \"%s\" setting value \"%s\"", + DPL::ToUTF8String(name).c_str(), + DPL::ToUTF8String(value).c_str()); +} diff --git a/src/domain/widget_data_types.h b/src/domain/widget_data_types.h new file mode 100755 index 0000000..65a522d --- /dev/null +++ b/src/domain/widget_data_types.h @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file have been implemented in compliance with W3C WARP SPEC. + * but there are some patent issue between W3C WARP SPEC and APPLE. + * so if you want to use this file, refer to the README file in root directory + */ +/** + * @file widget_data_types.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 0.1 + * @brief + */ + +#ifndef WRT_SRC_DOMAIN_WIDGET_DATA_TYPES_H_ +#define WRT_SRC_DOMAIN_WIDGET_DATA_TYPES_H_ + +#include +#include + +#include +#include +#include +#include +#include + +// WidgetIcon, LanguageTagsList, OptionalWidgetStartFileInfo, +// WidgetStartFileInfo +#include + +typedef std::list WarpIRIList; + +/** + * @brief Execution phase according to BONDI + * + * WidgetExecutionPhase_Unknown: + * Execution state is not defined + * + * WidgetExecutionPhase_WidgetInstall: + * Applies to access control queries made by a Widget User Agent during the + * processing of a Widget Resource as part of an installation or update + * operation + * + * WidgetExecutionPhase_WidgetInstantiate: + * Applies to access control queries made by a Widget User Agent during the + * instantiation of a Widget + * + * WidgetExecutionPhase_WebkitBind: + * Applies to access control queries made in response to a call to + * requestFeature() in the course of execution of a Website + * + * WidgetExecutionPhase_Invoke: + * Applies to access control queries made in response to invocation of a + * JavaScript API in the course of execution of a Web Application + */ +//enum WidgetExecutionPhase +//{ +// WidgetExecutionPhase_Unknown = 0, +// WidgetExecutionPhase_WidgetInstall = 1 << 0, +// WidgetExecutionPhase_WidgetInstantiate = 1 << 1, +// WidgetExecutionPhase_WebkitBind = 1 << 2, +// WidgetExecutionPhase_Invoke = 1 << 3 +//}; + +class WidgetModel; + +class WidgetAccessList +{ + public: + WidgetAccessList(); + + WidgetAccessList(const WrtDB::WidgetAccessInfoList &widgetAccessInfoList); + + bool getIsAccessAll() const; + + const WarpIRIList* getWarpIRIList() const; + + bool isRequiredIRI(const DPL::String &iri) const; + + bool operator ==(const WidgetAccessList& other) const; + + private: + WarpIRIList m_warpIriList; + bool m_isAccessAll; +}; + +namespace TizenSetting { +namespace Name { +const DPL::String SCREEN_ORIENTATION = L"screen-orientation"; +const DPL::String INDICATOR_PRESENCE = L"indicator-presence"; +const DPL::String BACKBUTTON_PRESENCE = L"backbutton-presence"; +const DPL::String CONTEXT_MENU = L"context-menu"; +const DPL::String BACKGROUND_SUPPORT = L"background-support"; +#if ENABLE(CUSTOM_USER_AGENT_SUPPORT) +const DPL::String USER_AGENT = L"user-agent"; +#endif // ENABLE(CUSTOM_USER_AGENT_SUPPORT) +const DPL::String PROGRESSBAR_PRESENCE = L"progressbar-presence"; +const DPL::String HWKEY_EVENT = L"hwkey-event"; +const DPL::String ACCESSIBILITY = L"accessibility"; +const DPL::String SOUND_MODE = L"sound-mode"; +const DPL::String ENCRYPTION = L"encryption"; +const DPL::String BACKGROUND_VIBRATION = L"background-vibration"; +} // namespace Name +namespace Value { +const DPL::String ENABLE = L"enable"; +const DPL::String DISABLE = L"disable"; +const DPL::String SCREEN_ORIENTATION_PORTRAIT = L"portrait"; +const DPL::String SCREEN_ORIENTATION_LANDSCAPE = L"landscape"; +const DPL::String SCREEN_ORIENTATION_AUTO_ROTATION = L"auto-rotation"; +const DPL::String INDICATOR_PRESENCE_ENALBE = ENABLE; +const DPL::String INDICATOR_PRESENCE_DISABLE = DISABLE; +const DPL::String BACKBUTTON_PRESENCE_ENALBE = ENABLE; +const DPL::String BACKBUTTON_PRESENCE_DISABLE = DISABLE; +const DPL::String CONTEXT_MENU_ENABLE = ENABLE; +const DPL::String CONTEXT_MENU_DISABLE = DISABLE; +const DPL::String ENCRYPTION_ENABLE = ENABLE; +const DPL::String ENCRYPTION_DISABLE = DISABLE; +const DPL::String PROGRESSBAR_PRESENCE_ENABLE = ENABLE; +const DPL::String PROGRESSBAR_PRESENCE_DISABLE = DISABLE; +const DPL::String HWKEY_EVENT_ENABLE = ENABLE; +const DPL::String HWKEY_EVENT_DISABLE = DISABLE; +const DPL::String ACCESSIBILITY_ENABLE = ENABLE; +const DPL::String ACCESSIBILITY_DISABLE = DISABLE; +const DPL::String SOUND_MODE_SAHRED = L"shared"; +const DPL::String SOUND_MODE_EXCLUSIVE = L"exclusive"; +} // namespace Value +} // namespace TizenSetting + +enum WidgetSettingScreenLock +{ + Screen_Portrait, /* Default */ + Screen_Landscape, + Screen_AutoRotation +}; + +enum WidgetSettingIndicatorPresence +{ + Indicator_Enable, /* Default */ + Indicator_Disable +}; + +enum WidgetSettingBackButtonPresence +{ + BackButton_Enable, + BackButton_Disable /* Default */ +}; + +enum WidgetSettingContextMenu +{ + ContextMenu_Enable, /* Default */ + ContextMenu_Disable +}; + +enum WidgetSettingEncryption +{ + Encryption_Enable, + Encryption_Disable /* Default */ +}; + +enum WidgetSettingBackgroundSupport +{ + BackgroundSupport_Enable, + BackgroundSupport_Disable /* Default */ +}; + +enum WidgetSettingProgressBarPresence +{ + ProgressBar_Enable, + ProgressBar_Disable /* Default */ +}; + +enum WidgetSettingHWkeyEventPresence +{ + HWkeyEvent_Enable, /* Default */ + HWkeyEvent_Disable +}; + +enum WidgetSettingAccessibility +{ + Accessibility_Enable, /* Default */ + Accessibility_Disable +}; + +enum WidgetSettingSoundMode +{ + SoundMode_Shared, /* Default */ + SoundMode_Exclusive +}; + +enum WidgetSettingBackgroundVibration +{ + BackgroundVibration_Enable, + BackgroundVibration_Disable /* Default */ +}; + +class WidgetSettingList +{ + public: + WidgetSettingList(); + WidgetSettingList(WrtDB::WidgetSettings &widgetSettings); + + WidgetSettingScreenLock getRotationValue() const; + WidgetSettingIndicatorPresence getIndicatorPresence() const; + WidgetSettingBackButtonPresence getBackButtonPresence() const; + WidgetSettingContextMenu getContextMenu() const; + WidgetSettingEncryption getEncryption() const; + WidgetSettingBackgroundSupport getBackgroundSupport() const; +#if ENABLE(CUSTOM_USER_AGENT_SUPPORT) + std::string getUserAgent() const; +#endif // ENABLE(CUSTOM_USER_AGENT_SUPPORT) + WidgetSettingProgressBarPresence getProgressBarPresence() const; + WidgetSettingHWkeyEventPresence getHWkeyEvent() const; + WidgetSettingAccessibility getAccessibility() const; + WidgetSettingSoundMode getSoundMode() const; + WidgetSettingBackgroundVibration getBackgroundVibration() const; + bool operator ==(const WidgetSettingList& other) const; + + private: + void displayError(const DPL::String& name, const DPL::String& value); + + bool m_logEnable; + WidgetSettingScreenLock m_RotationLock; + WidgetSettingIndicatorPresence m_IndicatorPresence; + WidgetSettingBackButtonPresence m_BackButtonPresence; + WidgetSettingContextMenu m_ContextMenu; + WidgetSettingEncryption m_Encryption; + WidgetSettingBackgroundSupport m_BackgroundSupport; + WidgetSettingProgressBarPresence m_ProgressbarPresence; + WidgetSettingHWkeyEventPresence m_HWkeyEvent; + WidgetSettingAccessibility m_Accessibility; + WidgetSettingSoundMode m_SoundMode; + WidgetSettingBackgroundVibration m_BackgroundVibration; +#if ENABLE(CUSTOM_USER_AGENT_SUPPORT) + std::string m_UserAgent; +#endif // ENABLE(CUSTOM_USER_AGENT_SUPPORT) +}; +typedef std::shared_ptr WidgetSettingListPtr; + +namespace OrientationAngle { +namespace W3C { +namespace Portrait { +const int PRIMARY = 0; +const int SECONDARY = 180; +} // namespace Portrait +namespace Landscape { +const int PRIMARY = 90; +const int SECONDARY = -90; +} // namespace Landscape +} // namespace W3C +namespace Window { +namespace Portrait { +const int PRIMARY = 0; +const int SECONDARY = 180; +} // namespace Portrait +namespace Landscape { +const int PRIMARY = 270; +const int SECONDARY = 90; +} // namespace Landscape +const int UNLOCK = -1; +} // namespace Window +} // namespace OrientationAngle + +namespace KeyName { +const std::string BACK = "back"; +const std::string MENU = "menu"; +} // KeyName + +enum ConsoleLogLevel { + Debug = 0, + Warning = 1, + Error = 2, +}; +#endif /* WRT_SRC_DOMAIN_WIDGET_DATA_TYPES_H_ */ diff --git a/src/domain/widget_deserialize_model.cpp b/src/domain/widget_deserialize_model.cpp new file mode 100644 index 0000000..4fbc20a --- /dev/null +++ b/src/domain/widget_deserialize_model.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 widget_deserialize_model.h + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief Widget deserialization creates WidgetModel from WidgetDAOReadOnly + */ + +#include "widget_model.h" + +#include +#include +#include +#include +// to apply widget default locales instead of calling localizeWidgetModel() +#include + +namespace Domain { +std::string getTimestamp() +{ + struct timeval tv; + char buff[128]; + + gettimeofday(&tv, NULL); + sprintf(buff, "%lf", (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f); + LogDebug("timestamp: " << buff); + return std::string(buff); +} + +std::shared_ptr deserializeWidgetModel(const std::string& tizenId) +{ + std::shared_ptr model; + DPL::String dplTizenId(DPL::FromUTF8String(tizenId)); + if (WrtDB::WidgetDAOReadOnly::isWidgetInstalled(dplTizenId)) { + LogDebug("Widget installed - creating model"); + model.reset(new WidgetModel(tizenId)); + + WrtDB::WidgetDAOReadOnly dao(dplTizenId); + DPL::String pkgId = dao.getTizenPkgId(); + model->PersistentStoragePath.Set( + DPL::FromUTF8String( + WrtDB::WidgetConfig::GetWidgetPersistentStoragePath(pkgId))); + model->TemporaryStoragePath.Set( + DPL::FromUTF8String( + WrtDB::WidgetConfig::GetWidgetTemporaryStoragePath(pkgId))); + + DPL::OptionalString defloc = model->defaultlocale.Get(); + if (!!defloc) { + LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales( + *defloc); + } + + WrtDB::WidgetAccessInfoList widgetAccessInfoList; + // widgetAccessInfoList is output parameter + dao.getWidgetAccessInfo(widgetAccessInfoList); + model->AccessList.Set(widgetAccessInfoList); + + // Widget app-control information data + WrtDB::WidgetAppControlList widgetApplicationControlList; + // widgetApplicationControlList is output parameter + dao.getAppControlList(widgetApplicationControlList); + model->AppControlList.Set(widgetApplicationControlList); + + // Set Widget Settings + WrtDB::WidgetSettings widgetSettings; + dao.getWidgetSettings(widgetSettings); + model->SettingList.Set(widgetSettings); + } else { + LogError("Widget is not installed - model not created"); + } + return model; +} + +} //Namespace Domain + diff --git a/src/domain/widget_deserialize_model.h b/src/domain/widget_deserialize_model.h new file mode 100644 index 0000000..5e277ed --- /dev/null +++ b/src/domain/widget_deserialize_model.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 widget_deserialize_model.h + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief Widget deserialization creates WidgetModel from WidgetDAO + */ +#ifndef WRT_ENGINE_SRC_DOMAIN_WIDGET_DESERIALIZE_MODEL_H_ +#define WRT_ENGINE_SRC_DOMAIN_WIDGET_DESERIALIZE_MODEL_H_ + +#include +#include +#include +#include +#include + +namespace Domain { +/** + * @brief Creates widget model associated with selected + * @param[in] tizenId + * @param[in] service index, NULL for widget content + * @retval WidgetModel + */ + std::shared_ptr deserializeWidgetModel(const std::string& tizenId); +} //Namespace Domain + +#endif // ifndef WRT_ENGINE_SRC_DOMAIN_WIDGET_DESERIALIZE_MODEL_H_ + diff --git a/src/domain/widget_model.cpp b/src/domain/widget_model.cpp new file mode 100644 index 0000000..7f806fe --- /dev/null +++ b/src/domain/widget_model.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 widget_model.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Implementation file for widget model + */ +#include "widget_model.h" + +#include +#include +#include +#include +#include + +using namespace WrtDB; + +template +struct BindToWidgetDAO : + DPL::Event::BindToDAO +{}; + +template +struct BindToWidgetDAOStatic : + DPL::Event::BindToDAO_Static +{}; + +WidgetModel::WidgetModel(const std::string &tizenId) : + TizenId(DPL::FromASCIIString(tizenId)), + TzPkgId(this, &BindToWidgetDAO::Get), + Type(this, &BindToWidgetDAO::Get), + CspPolicy(this, &BindToWidgetDAO::Get), + CspReportOnlyPolicy(this, &BindToWidgetDAO::Get), + StartURL(this), + //localized, so not binded + StartFileInfo(this), +#if ENABLE(APP_SCHEME) + PrefixURL(this, DPL::String(L"app://") + DPL::FromASCIIString(tizenId) + DPL::String(L"/")), +#else + //localized, so not binded + // file:// + / : without "/" path, webkit return security error + PrefixURL(this, DPL::String(L"file:///")), +#endif + InstallPath( + this, + &BindToWidgetDAO::Get), + PersistentStoragePath(this), + TemporaryStoragePath(this), + defaultlocale( + this, + &BindToWidgetDAO::Get), + Name(this), + //localized, so not binded + ShortName(this), + //localized, so not binded + Description(this), + //localized, so not binded + License(this), + //localized, so not binded + LicenseHref(this), + //localized, so not binded + Icon(this), + SplashImg( + this, + &BindToWidgetDAO::Get), + RequiredVersion(this, &BindToWidgetDAO::Get), + WindowModes( + this, + &BindToWidgetDAO::Get), + //localized, so not binded + // AccessNetwork(this, false), + // WarpDefinitionEmpty(this), + BackSupported( + this, + //TODO this type has to be here now, as Property constructor is wrongly + //chosen + (DPL::Event::Property:: + ReadDelegateType) & + BindToWidgetDAO::Get), + AccessList(this), + SettingList(this), + AppControlList(this), + WidgetPrivilegeList(this, &BindToWidgetDAO::Get), + SecurityModelVersion(this, &BindToWidgetDAO::Get) +{} + +DPL::String WidgetModel::getTizenId() const +{ + return TizenId; +} diff --git a/src/domain/widget_model.h b/src/domain/widget_model.h new file mode 100644 index 0000000..48aa76c --- /dev/null +++ b/src/domain/widget_model.h @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 widget_model.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Header file for widget model + */ +#ifndef SRC_DOMAIN_WIDGET_MODEL_H +#define SRC_DOMAIN_WIDGET_MODEL_H + +#include +#include + +#include +#include +#include +#include // definition of WidgetHandle + +#include "widget_data_types.h" + +/** + * @brief Widget model + * + * Widget model is the core object that hold information about + * properties of widget. After wrt launch each widget contained in database is + * mapped to WidgetModel. + * + * Widget model is a type of MVC model, so it is possible to listen for it's + * changes. + * + */ +class WidgetModel : public DPL::Event::Model +{ + public: + + /** + * @brief Tizen id + * + * ex> "TizenIDabc.appname" + * + * - TizenId / AppId : "TizenIDabc.appname" + * - TzPkgId : "TizenIDabc" + * - App name : "appname" + * + */ + DPL::String TizenId; + DPL::Event::Property TzPkgId; + + /** + * @brief Widget type + * + * Note: This is a readonly property + */ + DPL::Event::Property Type; + + /** + * @brief Config file based csp policy + */ + DPL::Event::Property CspPolicy; + + /** + * @brief Config file based csp policy - report only + */ + DPL::Event::Property + CspReportOnlyPolicy; + + /** + * @brief Start URL for widget + */ + DPL::Event::Property StartURL; + + /** + * @brief Start URL information for widget + */ + DPL::Event::Property StartFileInfo; + + /** + * @brief Prefix URL for widget + * + * This is a prefix address of html file that widget is displaying. + * The whole address is PrefixURL + StartURL. + */ + DPL::Event::Property PrefixURL; + + /** + * @brief Install path for widget + * + * Gets path in which files of widget are being kept + */ + DPL::Event::Property InstallPath; + + /** + * @brief Path to widget's persistent storage. + * + * Gets path in which widget may store its persistent private data. + */ + DPL::Event::Property PersistentStoragePath; + + /** + * @brief Path to widget's temporary storage. + * + * Gets path in which widget may store its temporary private data. + */ + DPL::Event::Property TemporaryStoragePath; + + /** + * @brief Widget defaultlocale + */ + DPL::Event::Property + defaultlocale; + + /** + * @brief Widget name + */ + DPL::Event::Property Name; + + /** + * @brief Widget short name + */ + DPL::Event::Property ShortName; + + /** + * @brief Widget description + */ + DPL::Event::Property Description; + + /** + * @brief Widget license + */ + DPL::Event::Property License; + + /** + * @brief Widget license href + */ + DPL::Event::Property LicenseHref; + + /** + * @brief Widget icon + */ + DPL::Event::Property Icon; + + /** + * @brief Widget splash image src + */ + DPL::Event::Property SplashImg; + + /** + * @brief Widget TizenRequired(minimum) Version + */ + DPL::Event::Property RequiredVersion; + + /** + * @brief window mode + */ + DPL::Event::Property WindowModes; + + // /** + // * @brief Value of network element. + // */ + // DPL::Event::Property AccessNetwork; + + // /** + // * @brief Does widget contain WARP definitions. + // */ + // DPL::Event::Property WarpDefinitionEmpty; + + /** + * @brief Is back supported + */ + DPL::Event::Property + BackSupported; + + /** + * @brief Widget access list + */ + DPL::Event::Property AccessList; + + DPL::Event::Property SettingList; + + /** + * @brief Widget app-control list + */ + DPL::Event::Property AppControlList; + + /** + * @brief Widget Privilege list + */ + DPL::Event::Property WidgetPrivilegeList; + + DPL::Event::Property SecurityModelVersion; + + WidgetModel(const std::string &tizenId); + + private: + DPL::String getTizenId() const; +}; +typedef std::shared_ptr WidgetModelPtr; + +#endif // SRC_DOMAIN_WIDGET_MODEL_H diff --git a/src/domain/widget_string.h b/src/domain/widget_string.h new file mode 100644 index 0000000..ad68223 --- /dev/null +++ b/src/domain/widget_string.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 widget_string.h + * @author Jihoon Chung(jihoon.chung@samsung.com) + * @version 0.1 + * @brief + */ + +#ifndef WRT_SRC_DOMAIN_WIDGET_STRING_H_ +#define WRT_SRC_DOMAIN_WIDGET_STRING_H_ + +#include +#include +#include + +#include + +#define WRT_PS "%s" +#define WRT_PNS "%d$s" + +namespace WrtText { +inline std::string replacePS(std::initializer_list strs) { + std::size_t size = strs.size(); + if (size <= 1 || size >= 10) { + return std::string(""); + } + + std::initializer_list::iterator it = strs.begin(); + std::string ret = *strs.begin(); + std::string arg = *(++it); + + // %s -> arg + std::size_t ps = ret.find(WRT_PS); + if (ps != std::string::npos) { + ret.replace(ps, std::string(WRT_PS).length(), arg); + return ret; + } + + // %n$s -> n_arg + std::string n = "1"; + for ( ; it != strs.end(); ++it) { + std::string pns = WRT_PNS; + pns.replace(1, 1, n); + n[0]++; + auto findit = ret.find(pns); + if( findit == std::string::npos) + break; + ret.replace(findit, 4, (*it).c_str()); + } + return ret; +} +} + +#define WRT_SK_OK dgettext("wrt", "IDS_BR_SK_OK") +#define WRT_SK_YES dgettext("wrt", "IDS_BR_SK_YES") +#define WRT_SK_NO dgettext("wrt", "IDS_BR_SK_NO") +#define WRT_SK_LOGIN dgettext("wrt", "IDS_BR_BUTTON_LOGIN") +#define WRT_SK_CANCEL dgettext("wrt", "IDS_BR_SK_CANCEL") +#define WRT_OPT_ALLOW dgettext("wrt", "IDS_BR_OPT_ALLOW") +#define WRT_OPT_DENY dgettext("wrt", "IDS_KA_BODY_DENY") + +#define WRT_POP_USERMEDIA_PERMISSION dgettext("wrt", "IDS_JAVA_POP_ALLOW_TO_USE_MEDIA_RECORDING_Q") +#define WRT_POP_WEB_NOTIFICATION_PERMISSION dgettext("wrt", "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_SHOW_NOTIFICATIONS") +#define WRT_POP_GEOLOCATION_PERMISSION dgettext("wrt", "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_ACCESS_YOUR_LOCATION") +#define WRT_POP_WEB_STORAGE_PERMISSION dgettext("wrt", "IDS_BR_POP_P1SS_HP2SS_IS_ATTEMPTING_TO_STORE_A_LARGE_AMOUNT_OF_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE") +#define WRT_POP_APPLICATION_CACHE_PERMISSION dgettext("wrt", "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_STORE_DATA_ON_YOUR_DEVICE_FOR_OFFLINE_USE") +#define WRT_POP_STARTING_DOWNLOADING dgettext("wrt", "IDS_BR_POP_STARTING_DOWNLOAD_ING") +#define WRT_POP_CERTIFICATE_PERMISSION dgettext("wrt", "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG") +#define WRT_BODY_AUTHENTICATION_REQUIRED dgettext("wrt", "IDS_BR_BODY_DESTINATIONS_AUTHENTICATION_REQUIRED") +#define WRT_BODY_PASSWORD dgettext("wrt", "IDS_BR_BODY_PASSWORD") +#define WRT_BODY_AUTHUSERNAME dgettext("wrt", "IDS_BR_BODY_AUTHUSERNAME") +#define WRT_BODY_REMEMBER_PREFERENCE dgettext("wrt", "IDS_BR_BODY_REMEMBER_PREFERENCE") +#define WRT_POP_CLEAR_DEFAULT_SETTINGS dgettext("wrt", "IDS_ST_POP_CLEAR_DEFAULT_APP_SETTINGS_BY_GOING_TO_SETTINGS_GENERAL_MANAGE_APPLICATIONS_ALL") +#define WRT_BODY_LOADING_ING dgettext("wrt", "IDS_BR_BODY_LOADING_ING") + +#endif // WRT_SRC_DOMAIN_WIDGET_STRING_H_ diff --git a/src/plugin-service/CMakeLists.txt b/src/plugin-service/CMakeLists.txt new file mode 100644 index 0000000..671a91d --- /dev/null +++ b/src/plugin-service/CMakeLists.txt @@ -0,0 +1,62 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# @file CMakeLists.txt +# @author Lukasz Marek (l.marek@samsung.com) +# @author Yunchan Cho (yunchan.cho@samgsung.com) +# @version 1.0 +# + +ADD_DEFINITIONS("-DWRT_PLUGINS_COMMON_LOG") + +PKG_CHECK_MODULES(WRT_PLUGIN_DEP + wrt-plugin-loading + wrt-plugin-js-overlay + REQUIRED) + +set(PLUGIN_MODULE_SRC_DIR ${PROJECT_SOURCE_DIR}/src/plugin-service) + +set(PLUGIN_MODULE_SOURCES + ${PLUGIN_MODULE_SRC_DIR}/wrt_plugin_module.cpp +) +ADD_DEFINITIONS(${WRT_PLUGIN_DEP_CFLAGS}) +INCLUDE_DIRECTORIES( + ${PLUGIN_MODULE_SRC_DIR} + ${WRT_PLUGIN_DEP_INCLUDE_DIRS} +) + +ADD_LIBRARY(${TARGET_PLUGIN_MODULE_LIB} SHARED + ${PLUGIN_MODULE_SOURCES} +) + +SET_TARGET_PROPERTIES(${TARGET_PLUGIN_MODULE_LIB} PROPERTIES + COMPILE_FLAGS -fPIC + LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both" +) + +SET_TARGET_PROPERTIES(${TARGET_PLUGIN_MODULE_LIB} PROPERTIES + SOVERSION ${PROJECT_API_VERSION} + VERSION ${PROJECT_VERSION} +) + +SET_TARGET_PROPERTIES(${TARGET_PLUGIN_MODULE_LIB} PROPERTIES + COMPILE_DEFINITIONS LOG_TAG="${LOG_TAG}") + +target_link_libraries(${TARGET_PLUGIN_MODULE_LIB} + ${WRT_PLUGIN_DEP_LIBRARIES} +) + +INSTALL(TARGETS ${TARGET_PLUGIN_MODULE_LIB} + DESTINATION lib) diff --git a/src/plugin-service/DESCRIPTION b/src/plugin-service/DESCRIPTION new file mode 100644 index 0000000..6ea1d6f --- /dev/null +++ b/src/plugin-service/DESCRIPTION @@ -0,0 +1,2 @@ +!!!options!!! stop +Plugin management diff --git a/src/plugin-service/wrt_plugin_module.cpp b/src/plugin-service/wrt_plugin_module.cpp new file mode 100644 index 0000000..5fe2951 --- /dev/null +++ b/src/plugin-service/wrt_plugin_module.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 wrt_plugin_module.cpp + * @author Lukasz Marek (l.marek@samgsung.com) + * @author Yunchan Cho (yunchan.cho@samgsung.com) + * @version + * @brief + */ + +#include "wrt_plugin_module.h" + +#include +#include +#include +#include +#include + +namespace PluginModule { +void init(int widgetHandle) +{ + _D("called"); + PluginLogicSingleton::Instance().initSession(widgetHandle); +} + +void start(int widgetHandle, + JSGlobalContextRef context, + double scale, + const char *encodedBundle, + const char *theme) +{ + PluginLogicSingleton::Instance().startSession(widgetHandle, + context, + scale, + encodedBundle, + theme); +} + +void shutdown() +{ + _D("called"); + PluginLogicSingleton::Instance().performLibrariesUnload(); +} + +void stop(JSGlobalContextRef context) +{ + _D("called"); + PluginLogicSingleton::Instance().stopSession(context); +} + +void setCustomProperties(JSGlobalContextRef context, + double scale, + const char* encodedBundle, + const char* theme) +{ + _D("called"); + PluginLogicSingleton::Instance().setCustomProperties(context, + scale, + encodedBundle, + theme); +} + +void dispatchJavaScriptEvent(JSGlobalContextRef context, + WrtPlugins::W3C::CustomEventType eventType, + void* data) +{ + _D("called"); + PluginLogicSingleton::Instance().dispatchJavaScriptEvent(context, + eventType, + data); +} + +void loadFrame(JSGlobalContextRef context) +{ + _D("load frame into web page (context: %p)", context); + PluginLogicSingleton::Instance().loadFrame(context); +} + +void unloadFrame(JSGlobalContextRef context) +{ + _D("unload frame from web page (context: %p)", context); + PluginLogicSingleton::Instance().unloadFrame(context); +} +} // PluginModule diff --git a/src/plugin-service/wrt_plugin_module.h b/src/plugin-service/wrt_plugin_module.h new file mode 100644 index 0000000..cd0d85f --- /dev/null +++ b/src/plugin-service/wrt_plugin_module.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 wrt_plugin_module.h + * @author Lukasz Marek (l.marek@samgsung.com) + * @author Yunchan Cho (yunchan.cho@samgsung.com) + * @version + * @brief + */ + +#ifndef WRT_SRC_PLUGIN_SERVICE_PLUGIN_MODULE_H_ +#define WRT_SRC_PLUGIN_SERVICE_PLUGIN_MODULE_H_ + +#include +#include + +extern "C" { +typedef struct OpaqueJSContext* JSGlobalContextRef; +} + +namespace PluginModule { +//forward declaration +void init(int widgetHandle); +void start(int widgetHandle, + JSGlobalContextRef context, + double scale, + const char* encodedBundle, + const char* theme); +void stop(JSGlobalContextRef context); +void shutdown(); +void setCustomProperties(JSGlobalContextRef context, + double scale, + const char* encodedBundle, + const char* theme); +void dispatchJavaScriptEvent(JSGlobalContextRef context, + WrtPlugins::W3C::CustomEventType eventType, + void* data); +void loadFrame(JSGlobalContextRef context); +void unloadFrame(JSGlobalContextRef context); +} // PluginModule + +#endif diff --git a/src/profiling/CMakeLists.txt b/src/profiling/CMakeLists.txt new file mode 100644 index 0000000..768de1a --- /dev/null +++ b/src/profiling/CMakeLists.txt @@ -0,0 +1,42 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +PKG_SEARCH_MODULE(PROFILING_DEPS REQUIRED dpl-efl) + +ADD_LIBRARY(${TARGET_PROFILING_LIB} SHARED + ${PROJECT_SOURCE_DIR}/src/profiling/profiling_util.cpp +) + +SET_TARGET_PROPERTIES(${TARGET_PROFILING_LIB} PROPERTIES + COMPILE_DEFINITIONS LOG_TAG="${LOG_TAG}") + +SET_TARGET_PROPERTIES(${TARGET_PROFILING_LIB} PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_API_VERSION}) + +INCLUDE_DIRECTORIES(${PROFILING_DEPS_CFLAGS}) + +SET_TARGET_PROPERTIES(${TARGET_PROFILING_LIB} PROPERTIES + COMPILE_FLAGS -fPIC) + +TARGET_LINK_LIBRARIES(${TARGET_PROFILING_LIB} + ${PROFILING_DEPS_LIBRARIES} +) + +INSTALL(TARGETS ${TARGET_PROFILING_LIB} + DESTINATION lib + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE +) diff --git a/src/profiling/profiling_util.cpp b/src/profiling/profiling_util.cpp new file mode 100644 index 0000000..371ebce --- /dev/null +++ b/src/profiling/profiling_util.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This is implementation file for profiling function. + */ + +#include "profiling_util.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +namespace { +const int PROFILING_OUTPUT_DESCRIPTOR = 3; + +unsigned long long toULong(const struct timeval& value) +{ + unsigned long long ret = static_cast(value.tv_sec) * + 1000000ULL; + ret += static_cast(value.tv_usec); + return ret; +} + +struct PacketResult +{ + unsigned long long time; + const char* name; + const char* prefix; + const char* description; + PacketResult() : + time(0), + name(0), + prefix(0), + description(0) + {} + PacketResult(unsigned long long t, + const char* n, + const char* p, + const char* d) : + time(t), + name(n), + prefix(p), + description(d) + {} + + void Print(FILE *filePtr) + { + if (!prefix) { + prefix = ""; + } + if (!description) { + description = ""; + } + fprintf(filePtr, "%s#%s#%llu#[%s]\n", prefix, name, time, description); + } +}; + +std::vector results; + +void dumpStatistic() +{ + FILE* fp = NULL; + int newfd = dup(PROFILING_OUTPUT_DESCRIPTOR); + if (-1 != newfd) { + fp = fdopen(newfd, "w"); + } + if (!fp) { + if (-1 != newfd) { + close(newfd); + } + fp = stdout; //fallback + } + fprintf(fp, "###PROFILING###START###\n"); + FOREACH(result, results) + { + result->Print(fp); + } + fprintf(fp, "###PROFILING###STOP###\n"); + fflush(fp); + if (stdout != fp) { + fclose(fp); // newfd is also closed + } +} + +void sigUsrHandler(int /*num*/) +{ + dumpStatistic(); +} + +DPL::Mutex* m_mutex = NULL; + +void initialize() +{ + m_mutex = new DPL::Mutex; + results.reserve(64 * 1024); + signal(SIGUSR1, &sigUsrHandler); + signal(SIGUSR2, &sigUsrHandler); + LogDebug("Initialized profiling"); + AddProfilingMeasurment("Profiling_Started"); +} + +std::string GetFormattedTime() +{ + timeval tv; + tm localNowTime; + + gettimeofday(&tv, NULL); + localtime_r(&tv.tv_sec, &localNowTime); + + char format[64]; + snprintf(format, + sizeof(format), + "%02i:%02i:%02i.%03i", + localNowTime.tm_hour, + localNowTime.tm_min, + localNowTime.tm_sec, + static_cast(tv.tv_usec / 1000)); + return format; +} +} // namespace anonymous + +void AddStdoutProfilingMeasurment(const char* name, bool start) +{ + Assert(m_mutex != NULL); + std::ostringstream output; + output << "[" << GetFormattedTime() << "] [](): " << name << " "; + output << (start ? "profiling##start" : "profiling##stop"); + fprintf(stdout, "%s\n", output.str().c_str()); +} + +#ifdef __cplusplus +extern "C" +#endif +void AddProfilingMeasurment(const char* name, + const char* prefix, + const char* description) +{ + DPL::Mutex::ScopedLock lock(m_mutex); + struct timeval value; + gettimeofday(&value, NULL); + results.push_back( + PacketResult(toULong(value), name, prefix, description)); +} + +STATIC_BLOCK +{ + initialize(); +} + diff --git a/src/profiling/profiling_util.h b/src/profiling/profiling_util.h new file mode 100644 index 0000000..3ce0de5 --- /dev/null +++ b/src/profiling/profiling_util.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This is header file for profiling function. + */ + +#ifndef WRT_ENGINE_SRC_PROFILING_PROFILING_UTIL_H +#define WRT_ENGINE_SRC_PROFILING_PROFILING_UTIL_H + +#ifdef PROFILING_ENABLED + +#ifndef __cplusplus +#include +#endif //__cplusplus + +#ifdef __cplusplus +extern "C" +void AddProfilingMeasurment(const char* name, + const char* prefix = 0, + const char* description = 0); +#define ADD_PROFILING_POINT(name, ...) AddProfilingMeasurment(name, \ + ##__VA_ARGS__) +#else //__cplusplus +void AddProfilingMeasurment(const char* name, + const char* prefix, + const char* description); +#define ADD_PROFILING_POINT(name, prefix, desc) AddProfilingMeasurment(name, \ + prefix, \ + desc) +#endif //__cplusplus + +void AddStdoutProfilingMeasurment(const char* name, bool start); +// profiling script additional proceeds stdout output +#define LOG_PROFILE_START(x) AddStdoutProfilingMeasurment(x, true) +#define LOG_PROFILE_STOP(x) AddStdoutProfilingMeasurment(x, false) +#else //PROFILING_ENABLED + +#define ADD_PROFILING_POINT(name, ...) (void)1 +#define LOG_PROFILE_START(x) (void)1 +#define LOG_PROFILE_STOP(x) (void)1 + +#endif //PROFILING_ENABLED + +#endif /* WRT_ENGINE_SRC_PROFILING_PROFILING_UTIL_H */ + diff --git a/src/profiling/script/profiling-host-part.pl b/src/profiling/script/profiling-host-part.pl new file mode 100755 index 0000000..fa85be5 --- /dev/null +++ b/src/profiling/script/profiling-host-part.pl @@ -0,0 +1,88 @@ +#!/usr/bin/perl +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +print "Stage 1:\n"; +my @files = `find -name prof-raw-data 2>/dev/null`; +for my $file (@files) { + chomp $file; + my $foutPoints = $file; $foutPoints =~ s/raw-data/-data-points/g; + my $foutRanges = $file; $foutRanges =~ s/raw-data/-data-ranges/g; + #print ">$file< >$fout<\n"; + #print ">>>~/git/wrt-engine/src/profiling/script/analyse.pl $foutPoints $foutRanges <<<\n"; + print "grep -v \"PROFILING\" $file | ./utils/analyse.pl $foutPoints $foutRanges\n"; + `grep -v \"PROFILING\" $file | ./utils/analyse.pl $foutPoints $foutRanges`; +} + +print "Stage 2:\n"; + +for my $dir (qw{OUTPUT/minimal/cold OUTPUT/minimal/warm OUTPUT/minimal/preload OUTPUT/Jet_Pack_Agent/cold OUTPUT/Jet_Pack_Agent/warm OUTPUT/Jet_Pack_Agent/preload OUTPUT/UnitTest/cold OUTPUT/UnitTest/warm OUTPUT/UnitTest/preload}) +{ + print $dir, "\n"; + print "./utils/csv-stats.pl -c -r -s avg \`find $dir -name prof--data-points 2>/dev/null\` > $dir/outpucik-points\n"; + print "`./utils/csv-stats.pl -c -r -s avg \`find $dir -name prof--data-ranges 2>/dev/null\` > $dir/outpucik-ranges\n"; + `./utils/csv-stats.pl -c -r -s avg \`find $dir -name prof--data-points 2>/dev/null\` > $dir/outpucik-points`; + `./utils/csv-stats.pl -c -r -s avg \`find $dir -name prof--data-ranges 2>/dev/null\` > $dir/outpucik-ranges`; +} + +print "Stage 3:\n"; +for my $dir (qw{OUTPUT/minimal OUTPUT/Jet_Pack_Agent OUTPUT/UnitTest}) +{ + my $name = substr($dir, 7); + my $file = "$name.svg"; + my $warm = "$dir/warm/outpucik-points"; + my $cold = "$dir/cold/outpucik-points"; + my $preload = "$dir/preload/outpucik-points"; + my $difffile = "$dir/diff-points"; + `paste -d, $cold $warm $preload > $difffile`; + my $title = "\"Performance profiling of WebRuntime - $name Widget\""; + + my $font = 12; + + my $wheader = 213; + my $hheader = 199; + my $max = 8100; + + print "+++++++++++++++++++++++++++ $name\n"; + + + my $maxtime = `cat $dir/cold/outpucik-points | tail -n1 | cut -d, -f2`; + my $nroftics = int($maxtime/100000 + 1); + my $maxtics = $nroftics * 100000; + print "NROFTIC: $nroftics\n"; + my $height = int(20.7 * $nroftics + $hheader); + if ($height > $max) + { + $height = $max; + } + + my $lines_count = `wc -l $warm`; + $lines_count = $lines_count - 2; + print "lc: $lines_count\n"; + my $width = int(23.5 * $lines_count + $wheader); + print "wi: $width\n"; + if ($width > $max) + { + my $newfont = int ($font * $max/$width); + $width = $max; + $height = $hheader + int (($height - $hheader)*$newfont/$font); + $font = $newfont + } + + print "Generating $file W: $width H: $height F: $font\n\n"; + print "./utils/generate-plot.sh $warm $cold $preload $file $title $font $width $height $maxtics\n\n\n"; + `./utils/generate-plot.sh $warm $cold $preload $file $title $font $width $height $maxtics $difffile`; +} + diff --git a/src/profiling/script/profiling-target-part.pl b/src/profiling/script/profiling-target-part.pl new file mode 100755 index 0000000..e20ece2 --- /dev/null +++ b/src/profiling/script/profiling-target-part.pl @@ -0,0 +1,308 @@ +#!/usr/bin/env perl +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +##### CONFIGURATION begin ##### + +my $WIDGET_PACKAGE_DIR = './test-widgets'; +my @WIDGETS = ( + ['minimal.wgt', 'minimal' ], + ['0Jet_Pack_Agent.wgt', 'Jet Pack Agent'], + ['UnitTestAuto.wgt', 'UnitTest' ], +); +my $WRT_INSTALL_ENV = 'WRT_TEST_MODE=1'; + +my $WRT_CLIENT_LAUNCH = 'wrt-client -l {}'; +my $WRT_CLIENT_QUERY = 'wrt-launcher -l 2>/dev/null'; +my $WRT_CLIENT_INSTALL = "$WRT_INSTALL_ENV wrt-installer -i {}"; +my $WRT_CLIENT_UNINSTALL = "$WRT_INSTALL_ENV wrt-installer -un {}"; +my $COLD_START_PREPARE_COMMAND = '/sbin/sysctl vm.drop_caches=3'; +my $OUTPUT_DIR = './OUTPUT'; +my $PRELOAD_LIBRARIES = './utils/wrt-preloader'; + +##### CONFIGURATION end ##### + + +use strict; +use Time::HiRes; +use Time::Local; +use List::Util; + + +##### Single test runners + +# $stream may be undef - then no output +sub runWidget { + my $widgetTizenId = shift; + my $stream = shift; + my $streamout = shift; + my $fnameerr = shift; + + unless (defined $fnameerr) { + $fnameerr = '/dev/null'; + } + + `mkdir -p $OUTPUT_DIR/tmp`; + + my $fnameerr = "$OUTPUT_DIR/tmp/additional.tmp"; + + my $command = $WRT_CLIENT_LAUNCH; + $command =~ s/\{\}/$widgetTizenId/; + $command .= " 2>$fnameerr 3>$OUTPUT_DIR/tmp/prof.tmp & echo TEST-WIDGET-PID \$\!"; + + print "$command\n"; + + my ($startSec, $startUSec) = Time::HiRes::gettimeofday(); + + my $f; + open $f, "$command |"; + + my $pid = undef; + + my $extralines = ""; + + while (my $line = <$f>) { + print "The line is: $line"; + if (defined $streamout) { + print $streamout $line; + } + chomp $line; + if (my ($p) = $line =~ /^TEST-WIDGET-PID (\d+)/) { + $pid = 0+$p; + } elsif ($line =~ /launched$/) { + print "launched detected $pid\n"; + kill 10, $pid; + my $again = 1; + while ($again) { + my $t = `tail -1 $OUTPUT_DIR/tmp/prof.tmp`; + if ($t =~ /###PROFILING###STOP###/) { + $again = 0; + } + } + kill 9, $pid; + print "killed\n"; + } elsif ($line =~ /\[([0-9]*):([0-9]*):([0-9]*).([0-9]*)\][^)]*\): *([A-Za-z0-9 ]+) *profiling##(start|stop)/) { #additionally take point from debug + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time()); + my $name = $5; + $hour = $1; + $min = $2; + $sec = $3; + my $msec = $4; + my $type = $6; + my $value = timelocal($sec,$min,$hour,$mday,$mon,$year); + my $value = $msec + 1000 * $value; + my $insert = "$type#$name#$value${msec}#[]\n"; + $extralines = "$extralines$insert"; + } + } + + close $f; + + #TODO: do it perl way + `cat $OUTPUT_DIR/tmp/prof.tmp | sort -k3,3 -t"#" -n > $OUTPUT_DIR/tmp/prof.tmp.new && mv $OUTPUT_DIR/tmp/prof.tmp.new $OUTPUT_DIR/tmp/prof.tmp`; + + open my $fin, "<", "$OUTPUT_DIR/tmp/prof.tmp"; + while (my $line = <$fin>) { + chomp $line; + if ($line =~ /^#Profiling_Started#/) { + if (defined $stream) { + printf $stream "#Profiling_Started#%d%06d#[]\n", $startSec, $startUSec; + } + } elsif ($line =~ /###PROFILING###STOP###/) { + if (defined $stream) { + print $stream "$extralines###PROFILING###STOP###\n"; + } + } else { + if (defined $stream) { + print $stream "$line\n"; + } + } + } + close $fin; +} + +# $mode: +# simple - just run the widget, no special preparations +# cold - after cache clean +# warm - the same widget first launched w/o logs for "warm-up" +# double-warm - two warm-up launches prior to proper test +# preload - preloaded webkit library and its dependencies +# TODO - OTHER MODES: +# - warming-up with ANOTHER widget? +# - warming-up by copying all required binaries/libraries to /dev/null +# - running with all binaries/libraries placed on tmpfs (i.e. in cache) +# - first clean cache, then fill it with garbage, by copying lots +# of useless data from disk to /dev/null, until `free' shows small +# enough free memory level +sub runTest { + my $widgetTizenId = shift; + my $mode = shift; + my $stream = shift; + my $streamout = shift; + my $fnameerr = shift; + + if ($mode eq 'simple') { + # no preparations necessary + } elsif ($mode eq 'cold') { + `$COLD_START_PREPARE_COMMAND`; + } elsif ($mode eq 'warm') { + runWidget( $widgetTizenId, undef, undef, undef ); + } elsif ($mode eq 'double-warm') { + runWidget( $widgetTizenId, undef, undef, undef ); + runWidget( $widgetTizenId, undef, undef, undef ); + } elsif ($mode eq 'preload') { + `$COLD_START_PREPARE_COMMAND`; + `$PRELOAD_LIBRARIES`; + } else { + die; + } + runWidget( $widgetTizenId, $stream, $streamout, $fnameerr ); +} + +##### Widget installation + +# returns \% a map: name->tizenId +sub dropAndInstallAll { + my $pwidgets = shift; + + { + print "Uninstalling all widgets\n"; + my @out = `$WRT_CLIENT_QUERY`; + for my $line (@out) { + if (my ($tizenId) = $line =~ /^\s+\d+.*\s+([A-Za-z0-9]+)$/) { + my $command = $WRT_CLIENT_UNINSTALL; + $command =~ s/\{\}/$tizenId/g; + print " uninstalling widget $tizenId [$command]\n"; + `$command > /dev/null 2>/dev/null`; + } + } + } + { + print "Checking if widget list is empty\n"; + my @out = `$WRT_CLIENT_QUERY`; + for my $line (@out) { + if (my ($tizenId) = $line =~ /^\s+\d+.*\s+([A-Za-z0-9]+)$/) { + print "WIDGET LIST NOT EMPTY!!!\n"; + die; + } + } + } + { + print "Installing all test widgets\n"; + for my $pwidgetData (@$pwidgets) { + my ($package, $name) = @$pwidgetData; + my $command = $WRT_CLIENT_INSTALL; + $command =~ s/\{\}/$WIDGET_PACKAGE_DIR\/$package/g; + print " installing $name ($package) [$command]\n"; + `$command > /dev/null 2>/dev/null`; + } + } + { + print "Checking if all widgets are installed, determining tizenIds\n"; + my %widgetMap = (); + for my $pwidgetData (@$pwidgets) { + my ($package, $name) = @$pwidgetData; + $widgetMap{$name} = undef; + } + my @out = `$WRT_CLIENT_QUERY`; + for my $line (@out) { + if (my ($name, $trash, $tizenId) = $line =~ /^\s*\d+\s+(([^ ]| [^ ])+)\s+.*\s+([A-Za-z0-9]{10}\.[^\s]+)\s*$/) { + print " found $name (tizenId $tizenId)\n"; + $widgetMap{$name} = $tizenId; + } + } + for my $name (keys %widgetMap) { + unless (defined $widgetMap{$name}) { + print " MISSING $name\n"; + die; + } + } + return \%widgetMap; +} +} + + +##### Test schemes + +# PARAMS: +# \@ list of widgets (can be undef, then will use @WIDGETS) +# \@ list of modes (modes can be as in runTest) +# number of repetitions of one widget/mode pair +sub fullRandomTest { + my $pwidgets = shift; $pwidgets = \@WIDGETS unless defined $pwidgets; +my $pmodes = shift; +my $repetitions = shift; + +my $pwidgetMap = dropAndInstallAll( $pwidgets ); + +my @testList = (); + +print "Preparing the test list\n"; +for my $pwidget (@$pwidgets) { + my ($package, $name) = @$pwidget; + for my $mode (@$pmodes) { + for (my $number = 0; $number < $repetitions; $number++) { + push @testList, [$name, $mode]; + } + } +} + +@testList = List::Util::shuffle( @testList ); + +print "Clearing the output dir\n"; +`rm -rf $OUTPUT_DIR`; + +print "Running tests\n"; +my %runNumbers = (); +my $globalTestNumber = 0; +my $totalTestCount = @testList; +for my $ptest (@testList) { + # find test parameters + my ($name, $mode) = @$ptest; + my $widgetTizenId = $$pwidgetMap{$name}; + my $runNo = $runNumbers{"$mode|$widgetTizenId"}; + print "next\n"; + if (defined $runNo) + { $runNo += 1; } + else + { $runNo = 0; } + $runNumbers{"$mode|$widgetTizenId"} = $runNo; + $globalTestNumber += 1; + print " Test $globalTestNumber of $totalTestCount: ". + "$name ($widgetTizenId) run $runNo, $mode\n"; + + # remove and create output dir + my $prepName = $name; + $prepName =~ s/ /_/g; + my $dirName = sprintf "$OUTPUT_DIR/$prepName/$mode/run%03d", $runNo; + `mkdir -p $dirName`; + + # create output files + open my $outFile, ">", "$dirName/prof-raw-data" or die; + open my $dumpOutFile, ">", "$dirName/dump-stdout" or die; + + # run test + runTest( $widgetTizenId, $mode, $outFile, $dumpOutFile, "$dirName/dump-stderr" ); + + # close output files + close $outFile; + close $dumpOutFile; + print "Done\n"; +} +} + +##### MAIN ##### + +fullRandomTest( undef, ['cold', 'warm', 'preload'], 10 ); diff --git a/src/profiling/script/ranges b/src/profiling/script/ranges new file mode 100644 index 0000000..0b06207 --- /dev/null +++ b/src/profiling/script/ranges @@ -0,0 +1,5 @@ +Whole startup:Profiling_Started-:wrt_launch-stop +Library loading:Profiling_Started-:main-entered-point +app_core/dpl operations:main-entered-point:wrt_init-start +wrt-init:wrt_init-start:wrt_init-stop +WRT launch:wrt_launch-start:wrt_launch-stop diff --git a/src/profiling/script/ranges.py b/src/profiling/script/ranges.py new file mode 100755 index 0000000..e6ae996 --- /dev/null +++ b/src/profiling/script/ranges.py @@ -0,0 +1,68 @@ +#!/usr/bin/python +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import os,sys + +def main(): + if sys.version[0] != "2": + exit(1) + + f = open('ranges', 'r') + # Array of ranges. + ranges = [] + for line in f: + r = line.rstrip().split(':') + r.append(0) + r.append(0) + r.append(0) + ranges.append(r) + f.close() + + # find directories with results + for root, dirs, files in os.walk('OUTPUT'): + path = root.rsplit('/',1) + if path[len(path)-1] not in ['cold','warm','preload']: + continue + + # open file with measurements + print '\n' + root + output = open(root + '/outpucik-points', 'r') + + # find matching points + for r in ranges: + output.seek(0) + for l in output: + if r[1] in l: + r[3] = l.split(',')[1] + if r[2] in l: + r[4] = l.split(',')[1] + + output.close() + + # calculate the difference + for r in ranges: + r[5] = int(r[4]) - int(r[3]) + + # save calculations + results = open(root + '/outpucik-results','w') + for r in ranges: + print " " + r[0] + ": " + str(float(r[5])/1000) + "ms" + results.write(r[0] + ": " + str(float(r[5])/1000) + "ms\n") + results.close() + +if __name__ == "__main__": + main() + diff --git a/src/profiling/script/test-widgets/0Jet_Pack_Agent.wgt b/src/profiling/script/test-widgets/0Jet_Pack_Agent.wgt new file mode 100644 index 0000000..a9b27fa Binary files /dev/null and b/src/profiling/script/test-widgets/0Jet_Pack_Agent.wgt differ diff --git a/src/profiling/script/test-widgets/UnitTestAuto.wgt b/src/profiling/script/test-widgets/UnitTestAuto.wgt new file mode 100644 index 0000000..57fb2e4 Binary files /dev/null and b/src/profiling/script/test-widgets/UnitTestAuto.wgt differ diff --git a/src/profiling/script/test-widgets/minimal.wgt b/src/profiling/script/test-widgets/minimal.wgt new file mode 100644 index 0000000..2406783 Binary files /dev/null and b/src/profiling/script/test-widgets/minimal.wgt differ diff --git a/src/profiling/script/utils/analyse.pl b/src/profiling/script/utils/analyse.pl new file mode 100755 index 0000000..25c1527 --- /dev/null +++ b/src/profiling/script/utils/analyse.pl @@ -0,0 +1,135 @@ +#!/usr/bin/env perl +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +use strict; +use warnings; +use diagnostics; + +my ($regular_out_file, $range_out_file) = @ARGV; + +print "Script requires two arguments, +which are file names to store the output\n +Regular points will be stored in first file, +ranges in second one.\n" and exit unless (defined $regular_out_file and defined $range_out_file); + + +print "Starting analysis\n"; +my @lines = ; + +my @packets; +foreach my $line (@lines) +{ + chomp($line); + my @splitted = split(/#/, $line); + my $prefix = $splitted[0]; + my $name = $splitted[1]; + my $time = $splitted[2]; + my $description = $splitted[3]; + my %packet; + $packet{time} = $time; + $packet{prefix} = $prefix; + $packet{name} = $name; + $packet{description} = $description; + push @packets, \%packet; +} + +@packets = sort { $$a{time} <=> $$b{time} } @packets; + +my $starttime; +my %tmps; +my @ranges; + +foreach my $packet (@packets) +{ + my $name = $$packet{name}; + my $prefix = $$packet{prefix}; + + if (not defined $starttime) + { + if (defined $name and $name eq "Profiling_Started") + { + $starttime = $$packet{time}; + } + else + { + print "***** No Profiling Start Point Found *****\n"; + exit(); + } + } + $$packet{time} = $$packet{time} - $starttime; + + if ($prefix eq "start") + { + if (exists($tmps{$name})) + { + print "***** Doubled start point found $name *****\n"; + print "[$name]\n"; + exit(); + } + $tmps{$name} = \%$packet; + } + elsif ($prefix eq "stop") + { + if (not exists($tmps{$name})) + { + print "***** No start point found *****\n"; + exit(); + } + my %tmp = %{$tmps{$name}}; + my %newpacket = %$packet; + $newpacket{time} = $newpacket{time} - $tmp{time}; + delete ($tmps{$name}); + my $found; + foreach my $p (@ranges) + { + if ($$p{name} eq $newpacket{name}) + { + $$p{time} += $newpacket{time}; + $found = 1; + } + } + if (not defined($found)) + { + push(@ranges, \%newpacket); + } + } +} + +open REGULAR_OUT_FILE, ">", $regular_out_file or die $!; + +print REGULAR_OUT_FILE "name,prefix,timestamp[µs],timespan[µs]\n"; +my $lastTime; +foreach my $point (@packets) +{ + if (not defined $lastTime) + { + $lastTime = $$point{time}; + } + my $toPrint = sprintf("%s-%s,%lu,%lu\n", $$point{name}, $$point{prefix}, $$point{time}, $$point{time} - $lastTime); + print REGULAR_OUT_FILE $toPrint; + $lastTime = $$point{time}; +} +close REGULAR_OUT_FILE; + +open RANGE_OUT_FILE, ">", $range_out_file or die $!; +print RANGE_OUT_FILE "range name,timespan[µs]\n"; +foreach my $range (@ranges) +{ + my $res = sprintf("%s,%lu\n", $$range{name}, $$range{time}); + print RANGE_OUT_FILE $res; +} +close RANGE_OUT_FILE; + diff --git a/src/profiling/script/utils/csv-stats.pl b/src/profiling/script/utils/csv-stats.pl new file mode 100755 index 0000000..69a9165 --- /dev/null +++ b/src/profiling/script/utils/csv-stats.pl @@ -0,0 +1,420 @@ +#!/usr/bin/perl -w +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +use warnings; +use diagnostics; +use strict; +use Getopt::Std; + +my %options = (); +my $delimiter = ','; +getopts("crs:d:h", \%options); + +if (defined $options{h}) +{ + print "HELP\n"; + exit; +} + +if (defined $options{d}) +{ + $delimiter = $options{d}; +} + +my $skip_row = defined $options{r}; +my $skip_col = defined $options{c}; +my @stats_names; + +if (defined $options{s}) +{ + @stats_names = split /,/, $options{s}; +} +else +{ + @stats_names = split /,/, "min,max,avg";#,std"; +} + +foreach(@stats_names) +{ + if (not ($_ eq "min" or $_ eq "max" or $_ eq "avg" or $_ eq "std")) + { + print "bad stat name: ", $_, "\n"; + print "Supported stats: min,max,avg,std\n"; + exit; + } +} + +my @FILES = @ARGV; +my $first_file; + +sub ParseCSV { + my($filename, $delimiter) = @_; + + + open FILE, "<", $filename or die $!; + my @file_rows = ; + my @desc_fields; + + if ($skip_col) + { + my $description_row = shift @file_rows; + chomp $description_row; #remove last \n + @desc_fields = split $delimiter, $description_row; + } + + my @description_col; + my $rows = []; + foreach (@file_rows) + { + chomp $_; #remove last \n + my @fields = split $delimiter, $_; + if ($skip_row) + { + push @description_col, shift @fields; + } + push @$rows, \@fields; + } + my $table = Table->new($rows); + my $csv = CSV->new($table); + if ($skip_col) + { + $csv->addColsDescription(\@desc_fields); + } + if ($skip_row) + { + $csv->addRowsDescription(\@description_col); + } + $csv; +} + +my $stats = {}; +foreach my $stat_name (@stats_names) +{ + my $stat_creator = createStatForName($stat_name); + $stats->{$stat_name} = $stat_creator; +} + +foreach (@FILES) +{ +# print "parsing ", $_, "\n"; + my $csv = ParseCSV($_, $delimiter); + while (my ($key, $value) = each (%$stats)) + { +# print "adding ", $key, " stats\n"; + $value->addResults($csv); + } +} + +while (my ($key, $value) = each (%$stats)) +{ +# print "printing ", $key, " stats\n"; + $value->finish(); + $value->writeToFile(*STDOUT); +} + +sub createStatForName { + my ($name) = @_; + if ($name eq "min") { + MinStat->new(); + } elsif ($name eq "max") { + MaxStat->new(); + } elsif ($name eq "avg") { + AvgStat->new(); + } +} + + +package MinStat; +sub new { + my $class = shift; + my $self = {}; + return bless $self, $class; +} + +sub addResults { + my ($self, $csv) = @_; + if (defined $self->{m_base_csv}) { + my $rowNr = 0; + foreach my $row (@{$csv->getTable()->getData()}) + { + my $colNr = 0; + foreach (@$row) + { + my $oldvalue = $self->{m_table}->getData()->[$rowNr][$colNr]; + my $newvalue = $_; + if ($newvalue < $oldvalue) { + $self->{m_table}->getData()->[$rowNr][$colNr] = $newvalue; + } + $colNr ++; + } + $rowNr ++; + } + } else { + my $newcsv = CSV->new(Table->new([])); + $newcsv->addColsDescription($csv->getColsDescription()); + $newcsv->addRowsDescription($csv->getRowsDescription()); + $self->{m_base_csv} = $newcsv; + my $table = []; + foreach(@{$csv->getTable()->getData()}) + { + my $new_row = []; + @$new_row = @$_; #array copy + push @$table, $new_row; + } + $self->{m_table} = Table->new($table); + } +} + +sub writeToFile { + my ($self, $file) = @_; + $self->{m_base_csv}->setTable($self->{m_table}); + $self->{m_base_csv}->writeToFile($file); +} + +sub finish { + my ($self) = @_; + $self->{m_base_csv}->setTable($self->{m_table}); +} + +package MaxStat; +sub new { + my $class = shift; + my $self = {}; + return bless $self, $class; +} + +sub addResults { + my ($self, $csv) = @_; + if (defined $self->{m_base_csv}) { + my $rowNr = 0; + foreach my $row (@{$csv->getTable()->getData()}) + { + my $colNr = 0; + foreach (@$row) + { + my $oldvalue = $self->{m_table}->getData()->[$rowNr][$colNr]; + my $newvalue = $_; + if ($newvalue > $oldvalue) { + $self->{m_table}->getData()->[$rowNr][$colNr] = $newvalue; + } + $colNr ++; + } + $rowNr ++; + } + } else { + my $newcsv = CSV->new(Table->new([])); + $newcsv->addColsDescription($csv->getColsDescription()); + $newcsv->addRowsDescription($csv->getRowsDescription()); + $self->{m_base_csv} = $newcsv; + my $table = []; + foreach(@{$csv->getTable()->getData()}) + { + my $new_row = []; + @$new_row = @$_; #array copy + push @$table, $new_row; + } + $self->{m_table} = Table->new($table); + } +} + +sub finish { + my ($self) = @_; + $self->{m_base_csv}->setTable($self->{m_table}); +} + +sub writeToFile { + my ($self, $file) = @_; + $self->{m_base_csv}->writeToFile($file); +} + +package AvgStat; +sub new { + my $class = shift; + my $self = {}; + return bless $self, $class; +} + +use Scalar::Util 'looks_like_number'; +sub addResults { + my ($self, $csv) = @_; + if (defined $self->{m_base_csv}) { + my $rowNr = 0; + foreach my $row (@{$csv->getTable()->getData()}) + { + my $colNr = 0; + foreach my $coldata (@$row) + { +# if (not $coldata gt 0) { +# die ("LINE: " . $rowNr . " COL: " . $colNr . " DATA: " . $coldata); +# } + $self->{m_table_with_mean}->getData()->[$rowNr][$colNr] += $coldata; + $self->{m_table_with_count}->getData()->[$rowNr][$colNr] ++; + $colNr ++; + } + $rowNr ++; + } + } else { + my $newcsv = CSV->new(Table->new([])); + $newcsv->addColsDescription($csv->getColsDescription()); + $newcsv->addRowsDescription($csv->getRowsDescription()); + $self->{m_base_csv} = $newcsv; + my $table = []; + my $table_2 = []; + foreach(@{$csv->getTable()->getData()}) + { + my $new_row = []; + @$new_row = @$_; #array copy + push @$table, $new_row; + my $new_row_2 = []; + my $len = @$_; + @$new_row_2 = ((1) x $len); + push @$table_2, $new_row_2; + } + $self->{m_table_with_mean} = Table->new($table); + $self->{m_table_with_count} = Table->new($table_2); + foreach my $row (@{$self->{m_table_with_count}->getData()}) + { + foreach my $field (@$row) + { + $field = 1; + } + } + } +} + +sub finish { + my ($self) = @_; + my $rowNr = 0; + foreach my $row (@{$self->{m_table_with_count}->getData()}) + { + my $colNr = 0; + foreach (@$row) + { + my $tmp = $self->{m_table_with_mean}->getData()->[$rowNr][$colNr]; +# print "DIV: ", $tmp, " : ", $_, "\n"; + $tmp = $tmp / $_; + $tmp = sprintf ("%.0f", $tmp); + $self->{m_table_with_mean}->getData()->[$rowNr][$colNr] = $tmp; + $colNr ++; + } + $rowNr ++; + } + $self->{m_base_csv}->setTable($self->{m_table_with_mean}); +} + +sub writeToFile { + my ($self, $file) = @_; + $self->{m_base_csv}->writeToFile($file); +} + + +package Table; +sub new { + my $class = shift; + my $self = { + m_data => shift, + }; + return bless $self, $class; +} + +sub setField { + my ($self, $row, $col, $value) = @_; + $self->{m_data}[$row][$col] = $value; +} + +sub getField { + my ($self, $row, $col) = @_; + $self->{m_data}[$row][$col]; +} + +sub addField { + my ($self, $row, $col, $value) = @_; + $self->{m_data}[$row][$col] += $value; +} + +sub incField { + my ($self, $row, $col) = @_; + $self->{m_data}[$row][$col] ++; +} + +sub getData { + my ($self) = @_; + $self->{m_data}; +} + +package CSV; +sub new { + my $class = shift; + my $self = { m_data => shift, }; + return bless $self, $class; +} + +sub addColsDescription { + my ($self, $desc) = @_; + $self->{m_cols_desc} = $desc; +} + +sub addRowsDescription { + my ($self, $desc) = @_; + $self->{m_rows_desc} = $desc; +} + +sub getColsDescription { + my ($self) = @_; + $self->{m_cols_desc}; +} + +sub getRowsDescription { + my ($self) = @_; + $self->{m_rows_desc}; +} + +sub getNrRows { + my ($self) = @_; + my $ret = @{$self->{m_data}->getData()}; +} + +sub getNrCols { + my ($self) = @_; + my $ret = @{@{$self->{m_data}->getData()}[0]}; +} + +sub getTable { + my ($self) = @_; + $self->{m_data}; +} + +sub setTable { + my ($self, $table) = @_; + $self->{m_data} = $table; +} + +sub writeToFile { + my ($self, $file) = @_; + if (defined $self->{m_cols_desc}) { + print $file join(',', @{$self->{m_cols_desc}}), "\n"; + } + my $rowNr = 0; + foreach(@{$self->{m_data}->getData()}) + { + my @row = @$_; + if (defined $self->{m_rows_desc}) { + print $file $self->{m_rows_desc}->[$rowNr], ','; + } + print $file join(',', @row), "\n"; + $rowNr ++; + } +} diff --git a/src/profiling/script/utils/generate-plot.sh b/src/profiling/script/utils/generate-plot.sh new file mode 100755 index 0000000..7e3b66f --- /dev/null +++ b/src/profiling/script/utils/generate-plot.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +WARM_FILE=$1 +COLD_FILE=$2 +PRELOAD_FILE=$3 +OUTPUT_FILE=$4 +PLOT_TITLE=$5 +FONT_SIZE=$6 +WIDTH=$7 +HEIGHT=$8 +MAXTICS=$9 +DIFFFILE=${10} + +gnuplot \ + -e "warm_file='$WARM_FILE'" \ + -e "cold_file='$COLD_FILE'" \ + -e "preload_file=\"$PRELOAD_FILE\"" \ + -e "output_file='$OUTPUT_FILE'" \ + -e "plot_title='$PLOT_TITLE'" \ + -e "font_size='$FONT_SIZE'" \ + -e "width='$WIDTH'" \ + -e "height='$HEIGHT'" \ + -e "maxtics='$MAXTICS'" \ + -e "difffile='$DIFFFILE'" \ + ./utils/plot-generator.gplot diff --git a/src/profiling/script/utils/plot-generator.gplot b/src/profiling/script/utils/plot-generator.gplot new file mode 100644 index 0000000..21b613b --- /dev/null +++ b/src/profiling/script/utils/plot-generator.gplot @@ -0,0 +1,33 @@ +#cold_file="OUTPUT/1002_WAC_Test/cold/outpucik-points" +#warm_file="OUTPUT/1002_WAC_Test/warm/outpucik-points" +#preload_file="OUTPUT/1002_WAC_Test/preload/outpucik-points" +#output_file="Some.svg" +#plot_title="some title" +#width +#height +#font_size +#tics +#difffile +set terminal svg size width height dynamic fsize font_size +set object 1 rect from screen 0, 0, 0 to screen 1, 1, 0 behind +set object 1 rect fc rgb "white" fillstyle solid 1.0 +set output output_file +set size 1.0,1.0 +set title plot_title +set style fill solid +set grid +set datafile separator "," +set style line 1 +set key top left +set ytics 0,100000,maxtics +set y2tics 0,100000,maxtics +set ylabel "time [us]" +set y2label "time [us]" +set format y "%2.1e" +set format y2 "%2.1e" +set xlabel "Execution points of WRT during launching" +set xtics border in nomirror rotate by -45 offset character 0, 0, 0 +plot warm_file u 2:xtic(1) with lines title " Warm", \ + cold_file u 2 with lines title " Cold", \ + preload_file u 2 with lines title " Preload", \ + difffile u ($3-$6) with fsteps title " Diff" diff --git a/src/profiling/script/utils/wrt-preloader b/src/profiling/script/utils/wrt-preloader new file mode 100755 index 0000000..5d2e8fc Binary files /dev/null and b/src/profiling/script/utils/wrt-preloader differ diff --git a/src/view/CMakeLists.txt b/src/view/CMakeLists.txt new file mode 100644 index 0000000..ec71158 --- /dev/null +++ b/src/view/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 src/view/CMakeLists.txt +# @author Pawel Sikorski (p.sikorski@samsung.com) + +SET(VIEW_MODULE_SOURCES + ${PROJECT_SOURCE_DIR}/src/view/view_module.cpp + ${PROJECT_SOURCE_DIR}/src/view/context_manager.cpp +) + +ADD_SUBDIRECTORY(common) #ViewModule common library +ADD_SUBDIRECTORY(webkit) #ViewModule based on Webkit2 + diff --git a/src/view/common/CMakeLists.txt b/src/view/common/CMakeLists.txt new file mode 100644 index 0000000..5ecf302 --- /dev/null +++ b/src/view/common/CMakeLists.txt @@ -0,0 +1,102 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 src/view/common/CMakeLists.txt +# @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + +PKG_CHECK_MODULES(SYS_VIEW_COMMON_DEP + wrt-commons-custom-handler-dao-ro + appsvc + aul + cert-svc-vcore + capi-appfw-app-manager + efl-assist + eina + elementary + evas +# haptic + deviced + libcurl # uri unescape + libiri + libpcrecpp + libsoup-2.4 + notification + security-client + security-core + secure-storage + REQUIRED +) + +PKG_CHECK_MODULES(VIEW_COMMON_DEP + dpl-efl + dpl-event-efl + dpl-wrt-dao-ro + wrt-commons-security-origin-dao + wrt-commons-certificate-dao + wrt-popup-wrt-runner + REQUIRED +) + +SET(VIEW_COMMON_SOURCES + ${PROJECT_SOURCE_DIR}/src/view/common/application_launcher.cpp + ${PROJECT_SOURCE_DIR}/src/view/common/evas_object.cpp + ${PROJECT_SOURCE_DIR}/src/view/common/scheme.cpp + ${PROJECT_SOURCE_DIR}/src/view/common/scheme_action_map.cpp + ${PROJECT_SOURCE_DIR}/src/view/common/view_logic_apps_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/common/view_logic_custom_header_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/common/view_logic_help_popup_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/common/view_logic_security_origin_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/common/view_logic_security_origin_support_util.cpp + ${PROJECT_SOURCE_DIR}/src/view/common/view_logic_security_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/common/view_logic_storage_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/common/view_logic_uri_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/common/view_logic_vibration_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/common/view_logic_certificate_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/common/view_logic_privilege_support.cpp +) + +SET(VIEW_COMMON_INCLUDES + ${PROJECT_SOURCE_DIR}/src/domain + ${PROJECT_SOURCE_DIR}/src/profiling + ${PROJECT_SOURCE_DIR}/src/view/common + ${VIEW_COMMON_DEP_INCLUDE_DIRS} + ) + +INCLUDE_DIRECTORIES(${VIEW_COMMON_INCLUDES}) +INCLUDE_DIRECTORIES(SYSTEM ${SYS_VIEW_COMMON_DEP_INCLUDE_DIRS}) + +ADD_LIBRARY(${TARGET_VIEW_COMMON_LIB_STATIC} STATIC + ${VIEW_COMMON_SOURCES} +) + +TARGET_LINK_LIBRARIES(${TARGET_VIEW_COMMON_LIB_STATIC} + ${VIEW_COMMON_DEP_LIBRARIES} + ${SYS_VIEW_COMMON_DEP_LIBRARIES} + ${PROF_LIB} +) + +SET_TARGET_PROPERTIES(${TARGET_VIEW_COMMON_LIB_STATIC} PROPERTIES + COMPILE_DEFINITIONS LOG_TAG="${LOG_TAG}") + +SET_TARGET_PROPERTIES(${TARGET_VIEW_COMMON_LIB_STATIC} PROPERTIES + SOVERSION ${PROJECT_API_VERSION} + VERSION ${PROJECT_VERSION} + ) +SET_TARGET_PROPERTIES(${TARGET_VIEW_COMMON_LIB_STATIC} PROPERTIES + COMPILE_FLAGS -fPIC) +SET_TARGET_PROPERTIES(${TARGET_VIEW_COMMON_LIB_STATIC} PROPERTIES + COMPILE_FLAGS "-include profiling_util.h" + LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both" + OUTPUT_NAME ${TARGET_VIEW_COMMON_LIB_STATIC}) diff --git a/src/view/common/application_launcher.cpp b/src/view/common/application_launcher.cpp new file mode 100644 index 0000000..72d00c4 --- /dev/null +++ b/src/view/common/application_launcher.cpp @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 application_launcher.cpp + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief Implementation file for application launcher + */ + +#include "application_launcher.h" + +#include +#include + +#include +#include +#include +#include +#include + +IMPLEMENT_SINGLETON(ApplicationLauncher) + +namespace { +const char * const APP_CONTROL_EXTRA_DATA_KEY_PATH = "path"; +const char * const APP_CONTROL_EXTRA_DATA_KEY_COOKIE = "cookie"; +const char * const APP_CONTROL_EXTRA_DATA_KEY_MODE = "mode"; +const char * const APP_CONTROL_EXTRA_DATA_VALUE_SLIENT = "silent"; + +const char * const SCHEME_TYPE_RTSP = "rtsp"; +const char * const SCHEME_TYPE_HTML5_VIDEO = "html5video"; +} + +ApplicationLauncher::ApplicationLauncher() : + m_windowHandle(0) +{ +} + +ApplicationLauncher::~ApplicationLauncher() +{} + +void ApplicationLauncher::OnEventReceived( + const ApplicationLauncherEvents::LaunchApplicationByAppService &event) +{ + int result; + app_control_h app_control = event.GetArg0(); + app_control_reply_cb responseCallback = event.GetArg1(); + void *userData = event.GetArg2(); + + if (m_windowHandle) { + app_control_set_window(app_control, m_windowHandle); + } + + result = app_control_send_launch_request(app_control, responseCallback, userData); + if (result != APP_CONTROL_ERROR_NONE) { + app_control_destroy(app_control); + _E("Failed to run app_control : %d", result); + return; + } + app_control_destroy(app_control); + _D("Success to run app_control"); +} + +void ApplicationLauncher::OnEventReceived( + const ApplicationLauncherEvents::LaunchApplicationByPkgname &event) +{ + using namespace ApplicationLauncherPkgname; + std::string pkgName(event.GetArg0()); + + if (PKG_NAME_DOWNLOAD_PROVIDER == pkgName) { + std::string url(event.GetArg1()); + // This value needs for checking video, music contents later. + //std::string mime_type(event.GetArg2()); + std::string cookie(event.GetArg3()); + + if ("null" == url) { + _E("url is empty"); + return; + } + + app_control_h app_control = NULL; + int ret = APP_CONTROL_ERROR_NONE; + + // create app_control + ret = app_control_create(&app_control); + if (APP_CONTROL_ERROR_NONE != ret && NULL == app_control) { + _E("Fail to create app_control"); + return; + } + + // set app_control operation + ret = app_control_set_operation(app_control, APP_CONTROL_OPERATION_DOWNLOAD); + if (APP_CONTROL_ERROR_NONE != ret) { + _E("Fail to set operation [%d]", ret); + app_control_destroy(app_control); + return; + } + + // set app_control uri + ret = app_control_set_uri(app_control, url.c_str()); + if (APP_CONTROL_ERROR_NONE != ret) { + _E("Fail to set uri [%d]", ret); + app_control_destroy(app_control); + return; + } + + // set cookie + if (cookie != "null") { + ret = app_control_add_extra_data(app_control, + APP_CONTROL_EXTRA_DATA_KEY_COOKIE, + cookie.c_str()); + if (APP_CONTROL_ERROR_NONE != ret) { + _D("Fail to add cookie [%d]", ret); + app_control_destroy(app_control); + return; + } + } + + ret = app_control_add_extra_data(app_control, + APP_CONTROL_EXTRA_DATA_KEY_MODE, + APP_CONTROL_EXTRA_DATA_VALUE_SLIENT); + if (APP_CONTROL_ERROR_NONE != ret) { + _E("Fail to set app_control extra data [%d]", ret); + app_control_destroy(app_control); + return; + } + + if (m_windowHandle) { + app_control_set_window(app_control, m_windowHandle); + } + + //launch app_control + ret = app_control_send_launch_request(app_control, NULL, NULL); + if (APP_CONTROL_ERROR_NONE != ret) { + _E("Fail to launch app_control [%d]", ret); + app_control_destroy(app_control); + return; + } + app_control_destroy(app_control); + notification_status_message_post(WRT_POP_STARTING_DOWNLOADING); + return; + } else if (PKG_NAME_VIDEO_PLAYER == pkgName) { + bool isRunning = false; + if (APP_MANAGER_ERROR_NONE != + app_manager_is_running(PKG_NAME_VT_MAIN.c_str(), &isRunning)) + { + _E("Fail to get app running information"); + return; + } + if (true == isRunning) { + _E("video-call is running"); + return; + } + + std::string scheme(event.GetArg1()); + std::string uri(event.GetArg2()); + std::string cookie(event.GetArg3()); + const char* url; + + if ("null" == scheme) { + _E("scheme is empty"); + return; + } + if ("null" == uri) { + _E("uri is empty"); + return; + } + + if (SCHEME_TYPE_RTSP == scheme || + SCHEME_TYPE_HTML5_VIDEO == scheme) + { + url = uri.c_str(); + } else { + _E("scheme is invalid!!"); + return; + } + + app_control_h app_control = NULL; + int ret = APP_CONTROL_ERROR_NONE; + + // create app_control + ret = app_control_create(&app_control); + if (APP_CONTROL_ERROR_NONE != ret && NULL == app_control) { + _E("Fail to create app_control"); + return; + } + + // set url + if (!url || strlen(url) == 0) { + _E("Fail to get url"); + app_control_destroy(app_control); + return; + } + ret = app_control_add_extra_data(app_control, + APP_CONTROL_EXTRA_DATA_KEY_PATH, + url); + if (APP_CONTROL_ERROR_NONE != ret) { + _E("Fail to set url [%d]", ret); + app_control_destroy(app_control); + return; + } + + // set cookie + if (SCHEME_TYPE_HTML5_VIDEO == scheme) { + if ("null" != cookie) { + ret = app_control_add_extra_data(app_control, + APP_CONTROL_EXTRA_DATA_KEY_COOKIE, + cookie.c_str()); + if (APP_CONTROL_ERROR_NONE != ret) { + _E("Fail to add cookie [%d]", ret); + app_control_destroy(app_control); + return; + } + } + } + + // set package + ret = app_control_set_app_id(app_control, PKG_NAME_VIDEO_PLAYER.c_str()); + if (APP_CONTROL_ERROR_NONE != ret) { + _E("Fail to set package app_control [%d]", ret); + app_control_destroy(app_control); + return; + } + + // set window handle when available + if (m_windowHandle) { + app_control_set_window(app_control, m_windowHandle); + } + + //launch app_control + ret = app_control_send_launch_request(app_control, NULL, NULL); + if (APP_CONTROL_ERROR_NONE != ret) { + _E("Fail to launch app_control [%d]", ret); + app_control_destroy(app_control); + return; + } + app_control_destroy(app_control); + return; + } else { + _E("Not implemented application : %s", pkgName.c_str()); + } + + _D("Success to launch application : %s", pkgName.c_str()); + return; +} + +void ApplicationLauncher::setWidgetTizenId(const std::string& tizenId) +{ + m_tizenId = tizenId; +} + +void ApplicationLauncher::setWindowHandle(unsigned windowHandle) +{ + m_windowHandle = windowHandle; +} diff --git a/src/view/common/application_launcher.h b/src/view/common/application_launcher.h new file mode 100644 index 0000000..440892e --- /dev/null +++ b/src/view/common/application_launcher.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 application_launcher.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief Header file for application launcher + */ + +#ifndef APPLICATION_LAUNCHER_H +#define APPLICATION_LAUNCHER_H + +#include +#include +#include +#include + +#include + +namespace ApplicationLauncherEvents { +DECLARE_GENERIC_EVENT_3(LaunchApplicationByAppService, + app_control_h, + app_control_reply_cb, + void*) +DECLARE_GENERIC_EVENT_4(LaunchApplicationByPkgname, + std::string, + std::string, + std::string, + std::string) +} //namespace ApplicationLauncherEvents + +namespace ApplicationLauncherPkgname { +const std::string PKG_NAME_PREFIX = "com.samsung."; +const std::string PKG_NAME_DOWNLOAD_PROVIDER = PKG_NAME_PREFIX + + "download-provider"; +const std::string PKG_NAME_VIDEO_PLAYER = PKG_NAME_PREFIX + "video-player"; +const std::string PKG_NAME_VT_MAIN = PKG_NAME_PREFIX + "vtmain"; +} // namespace ApplicationLauncherPkgname + +class ApplicationLauncher : + public DPL::Event::Controller::Type> +{ + public: + ApplicationLauncher(); + virtual ~ApplicationLauncher(); + void setWidgetTizenId(const std::string& tizenId); + void setWindowHandle(unsigned windowHandle); + + protected: + virtual void OnEventReceived( + const ApplicationLauncherEvents:: + LaunchApplicationByPkgname &event); + virtual void OnEventReceived( + const ApplicationLauncherEvents:: + LaunchApplicationByAppService &event); + + private: + std::string m_tizenId; + unsigned m_windowHandle; +}; + +typedef DPL::Singleton ApplicationLauncherSingleton; + +#endif //APPLICATION_LAUNCHER_H diff --git a/src/view/common/evas_object.cpp b/src/view/common/evas_object.cpp new file mode 100644 index 0000000..edc33d4 --- /dev/null +++ b/src/view/common/evas_object.cpp @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 evas_object.cpp + * @author Lukasz Wrzosek (l.wrzosel@samsung.com) + * @version 1.0 + * @brief This file is the implementation for Evas_Object wrapper from + * Efl. + */ + +#include "evas_object.h" +#include + +Evas_Object* EvasObject::IConnection::GetEvasObject() +{ + return m_object->GetObject(); +} + +void EvasObject::IConnection::Disconnect() +{ + m_object->DisconnectCallback(this); +} + +EvasObject::IConnection::IConnection(EvasObject::EvasObjectShared* object) : + m_object(object) +{} + +void EvasObject::IConnection::SmartCallbackWrapper(void* data, + Evas_Object* /*object*/, + void* event_info) +{ + Assert(data); + IConnection* Calle = static_cast(data); + Calle->Call(event_info); +} + +void EvasObject::IConnection::EvasCallbackWrapper(void* data, + Evas* /*evas*/, + Evas_Object* /*object*/, + void* event_info) +{ + Assert(data); + IConnection* Calle = static_cast(data); + Calle->Call(event_info); +} + +Evas_Object* EvasObject::EvasObjectShared::GetObject() +{ + return m_object; +} + +EvasObject::EvasObjectShared::SmartConnectionBase::SmartConnectionBase( + const std::string& name, + EvasObject::EvasObjectShared* object) : + IConnection(object), + m_callbackName(name) +{} + +void EvasObject::EvasObjectShared::SmartConnectionBase::ConnectPrv() +{ + evas_object_smart_callback_add(GetEvasObject(), + m_callbackName.c_str(), + &IConnection::SmartCallbackWrapper, this); +} + +void EvasObject::EvasObjectShared::SmartConnectionBase::DisconnectPrv() +{ + evas_object_smart_callback_del(GetEvasObject(), + m_callbackName.c_str(), + &IConnection::SmartCallbackWrapper); +} + +EvasObject::EvasObjectShared::EvasConnectionBase::EvasConnectionBase( + Evas_Callback_Type type, + EvasObject::EvasObjectShared* object) : + IConnection(object), + m_callbackType(type) +{} + +void EvasObject::EvasObjectShared::EvasConnectionBase::ConnectPrv() +{ + evas_object_event_callback_add( + GetEvasObject(), m_callbackType, &IConnection::EvasCallbackWrapper, + this); +} + +void EvasObject::EvasObjectShared::EvasConnectionBase::DisconnectPrv() +{ + evas_object_event_callback_del_full( + GetEvasObject(), m_callbackType, &IConnection::EvasCallbackWrapper, + this); +} + +EvasObject::EvasObjectShared::EvasObjectShared() : + m_object(NULL) +{} + +EvasObject::EvasObjectShared::EvasObjectShared(Evas_Object* object) : + m_object(object) +{ + Assert(m_object); + evas_object_event_callback_add(m_object, + EVAS_CALLBACK_DEL, + &StaticOnDelEvent, + this); +} + +void EvasObject::EvasObjectShared::SetObject(Evas_Object* object) +{ + Assert(m_object == NULL); + Assert(object != NULL); + m_object = object; + evas_object_event_callback_add(m_object, + EVAS_CALLBACK_DEL, + &StaticOnDelEvent, + this); +} + +EvasObject::EvasObjectShared::~EvasObjectShared() +{ + if (m_object) { + DisconnectAll(); + evas_object_event_callback_del(m_object, + EVAS_CALLBACK_DEL, + &StaticOnDelEvent); + m_object = NULL; + } +} + +bool EvasObject::EvasObjectShared::DisconnectCallback(IConnection* connection) +{ + IConnectionsSet::iterator it = m_connections.find(connection); + if (it != m_connections.end()) { + (*it)->DisconnectPrv(); + delete connection; + m_connections.erase(it); + return true; + } + return false; +} + +void EvasObject::EvasObjectShared::DisconnectAll() +{ + FOREACH(it, m_connections) + { + (*it)->DisconnectPrv(); + delete *it; + } + m_connections.clear(); +} + +void EvasObject::EvasObjectShared::StaticOnDelEvent(void* data, + Evas* /*e*/, + Evas_Object* /*o*/, + void* /*ev*/) +{ + Assert(data); + EvasObjectShared* This = static_cast(data); + if (This->m_object) { + evas_object_event_callback_del(This->m_object, + EVAS_CALLBACK_DEL, + &StaticOnDelEvent); + This->DisconnectAll(); + This->m_object = NULL; + } +} + +EvasObject::EvasObject() : + m_object(new EvasObjectShared()) +{} + +EvasObject::EvasObject(Evas_Object* object) : + m_object(new EvasObjectShared(object)) +{} + +EvasObject::EvasObject(const EvasObject& other) : + m_object(other.m_object) +{} + +//this destructor must be here to let pimpl with shared_ptr work without warning +EvasObject::~EvasObject() +{} + +EvasObject& EvasObject::operator=(const EvasObject& other) +{ + Assert(m_object); + m_object = other.m_object; + return *this; +} + +EvasObject* EvasObject::operator=(Evas_Object* object) +{ + Assert(m_object); + m_object->SetObject(object); + return this; +} + +bool EvasObject::DisconnectCallback(IConnection* connection) +{ + Assert(m_object); + return m_object->DisconnectCallback(connection); +} + +void EvasObject::DisconnectAll() +{ + Assert(m_object); + m_object->DisconnectAll(); +} + +EvasObject::operator Evas_Object *() +{ + Assert(m_object); + return m_object->GetObject(); +} diff --git a/src/view/common/evas_object.h b/src/view/common/evas_object.h new file mode 100644 index 0000000..5073919 --- /dev/null +++ b/src/view/common/evas_object.h @@ -0,0 +1,647 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 evas_object.h + * @author Lukasz Wrzosek (l.wrzosel@samsung.com) + * @version 1.0 + * @brief This file is the header for Evas_Object wrapper from Efl. + */ +#ifndef WRT_SRC_DOMAIN_EFL_EVAS_OBJECT_H +#define WRT_SRC_DOMAIN_EFL_EVAS_OBJECT_H + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +class EvasObject +{ + class EvasObjectShared; + typedef std::shared_ptr EvasObjectSharedPtr; + + public: + class IConnection + { + public: + Evas_Object* GetEvasObject(); + void Disconnect(); + + private: + IConnection(EvasObjectShared* object); + virtual ~IConnection() + {} + virtual void Call(void* /*event_info*/) = 0; + + static void SmartCallbackWrapper(void* data, + Evas_Object* /*object*/, + void* event_info); + static void EvasCallbackWrapper(void* data, + Evas* /*evas*/, + Evas_Object* /*object*/, + void* event_info); + + virtual void ConnectPrv() = 0; + virtual void DisconnectPrv() = 0; + + friend class EvasObjectShared; + + EvasObjectShared* m_object; + }; + + private: + class EvasObjectShared : DPL::Noncopyable + { + public: + friend class IConnection; + Evas_Object* GetObject(); + + typedef std::set IConnectionsSet; + + class SmartConnectionBase : public IConnection + { + public: + SmartConnectionBase(const std::string& name, + EvasObjectShared* object); + + virtual void ConnectPrv(); + virtual void DisconnectPrv(); + std::string m_callbackName; + }; + + template + class SmartConnection : public SmartConnectionBase + { + public: + typedef void (*CbType)(IConnection* connection, + void* event_info, + Args ... args); + + SmartConnection(const std::string& name, + CbType callback, + EvasObjectShared* object, + Args ... args) : + SmartConnectionBase(name, object), + m_callback(callback), + m_args(args ...) + {} + + virtual ~SmartConnection() + {} + + virtual void Call(void* event_info) + { + DPL::Apply(m_callback, + m_args, + this, + event_info); + } + + private: + CbType m_callback; + std::tuple m_args; + }; + + template + class SmartMemberConnection1 : public SmartConnectionBase + { + public: + typedef void (ThisType::*CbType)(IConnection* connection, + void* event_info, ArgType1 *arg1); + + SmartMemberConnection1(const std::string& name, + CbType callback, + ThisType* callee, + ArgType1* arg1, + EvasObjectShared* object) : + SmartConnectionBase(name, object), + m_callback(callback), + m_callee(callee), + m_arg1(arg1) + {} + + virtual ~SmartMemberConnection1() + {} + + virtual void Call(void* event_info) + { + (m_callee->*m_callback)(this, event_info, m_arg1); + } + + private: + CbType m_callback; + ThisType* m_callee; + ArgType1* m_arg1; + }; + + template + class SmartMemberConnection2 : public SmartConnectionBase + { + public: + typedef void (ThisType::*CbType)(IConnection* connection, + void* event_info, ArgType1 *arg1, + ArgType2* arg2); + + SmartMemberConnection2(const std::string& name, + CbType callback, + ThisType* callee, + ArgType1* arg1, + ArgType2* arg2, + EvasObjectShared* object) : + SmartConnectionBase(name, object), + m_callback(callback), + m_callee(callee), + m_arg1(arg1), + m_arg2(arg2) + {} + + virtual ~SmartMemberConnection2() + {} + + virtual void Call(void* event_info) + { + (m_callee->*m_callback)(this, event_info, m_arg1, m_arg2); + } + + private: + CbType m_callback; + ThisType* m_callee; + ArgType1* m_arg1; + ArgType2* m_arg2; + }; + + class EvasConnectionBase : public IConnection + { + public: + EvasConnectionBase(Evas_Callback_Type type, + EvasObjectShared* object); + + virtual void ConnectPrv(); + virtual void DisconnectPrv(); + + Evas_Callback_Type m_callbackType; + }; + + template + class EvasConnection1 : public EvasConnectionBase + { + public: + typedef void (*CbType)(IConnection* connection, void* event_info, + ArgType1 *arg1); + + EvasConnection1(Evas_Callback_Type type, + CbType callback, + ArgType1* arg1, + EvasObjectShared* object) : + EvasConnectionBase(type, object), + m_callback(callback), + m_arg1(arg1) + {} + + virtual ~EvasConnection1() + {} + + virtual void Call(void* event_info) + { + m_callback(this, event_info, m_arg1); + } + + private: + CbType m_callback; + ArgType1* m_arg1; + }; + + template + class EvasConnection2 : public EvasConnectionBase + { + public: + typedef void (*CbType)(IConnection* connection, void* event_info, + ArgType1 *arg1, ArgType2 *arg2); + + EvasConnection2(Evas_Callback_Type type, + CbType callback, + ArgType1* arg1, + ArgType2* arg2, + EvasObjectShared* object) : + EvasConnectionBase(type, object), + m_callback(callback), + m_arg1(arg1), + m_arg2(arg2) + {} + + virtual ~EvasConnection2() + {} + + virtual void Call(void* event_info) + { + m_callback(this, event_info, m_arg1, m_arg2); + } + + private: + CbType m_callback; + ArgType1* m_arg1; + ArgType2* m_arg2; + }; + + template + class EvasMemberConnection1 : public EvasConnectionBase + { + public: + typedef void (ThisType::*CbType)(IConnection* connection, + void* event_info, ArgType1 *arg1); + + EvasMemberConnection1(Evas_Callback_Type type, + CbType callback, + ThisType* callee, + ArgType1* arg1, + EvasObjectShared* object) : + EvasConnectionBase(type, object), + m_callback(callback), + m_callee(callee), + m_arg1(arg1) + {} + + virtual ~EvasMemberConnection1() + {} + + virtual void Call(void* event_info) + { + (m_callee->*m_callback)(this, event_info, m_arg1); + } + + private: + CbType m_callback; + ThisType* m_callee; + ArgType1* m_arg1; + }; + + template + class EvasMemberConnection2 : public EvasConnectionBase + { + public: + typedef void (ThisType::*CbType)(IConnection* connection, + void* event_info, ArgType1* arg1, + ArgType2* arg2); + + EvasMemberConnection2(Evas_Callback_Type type, + CbType callback, + ThisType* callee, + ArgType1* arg1, + ArgType2* arg2, + EvasObjectShared* object) : + EvasConnectionBase(type, object), + m_callback(callback), + m_callee(callee), + m_arg1(arg1), + m_arg2(arg2) + {} + + virtual ~EvasMemberConnection2() + {} + + virtual void Call(void* event_info) + { + (m_callee->*m_callback)(this, event_info, m_arg1, m_arg2); + } + + private: + CbType m_callback; + ThisType* m_callee; + ArgType1* m_arg1; + ArgType2* m_arg2; + }; + + EvasObjectShared(); + explicit EvasObjectShared(Evas_Object* object); + void SetObject(Evas_Object* object); + ~EvasObjectShared(); + + template + IConnection* ConnectSmartCallback( + const char* callbackName, + typename SmartConnection:: + CbType callback, + Args ... args) + { + Assert(m_object); + Assert(callbackName); + Assert(callback); + IConnection* connection = new SmartConnection( + callbackName, + callback, + this, + args ...); + m_connections.insert(connection); + connection->ConnectPrv(); + return connection; + } + + template + IConnection* ConnectMemberSmartCallback( + const char* callbackName, + typename SmartMemberConnection2::CbType callback, + ThisType* callee, + ArgType1* arg1, + ArgType2* arg2) + { + Assert(m_object); + Assert(callee); + Assert(callbackName); + Assert(callback); + IConnection* connection = + new SmartMemberConnection2( + callbackName, + callback, + callee, + arg1, + arg2, + this); + m_connections.insert(connection); + connection->ConnectPrv(); + return connection; + } + + template + IConnection* ConnectMemberSmartCallback( + const char* callbackName, + typename SmartMemberConnection1::CbType callback, + ThisType* callee, + ArgType1* arg1) + { + Assert(m_object); + Assert(callee); + Assert(callbackName); + Assert(callback); + IConnection* connection = + new SmartMemberConnection1(callbackName, + callback, + callee, + arg1, + this); + m_connections.insert(connection); + connection->ConnectPrv(); + return connection; + } + + template + IConnection* ConnectEvasCallback(Evas_Callback_Type callbackType, + typename EvasConnection2:: + CbType callback, + ArgType1* arg1, + ArgType2* arg2) + { + Assert(m_object); + Assert(callbackType); + Assert(callback); + IConnection* connection = new EvasConnection2( + callbackType, + callback, + arg1, + arg2, + this); + m_connections.insert(connection); + connection->ConnectPrv(); + return connection; + } + + template + IConnection* ConnectEvasCallback( + Evas_Callback_Type callbackType, + typename EvasConnection1:: + CbType callback, + ArgType1* arg1) + { + Assert(m_object); + Assert(callbackType); + Assert(callback); + IConnection* connection = new EvasConnection1( + callbackType, + callback, + arg1, + this); + m_connections.insert(connection); + connection->ConnectPrv(); + return connection; + } + + template + IConnection* ConnectMemberEvasCallback( + Evas_Callback_Type callbackType, + typename EvasMemberConnection2::CbType callback, + ThisType* callee, + ArgType1* arg1, + ArgType2* arg2) + { + Assert(m_object); + Assert(callee); + Assert(callbackType); + Assert(callback); + IConnection* connection = + new EvasMemberConnection2( + callbackType, + callback, + callee, + arg1, + arg2, + this); + m_connections.insert(connection); + connection->ConnectPrv(); + return connection; + } + + template + IConnection* ConnectMemberEvasCallback( + Evas_Callback_Type callbackType, + typename EvasMemberConnection1::CbType callback, + ThisType* callee, + ArgType1* arg1) + { + Assert(m_object); + Assert(callee); + Assert(callbackType); + Assert(callback); + IConnection* connection = + new EvasMemberConnection1(callbackType, + callback, + callee, + arg1, + this); + m_connections.insert(connection); + connection->ConnectPrv(); + return connection; + } + + bool DisconnectCallback(IConnection* connection); + void DisconnectAll(); + + static void StaticOnDelEvent(void* data, + Evas* /*e*/, + Evas_Object* /*o*/, + void* /*ev*/); + + IConnectionsSet m_connections; + Evas_Object* m_object; + }; + + public: + EvasObject(); + explicit EvasObject(Evas_Object* object); + EvasObject(const EvasObject& other); + ~EvasObject(); + + EvasObject& operator=(const EvasObject& other); + EvasObject* operator=(Evas_Object* object); + + operator Evas_Object *(); + + bool IsValid() const + { + Assert(m_object); + return m_object->GetObject() != NULL; + } + + bool DisconnectCallback(IConnection* connection); + void DisconnectAll(); + + template + IConnection* ConnectSmartCallback( + const char* callbackName, + typename EvasObjectShared::SmartConnection::CbType + callback, + Args ... args) + { + Assert(m_object); + return m_object->ConnectSmartCallback(callbackName, callback, args ...); + } + + template + IConnection* ConnectMemberSmartCallback( + const char* callbackName, + typename EvasObjectShared::SmartMemberConnection2::CbType + callback, + ThisType* callee, + ArgType1* arg1, + ArgType2* arg2) + { + Assert(m_object); + Assert(callee); + Assert(callback); + return m_object->ConnectMemberSmartCallback(callbackName, + callback, + callee, + arg1, + arg2); + } + + template + IConnection* ConnectMemberSmartCallback( + const char* callbackName, + typename EvasObjectShared::SmartMemberConnection1::CbType + callback, + ThisType* callee, + ArgType1* arg1) + { + Assert(m_object); + Assert(callee); + Assert(callback); + return m_object->ConnectMemberSmartCallback(callbackName, + callback, + callee, + arg1); + } + + template + IConnection* ConnectEvasCallback( + Evas_Callback_Type callbackType, + typename EvasObjectShared::EvasConnection1::CbType + callback, + ArgType1* arg1, + ArgType2* arg2) + { + Assert(m_object); + return m_object->ConnectEvasCallback(callbackType, callback, arg1, arg2); + } + + template + IConnection* ConnectEvasCallback( + Evas_Callback_Type callbackType, + typename EvasObjectShared::EvasConnection1::CbType + callback, + ArgType1* arg1) + { + Assert(m_object); + return m_object->ConnectEvasCallback(callbackType, callback, arg1); + } + + template + IConnection* ConnectMemberEvasCallback( + Evas_Callback_Type callbackType, + typename EvasObjectShared::EvasMemberConnection1::CbType + callback, + ThisType* callee, + ArgType1* arg1) + { + Assert(m_object); + Assert(callee); + Assert(callback); + return m_object->ConnectMemberEvasCallback(callbackType, + callback, + callee, + arg1); + } + + template + IConnection* ConnectMemberEvasCallback( + Evas_Callback_Type callbackType, + typename EvasObjectShared::EvasMemberConnection2::CbType + callback, + ThisType* callee, + ArgType1* arg1, + ArgType2* arg2) + { + Assert(m_object); + Assert(callee); + Assert(callback); + return m_object->ConnectMemberEvasCallback(callbackType, + callback, + callee, + arg1, + arg2); + } + + private: + EvasObjectSharedPtr m_object; +}; + +#endif //WRT_SRC_DOMAIN_EFL_EVAS_OBJECT_H + diff --git a/src/view/common/message_support.h b/src/view/common/message_support.h new file mode 100644 index 0000000..a90108c --- /dev/null +++ b/src/view/common/message_support.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 message_support.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @author Yunchan Cho (yunchan.cho@samsung.com) + * @brief definition of messages between UI Process and Injected bundle + */ +#ifndef WRT_SRC_VIEW_COMMON_MESSAGE_SUPPORT_H_ +#define WRT_SRC_VIEW_COMMON_MESSAGE_SUPPORT_H_ + +namespace Message { + +namespace ToInjectedBundle { +const char * const INIT = "ToInjectedBundle::INIT"; +const char * const START = "ToInjectedBundle::START"; +const char * const SHUTDOWN = "ToInjectedBundle::SHUTDOWN"; +const char * const SET_CUSTOM_PROPERTIES = + "ToInjectedBundle::SET_CUSTOM_PROPERTIES"; +const char * const DISPATCH_JS_EVENT = "ToInjectedBundle::DISPATCH_JS_EVENT"; +const char * const SET_XWINDOW_HANDLE = "ToInjectedBundle::SET_XWINDOW_HANDLE"; +const char * const SET_VIEWMODES = "ToInjectedBundle::SET_VIEWMODES"; +const char * const SET_VIEWMODES_MSGBODY_EXIT = "exit"; +} // namespace ToInectedBundle + +namespace ToUIProcess { +const char * const BLOCKED_URL = "ToUIProcess::BLOCKED_URL"; +const char * const SEND_WEBPROCESS_PID = "ToUIProcess::SEND_WEBPROCESS_PID"; +} // namespace ToUIProcess + +namespace TizenScheme { +const char * const GET_WINDOW_HANDLE = "tizen://getWindowHandle"; +const char * const CLEAR_ALL_COOKIES = "tizen://clearAllCookies"; +} // namespace ToUIProcess + +} //namespace BundleMessages + +#endif // WRT_SRC_VIEW_COMMON_MESSAGE_SUPPORT_H_ diff --git a/src/view/common/scheme.cpp b/src/view/common/scheme.cpp new file mode 100644 index 0000000..1e255b1 --- /dev/null +++ b/src/view/common/scheme.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 scheme.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#include "scheme.h" +#include +#include +#include + +namespace ViewModule { +namespace { +const char * const type2name[Scheme::COUNT] = { + "file", + "sms", + "smsto", + "mmsto", + "mailto", + "data", + "tel", + "http", + "https", + "widget", +#if ENABLE(APP_SCHEME) + "app", +#endif + "rtsp", + "about" +}; + +typedef std::map SchemeMap; + +SchemeMap PopulateMap() +{ + LogDebug("Populating scheme map..."); + SchemeMap map; + for (size_t st = Scheme::FILE; st < Scheme::COUNT; ++st) { + LogDebug(" * " << type2name[st] << "->" << st); + map[type2name[st]] = static_cast(st); + } + return map; +} + +const SchemeMap name2type = PopulateMap(); +} // namespace + +Scheme::Scheme(const std::string& name) : m_name(name), m_type(INVALID) +{ + m_type = GetType(name); +} + +std::string Scheme::GetName (Type type) +{ + Assert(type >= FILE && type < COUNT); + return type2name[type]; +} + +Scheme::Type Scheme::GetType(const std::string& name) +{ + auto it = name2type.find(name); + if (it == name2type.end()) { + LogError("Invalid scheme: " << name); + return INVALID; + } + return it->second; +} +} /* namespace ViewModule */ diff --git a/src/view/common/scheme.h b/src/view/common/scheme.h new file mode 100644 index 0000000..4eed310 --- /dev/null +++ b/src/view/common/scheme.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 scheme.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#ifndef SCHEME_H_ +#define SCHEME_H_ + +#include + +#include + +namespace ViewModule { +class Scheme +{ + public: + enum Type { + INVALID = -1, + FILE = 0, + SMS, + SMSTO, + MMSTO, + MAILTO, + DATA, + TEL, + HTTP, + HTTPS, + WIDGET, +#if ENABLE(APP_SCHEME) + APP, +#endif + RTSP, + ABOUT, + + COUNT + }; + + explicit Scheme(const std::string& name); + virtual ~Scheme() {} + + std::string GetName() const + { + return m_name; + } + Type GetType() const + { + return m_type; + } + + static std::string GetName (Type type); + static std::string GetName (size_t type) + { + return GetName(static_cast(type)); + } + static Type GetType(const std::string& name); + + private: + std::string m_name; + Type m_type; +}; +} /* namespace ViewModule */ +#endif /* SCHEME_H_ */ diff --git a/src/view/common/scheme_action_map.cpp b/src/view/common/scheme_action_map.cpp new file mode 100644 index 0000000..bab49da --- /dev/null +++ b/src/view/common/scheme_action_map.cpp @@ -0,0 +1,416 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 scheme_action_map.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#include "scheme_action_map.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "scheme_action_map_data.h" + +namespace ViewModule { +namespace { +/* + * Lazy construction pattern. + * TODO Make it more general. Use variadic template/tuples/lambdas or sth. Move + * to DPL. + */ +template +class Lazy +{ + public: + explicit Lazy(const Arg1& arg1) : + m_arg1(arg1), + m_object(new std::unique_ptr()) + {} + Lazy(const Lazy& other) : + m_arg1(other.m_arg1), + m_object(other.m_object) + {} + + T& operator*() + { + return GetObject(); + } + const T& operator*() const + { + return GetObject(); + } + const T* operator->() const + { + return &GetObject(); + } + T* operator->() + { + return &GetObject(); + } + + Lazy& operator=(const Lazy& other) + { + m_arg1 = other.m_arg1; + m_object = other.m_object; + return *this; + } + + private: + T& GetObject() const + { + if (!(*m_object)) { + (*m_object).reset(new T(m_arg1)); + } + return **m_object; + } + + Arg1 m_arg1; + // single unique_ptr shared among many Lazy copies + mutable std::shared_ptr > m_object; +}; + +/* + * Struct defining conversion of scheme for given appsvc key for example: + * sms:5551212?body=expected%20text => APPSVC_DATA_TEXT + expected%20text + */ +struct AppSvcConversion { + AppSvcConversion(char const * const keyValue, + const std::string& regexStr) : + key(keyValue), + regex(regexStr) {} + char const * const key; + Lazy regex; +}; + +/* + * Struct defining an appsvc operation and a list of scheme conversions used to + * fill in additional appsvc data. + */ +struct ServiceOperation { + const char* operation; + const char* fakeUri; + const char* mime; + std::list conversions; +}; + +typedef std::map ServiceOperationMap; + +// Regular expressions used to extract appsvc data from scheme +// TODO what about multiple recipients? +char const * const REGEX_BODY = ".*[?&]body=([^&]+).*"; +char const * const REGEX_SMS = "sms:([^&]+).*"; +char const * const REGEX_SMSTO = "smsto:([^&]+).*"; +char const * const REGEX_MMSTO = "mmsto:([^&]+).*"; +char const * const REGEX_MAILTO = "mailto:([^&]+).*"; +char const * const REGEX_TO = ".*[?&]to=([^&]+).*"; +char const * const REGEX_CC = ".*[?&]cc=([^&]+).*"; +char const * const REGEX_BCC = ".*[?&]bcc=([^&]+).*"; +char const * const REGEX_SUBJECT = ".*[?&]subject=([^&]+).*"; +char const * const REGEX_DATA_CONTEXT = ".*;phone-context=([^:]+).*"; + +ServiceOperationMap initializeAppSvcOperations() +{ + ServiceOperationMap ret; + + // FILE, HTTP & HTTPS + ServiceOperation viewOp; + viewOp.operation = APP_CONTROL_OPERATION_VIEW; + viewOp.fakeUri = NULL; + viewOp.mime = NULL; + // no additional data + ret.insert(std::make_pair(Scheme::FILE, viewOp)); + ret.insert(std::make_pair(Scheme::HTTP, viewOp)); + ret.insert(std::make_pair(Scheme::HTTPS, viewOp)); + + // SMS + ServiceOperation smsOp; + smsOp.operation = APP_CONTROL_OPERATION_COMPOSE; + smsOp.fakeUri = NULL; + smsOp.mime = "*/*"; + smsOp.conversions.push_back(AppSvcConversion(APP_CONTROL_DATA_TO, REGEX_SMS)); + smsOp.conversions.push_back(AppSvcConversion(APP_CONTROL_DATA_TEXT, REGEX_BODY)); + ret.insert(std::make_pair(Scheme::SMS, smsOp)); + + // SMSTO + ServiceOperation smstoOp; + smstoOp.operation = APP_CONTROL_OPERATION_COMPOSE; + smstoOp.fakeUri = "sms"; + smstoOp.mime = "*/*"; + smstoOp.conversions.push_back(AppSvcConversion(APP_CONTROL_DATA_TO, REGEX_SMSTO)); + smstoOp.conversions.push_back(AppSvcConversion(APP_CONTROL_DATA_TEXT, REGEX_BODY)); + ret.insert(std::make_pair(Scheme::SMSTO, smstoOp)); + + + // MMSTO & MAILTO + ServiceOperation sendOp; + sendOp.operation = APP_CONTROL_OPERATION_COMPOSE; + sendOp.fakeUri = NULL; + sendOp.mime = NULL; + sendOp.conversions.push_back(AppSvcConversion(APP_CONTROL_DATA_TO, REGEX_MMSTO)); + sendOp.conversions.push_back(AppSvcConversion(APP_CONTROL_DATA_TO, REGEX_MAILTO)); + sendOp.conversions.push_back(AppSvcConversion(APP_CONTROL_DATA_CC, REGEX_CC)); + sendOp.conversions.push_back( + AppSvcConversion(APP_CONTROL_DATA_BCC, REGEX_BCC)); + sendOp.conversions.push_back( + AppSvcConversion(APP_CONTROL_DATA_SUBJECT, REGEX_SUBJECT)); + sendOp.conversions.push_back( + AppSvcConversion(APP_CONTROL_DATA_TEXT, REGEX_BODY)); + ret.insert(std::make_pair(Scheme::MAILTO, sendOp)); + sendOp.mime = "*/*"; + ret.insert(std::make_pair(Scheme::MMSTO, sendOp)); + + // TODO what about DATA? + + // TEL + ServiceOperation telOp; + telOp.operation = APP_CONTROL_OPERATION_CALL; + telOp.fakeUri = NULL; + telOp.mime = NULL; + ret.insert(std::make_pair(Scheme::TEL, telOp)); + + return ret; +} + +ServiceOperationMap g_serviceOperationMap = initializeAppSvcOperations(); + +void handleTizenServiceScheme(const char* uri) +{ + // Tizen Service + std::string parameter = std::string(uri); + std::string appId; + size_t start, end = 0; + + if (parameter.find("AppID=") != std::string::npos) { + start = parameter.find("AppID=") + strlen("AppID="); + end = parameter.find(";", start); + appId = parameter.substr(start, end-start); + } else { + LogError("parameter doesn't contain appID"); + return; + } + + app_control_h handle = NULL; + if (app_control_create(&handle) != APP_CONTROL_ERROR_NONE) { + LogError("Fail to create service handle"); + return; + } + + if (app_control_set_app_id(handle, appId.c_str()) < 0) { + LogError("Fail to service_set_app_id"); + app_control_destroy(handle); + return; + } + + const char* KEY_KEY = "key="; + const char* KEY_VALUE = "value="; + + char* buf = strdup(parameter.c_str()); + const char* ptr = strtok(buf,";"); + while (ptr != NULL) { + std::string string = ptr; + ptr = strtok (NULL, ";"); + + size_t devide = string.find(','); + if (devide == std::string::npos) { + continue; + } + size_t keyPos = string.find(KEY_KEY); + if (keyPos == std::string::npos) { + continue; + } + size_t valuePos = string.find(KEY_VALUE); + if (valuePos == std::string::npos) { + continue; + } + + std::string key = + string.substr(keyPos + std::string(KEY_KEY).size(), + devide - (keyPos + std::string(KEY_KEY).size())); + std::string value = + string.substr(valuePos + std::string(KEY_VALUE).size()); + + if (app_control_add_extra_data(handle, key.c_str(), value.c_str())) { + LogError("service_add_extra_data is failed."); + app_control_destroy(handle); + free(buf); + return; + } + } + free(buf); + + CONTROLLER_POST_EVENT( + ApplicationLauncher, + ApplicationLauncherEvents::LaunchApplicationByAppService( + handle, + NULL, + NULL)); +} + +void handleUnknownScheme(const char* scheme, const char* uri) +{ + LogError("Invalid scheme: " << scheme); + // case of unknown scheme, send to app-control + // This is temporary soultion. "invalid" scheme should be handled by + // scheme map data + + if (!strcmp(scheme, "tizen-service")) { + handleTizenServiceScheme(uri); + return; + } else { + // create app_control + app_control_h app_control = NULL; + if (APP_CONTROL_ERROR_NONE == app_control_create(&app_control)) { + app_control_set_operation(app_control, APP_CONTROL_OPERATION_VIEW); + app_control_set_uri(app_control, uri); + CONTROLLER_POST_EVENT( + ApplicationLauncher, + ApplicationLauncherEvents::LaunchApplicationByAppService( + app_control, + NULL, + NULL)); + } + } +} + + +} // namespace + +namespace SchemeActionMap { +bool HandleUri(const char* uri, NavigationContext context) +{ + if (!uri) { + LogError("wrong arguments passed"); + return false; + } + LogDebug("Uri being checked: " << uri); + + const char *end = strstr(uri, ":"); + if (!end) { + LogError("Lack of scheme - ignoring"); + return false; + } + std::string name(uri, end); + Scheme scheme(name); + LogDebug("Scheme: " << name); + + Scheme::Type type = scheme.GetType(); + if (type < Scheme::FILE || type >= Scheme::COUNT) { + LogError("Invalid scheme: " << name); + handleUnknownScheme(name.c_str(), uri); + return false; + } + + LogDebug("Scheme type: " << type); + LogDebug("Navigation context: " << context); + + UriAction action = g_tizenActionMap[type][context]; + + LogDebug("Uri action: " << action); + + // execute action if necessary + switch (action) { + case URI_ACTION_APPSVC: + { + // find AppSvcOperation for given scheme type + auto it = g_serviceOperationMap.find(type); + if (it == g_serviceOperationMap.end()) { + LogError("No entry for scheme: " << name); + return false; + } + + // prepare appsvc bundle + app_control_h app_control = NULL; + app_control_create(&app_control); + LogDebug("appsvc operation " << it->second.operation); + app_control_set_operation(app_control, it->second.operation); + if (it->second.fakeUri) { + size_t size = strlen(it->second.fakeUri) + strlen(uri) + 1; + char *newUri = new char[size]; + strcpy(newUri, it->second.fakeUri); + const char* uriArgs = strstr(uri, ":"); + strcpy(newUri + strlen(it->second.fakeUri), uriArgs); + app_control_set_uri(app_control, newUri); + delete [] newUri; + } + else { + app_control_set_uri(app_control, uri); + } + if (it->second.mime) { + app_control_set_mime(app_control, it->second.mime); + } + + // this is safe as there are no other threads + CURL* curl = curl_easy_init(); + // unescape the url + int outLength = 0; + char* unescaped = curl_easy_unescape(curl, uri, 0, &outLength); + if (unescaped == NULL) { + LogError("unescaped is null"); + app_control_destroy(app_control); + curl_easy_cleanup(curl); + return false; + } + std::string uUri(unescaped, outLength); + curl_free(unescaped); + curl_easy_cleanup(curl); + LogDebug("unescaped " << uUri); + + // setup additional appsvc data + FOREACH(cit, it->second.conversions) { + LogDebug("extracting data for key " << cit->key); + + std::string match; + pcrecpp::StringPiece input(uUri); + + // convert scheme text to appsvc format + while (cit->regex->Consume(&input, &match)) { + LogDebug("Adding apssvc data: " << cit->key << " " << match); + app_control_add_extra_data(app_control, cit->key, match.c_str()); + } + } + + // TODO do we need a callback? + CONTROLLER_POST_EVENT( + ApplicationLauncher, + ApplicationLauncherEvents::LaunchApplicationByAppService( + app_control, + NULL, + NULL)); + break; + } + + case URI_ACTION_VIDEO: + CONTROLLER_POST_EVENT( + ApplicationLauncher, + ApplicationLauncherEvents::LaunchApplicationByPkgname( + ApplicationLauncherPkgname::PKG_NAME_VIDEO_PLAYER, + name, + uri, + "null")); + break; + default: + break; + } + return (action == URI_ACTION_WRT); +} +} // namespace SchemeActionMap +} /* namespace ViewModule */ diff --git a/src/view/common/scheme_action_map.h b/src/view/common/scheme_action_map.h new file mode 100644 index 0000000..04973df --- /dev/null +++ b/src/view/common/scheme_action_map.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 scheme_action_map.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#ifndef SCHEME_ACTION_MAP_H_ +#define SCHEME_ACTION_MAP_H_ + +#include "scheme_action_map_type.h" + +namespace ViewModule { +namespace SchemeActionMap { +bool HandleUri(const char* uri, + NavigationContext context); +}; +} /* namespace ViewModule */ +#endif /* SCHEME_ACTION_MAP_H_ */ diff --git a/src/view/common/scheme_action_map_data.h b/src/view/common/scheme_action_map_data.h new file mode 100644 index 0000000..3abff0a --- /dev/null +++ b/src/view/common/scheme_action_map_data.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 scheme_action_map_data.h + * @author Tae-Jeong Lee (taejeong.lee@samsung.com) + * @version 1.0 + */ + +#include "scheme_action_map.h" + +#include + +#include + +namespace ViewModule { +namespace { +enum UriAction { + URI_ACTION_WRT, // load in WRT + URI_ACTION_APPSVC, // launch in APPSVC + URI_ACTION_VIDEO, // launch in VIDEO player + URI_ACTION_ERROR +}; + +/** + * WS-1501 - No top-level window navigation outside the widget. Deafult browser + * should be used instead. Frames/iframes are allowed to navigate. + * This requirement can't be applied to tizen hosted app as in its + * case the whole widget is "outside". + * + * WS-1502 - When calling window.open() with scheme HTTP/HTTPS and target + * attribute set to "_blank" WRT should open default browser. At the + * moment we can't distinguish target attributes, therefore all new + * windows are opened in the browser regardless of the attribute (the + * value "_new" is also treated this way). Tizen won't satisfy this + * requirement. It should open new windows in WRT. + * + * Video - YOUTUBE and RSTP are handled by video player. + * + * File scheme - FILE scheme has to be handled by WRT + * + * WS-1510/20/30/40/50 - All remaining cases are always handled by appsvc + */ + +// TIZEN +const UriAction g_tizenActionMap[Scheme::COUNT][SchemeActionMap::COUNT] = { + // TOP_LEVEL FRAME_LEVEL NEW_WINDOW + { URI_ACTION_WRT, URI_ACTION_WRT, URI_ACTION_WRT }, // FILE + { URI_ACTION_APPSVC, URI_ACTION_APPSVC, URI_ACTION_APPSVC }, // SMS + { URI_ACTION_APPSVC, URI_ACTION_APPSVC, URI_ACTION_APPSVC }, // SMSTO + { URI_ACTION_APPSVC, URI_ACTION_APPSVC, URI_ACTION_APPSVC }, // MMSTO + { URI_ACTION_APPSVC, URI_ACTION_APPSVC, URI_ACTION_APPSVC }, // MAILTO + { URI_ACTION_WRT, URI_ACTION_WRT, URI_ACTION_WRT }, // DATA + { URI_ACTION_APPSVC, URI_ACTION_APPSVC, URI_ACTION_APPSVC }, // TEL + { URI_ACTION_WRT, URI_ACTION_WRT, URI_ACTION_WRT }, // HTTP + { URI_ACTION_WRT, URI_ACTION_WRT, URI_ACTION_WRT }, // HTTPS + { URI_ACTION_WRT, URI_ACTION_WRT, URI_ACTION_WRT }, // WIDGET +#if ENABLE(APP_SCHEME) + { URI_ACTION_WRT, URI_ACTION_WRT, URI_ACTION_WRT }, // APP +#endif + { URI_ACTION_VIDEO, URI_ACTION_VIDEO, URI_ACTION_VIDEO } // RTSP +}; + +} +} diff --git a/src/view/common/scheme_action_map_type.h b/src/view/common/scheme_action_map_type.h new file mode 100644 index 0000000..334e01e --- /dev/null +++ b/src/view/common/scheme_action_map_type.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 scheme_action_map_type.h + * @author Tae-Jeong Lee (taejeong.lee@samsung.com) + * @version 1.0 + */ + +#ifndef SCHEME_ACTION_MAP_TYPE_H_ +#define SCHEME_ACTION_MAP_TYPE_H_ + +namespace ViewModule { +namespace SchemeActionMap { +enum NavigationContext { + TOP_LEVEL = 0, + FRAME_LEVEL, + NEW_WINDOW, + + COUNT +}; +} // namespace SchemeActionMap +} // namespace ViewModule +#endif /* SCHEME_ACTION_MAP_TYPE_H_ */ diff --git a/src/view/common/view_logic_apps_support.cpp b/src/view/common/view_logic_apps_support.cpp new file mode 100644 index 0000000..0af0083 --- /dev/null +++ b/src/view/common/view_logic_apps_support.cpp @@ -0,0 +1,402 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_apps_support.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @brief Implementation file of AppsSupport class used by ViewLogic + */ + +#include "view_logic_apps_support.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace ViewModule { +namespace { +const char* const SCHEME_TYPE_HTML5_VIDEO = "html5video"; +const char* const HTTP_STREAMING_MPEG_MIMETYPE = "application/x-mpegurl"; +const char* const HTTP_STREAMING_APPLE_MIMETYPE = + "application/vnd.apple.mpegurl"; +const char* const SCHEM_FILE = "file"; +const char* const DOWNLOAD_PATH = "/opt/usr/media/Downloads/"; +} + +//Implementation class +class AppsSupportImplementation +{ + private: + WidgetModel *m_widgetModel; + bool m_initialized; + int m_notiId; + + struct HTML5Video { + const char* path; + const char* cookie; + }; + + bool httpMultimediaRequest(std::string mimeType, std::string uri) + { + LogDebug("httpMultimediaRequest called"); + + if ("null" == mimeType || "null" == uri) { + LogError("uri/mimeType is null"); + return false; + } + + app_control_h app_control = NULL; + app_control_create(&app_control); + + // ignore case match of string of mime type + // if needed, define appsvc response callback + // and its user data per mimetype + if (!strcasecmp(mimeType.c_str(), HTTP_STREAMING_APPLE_MIMETYPE) || + !strcasecmp(mimeType.c_str(), HTTP_STREAMING_MPEG_MIMETYPE)) + { + app_control_set_operation(app_control, APP_CONTROL_OPERATION_VIEW); + app_control_set_mime(app_control, mimeType.c_str()); + app_control_set_uri(app_control, uri.c_str()); + } else { + LogDebug("Not Supported MIME type in WRT"); + app_control_destroy(app_control); + return false; + } + + CONTROLLER_POST_EVENT( + ApplicationLauncher, + ApplicationLauncherEvents::LaunchApplicationByAppService( + app_control, + NULL, + NULL)); + + return true; + } + + bool isFileExist(std::string path, bool isDirectory) + { + struct stat fileState; + if (stat(path.c_str(), &fileState) != 0) { + LogError("Fail to get file stat"); + return false; + } + + if (isDirectory && S_ISDIR(fileState.st_mode)) { + return true; + } + if (!isDirectory && S_ISREG(fileState.st_mode)) { + return true; + } + return false; + } + + bool copyFile(std::string file, std::string dest) + { + std::ifstream in (file); + if (in.is_open() == false) { + LogError("Fail to open input file"); + return false; + } + std::ofstream out(dest); + if (out.is_open() == false) { + LogError("Fail to open output file"); + return false; + } + out << in.rdbuf(); + out.close(); + in.close(); + + return true; + } + + void freeResource(notification_h n, bundle *b) + { + if (n) { + notification_free(n); + } + if (b) { + bundle_free(b); + } + return; + } + + int createCompleteNotification(std::string fileName, std::string filePath, std::string result) + { + // create notification + notification_h noti = NULL; + noti = notification_create(NOTIFICATION_TYPE_NOTI); + if (noti == NULL) { + LogError("Fail to notification_create"); + return -1; + } + + // set notification layout + int ret; + ret = notification_set_layout(noti, NOTIFICATION_LY_ONGOING_EVENT); + if (ret != NOTIFICATION_ERROR_NONE) { + LogError("Fail to notification_set_layout"); + freeResource(noti, NULL); + return -1; + } + + // set notification title text + ret = notification_set_text(noti, + NOTIFICATION_TEXT_TYPE_TITLE, + fileName.c_str(), + NULL, + NOTIFICATION_VARIABLE_TYPE_NONE); + if (ret != NOTIFICATION_ERROR_NONE) { + LogError("Fail to notification_set_text title"); + freeResource(noti, NULL); + return -1; + } + + // set notification content text + ret = notification_set_text(noti, + NOTIFICATION_TEXT_TYPE_CONTENT, + result.c_str(), + NULL, + NOTIFICATION_VARIABLE_TYPE_NONE); + if (ret != NOTIFICATION_ERROR_NONE) { + LogError("Fail to notification_set_text content"); + freeResource(noti, NULL); + return -1; + } + + // set bundle data + bundle *b = bundle_create(); + if (!b) { + LogError("Fail to bundle_create"); + freeResource(noti, NULL); + return -1; + } + if (appsvc_set_operation(b, APPSVC_OPERATION_VIEW) != APPSVC_RET_OK) { + LogError("Fail to appsvc_set_operation"); + freeResource(noti, b); + return -1; + } + if (appsvc_set_uri(b, filePath.c_str()) != APPSVC_RET_OK) { + LogError("Fail to appsvc_set_uri"); + freeResource(noti, b); + return -1; + } + + // set notification execute option + ret = notification_set_execute_option(noti, + NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, + "View", + NULL, + b); + if (ret != NOTIFICATION_ERROR_NONE) { + LogError("Fail to notification_set_execute_option"); + freeResource(noti, b); + return -1; + } + + int privId; + ret = notification_insert(noti, &privId); + if (ret != NOTIFICATION_ERROR_NONE) { + LogError("Fail to notification_insert"); + freeResource(noti, b); + return -1; + } + freeResource(noti, b); + return privId; + } + + void localUriRequest(std::string filePath) + { + LogDebug("file path = [" << filePath << "]"); + + // verify request file path + if (isFileExist(filePath, false) == false) { + LogError("Request file path isn't existed"); + return; + } + + // create destPath + if (isFileExist(DOWNLOAD_PATH, true) == false) { + LogError("Downloads directory isn't existed"); + return; + } + + // create destFileFullPath + std::string fileName = filePath.substr(filePath.rfind('/') + 1); + unsigned int renameSuffixNb = 0; + std::string destFileName = fileName; + while (isFileExist(DOWNLOAD_PATH + destFileName, false)) { + std::ostringstream suffixOstr; + suffixOstr.str(""); + suffixOstr << fileName << "_" << renameSuffixNb++; + + destFileName = fileName; + destFileName.insert(destFileName.find('.'), suffixOstr.str()); + } + std::string destFileFullPath = DOWNLOAD_PATH + destFileName; + + // copy + if (copyFile(filePath, destFileFullPath) == false) { + LogError("Fail to copy file"); + return; + } + m_notiId = createCompleteNotification(destFileName, + destFileFullPath, + "Download Complete"); + } + + public: + AppsSupportImplementation() : + m_widgetModel(NULL), + m_initialized(false) + {} + + ~AppsSupportImplementation() + { + AssertMsg(!m_initialized, + "AppsSupport has to be deinitialized prior destroying!"); + } + + void initialize(WidgetModel *widgetModel, unsigned windowHandle) + { + AssertMsg(!m_initialized, "Already initialized!"); + + LogDebug("Initializing Apps Support"); + AssertMsg(widgetModel, "Passed widgetModel is NULL!"); + m_widgetModel = widgetModel; + + ApplicationLauncherSingleton::Instance().Touch(); + ApplicationLauncherSingleton::Instance().setWidgetTizenId( + DPL::ToUTF8String(m_widgetModel->TizenId)); + ApplicationLauncherSingleton::Instance().setWindowHandle(windowHandle); + + LogDebug("Initialized"); + m_initialized = true; + } + + void deinitialize() + { + AssertMsg(m_initialized, "Not initialized!"); + LogDebug("Deinitialized"); + m_widgetModel = NULL; + m_initialized = false; + } + + void downloadRequest(const char *url, + const char *mimeType, + const char *userParam) + { + LogDebug("Download info : " << url << "(" << + mimeType << ", " << userParam << ")"); + + // separate local & host scheme + std::unique_ptr iri(iri_parse(url), iri_destroy); + if (!iri.get()) { + LogDebug("Fail to get iri"); + return; + } + if (!iri->scheme) { + LogError("Fail to get scheme"); + return; + } + if (std::string(iri->scheme) == SCHEM_FILE) { + LogDebug("copy to Download directory"); + if (!iri->path) { + LogError("file path is empty"); + return; + } + localUriRequest(iri->path); + return; + } + + // ignore case match of string of mime type + bool isAppServiceable = httpMultimediaRequest( + mimeType ? std::string(mimeType) : "null", + url ? std::string(url) : "null"); + + if (isAppServiceable) { + LogDebug("Application Service start"); + return; + } + + CONTROLLER_POST_EVENT( + ApplicationLauncher, + ApplicationLauncherEvents::LaunchApplicationByPkgname( + ApplicationLauncherPkgname::PKG_NAME_DOWNLOAD_PROVIDER, + url ? std::string(url) : "null", + mimeType && strlen(mimeType) != 0 ? mimeType : "null", + userParam && strlen(userParam) != 0 ? userParam : "null")); + } + + void html5VideoRequest(void* event_info) + { + LogDebug("html5VideoRequestCallback called"); + Assert(event_info); + HTML5Video* video = static_cast(event_info); + + LogDebug("video->path : " << video->path); + LogDebug("video->cookie : " << video->cookie); + if (NULL == video->path) { + LogError("path is null"); + return; + } + CONTROLLER_POST_EVENT( + ApplicationLauncher, + ApplicationLauncherEvents::LaunchApplicationByPkgname( + ApplicationLauncherPkgname::PKG_NAME_VIDEO_PLAYER, + SCHEME_TYPE_HTML5_VIDEO, + video->path ? video->path : "null", + video->cookie ? video->cookie : "null")); + } +}; + +AppsSupport::AppsSupport() : m_impl(new AppsSupportImplementation) +{} + +AppsSupport::~AppsSupport() +{} + +void AppsSupport::initialize(WidgetModel *widgetModel, unsigned windowHandle) +{ + m_impl->initialize(widgetModel, windowHandle); +} + +void AppsSupport::deinitialize() +{ + m_impl->deinitialize(); +} + +void AppsSupport::html5VideoRequest(void* event_info) +{ + m_impl->html5VideoRequest(event_info); +} + +void AppsSupport::downloadRequest(const char *url, + const char *mimeType, + const char *userParam) +{ + m_impl->downloadRequest(url, mimeType, userParam); +} +} //namespace diff --git a/src/view/common/view_logic_apps_support.h b/src/view/common/view_logic_apps_support.h new file mode 100644 index 0000000..505f3ac --- /dev/null +++ b/src/view/common/view_logic_apps_support.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_apps_support.h + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @brief Header file of AppsSupport class used by ViewLogic + */ + +#ifndef VIEW_LOGIC_APPS_SUPPORT_H_ +#define VIEW_LOGIC_APPS_SUPPORT_H_ + +#include +#include + +class WidgetModel; //Forward declaration + +namespace ViewModule { +class AppsSupportImplementation; //Forward declaration + +class AppsSupport +{ + public: + AppsSupport(); + virtual ~AppsSupport(); + + void initialize(WidgetModel *, unsigned); + void deinitialize(); + void html5VideoRequest(void* event_info); + void downloadRequest( + const char *url, + const char *mimeType, + const char *userParam); + + private: + std::unique_ptr m_impl; +}; +} //namespace + +#endif /* VIEW_LOGIC_APPS_SUPPORT_H_ */ diff --git a/src/view/common/view_logic_certificate_support.cpp b/src/view/common/view_logic_certificate_support.cpp new file mode 100644 index 0000000..8a520fe --- /dev/null +++ b/src/view/common/view_logic_certificate_support.cpp @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_certificate_origin_support.cpp + * @author Leerang Song (leerang.song@samsung.com) + * @version 1.0 + * @brief Support certificate dao + */ + +#include "view_logic_certificate_support.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ViewModule { +namespace { +const double MAX_POPUP_HEIGHT = 0.80; +const double MAX_SCROLLER_HEIGHT = 0.5; + +struct CallbackData { + Evas_Smart_Cb eaKeyCallback; +}; + +static void deleteCallback(void* data, Evas* e, Evas_Object* obj, void* eventInfo); +static void resizeCallback(void* data, Evas* e, Evas_Object* obj, void* eventInfo); + +static void deleteCallback(void* data, Evas* e, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + Assert(obj); + + DPL_UNUSED_PARAM(e); + DPL_UNUSED_PARAM(eventInfo); + + CallbackData* callbackData = static_cast(data); + if (callbackData) { + ea_object_event_callback_del(obj, EA_CALLBACK_BACK, callbackData->eaKeyCallback); + delete callbackData; + } + evas_object_event_callback_del(obj, EVAS_CALLBACK_RESIZE, resizeCallback); +} + +static void resizeCallback(void* data, Evas* e, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + Assert(obj); + + DPL_UNUSED_PARAM(data); + DPL_UNUSED_PARAM(e); + DPL_UNUSED_PARAM(eventInfo); + + Evas_Object* popup = obj; + int popupH; + evas_object_geometry_get(popup, 0, 0, 0, &popupH); + + Evas_Object* parent = PopupUtil::getParentWindow(popup); + int parentW, parentH; + evas_object_geometry_get(parent, 0, 0, &parentW, &parentH); + + // compare current popup height with screen height. + // To avoid popup is filled full screen, used magic number to be filled 80% of screen height. + // TODO: Automatically add scroller feature should implement in the elementary + double threshold = parentH * MAX_POPUP_HEIGHT; + double currentH = popupH; + if (threshold < currentH) { + _D("text is overflow popup height. add scroller"); + Evas_Object* layout = elm_object_content_get(obj); + Evas_Object* label = elm_object_part_content_get(layout, "elm.swallow.label"); + + Evas_Object* scroller = elm_scroller_add(layout); + elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_ON, ELM_SCROLLER_POLICY_AUTO); + evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_scroller_content_min_limit(scroller, EINA_TRUE, EINA_TRUE); + int scrollerHeight = parentW > parentH ? parentH : parentW; + evas_object_size_hint_max_set(scroller, -1, scrollerHeight * MAX_SCROLLER_HEIGHT); + + elm_object_part_content_unset(layout, "elm.swallow.label"); + elm_object_content_set(scroller, label); + elm_object_part_content_set(layout, "elm.swallow.label", scroller); + evas_object_show(layout); + } +} +} + +class CertificateSupportImplementation +{ + private: + WidgetModel* m_model; + CertificateDB::CertificateDAOPtr m_certificateDAO; + + public: + CertificateSupportImplementation(WidgetModel* widgetModel) : + m_model(NULL) + { + Assert(widgetModel); + m_model = widgetModel; + } + + ~CertificateSupportImplementation() + {} + + CertificateDB::CertificateDAO* getCertificateDAO(void) + { + Assert(m_model); + if (!m_certificateDAO) { + LogDebug("initialize CertificateDAO"); + m_certificateDAO = + CertificateDB::CertificateDAOPtr( + new CertificateDB::CertificateDAO(m_model->TzPkgId. + Get())); + // initialize certificate result data. Remove allow, deny for + m_certificateDAO->removeCertificateData( + CertificateDB::RESULT_ALLOW_ONCE); + m_certificateDAO->removeCertificateData( + CertificateDB::RESULT_DENY_ONCE); + } + return m_certificateDAO.get(); + } +}; + +CertificateSupport::CertificateSupport(WidgetModel* widgetModel) : + m_impl(new CertificateSupportImplementation(widgetModel)) +{} + +CertificateSupport::~CertificateSupport() +{} + +CertificateDB::CertificateDAO* CertificateSupport:: + getCertificateDAO(void) +{ + return m_impl->getCertificateDAO(); +} + +Evas_Object* CertificateSupportUtil::createPopup( + Evas_Object* window, + const char* bodyText, + const char* checkText, + Evas_Smart_Cb buttonCallback, + Evas_Smart_Cb keyCallback, + void* data) +{ + LogDebug("createPopup"); + + Evas_Object* parentWindow = PopupUtil::getParentWindow(window); + Evas_Object* popup = elm_popup_add(parentWindow); + + CallbackData* callbackData = NULL; + if (keyCallback) { + callbackData = new CallbackData; + callbackData->eaKeyCallback = keyCallback; + ea_object_event_callback_add(popup, EA_CALLBACK_BACK, keyCallback, data); + } + evas_object_event_callback_add(popup, EVAS_CALLBACK_DEL, deleteCallback, static_cast(callbackData)); + evas_object_event_callback_add(popup, EVAS_CALLBACK_RESIZE, resizeCallback, NULL); + + elm_object_style_set(popup, "popup/default"); + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(popup, EVAS_HINT_FILL, EVAS_HINT_FILL); + + Evas_Object* layout = elm_layout_add(popup); + elm_layout_file_set(layout, WRT_EDJ_PATH, "popupWithCheck"); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL); + + Evas_Object* label = elm_label_add(popup); + elm_label_line_wrap_set(label, ELM_WRAP_MIXED); + elm_object_text_set(label, bodyText); + evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + + Evas_Object* check = elm_check_add(layout); + elm_object_style_set(check, "multiline"); + elm_object_text_set(check, checkText); + + elm_object_part_content_set(layout, "elm.swallow.label", label); + elm_object_part_content_set(layout, "elm.swallow.checkbox", check); + elm_object_content_set(popup, layout); + + Evas_Object* btn1 = elm_button_add(popup); + elm_object_style_set(btn1, "popup"); + elm_object_text_set(btn1, WRT_OPT_DENY); + elm_object_part_content_set(popup, "button1", btn1); + evas_object_smart_callback_add(btn1, "clicked", buttonCallback, data); + Evas_Object* btn2 = elm_button_add(popup); + elm_object_style_set(btn2, "popup"); + elm_object_text_set(btn2, WRT_OPT_ALLOW); + elm_object_part_content_set(popup, "button2", btn2); + evas_object_smart_callback_add(btn2, "clicked", buttonCallback, data); + + return popup; +} + +Evas_Object* CertificateSupportUtil::getPopup(Evas_Object* button) +{ + Assert(button); + + Evas_Object* popup = button; + while (strcmp(elm_object_widget_type_get(popup), "elm_popup")) { + popup = elm_object_parent_widget_get(popup); + if (!popup) { + return NULL; + } + } + return popup; +} + +Evas_Object* CertificateSupportUtil::getCheck(Evas_Object* popup) +{ + Assert(popup); + if (strcmp(elm_object_widget_type_get(popup), "elm_popup")) { + return NULL; + } + Evas_Object* check = elm_object_part_content_get( + elm_object_content_get(popup), + "elm.swallow.checkbox"); + return check; +} + +CertificateDB::Result CertificateSupportUtil::getResult( + Evas_Object* button) +{ + using namespace CertificateDB; + + Assert(button); + // get popup evas_object + Evas_Object* popup = getPopup(button); + if (popup == NULL) { + return RESULT_UNKNOWN; + } + bool allow = !strcmp(WRT_OPT_ALLOW, elm_object_text_get(button)); + + // get check evas_object + Evas_Object* check = getCheck(popup); + if (check == NULL) { + return RESULT_UNKNOWN; + } + if (allow) { + return elm_check_state_get(check) ? RESULT_ALLOW_ALWAYS : + RESULT_ALLOW_ONCE; + } else { + return elm_check_state_get(check) ? RESULT_DENY_ALWAYS : + RESULT_DENY_ONCE; + } +} +} // namespace ViewModule diff --git a/src/view/common/view_logic_certificate_support.h b/src/view/common/view_logic_certificate_support.h new file mode 100644 index 0000000..15b541b --- /dev/null +++ b/src/view/common/view_logic_certificate_support.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_certificate_origin_support.h + * @author Leerang Song (leerang.song@samsung.com) + * @version 1.0 + * @brief Header file for certificate + */ + +#ifndef VIEW_LOGIC_CERTIFICATE_SUPPORT_H_ +#define VIEW_LOGIC_CERTIFICATE_SUPPORT_H_ + +#include +#include +#include +#include +#include + +class WidgetModel; +namespace CertificateDB { +class CertificateDAO; +} + +namespace ViewModule { +class CertificateSupportImplementation; + +class CertificateSupport +{ + public: + CertificateSupport(WidgetModel* widgetModel); + virtual ~CertificateSupport(); + CertificateDB::CertificateDAO* getCertificateDAO(); + + private: + std::unique_ptr m_impl; +}; + +namespace CertificateSupportUtil { +class PermissionData +{ + public: + CertificateDB::CertificateDAO* m_certiDao; + CertificateDB::CertificateData m_certiData; + void* m_data; + + PermissionData( + CertificateDB::CertificateDAO* certiDao, + CertificateDB::CertificateData certiData, + void* data) : + m_certiDao(certiDao), + m_certiData(certiData), + m_data(data) + {} +}; + +Evas_Object* createPopup(Evas_Object* window, + const char* bodyText, + const char* checkText, + Evas_Smart_Cb buttonCallback, + Evas_Smart_Cb keyCallback, + void* data); +Evas_Object* getPopup(Evas_Object* button); +Evas_Object* getCheck(Evas_Object* popup); +CertificateDB::Result getResult(Evas_Object* button); +}; +} // namespace ViewModule + +#endif // VIEW_LOGIC_CERTIFICATE_SUPPORT_H_ \ No newline at end of file diff --git a/src/view/common/view_logic_custom_header_support.cpp b/src/view/common/view_logic_custom_header_support.cpp new file mode 100644 index 0000000..8c648c6 --- /dev/null +++ b/src/view/common/view_logic_custom_header_support.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_custom_header_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @brief Implementation file of CustomHeaderSupport API used by ViewLogic + */ + +#include "view_logic_custom_header_support.h" + +#include +#include + +#include +#include + +namespace { +const std::string LANGUAGE_EN = "en"; +}; + +namespace ViewModule { +namespace CustomHeaderSupport { +std::string getValueByField(const std::string &field) +{ + LogDebug("Field : " << field); + std::string ret; + + if (field == ACCEPT_LANGUAGE) { + char *systemLanguageSet = NULL; + systemLanguageSet = vconf_get_str(VCONFKEY_LANGSET); + if (systemLanguageSet != NULL) + LogDebug("system language = [" << systemLanguageSet << "]"); + + if (!systemLanguageSet) { + LogError("Failed to get VCONFKEY_LANGSET. set as English"); + ret.append(LANGUAGE_EN); + } else { + // copy first 2bytes of language set (en, ko, po) + ret.append(systemLanguageSet, 2); + } + + if (systemLanguageSet) { + free(systemLanguageSet); + } + } else { + LogError("Wrong field is passed"); + Assert(false); + } + + return ret; +} +} // namespace CustomHeaderSupport +} // namespace ViewModule diff --git a/src/view/common/view_logic_custom_header_support.h b/src/view/common/view_logic_custom_header_support.h new file mode 100644 index 0000000..99ab3e9 --- /dev/null +++ b/src/view/common/view_logic_custom_header_support.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_custom_header_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @brief Header file of CustomHeaderSupport API used by ViewLogic + */ + +#ifndef VIEW_LOGIC_CUSTOM_HEADER_SUPPORT_H_ +#define VIEW_LOGIC_CUSTOM_HEADER_SUPPORT_H_ + +#include + +namespace ViewModule { +namespace CustomHeaderSupport { +const std::string ACCEPT_LANGUAGE = "Accept-Language"; + +std::string getValueByField(const std::string &field); +} // namespace UserAgentSupport +} // namespace CustomHeaderSupport + +#endif /* VIEW_LOGIC_CUSTOM_HEADER_SUPPORT_H_ */ diff --git a/src/view/common/view_logic_get_parent_window_util.h b/src/view/common/view_logic_get_parent_window_util.h new file mode 100644 index 0000000..8dc2707 --- /dev/null +++ b/src/view/common/view_logic_get_parent_window_util.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_get_parent_window_util.h + * @author Tae-Jeong Lee (taejeong.lee@samsung.com) + */ + +#ifndef VIEW_LOGIC_GET_PARENT_WINDOW_UTIL_H_ +#define VIEW_LOGIC_GET_PARENT_WINDOW_UTIL_H_ + +#include +#include + +namespace ViewModule { +namespace PopupUtil { + +static Evas_Object* getParentWindow(Evas_Object* object) +{ + Evas_Object* parent = elm_object_parent_widget_get(object); + Evas_Object* win = parent; + + while (parent) { + const char* type = elm_object_widget_type_get(parent); + if (type) { + if (!strncmp(type, "elm_win", strlen("elm_win"))) { + win = parent; + break; + } + } + parent = elm_object_parent_widget_get(parent); + } + + if (!win) + { + LogError("Parent window was not found!"); + win = object; + } + + return win; +} + +} //namespace ViewModule +} //namespace PopupUtil +#endif //VIEW_LOGIC_GET_PARENT_WINDOW_UTIL_H_ diff --git a/src/view/common/view_logic_help_popup_support.cpp b/src/view/common/view_logic_help_popup_support.cpp new file mode 100644 index 0000000..5f4299e --- /dev/null +++ b/src/view/common/view_logic_help_popup_support.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_help_popup_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + */ + +#include "view_logic_help_popup_support.h" + +#include +#include +#include +#include +#include + +#include +#include + +namespace ViewModule { +namespace { +Evas_Object* getPopup(Evas_Object* object); +static void buttonClickedCallback(void* data, Evas_Object* obj, void* eventInfo); + +Evas_Object* getPopup(Evas_Object* object) +{ + Assert(object); + + Evas_Object* popup = object; + while (strcmp(elm_object_widget_type_get(popup), "elm_popup")) { + popup = elm_object_parent_widget_get(popup); + if (!popup) { + return NULL; + } + } + return popup; +} + +static void buttonClickedCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + Assert(obj); + + DPL_UNUSED_PARAM(data); + DPL_UNUSED_PARAM(eventInfo); + + Evas_Object* popup = getPopup(obj); + if (!popup) { + _W("Fail to get popup object"); + return; + } + evas_object_hide(popup); + evas_object_del(popup); +} +} // namespace anonymous + +void HelpPopupSupport::showClearDefaultPopup(Evas_Object* object) +{ + _D("called"); + + Assert(object); + + // create popup + Evas_Object* parentWindow = PopupUtil::getParentWindow(object); + Evas_Object* popup = elm_popup_add(parentWindow); + elm_object_text_set(popup, WRT_POP_CLEAR_DEFAULT_SETTINGS); + ea_object_event_callback_add(popup, EA_CALLBACK_BACK, ea_popup_back_cb, NULL); + + // create button + Evas_Object* button = elm_button_add(popup); + elm_object_style_set(button, "popup"); + elm_object_text_set(button, WRT_SK_OK); + elm_object_part_content_set(popup, "button1", button); + evas_object_smart_callback_add(button, "clicked", buttonClickedCallback, NULL); + + evas_object_show(popup); +} +} // namespace ViewModule diff --git a/src/view/common/view_logic_help_popup_support.h b/src/view/common/view_logic_help_popup_support.h new file mode 100644 index 0000000..1abbaa9 --- /dev/null +++ b/src/view/common/view_logic_help_popup_support.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_help_popup_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ + +#ifndef VIEW_LOGIC_HELP_POPUP_SUPPORT_H_ +#define VIEW_LOGIC_HELP_POPUP_SUPPORT_H_ + +#include + +namespace ViewModule { +namespace HelpPopupSupport { + +void showClearDefaultPopup(Evas_Object* object); + +} //namespace HelpPopupSupport +} //namespace ViewModule +#endif //VIEW_LOGIC_HELP_POPUP_SUPPORT_H_ \ No newline at end of file diff --git a/src/view/common/view_logic_privilege_support.cpp b/src/view/common/view_logic_privilege_support.cpp new file mode 100644 index 0000000..16043fd --- /dev/null +++ b/src/view/common/view_logic_privilege_support.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_privilege_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ + +#include "view_logic_privilege_support.h" + +#include +#include + +#include +#include +#include +#include + +namespace ViewModule { +namespace { +const std::map privilegeTextMap = { + {PrivilegeSupport::Privilege::CAMERA, "http://tizen.org/privilege/camera"}, + {PrivilegeSupport::Privilege::LOCATION, "http://tizen.org/privilege/location"}, + {PrivilegeSupport::Privilege::MEDIACAPTURE, "http://tizen.org/privilege/mediacapture"}, + {PrivilegeSupport::Privilege::RECORDER, "http://tizen.org/privilege/recorder"} +}; +} + +//Implementation class +class PrivilegeSupportImplementation +{ + private: + WidgetModel* m_model; + bool m_isLegacyPolicy; + std::map m_cacheResult; + + void initializePrivilegePolicy(void) + { + Assert(m_model); + + DPL::OptionalString requiredVersionString = m_model->RequiredVersion.Get(); + if (!requiredVersionString) { + // tizen required_version is mandatory element + Assert(false && "Required version is empty"); + } + + double requiredVersion = atof(DPL::ToUTF8String(*requiredVersionString).c_str()); + + if (requiredVersion < 2.3) { + // tizen v1.0 ~ v2.2 + m_isLegacyPolicy = true; + } else { + // tizen v2.3 ~ + m_isLegacyPolicy = false; + } + } + + bool isCached(PrivilegeSupport::Privilege priv) + { + return m_cacheResult.find(priv) != m_cacheResult.end(); + } + + void setCache(PrivilegeSupport::Privilege priv, DPL::OptionalBool result) + { + m_cacheResult[priv] = result; + } + + DPL::OptionalBool getCache(PrivilegeSupport::Privilege priv) + { + return m_cacheResult[priv]; + } + + bool searchPrivilege(PrivilegeSupport::Privilege priv) + { + std::string target = privilegeTextMap.find(priv)->second; + WrtDB::PrivilegeList list = m_model->WidgetPrivilegeList.Get(); + FOREACH(it, list) { + if (target == DPL::ToUTF8String(*it)) { + return true; + } + } + return false; + } + + + public: + PrivilegeSupportImplementation(WidgetModel* model) : + m_model(model), + m_isLegacyPolicy(false) + { + // Distribute required version + initializePrivilegePolicy(); + } + + ~PrivilegeSupportImplementation() + { + } + + DPL::OptionalBool getPrivilegeStatus(PrivilegeSupport::Privilege priv) + { + // ALLOW : return true + // DENY : return false + // ASK : return empty + DPL::OptionalBool ret; + + if (m_isLegacyPolicy) { + return ret; + } + + if (isCached(priv)) { + return getCache(priv); + } + + if (searchPrivilege(priv)) { + setCache(priv, ret); + return ret; + } + + ret = false; + setCache(priv, ret); + return ret; + } +}; + +PrivilegeSupport::PrivilegeSupport(WidgetModel* model) : m_impl(new PrivilegeSupportImplementation(model)) +{ +} + +PrivilegeSupport::~PrivilegeSupport() +{ +} + +DPL::OptionalBool PrivilegeSupport::getPrivilegeStatus(PrivilegeSupport::Privilege priv) +{ + return m_impl->getPrivilegeStatus(priv); +} + +} //namespace ViewModule diff --git a/src/view/common/view_logic_privilege_support.h b/src/view/common/view_logic_privilege_support.h new file mode 100644 index 0000000..8f2e6c7 --- /dev/null +++ b/src/view/common/view_logic_privilege_support.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_privilege_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ + +#ifndef VIEW_LOGIC_PRIVILEGE_SUPPORT_H_ +#define VIEW_LOGIC_PRIVILEGE_SUPPORT_H_ + +#include + +#include + +//Forward declaration +class WidgetModel; + +namespace ViewModule { +//Forward declaration +class PrivilegeSupportImplementation; + +class PrivilegeSupport +{ + public: + enum class Privilege { + CAMERA, // http://tizen.org/privilege/camera + LOCATION, // http://tizen.org/privilege/location + MEDIACAPTURE, // http://tizen.org/privilege/mediacapture + RECORDER // http://tizen.org/privilege/recorder + }; + + PrivilegeSupport(WidgetModel* model); + virtual ~PrivilegeSupport(); + + DPL::OptionalBool getPrivilegeStatus(Privilege pri); + + private: + std::unique_ptr m_impl; +}; + +} // namespace ViewModule + +#endif // VIEW_LOGIC_PRIVILEGE_SUPPORT_H_ diff --git a/src/view/common/view_logic_security_origin_support.cpp b/src/view/common/view_logic_security_origin_support.cpp new file mode 100644 index 0000000..d253c99 --- /dev/null +++ b/src/view/common/view_logic_security_origin_support.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_security_origin_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + * @brief Support security origin dao + */ + +#include "view_logic_security_origin_support.h" + +#include +#include +#include +#include +#include + +namespace ViewModule { + + class SecurityOriginSupportImplementation +{ + private: + WidgetModel* m_model; + SecurityOriginDB::SecurityOriginDAOPtr m_securityOriginDAO; + + public: + SecurityOriginSupportImplementation(WidgetModel* widgetModel) : + m_model(NULL) + { + Assert(widgetModel); + m_model = widgetModel; + } + + ~SecurityOriginSupportImplementation() + {} + + SecurityOriginDB::SecurityOriginDAO* getSecurityOriginDAO(void) + { + Assert(m_model); + if (!m_securityOriginDAO) { + _D("initialize securityOriginDAO"); + m_securityOriginDAO = + SecurityOriginDB::SecurityOriginDAOPtr( + new SecurityOriginDB::SecurityOriginDAO(m_model->TzPkgId. + Get())); + // initialize security result data. Remove allow, deny for + m_securityOriginDAO->removeSecurityOriginData( + SecurityOriginDB::RESULT_ALLOW_ONCE); + m_securityOriginDAO->removeSecurityOriginData( + SecurityOriginDB::RESULT_DENY_ONCE); + } + return m_securityOriginDAO.get(); + } +}; + +SecurityOriginSupport::SecurityOriginSupport(WidgetModel* widgetModel) : + m_impl(new SecurityOriginSupportImplementation(widgetModel)) +{} + +SecurityOriginSupport::~SecurityOriginSupport() +{} + +SecurityOriginDB::SecurityOriginDAO* SecurityOriginSupport:: + getSecurityOriginDAO(void) +{ + return m_impl->getSecurityOriginDAO(); +} + +} // namespace ViewModule diff --git a/src/view/common/view_logic_security_origin_support.h b/src/view/common/view_logic_security_origin_support.h new file mode 100755 index 0000000..f658b81 --- /dev/null +++ b/src/view/common/view_logic_security_origin_support.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_security_origin_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + * @brief Header file for security origin + */ + +#ifndef VIEW_LOGIC_SECURITY_ORIGIN_SUPPORT_H_ +#define VIEW_LOGIC_SECURITY_ORIGIN_SUPPORT_H_ + +#include + +class WidgetModel; +namespace SecurityOriginDB { +class SecurityOriginDAO; +} + +namespace ViewModule { +class SecurityOriginSupportImplementation; + +class SecurityOriginSupport +{ + public: + SecurityOriginSupport(WidgetModel* widgetModel); + virtual ~SecurityOriginSupport(); + SecurityOriginDB::SecurityOriginDAO* getSecurityOriginDAO(); + + private: + std::unique_ptr m_impl; +}; + +} // namespace ViewModule + +#endif // VIEW_LOGIC_SECURITY_ORIGIN_SUPPORT_H_ diff --git a/src/view/common/view_logic_security_origin_support_util.cpp b/src/view/common/view_logic_security_origin_support_util.cpp new file mode 100644 index 0000000..564d283 --- /dev/null +++ b/src/view/common/view_logic_security_origin_support_util.cpp @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_security_origin_support_util.cpp + * @author Adam Banasiak (a.banasiak@samsung.com) + * @version 1.0 + * @brief Support security origin utility + */ + +#include "view_logic_security_origin_support_util.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ViewModule { + +namespace { +const double MAX_POPUP_HEIGHT = 0.80; +const double MAX_SCROLLER_HEIGHT = 0.5; + +struct CallbackData { + Evas_Smart_Cb eaKeyCallback; +}; + +static void resizeCallback(void* data, Evas* e, Evas_Object* obj, void* eventInfo); + +static void deleteCallback(void* data, Evas* e, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + DPL_UNUSED_PARAM(e); + DPL_UNUSED_PARAM(eventInfo); + + CallbackData* callbackData = static_cast(data); + Assert(obj); + if (callbackData) { + ea_object_event_callback_del(obj, EA_CALLBACK_BACK, callbackData->eaKeyCallback); + delete callbackData; + } + evas_object_event_callback_del(obj, EVAS_CALLBACK_RESIZE, resizeCallback); +} +static void resizeCallback(void* data, Evas* e, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + DPL_UNUSED_PARAM(data); + DPL_UNUSED_PARAM(e); + DPL_UNUSED_PARAM(eventInfo); + + Assert(obj); + Evas_Object* popup = obj; + int popupH; + evas_object_geometry_get(popup, 0, 0, 0, &popupH); + + Evas_Object* parent = PopupUtil::getParentWindow(popup); + int parentW, parentH; + evas_object_geometry_get(parent, 0, 0, &parentW, &parentH); + + // compare current popup height with screen height. + // To avoid popup is filled full screen, used magic number to be filled 80% of screen height. + // TODO: Automatically add scroller feature should implement in the elementary + double threshold = parentH * MAX_POPUP_HEIGHT; + double currentH = popupH; + if (threshold < currentH) { + _D("text is overflow popup height. add scroller"); + Evas_Object* layout = elm_object_content_get(obj); + Evas_Object* label = elm_object_part_content_get(layout, "elm.swallow.label"); + + Evas_Object* scroller = elm_scroller_add(layout); + elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_ON, ELM_SCROLLER_POLICY_AUTO); + evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_scroller_content_min_limit(scroller, EINA_TRUE, EINA_TRUE); + int scrollerHeight = parentW > parentH ? parentH : parentW; + evas_object_size_hint_max_set(scroller, -1, scrollerHeight * MAX_SCROLLER_HEIGHT); + + elm_object_part_content_unset(layout, "elm.swallow.label"); + elm_object_content_set(scroller, label); + elm_object_part_content_set(layout, "elm.swallow.label", scroller); + evas_object_show(layout); + } +} +} // anonymous namespace + +Evas_Object* SecurityOriginSupportUtil::createPopup( + Evas_Object* window, + const char* bodyText, + const char* checkText, + Evas_Smart_Cb buttonCallback, + Evas_Smart_Cb keyCallback, + void* data) +{ + _D("createPopup"); + Evas_Object* parentWindow = PopupUtil::getParentWindow(window); + Evas_Object* popup = elm_popup_add(parentWindow); + + CallbackData* callbackData = NULL; + if (keyCallback) { + callbackData = new CallbackData; + callbackData->eaKeyCallback = keyCallback; + ea_object_event_callback_add(popup, EA_CALLBACK_BACK, keyCallback, data); + } + evas_object_event_callback_add(popup, EVAS_CALLBACK_DEL, deleteCallback, static_cast(callbackData)); + evas_object_event_callback_add(popup, EVAS_CALLBACK_RESIZE, resizeCallback, NULL); + + // elm_object_style_set(popup, "popup/default"); + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(popup, EVAS_HINT_FILL, EVAS_HINT_FILL); + + Evas_Object* layout = elm_layout_add(popup); + elm_layout_file_set(layout, WRT_EDJ_PATH, "popupWithCheck"); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL); + + Evas_Object* label = elm_label_add(popup); + elm_label_line_wrap_set(label, ELM_WRAP_WORD); + elm_object_text_set(label, bodyText); + evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + + Evas_Object* check = elm_check_add(layout); + elm_object_style_set(check, "multiline"); + elm_object_text_set(check, checkText); + + elm_object_part_content_set(layout, "elm.swallow.label", label); + elm_object_part_content_set(layout, "elm.swallow.checkbox", check); + elm_object_content_set(popup, layout); + + Evas_Object* btn1 = elm_button_add(popup); + elm_object_style_set(btn1, "popup"); + elm_object_text_set(btn1, WRT_OPT_DENY); + elm_object_part_content_set(popup, "button1", btn1); + evas_object_smart_callback_add(btn1, "clicked", buttonCallback, data); + + Evas_Object* btn2 = elm_button_add(popup); + elm_object_style_set(btn2, "popup"); + elm_object_text_set(btn2, WRT_OPT_ALLOW); + elm_object_part_content_set(popup, "button2", btn2); + evas_object_smart_callback_add(btn2, "clicked", buttonCallback, data); + + return popup; +} + +Evas_Object* SecurityOriginSupportUtil::getPopup(Evas_Object* button) +{ + Assert(button); + + Evas_Object* popup = button; + while (strcmp(elm_object_widget_type_get(popup), "elm_popup")) { + popup = elm_object_parent_widget_get(popup); + if (!popup) { + return NULL; + } + } + return popup; +} + +Evas_Object* SecurityOriginSupportUtil::getCheck(Evas_Object* popup) +{ + Assert(popup); + if (strcmp(elm_object_widget_type_get(popup), "elm_popup")) { + return NULL; + } + Evas_Object* check = elm_object_part_content_get( + elm_object_content_get(popup), + "elm.swallow.checkbox"); + return check; +} + +SecurityOriginDB::Result SecurityOriginSupportUtil::getResult( + Evas_Object* button) +{ + using namespace SecurityOriginDB; + + Assert(button); + // get popup evas_object + Evas_Object* popup = getPopup(button); + if (popup == NULL) { + return RESULT_UNKNOWN; + } + bool allow = !strcmp(WRT_OPT_ALLOW, elm_object_text_get(button)); + + // get check evas_object + Evas_Object* check = getCheck(popup); + if (check == NULL) { + return RESULT_UNKNOWN; + } + if (allow) { + return elm_check_state_get(check) ? RESULT_ALLOW_ALWAYS : + RESULT_ALLOW_ONCE; + } else { + return elm_check_state_get(check) ? RESULT_DENY_ALWAYS : + RESULT_DENY_ONCE; + } +} + +bool SecurityOriginSupportUtil::isNeedHelpPopup(Evas_Object* popup) +{ + Assert(popup); + + if (strcmp(elm_object_widget_type_get(popup), "elm_popup")) { + return false; + } + Evas_Object* check = getCheck(popup); + if (check && elm_check_state_get(check)) { + return true; + } + return false; +} + +} // namespace ViewModule diff --git a/src/view/common/view_logic_security_origin_support_util.h b/src/view/common/view_logic_security_origin_support_util.h new file mode 100644 index 0000000..2b39072 --- /dev/null +++ b/src/view/common/view_logic_security_origin_support_util.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_security_origin_support_util.h + * @author Adam Banasiak (a.banasiak@samsung.com) + * @version 1.0 + * @brief Header file for security origin utility + */ + +#ifndef VIEW_LOGIC_SECURITY_ORIGIN_SUPPORT_UTILITY_H +#define VIEW_LOGIC_SECURITY_ORIGIN_SUPPORT_UTILITY_H + +#include +#include +#include + +namespace ViewModule { +namespace SecurityOriginSupportUtil { +class PermissionData +{ + public: + SecurityOriginDB::SecurityOriginDAO* m_originDao; + SecurityOriginDB::SecurityOriginData m_originData; + void* m_data; + DPL::String m_pkgId; + + PermissionData( + SecurityOriginDB::SecurityOriginDAO* originDao, + SecurityOriginDB::SecurityOriginData originData, + void* data) : + m_originDao(originDao), + m_originData(originData), + m_data(data) + {} + + PermissionData( + SecurityOriginDB::SecurityOriginDAO* originDao, + SecurityOriginDB::SecurityOriginData originData, + void* data, + DPL::String& pkgId): + m_originDao(originDao), + m_originData(originData), + m_data(data), + m_pkgId(pkgId) + {} +}; + +Evas_Object* createPopup(Evas_Object* window, + const char* bodyText, + const char* checkText, + Evas_Smart_Cb buttonCallback, + Evas_Smart_Cb keyCallback, + void* data); +Evas_Object* getPopup(Evas_Object* button); +Evas_Object* getCheck(Evas_Object* popup); +SecurityOriginDB::Result getResult(Evas_Object* button); +bool isNeedHelpPopup(Evas_Object* popup); +} // namespace SecurityOriginSupportUtil +} // namespace ViewModule + + +#endif /* VIEW_LOGIC_SECURITY_ORIGIN_SUPPORT_UTILITY_H */ + diff --git a/src/view/common/view_logic_security_support.cpp b/src/view/common/view_logic_security_support.cpp new file mode 100644 index 0000000..abd1c38 --- /dev/null +++ b/src/view/common/view_logic_security_support.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_keys_support.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @brief Implementation file of SecuritySupport API used by ViewLogic + */ + +#include "view_logic_security_support.h" +#include +#include +#include +#include +#include +#include +#include + +namespace ViewModule { +namespace SecuritySupport { +namespace { +const char *GEOLOCATION_DEV_CAP = "geolocation.position"; +const char *GEOLOCATION_PARAM_NAME = "param:enableHighAccuracy"; +const char *GEOLOCATION_PARAM_VALUE = "true"; + +bool simpleAceCheck( + const DPL::String& tizenId, + const char *devCap, + const char *paramName, + const char *paramValue) +{ + WrtDB::WidgetDAOReadOnly dao(tizenId); + ace_request_t aceRequest; + aceRequest.widget_handle = dao.getHandle(); + aceRequest.session_id = const_cast(""); + aceRequest.feature_list.count = 0; + aceRequest.dev_cap_list.count = 1; + aceRequest.dev_cap_list.items = new ace_dev_cap_t[1]; + aceRequest.dev_cap_list.items[0].name = + const_cast(devCap); + + aceRequest.dev_cap_list.items[0].param_list.count = paramName ? 1 : 0; + aceRequest.dev_cap_list.items[0].param_list.items = NULL; + + if (paramName) { + aceRequest.dev_cap_list.items[0].param_list.items = new ace_param_t[1]; + aceRequest.dev_cap_list.items[0].param_list.items[0].name = + const_cast(paramName); + aceRequest.dev_cap_list.items[0].param_list.items[0].value = + const_cast(paramValue); + } + + LogDebug("Making ace check with new C-API"); + ace_check_result_t result = ACE_PRIVILEGE_DENIED; + ace_return_t ret = ace_check_access_ex(&aceRequest, &result); + + LogDebug("Result is: " << static_cast(result)); + + delete[] aceRequest.dev_cap_list.items[0].param_list.items; + delete[] aceRequest.dev_cap_list.items; + + return ACE_OK == ret && ACE_ACCESS_GRANTED == result; +} +} //TODO copied from view_logic.cpp + +bool geolocationACECheck(const DPL::String& tizenId, bool highAccuracy) +{ + const char *paramName = NULL; + const char *paramValue = NULL; + if (highAccuracy) { + paramName = GEOLOCATION_PARAM_NAME; + paramValue = GEOLOCATION_PARAM_VALUE; + } + return simpleAceCheck( + tizenId, + GEOLOCATION_DEV_CAP, + paramName, + paramValue); +} +} // namespace SecuritySupport +} //namespace ViewModule diff --git a/src/view/common/view_logic_security_support.h b/src/view/common/view_logic_security_support.h new file mode 100644 index 0000000..bcf0e66 --- /dev/null +++ b/src/view/common/view_logic_security_support.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_security_support.h + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @brief Header file of SecuritySupport API used by ViewLogic + */ + +#ifndef VIEW_LOGIC_SECURITY_SUPPORT_H_ +#define VIEW_LOGIC_SECURITY_SUPPORT_H_ + +#include +#include + +//Forward declaration +class WidgetModel; + +namespace ViewModule { +namespace SecuritySupport { +char const * const PARAM_URL = "param:url"; +bool geolocationACECheck(const DPL::String& tizenId, bool highAccuracy); +} // namespace SecuritySupport +} // namespace ViewModule + +#endif /* VIEW_LOGIC_SECURITY_SUPPORT_H_ */ diff --git a/src/view/common/view_logic_storage_support.cpp b/src/view/common/view_logic_storage_support.cpp new file mode 100644 index 0000000..aae065f --- /dev/null +++ b/src/view/common/view_logic_storage_support.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_storage_support.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @brief Implementation file of StorageSupport API used by ViewLogic + */ +#include "view_logic_storage_support.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace ViewModule { +namespace StorageSupport { +namespace { //anonymous +const mode_t TEMPORARY_STORAGE_MODE = 0700; +static bool rootDirectory = true; + +static int removeFile(const char* path, const struct stat* /*sb*/, int tflag) +{ + if (path == NULL) { + LogError("Wrong input path"); + return 0; + } + LogDebug(path); + std::string inputPath = path; + + if (rootDirectory) { + LogDebug("Skip root directory"); + rootDirectory = false; + return 0; + } + + if (tflag == FTW_F || tflag == FTW_D) { + if (!WrtUtilRemove(inputPath)) { + LogError("Fail to remove"); + } + } else if (tflag == FTW_DNR) { + LogError("This is directory which can't be read"); + } else if (tflag == FTW_NS) { + LogError("Unknow error"); + } + + return 0; +} + +bool removeDirectory(const char* path) +{ + rootDirectory = true; + if (ftw(path, removeFile, 20) != 0) { + return false; + } + return true; +} +} + +void initializeStorage(WidgetModel *widgetModel) +{ + LogDebug("initializeStorage"); + AssertMsg(widgetModel, "Passed widgetModel is NULL!"); + + // create temporary storage + std::string path = + DPL::ToUTF8String(widgetModel->TemporaryStoragePath.Get()); + if (!WrtUtilDirExists(path)) { + if (!WrtUtilMakeDir(path, TEMPORARY_STORAGE_MODE)) { + ThrowMsg(DPL::CommonException::InternalError, + "Fail to initialize temporary storage"); + } + } else { + if (!removeDirectory(path.c_str())) { + LogError("Failed to clean temporary storage"); + } + } +} + +void deinitializeStorage(WidgetModel *widgetModel) +{ + LogDebug("deinitializeStorage"); + AssertMsg(widgetModel, "Passed widgetModel is NULL!"); + + // clean-up temporary storage + std::string path = + DPL::ToUTF8String(widgetModel->TemporaryStoragePath.Get()); + if (!removeDirectory(path.c_str())) { + LogError("Fail to deinitialize temporary storage"); + } +} +} // namespace StorageSupport +} // namespace ViewModule diff --git a/src/view/common/view_logic_storage_support.h b/src/view/common/view_logic_storage_support.h new file mode 100644 index 0000000..c7c9eb1 --- /dev/null +++ b/src/view/common/view_logic_storage_support.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_storage_support.h + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @brief Header file of StorageSupport API used by ViewLogic + */ + +#ifndef VIEW_LOGIC_STORAGE_SUPPORT_H_ +#define VIEW_LOGIC_STORAGE_SUPPORT_H_ + +//Forward declaration +class WidgetModel; + +namespace ViewModule { +namespace StorageSupport { +void initializeStorage(WidgetModel *widgetModel); +void deinitializeStorage(WidgetModel *widgetModel); +} // namespace StorageSupport +} // namespace ViewModule + +#endif /* VIEW_LOGIC_STORAGE_SUPPORT_H_ */ diff --git a/src/view/common/view_logic_uri_support.cpp b/src/view/common/view_logic_uri_support.cpp new file mode 100644 index 0000000..c456d90 --- /dev/null +++ b/src/view/common/view_logic_uri_support.cpp @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_uri_support.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @brief Implementation file of UriSupport API used by ViewLogic + */ + +#include "view_logic_uri_support.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace ViewModule { +namespace UriSupport { +namespace { +struct AppControlCompareData { +std::string operation; +std::string uri; +std::string scheme; +std::string mime; +}; +enum ServiceDataType +{ + APP_CONTROL_DATA_TYPE_OPERATION, + APP_CONTROL_DATA_TYPE_URI, + APP_CONTROL_DATA_TYPE_URI_SCHEME, + APP_CONTROL_DATA_TYPE_MIME +}; + +#if ENABLE(APP_SCHEME) +char const * const SCHEME_TYPE_APP = "app"; +#endif +char const * const SCHEME_TYPE_FILE = "file"; +char const * const SCHEME_TYPE_HTTP = "http"; +char const * const SCHEME_TYPE_HTTPS = "https"; +char const * const SCHEME_TYPE_WIDGET = "widget"; +const char * const SCHEME_TYPE_FILE_SLASH = "file://"; + +bool wildcardCompare(const std::string& wildcardString, const std::string& target) +{ + std::string re = wildcardString; + + // replace special character to meaning character + pcrecpp::RE("\\\\").GlobalReplace("\\\\\\\\", &re); + pcrecpp::RE("\\.").GlobalReplace("\\\\.", &re); + pcrecpp::RE("\\+").GlobalReplace("\\\\+", &re); + pcrecpp::RE("\\?").GlobalReplace("\\\\?", &re); + pcrecpp::RE("\\^").GlobalReplace("\\\\^", &re); + pcrecpp::RE("\\$").GlobalReplace("\\\\$", &re); + pcrecpp::RE("\\[").GlobalReplace("\\\\[", &re); + pcrecpp::RE("\\]").GlobalReplace("\\\\]", &re); + pcrecpp::RE("\\{").GlobalReplace("\\\\{", &re); + pcrecpp::RE("\\}").GlobalReplace("\\\\}", &re); + pcrecpp::RE("\\(").GlobalReplace("\\\\(", &re); + pcrecpp::RE("\\)").GlobalReplace("\\\\)", &re); + pcrecpp::RE("\\|").GlobalReplace("\\\\|", &re); + + // replace wildcard character to regex type + pcrecpp::RE("\\*").GlobalReplace(".*", &re); + + return pcrecpp::RE(re).FullMatch(target); +} + +bool compareServiceData(ServiceDataType type, + std::string origin, + std::string other) +{ + if (APP_CONTROL_DATA_TYPE_OPERATION == type) + { + return origin == other; + } + else if (APP_CONTROL_DATA_TYPE_URI == type) + { + return wildcardCompare(origin, other); + } + else if (APP_CONTROL_DATA_TYPE_URI_SCHEME == type) + { + return origin == other; + } + else if (APP_CONTROL_DATA_TYPE_MIME == type) + { + return wildcardCompare(origin, other); + } + else + { + LogError("Wrong data type"); + return false; + } +} + +std::string getAppControlSrc( + WrtDB::WidgetAppControlList appControlLost, + AppControlCompareData data) +{ + LogDebug(" - operation : " << data.operation); + LogDebug(" - uri : " << data.uri); + LogDebug(" - scheme : " << data.scheme); + LogDebug(" - mimetype : " << data.mime); + + FOREACH(appControlIt, appControlLost) + { + if (compareServiceData(APP_CONTROL_DATA_TYPE_OPERATION, DPL::ToUTF8String(appControlIt->operation), data.operation)) + { + if (compareServiceData(APP_CONTROL_DATA_TYPE_URI_SCHEME, DPL::ToUTF8String(appControlIt->uri), data.scheme) || + compareServiceData(APP_CONTROL_DATA_TYPE_URI, DPL::ToUTF8String(appControlIt->uri), data.uri) ) + { + if (compareServiceData(APP_CONTROL_DATA_TYPE_MIME, DPL::ToUTF8String(appControlIt->mime), data.mime)) + { + LogDebug("Matched with : " << appControlIt->src); + LogDebug(" - operation : " << appControlIt->operation); + LogDebug(" - uri : " << appControlIt->uri); + LogDebug(" - mimetype : " << appControlIt->mime); + return DPL::ToUTF8String(appControlIt->src); + } + } + } + } + return std::string(); +} + +} + +std::string prepareUrl(const std::string &url, const std::string &insert) +{ + std::string urlFixed = url; + if (urlFixed.find("file://") == 0) { + urlFixed.erase(0, 6); + } + //replace %s in url with given from appservice + int size = snprintf(NULL, 0, urlFixed.c_str(), insert.c_str()) + 1; + char buffer[size]; + snprintf(buffer, size, urlFixed.c_str(), insert.c_str()); + return std::string(buffer); +} + +std::string getCustomHandlerProtocolUri( + WidgetModel *widgetModel, + const std::string &schemeType, + const std::string &schemeValue) +{ + CustomHandlerDB::Interface::attachDatabaseRO(); + CustomHandlerDB::CustomHandlerDAOReadOnly handlersDao(widgetModel->TizenId); + CustomHandlerDB::CustomHandlerPtr handler = + handlersDao.getActivProtocolHandler( + DPL::FromASCIIString(schemeType)); + CustomHandlerDB::Interface::detachDatabase(); + if (handler) { + LogDebug("Found handler, url: " << handler->url); + return prepareUrl(DPL::ToUTF8String(handler->base_url) + + DPL::ToUTF8String(handler->url), schemeValue); + } + return ""; +} + +std::string getCustomHandlerContentUri( + WidgetModel *widgetModel, + const std::string &mime, + const std::string &mimeValue) +{ + CustomHandlerDB::Interface::attachDatabaseRO(); + CustomHandlerDB::CustomHandlerDAOReadOnly handlersDao(widgetModel->TizenId); + CustomHandlerDB::CustomHandlerPtr handler = + handlersDao.getActivContentHandler( + DPL::FromASCIIString(mime)); + CustomHandlerDB::Interface::detachDatabase(); + if (handler) { + LogDebug("Found handler, url: " << handler->url); + return prepareUrl(DPL::ToUTF8String(handler->base_url) + + DPL::ToUTF8String(handler->url), mimeValue); + } + return ""; +} + +std::string getAppControlUri(bundle *bundle, WidgetModel *widgetModel) +{ + if (!bundle) + { + LogError("Bundle is empty"); + return std::string(""); + } + + AppControlCompareData data; + // get operation. Operation is mandatory. + const char* value = NULL; + value = appsvc_get_operation(bundle); + data.operation = value ? value : ""; + // ignore operation is NULL case + if (data.operation.empty()) { + LogDebug("Operation is NULL"); + return std::string(""); + } + + // get mime + value = appsvc_get_mime(bundle); + data.mime = value ? value : ""; + + // get uri + value = appsvc_get_uri(bundle); + data.uri = value ? value : ""; + + LogDebug("Passed AppControl data"); + LogDebug(" - operation : " << data.operation); + LogDebug(" - uri : " << data.uri); + LogDebug(" - mimetype : " << data.mime); + + + // get scheme and mime + std::string originScheme = ""; + std::string originPath = ""; + if (!data.uri.empty()) { + std::unique_ptr iri(iri_parse(data.uri.c_str()), iri_destroy); + if (!iri.get()) { + LogDebug("Fail to get iri"); + originScheme = ""; + originPath = ""; + } + if (iri->scheme) { + originScheme = iri->scheme; + } + if (iri->path) { + originPath = iri->path; + } + + // checking condition that mime is empthy and uri is available + if (data.mime.empty() && !data.uri.empty()) { + // checking passed uri is local file + // case 1. uri = file:///xxxx + // case 2. uri = /xxxx + if (!data.scheme.empty() && data.scheme != SCHEME_TYPE_FILE) { + LogDebug("Passed uri isn't local file"); + } else { + const char* FILE_URI_CASE_1 = "/"; + const char* FILE_URI_CASE_2 = "file:/"; + const char* FILE_URI_CASE_3 = "file:///"; + + char mimetype[128] = {0,}; + int ret = AUL_R_EINVAL; + const char* uri_c_str = data.uri.c_str(); + + if(strncmp(uri_c_str, FILE_URI_CASE_1, 1) == 0){ + ret = aul_get_mime_from_file(uri_c_str, + mimetype, + sizeof(mimetype)); + } else if(strncmp(uri_c_str, FILE_URI_CASE_2, 6) == 0){ + ret = aul_get_mime_from_file(&uri_c_str[5], + mimetype, + sizeof(mimetype)); + } else if(strncmp(uri_c_str, FILE_URI_CASE_3, 8) == 0){ + ret = aul_get_mime_from_file(&uri_c_str[7], + mimetype, + sizeof(mimetype)); + } + + if (AUL_R_OK == ret) { + data.mime = mimetype; + } + } + } + } + + WrtDB::WidgetAppControlList appControlList = + widgetModel->AppControlList.Get(); + if (!appControlList.empty()) { + // case 0, operation only + // scheme = + // uri = + if (data.uri.empty()) { + LogDebug("AppControl case 0 (NULL, NULL)"); + std::string src = getAppControlSrc(appControlList, data); + if (!src.empty()) { + return src; + } + return std::string(); + } + + // case 1 + // scheme = nfc + // uri = nfc:///xxx/xxx + if (!originScheme.empty()) { + data.scheme = originScheme; + LogDebug("AppControl case 1 (file, file:///xxx/xxx)"); + std::string src = getAppControlSrc(appControlList, data); + if (!src.empty()) { + return src; + } + } + + // case 2 + // scheme = + // uri = file:///xxx/xxx + data.scheme = ""; + LogDebug("AppControl case 2 (NULL, file:///xxx/xxx)"); + std::string src = getAppControlSrc(appControlList, data); + if (!src.empty()) { + return src; + } + + // case 3 + // scheme = file + // uri = /xxx/xxx + if (!originScheme.empty() && !originPath.empty()) { + data.scheme = originScheme; + data.uri = originPath; + LogDebug("AppControl case 3 (file, /xxx/xxx)"); + std::string src = getAppControlSrc(appControlList, data); + if (!src.empty()) { + return src; + } + } + + // case 4 + // scheme = + // uri = /xxx/xxx + if (!originPath.empty()) { + data.scheme = ""; + data.uri = originPath; + LogDebug("AppControl case 4 (NULL, /xxx/xxx)"); + std::string src = getAppControlSrc(appControlList, data); + if (!src.empty()) { + return src; + } + } + } + + if (!originScheme.empty()) { + LogDebug("Scheme parts: " << originScheme << ", " << originPath); + return getCustomHandlerProtocolUri( + widgetModel, originScheme, originPath); + } + if (data.mime != "") { + value = appsvc_get_data(bundle, APPSVC_DATA_SELECTED); + if (value != NULL) { + LogDebug("Use mime type for: " << value); + return getCustomHandlerContentUri( + widgetModel, data.mime, std::string(value)); + } else { + LogError("Selected file for mime is null, nothind to do"); + } + } + LogDebug("no matching result"); + return std::string(""); +} + +std::string getUri(WidgetModel *widgetModel, const std::string &defaultUri, bool* isSelfTarget) +{ + DPL::String uri; + std::string startUri; + LogDebug("default uri: " << defaultUri); + bundle *originBundle = ApplicationDataSingleton::Instance().getBundle(); + // search app-control data + startUri = getAppControlUri(originBundle, widgetModel).c_str(); + LogDebug("app-control start uri is " << startUri); + if (startUri == "") { + LogDebug("app-control data doesn't have matched data"); + startUri = defaultUri; + } else if (startUri == SELF_TARGET) { + startUri = defaultUri; + if (isSelfTarget) { + *isSelfTarget = true; + } + } + + // insert prefix path + std::string preFix = DPL::ToUTF8String(widgetModel->PrefixURL.Get()); + if (strstr(startUri.c_str(), SCHEME_TYPE_HTTP) == startUri.c_str() || + strstr(startUri.c_str(), SCHEME_TYPE_HTTPS) == startUri.c_str() || + strstr(startUri.c_str(), preFix.c_str()) == startUri.c_str()) + { + return startUri; + } else { + return preFix + startUri; + } +} + +DPL::OptionalString localizeURI(const DPL::String& inputURI, + const WidgetModel* model) +{ + auto uri = DPL::ToUTF8String(inputURI); + LogDebug("localizing url: " << uri); + + auto urlcstr = uri.c_str(); + + const char *end = strstr(urlcstr, ":"); + if (!end) { + LogDebug("no schema in link, return null"); + // lack of schema + return DPL::OptionalString(); + } + + std::string scheme(urlcstr, end); +#if ENABLE(APP_SCHEME) + if (scheme != SCHEME_TYPE_WIDGET && scheme != SCHEME_TYPE_FILE && scheme != SCHEME_TYPE_APP) { +#else + if (scheme != SCHEME_TYPE_WIDGET && scheme != SCHEME_TYPE_FILE) { +#endif + LogDebug("scheme doesn't need to localize"); + return DPL::OptionalString(inputURI); + } + + DPL::OptionalString found = + W3CFileLocalization::getFilePathInWidgetPackageFromUrl( + model->TizenId, + DPL::FromUTF8String(uri)); + + if (!found) { + // In this case, path doesn't need to localize. return input uri + LogDebug("Path not found within current locale in current widget"); + return DPL::OptionalString(inputURI); + } else { + DPL::String uri(L"file://" + *found); + LogDebug("Will load resource: " << uri); + LogDebug("finished"); + return DPL::OptionalString(uri); + } +} +} // namespace UriSupportImplementation +} // namespace ViewModule diff --git a/src/view/common/view_logic_uri_support.h b/src/view/common/view_logic_uri_support.h new file mode 100644 index 0000000..4d64de5 --- /dev/null +++ b/src/view/common/view_logic_uri_support.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_uri_support.h + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @brief Header file of UriSupport API used by ViewLogic + */ + +#ifndef VIEW_LOGIC_URI_SUPPORT_H_ +#define VIEW_LOGIC_URI_SUPPORT_H_ + +#include +#include +#include + +// Forward declare +class WidgetModel; + +namespace { +// Special key for supporting app-control service base on event +const char* const SELF_TARGET = "_self"; +} + +namespace ViewModule { +namespace UriSupport { + +std::string getUri(WidgetModel *widgetModel, const std::string &defaultUri, bool* isSelfTarget=NULL); +DPL::OptionalString localizeURI(const DPL::String& inputURI, + const WidgetModel* model); +} // namespace UriSupport +} // namespace ViewModule + +#endif /* VIEW_LOGIC_URI_SUPPORT_H_ */ diff --git a/src/view/common/view_logic_vibration_support.cpp b/src/view/common/view_logic_vibration_support.cpp new file mode 100644 index 0000000..71ab5c1 --- /dev/null +++ b/src/view/common/view_logic_vibration_support.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_vibration_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ + +#include "view_logic_vibration_support.h" +#include +#include + +namespace ViewModule { +VibrationSupport::VibrationSupport() : m_initialized(false), + m_handle(NULL), + m_effect_handle(NULL) +{} + +VibrationSupport::~VibrationSupport() +{} + +void VibrationSupport::initialize(void) +{ + LogDebug("initialize"); + initializeVibration(); +} + +void VibrationSupport::deinitialize(void) +{ + LogDebug("deinitialize"); + + if (m_initialized) { + int ret = haptic_close(m_handle); + + if (HAPTIC_ERROR_NONE == ret) { + m_initialized = false; + LogDebug("deinitialize success"); + } else { + m_initialized = true; + LogDebug("deinitialize failed - error code : " << ret); + } + } +} + +void VibrationSupport::startVibration(const long vibrationTime) +{ + LogDebug("startVibration called"); + + if (m_initialized == false) { + if (initializeVibration() == false) { + return; + } + } + + int time = static_cast(vibrationTime); + int ret = haptic_vibrate_monotone(m_handle, time, &m_effect_handle); + + if (HAPTIC_ERROR_NONE == ret) { + LogDebug("haptic_vibrate_monotone success"); + } else { + LogDebug("haptic_vibrate_monotone failed - error code : " << ret); + } + + return; +} + +void VibrationSupport::stopVibration(void) +{ + LogDebug("stopVibration called"); + + if (m_initialized == false) { + if (initializeVibration() == false) { + return; + } + } + + int ret = haptic_stop_all_effects(m_handle); + + if (HAPTIC_ERROR_NONE == ret) { + LogDebug("haptic_stop_all_effects success"); + } else { + LogDebug("haptic_stop_all_effects failed - error code : " << ret); + } + + return; +} + +bool VibrationSupport::initializeVibration(void) +{ + LogDebug("initializeVibration called"); + + if (m_initialized == false) { + haptic_device_h handle = NULL; + int ret = haptic_open(HAPTIC_DEVICE_0, &handle); + + if (ret == HAPTIC_ERROR_NONE) { + LogDebug("initializeVibration success"); + m_initialized = true; + m_handle = handle; + } else { + LogDebug("initializeVibration failed - error code : " << ret); + m_initialized = false; + m_handle = NULL; + } + } + + return m_initialized; +} +} // namespace ViewModule diff --git a/src/view/common/view_logic_vibration_support.h b/src/view/common/view_logic_vibration_support.h new file mode 100644 index 0000000..0a99e32 --- /dev/null +++ b/src/view/common/view_logic_vibration_support.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_vibration_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ + +#ifndef VIEW_LOGIC_VIBRATION_SUPPORT_H_ +#define VIEW_LOGIC_VIBRATION_SUPPORT_H_ + +#include + +namespace ViewModule { +class VibrationSupport +{ + public: + VibrationSupport(); + virtual ~VibrationSupport(); + + void initialize(); + void deinitialize(); + void startVibration(const long vibrationTime); + void stopVibration(void); + + private: + bool m_initialized; + haptic_device_h m_handle; + haptic_effect_h m_effect_handle; + + bool initializeVibration(void); +}; +} // namespace ViewModule + +#endif // VIEW_LOGIC_VIBRATION_SUPPORT_H_ diff --git a/src/view/context_manager.cpp b/src/view/context_manager.cpp new file mode 100644 index 0000000..6465bf7 --- /dev/null +++ b/src/view/context_manager.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 context_manager.cpp + * @author Andrzej Surdej (a.surdej@samsung.com) + * @version 1.0 + * @brief context getter function implementation + */ + +#include "i_context_manager.h" +#include + +namespace ViewModule { + +ContextManagerPtr contextManagerFactoryMethod( + const std::string& id, + Ewk_Context* c, + IViewModulePtr view) +{ + ContextManagerPtr ptr (new EwkContextManager(id, c, view)); + return ptr; +} + +ContextManagerFactoryMethod makeContextManagerFactoryMethod() +{ + return contextManagerFactoryMethod; +} + +} // namespace ViewModule diff --git a/src/view/i_context_manager.h b/src/view/i_context_manager.h new file mode 100644 index 0000000..8700b90 --- /dev/null +++ b/src/view/i_context_manager.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 i_context_manager.h + * @author Iwanek Tomasz (t.iwanek@samsung.com) + * @version 0.1 + * @brief Abstract file for handling operation regarding Ewk_Context. + */ + +#ifndef ABSTRACT_CONTEXT_MANAGER_H +#define ABSTRACT_CONTEXT_MANAGER_H + +#include +#include +#include +#include + +#include + +namespace ViewModule { + +class IContextManager; +typedef std::shared_ptr ContextManagerPtr; + +typedef std::function ContextManagerFactoryMethod; + +/** + * @brief The AbstractContextManager class Factory for ewk context + * + * This is interface class for ewk context factory. + * It's uses tizenId, view module to initialize it approriatly context. + * + * Constructor should create new context only if ewkContext parameter is NULL. + * If ewkContext parameter is not NULL, context should not be destroyed in destructor. + * This means used context is managed by manager only if was created internally. + * + * NOTE: This interface in not visible outside core module and it should not be. + * Reason for this code is not modify RunnableWidgetObject behaviour for mocks. + */ +class IContextManager { +public: + IContextManager( + const std::string& tizenAppId, + Ewk_Context* ewkContext, + ViewModule::IViewModulePtr viewModule) : + m_appId(tizenAppId), m_ewkContext(ewkContext), m_view(viewModule) {} + virtual ~IContextManager() {} + /** + * @brief getEwkContext returns ewk context + * @return ewk context + */ + virtual Ewk_Context* getEwkContext() const = 0; + /** + * @brief handleLowMemory + * + * Handles low memory conditions + */ + virtual void handleLowMemory() = 0; +protected: + std::string m_appId; + Ewk_Context* m_ewkContext; + IViewModulePtr m_view; +}; + +ContextManagerPtr contextManagerFactoryMethod(const std::string& id, Ewk_Context* c, IViewModulePtr view); + +ContextManagerFactoryMethod makeContextManagerFactoryMethod(); + +} // namespace ViewModule + +#endif // ABSTRACT_CONTEXT_MANAGER_H diff --git a/src/view/i_view_module.h b/src/view/i_view_module.h new file mode 100644 index 0000000..17dcbc8 --- /dev/null +++ b/src/view/i_view_module.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 i_view_module.h + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief Interface for ViewModule + */ + +#ifndef WRT_SRC_VIEW_I_VIEW_MODULE_H_ +#define WRT_SRC_VIEW_I_VIEW_MODULE_H_ + +#include +#include +#include +#include +#include +#include + +class WidgetModel; //FORWARD DECLARATION +namespace ViewModule { +/** \brief Interface to ViewModule. Object of IViewModule type is returned from + * ViewModuleMgr factory. + */ +class IViewModule +{ + public: + virtual ~IViewModule() { } + virtual bool createView(Ewk_Context* context, Evas_Object* window) = 0; + virtual void prepareView(WidgetModel *, const std::string &, int category) = 0; + virtual void showWidget() = 0; + virtual void hideWidget() = 0; + virtual void suspendWidget() = 0; + virtual void resumeWidget() = 0; + virtual void resetWidgetFromSuspend() = 0; + virtual void resetWidgetFromResume() = 0; + virtual void TimeTick(long time) = 0; + virtual void AmbientTick(long time) = 0; + virtual void AmbientModeChanged(bool ambient_mode) = 0; + virtual void backward() = 0; + virtual void reloadStartPage() = 0; + virtual Evas_Object* getCurrentWebview() = 0; + virtual void fireJavascriptEvent(int event, void* data) = 0; + virtual void setUserCallbacks(const WRT::UserDelegatesPtr& cbs) = 0; + virtual void checkSyncMessageFromBundle( + const char* name, + const char* body, + char** returnData) = 0; + virtual void checkAsyncMessageFromBundle( + const char* name, + const char* body) = 0; + virtual void downloadData(const char* url) = 0; + virtual void activateVibration(bool on, uint64_t time) = 0; +}; + +typedef std::shared_ptr IViewModulePtr; + +/** + * \brief This is a function for retrieving View object. It returns a pointer + * to IViewModule object. + */ +IViewModulePtr createView(); +} //namespace + +#endif /* WRT_SRC_VIEW_I_VIEW_MODULE_H_ */ diff --git a/src/view/view_module.cpp b/src/view/view_module.cpp new file mode 100644 index 0000000..79f1993 --- /dev/null +++ b/src/view/view_module.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_module.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief getView function implementation + */ + +#include "i_view_module.h" +#include + +namespace ViewModule { +IViewModulePtr createView() +{ + IViewModulePtr ptr(new ViewLogic()); + return ptr; +} +} //namespace diff --git a/src/view/webkit/CMakeLists.txt b/src/view/webkit/CMakeLists.txt new file mode 100644 index 0000000..2d985a6 --- /dev/null +++ b/src/view/webkit/CMakeLists.txt @@ -0,0 +1,104 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 src/view/webkit/CMakeLists.txt +# @author Pawel Sikorski (p.sikorski@samsung.com) + +ADD_DEFINITIONS("-DWRT_LOG") + +include(FindPkgConfig) + +PKG_CHECK_MODULES(VIEW_MODULE_DEP + dpl-dbus-efl + dpl-utils-efl + dpl-wrt-dao-ro + notification + wrt-commons-custom-handler-dao-rw + wrt-dispatch-event + wrt-plugins-ipc-message + wrt-plugin-js-overlay + wrt-popup-wrt-runner + security-core + security-client +# haptic + deviced + capi-system-system-settings + efl-assist + privacy-manager-client + REQUIRED +) + +PKG_CHECK_MODULES(SYS_VIEW_MODULE_DEP + appsvc + capi-appfw-app-manager + eina + ewebkit2 + REQUIRED +) + +SET(VIEW_MODULE_SOURCES + ${PROJECT_SOURCE_DIR}/src/view/webkit/ewk_context_manager.cpp + ${PROJECT_SOURCE_DIR}/src/view/webkit/view_logic.cpp + ${PROJECT_SOURCE_DIR}/src/view/webkit/view_logic_authentication_request_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/webkit/view_logic_certificate_confirm_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/webkit/view_logic_geolocation_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/webkit/view_logic_message_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/webkit/view_logic_orientation_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/webkit/view_logic_scheme_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/webkit/view_logic_usermedia_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/webkit/view_logic_web_notification_data.cpp + ${PROJECT_SOURCE_DIR}/src/view/webkit/view_logic_web_notification_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/webkit/view_logic_web_notification_permission_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/webkit/view_logic_web_storage_support.cpp + ${VIEW_MODULE_SOURCES} +) + +SET(VIEW_MODULE_INCLUDES + ${PROJECT_SOURCE_DIR}/src/api_new + ${PROJECT_SOURCE_DIR}/src/domain + ${PROJECT_SOURCE_DIR}/src/profiling + ${PROJECT_SOURCE_DIR}/src/view + ${PROJECT_SOURCE_DIR}/src/view/webkit + ${PROJECT_SOURCE_DIR}/src/plugin-service + ${VIEW_MODULE_DEP_INCLUDE_DIRS} +) + +ADD_DEFINITIONS(${VIEW_MODULE_DEP_CFLAGS}) + +INCLUDE_DIRECTORIES(${VIEW_MODULE_INCLUDES}) +INCLUDE_DIRECTORIES(SYSTEM ${SYS_VIEW_MODULE_DEP_INCLUDE_DIRS}) + +ADD_LIBRARY(${TARGET_VIEW_MODULE_LIB} STATIC + ${VIEW_MODULE_SOURCES} +) + +TARGET_LINK_LIBRARIES(${TARGET_VIEW_MODULE_LIB} + ${VIEW_MODULE_DEP_LIBRARIES} + ${PROF_LIB} +# ${TARGET_PLUGIN_MODULE_LIB} +) + +SET_TARGET_PROPERTIES(${TARGET_VIEW_MODULE_LIB} PROPERTIES + COMPILE_DEFINITIONS LOG_TAG="${LOG_TAG}") + +SET_TARGET_PROPERTIES(${TARGET_VIEW_MODULE_LIB} PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_API_VERSION}) +SET_TARGET_PROPERTIES(${TARGET_VIEW_MODULE_LIB} PROPERTIES + COMPILE_FLAGS "-include profiling_util.h" + OUTPUT_NAME ${TARGET_VIEW_MODULE_LIB} +) + +ADD_SUBDIRECTORY(injected-bundle) diff --git a/src/view/webkit/ewk_context_manager.cpp b/src/view/webkit/ewk_context_manager.cpp new file mode 100644 index 0000000..40ed513 --- /dev/null +++ b/src/view/webkit/ewk_context_manager.cpp @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 ewk_context_manager.cpp + * @author Yunchan Cho (yunchan.cho@samsung.com) + * @version 0.1 + * @brief Implementation of EwkContextManager class. + * This file handles operation regarding Ewk_Context + */ + +#include "ewk_context_manager.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace ViewModule { +namespace { +const std::string bundlePath("/usr/lib/libwrt-injected-bundle.so"); +std::map defaultExtensibleAPI = { + { EWK_EXTENSIBLE_API_MEDIA_STREAM_RECORD, EINA_TRUE }, + { EWK_EXTENSIBLE_API_ROTATE_CAMERA_VIEW, EINA_FALSE }, +#if !USE(WEB_PROVIDER_EXCEPTION_IN_EWK_CONTEXT) + { EWK_EXTENSIBLE_API_MEDIA_VOLUME_CONTROL, EINA_TRUE }, +#endif + { EWK_EXTENSIBLE_API_FULL_SCREEN_FORBID_AUTO_EXIT, EINA_TRUE }, + { EWK_EXTENSIBLE_API_ENCRYPTION_DATABASE, EINA_TRUE }, + { EWK_EXTENSIBLE_API_XWINDOW_FOR_FULL_SCREEN_VIDEO, EINA_TRUE }, + { EWK_EXTENSIBLE_API_CAMERA_CONTROL, EINA_FALSE } +}; +} // anonymous namespace + +EwkContextManager::EwkContextManager( + const std::string& tizenAppId, + Ewk_Context* ewkContext, + IViewModulePtr viewModule) + : IContextManager(tizenAppId, ewkContext, viewModule), + m_initialized(false), m_isInternalContext(false) +{ + if (!initialize()) { + ThrowMsg(DPL::Exception, "Fail to intialize EwkContextManager"); + } + // set ewk context callbacks + setCallbacks(); +} + +EwkContextManager::~EwkContextManager() +{ + // unset registered ewk context callbacks + unsetCallbacks(); + destroy(); +} + +Ewk_Context * EwkContextManager::getEwkContext() const +{ + return m_ewkContext; +} + +bool EwkContextManager::initialize() +{ + if (!m_ewkContext) { + m_ewkContext = ewk_context_new_with_injected_bundle_path(bundlePath.c_str()); + + if (!m_ewkContext) { + return false; + } + + m_isInternalContext = true; + } + + // cache model setting + ewk_context_cache_model_set( + m_ewkContext, + EWK_CACHE_MODEL_DOCUMENT_BROWSER); + ADD_PROFILING_POINT("WebProcess fork", "start"); + // To fork a Webprocess as soon as possible, + // the following ewk_api is called explicitly. + ewk_cookie_manager_accept_policy_set( + ewk_context_cookie_manager_get(m_ewkContext), + EWK_COOKIE_ACCEPT_POLICY_ALWAYS); + ADD_PROFILING_POINT("WebProcess fork", "stop"); + + // proxy server setting + setNetworkProxy(); + + LogDebug("ewk_context_certificate_file_set() was called."); + const char* caCertPath = cert_svc_get_certificate_crt_file_path(); + if (caCertPath) { + ewk_context_certificate_file_set(m_ewkContext, caCertPath); + } else { + LogError("cert path is null"); + } + + FOREACH(it, defaultExtensibleAPI) { + ewk_context_tizen_extensible_api_set(m_ewkContext, + it->first, + it->second); + } + + // ewk storage_path set + ewk_context_storage_path_reset(m_ewkContext); + + // set w3c features + setW3CFeatureByPrivilege(); + + // web application dependent settings + WrtDB::WidgetDAOReadOnly dao(DPL::FromUTF8String(m_appId)); +#if ENABLE(CONTENT_SECURITY_POLICY) + if (dao.getSecurityModelVersion() == + WrtDB::WidgetSecurityModelVersion::WIDGET_SECURITY_MODEL_V2) + { + ewk_context_tizen_extensible_api_set(m_ewkContext, + EWK_EXTENSIBLE_API_CSP, + EINA_TRUE); + } +#endif + + // WidgetSettingList dependent settings + WrtDB::WidgetSettings widgetSettings; + dao.getWidgetSettings(widgetSettings); + WidgetSettingList settings(widgetSettings); + + ewk_context_tizen_extensible_api_set( + m_ewkContext, + EWK_EXTENSIBLE_API_BACKGROUND_MUSIC, + settings.getBackgroundSupport() == BackgroundSupport_Enable ? + EINA_TRUE : EINA_FALSE); + ewk_context_tizen_extensible_api_set( + m_ewkContext, + EWK_EXTENSIBLE_API_SOUND_MODE, + settings.getSoundMode() == SoundMode_Exclusive ? + EINA_TRUE : EINA_FALSE); + ewk_context_tizen_extensible_api_set( + m_ewkContext, + EWK_EXTENSIBLE_API_ROTATION_LOCK, + settings.getRotationValue() == Screen_AutoRotation ? + EINA_FALSE : EINA_TRUE); + + // note: EWK_EXTENSIBLE_API_VISIBILITY_SUSPEND - private package only + ewk_context_tizen_extensible_api_set( + m_ewkContext, + EWK_EXTENSIBLE_API_VISIBILITY_SUSPEND, + settings.getBackgroundSupport() == BackgroundSupport_Enable ? + EINA_TRUE : EINA_FALSE); + + ewk_context_tizen_extensible_api_set( + m_ewkContext, + EWK_EXTENSIBLE_API_BACKGROUND_VIBRATION, + settings.getBackgroundVibration() == BackgroundVibration_Enable ? + EINA_TRUE : EINA_FALSE); + + std::string pluginsPath = + WrtDB::WidgetConfig::GetWidgetNPRuntimePluginsPath( + dao.getTizenPkgId()); + + // npruntime plugins path set + LogDebug("ewk_context_additional_plugin_path_set() : " << pluginsPath); + + ewk_context_additional_plugin_path_set(m_ewkContext, pluginsPath.c_str()); + + m_initialized = true; + + return true; +} + +void EwkContextManager::destroy() +{ + // only in the following case, webkit context should be deleted + if (m_initialized && m_isInternalContext) { + ewk_object_unref(m_ewkContext); + } +} + +void EwkContextManager::setCallbacks() +{ + if (!m_initialized) { + return; + } + + ewk_context_message_from_injected_bundle_callback_set( + m_ewkContext, + messageFromInjectedBundleCallback, + this); + + ewk_context_did_start_download_callback_set( + m_ewkContext, + didStartDownloadCallback, + this); + + vconf_notify_key_changed(VCONFKEY_NETWORK_PROXY, + vconfChangedCallback, + this); +} + +void EwkContextManager::unsetCallbacks() +{ + if (!m_initialized) { + return; + } + + ewk_context_message_from_injected_bundle_callback_set( + m_ewkContext, NULL, NULL); + ewk_context_did_start_download_callback_set( + m_ewkContext, NULL, NULL); + + vconf_ignore_key_changed(VCONFKEY_NETWORK_PROXY, + vconfChangedCallback); +} + +void EwkContextManager::setW3CFeatureByPrivilege() +{ + using namespace WrtDB; + WrtDB::WidgetDAOReadOnly dao(DPL::FromUTF8String(m_appId)); + if(!m_ewkContext) { + return; + } + std::list widgetPrivilege = dao.getWidgetPrivilege(); + + bool camera = false; + bool fullscreen = false; + bool audio = false; + + FOREACH(it, widgetPrivilege) { + std::map::const_iterator result = + g_W3CPrivilegeTextMap.find(DPL::ToUTF8String(*it)); + if (result != g_W3CPrivilegeTextMap.end()) { + switch (result->second) { + case FEATURE_FULLSCREEN_MODE: + LogDebug("fullscreen feature exists"); + fullscreen = true; + break; + case FEATURE_CAMERA: + LogDebug("camera feature exists"); + camera = true; + break; + case FEATURE_AUDIO_RECORDER: + LogDebug("audiorecorder feature exists"); + audio = true; + break; + default: + break; + } + } + } + // set auto full screen mode + ewk_context_tizen_extensible_api_set(m_ewkContext, + EWK_EXTENSIBLE_API_FULL_SCREEN, + fullscreen); + + // set camera + ewk_context_tizen_extensible_api_set(m_ewkContext, + EWK_EXTENSIBLE_API_CAMERA_CONTROL, + camera); + + // set audio recorder + ewk_context_tizen_extensible_api_set(m_ewkContext, + EWK_EXTENSIBLE_API_AUDIO_RECORDING_CONTROL, + audio); +} + +void EwkContextManager::setNetworkProxy() +{ + Assert(m_ewkContext); + + char* proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY); + if (proxy && strlen(proxy) && strcmp(proxy, "0.0.0.0")) { + LogDebug("proxy address: " << proxy); + ewk_context_proxy_uri_set(m_ewkContext, proxy); + } else { + LogDebug("proxy address is empty"); + ewk_context_proxy_uri_set(m_ewkContext, NULL); + } +} + +void EwkContextManager::messageFromInjectedBundleCallback( + const char* name, + const char* body, + char** returnData, + void* clientInfo) +{ + LogDebug("enter"); + + EwkContextManager* This = static_cast(clientInfo); + if (returnData) { + This->m_view->checkSyncMessageFromBundle(name, body, returnData); + } else { + This->m_view->checkAsyncMessageFromBundle(name, body); + } +} + +void EwkContextManager::didStartDownloadCallback(const char* downloadUrl, void* data) +{ + LogDebug("enter"); + + EwkContextManager* This = static_cast(data); + This->m_view->downloadData(downloadUrl); +} + +void EwkContextManager::vconfChangedCallback(keynode_t* keynode, void* data) +{ + LogDebug("enter"); + char* key = vconf_keynode_get_name(keynode); + + if (NULL == key) { + LogError("key is null"); + return; + } + std::string keyString = key; + Assert(data); + EwkContextManager* This = static_cast(data); + if (keyString == VCONFKEY_NETWORK_PROXY) { + This->setNetworkProxy(); + } +} + +void EwkContextManager::handleLowMemory() +{ + if (!m_ewkContext) { + return; + } + + //ewk_context_resource_cache_clear(m_ewkContext); + //ewk_context_notify_low_memory(m_ewkContext); +} + +ContextManagerPtr createEwkContextManager( + std::string& tizenAppId, + Ewk_Context* ewkContext, + ViewModule::IViewModulePtr viewModule) +{ + return ContextManagerPtr(new EwkContextManager(tizenAppId, ewkContext, viewModule)); +} + +} // namespace ViewModule diff --git a/src/view/webkit/ewk_context_manager.h b/src/view/webkit/ewk_context_manager.h new file mode 100644 index 0000000..16c361d --- /dev/null +++ b/src/view/webkit/ewk_context_manager.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 ewk_context_manager.h + * @author Yunchan Cho (yunchan.cho@samsung.com) + * @version 0.1 + * @brief Declaration of EwkContextManager class. + * This file handles operation regarding Ewk_Context. + */ + +#ifndef EWK_CONTEXT_MANAGER_H +#define EWK_CONTEXT_MANAGER_H + +#include +#include + +#include +#include +#include +#include +#include + +namespace ViewModule { + +class EwkContextManager : public IContextManager { + public: + EwkContextManager( + const std::string& tizenAppId, + Ewk_Context* ewkContext, + ViewModule::IViewModulePtr viewModule); + Ewk_Context * getEwkContext() const; + void handleLowMemory(); + ~EwkContextManager(); + + private: + bool initialize(); + void destroy(); + void setCallbacks(); + void unsetCallbacks(); + void setW3CFeatureByPrivilege(); + void setNetworkProxy(); + + // ewk context callback functions + static void messageFromInjectedBundleCallback( + const char* name, + const char* body, + char** returnData, + void* clientInfo); + static void didStartDownloadCallback(const char* downloadUrl, void* data); + + // vconf callback functions + static void vconfChangedCallback(keynode_t* keynode, void* data); + + // members + bool m_initialized; + bool m_isInternalContext; +}; +} // namespace ViewModule + +#endif // EWK_CONTEXT_MANAGER_H diff --git a/src/view/webkit/injected-bundle/CMakeLists.txt b/src/view/webkit/injected-bundle/CMakeLists.txt new file mode 100644 index 0000000..608c4b3 --- /dev/null +++ b/src/view/webkit/injected-bundle/CMakeLists.txt @@ -0,0 +1,100 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 src/view/webkit/injected-bundle/CMakeLists.txt +# @author Lukasz Wrzosek (l.wrzosek@samsung.com) + +ADD_DEFINITIONS("-DWRT_BUNDLE_LOG") + +include(FindPkgConfig) + +SET(INJECTED_BUNDLE_DEP_PACKAGES + dpl-efl + dpl-utils-efl + dpl-wrt-dao-ro + ewebkit2 + libprivilege-control + libiri + libpcrecpp + wrt-plugins-ipc-message + wrt-dispatch-event + pkgmgr-info + vconf + libresourced +) + +PKG_CHECK_MODULES(INJECTED_BUNDLE_DEP + ${INJECTED_BUNDLE_DEP_PACKAGES} + REQUIRED +) + +SET(INJECTED_BUNDLE_SOURCES + ${PROJECT_SOURCE_DIR}/src/view/webkit/injected-bundle/wrt-injected-bundle.cpp + ${PROJECT_SOURCE_DIR}/src/view/webkit/injected-bundle/injected_bundle_uri_handling.cpp + ${PROJECT_SOURCE_DIR}/src/view/webkit/injected-bundle/injected_bundle_decryption_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/webkit/injected-bundle/injected_bundle_viewmodes_support.cpp + ${PROJECT_SOURCE_DIR}/src/view/webkit/injected-bundle/page_global_context_container.cpp + ${PROJECT_SOURCE_DIR}/src/view/common/scheme.cpp +) + +SET(INJECTED_BUNDLE_INCLUDES + ${INJECTED_BUNDLE_DEP_INCLUDE_DIRS} + ${PROJECT_SOURCE_DIR}/src/plugin-service + ${PROJECT_SOURCE_DIR}/src/view/common + ${PROJECT_SOURCE_DIR}/src/domain +) + +ADD_DEFINITIONS(${INJECTED_BUNDLE_DEP_CFLAGS}) +INCLUDE_DIRECTORIES( + ${INJECTED_BUNDLE_INCLUDES} + ${SMACK_LABELING_SUPPORT_INCLUDES} + ) + +ADD_LIBRARY(${TARGET_INJECTED_BUNDLE_LIB} SHARED + ${INJECTED_BUNDLE_SOURCES} +) + +TARGET_LINK_LIBRARIES( + ${TARGET_INJECTED_BUNDLE_LIB} + ${INJECTED_BUNDLE_DEP_LIBRARIES} + ${TARGET_WRT_ENGINE_STATIC} + ${TARGET_PLUGIN_MODULE_LIB} + ${PROF_LIB} + ${SMACK_LABELING_SUPPORT_STATIC} +) + +# for encryption +TARGET_LINK_LIBRARIES(${TARGET_INJECTED_BUNDLE_LIB} "-lss-client") + +# Overriden log tag! +SET_TARGET_PROPERTIES(${TARGET_INJECTED_BUNDLE_LIB} PROPERTIES + COMPILE_DEFINITIONS LOG_TAG="WRT_BUNDLE") + +SET_TARGET_PROPERTIES(${TARGET_INJECTED_BUNDLE_LIB} PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_API_VERSION}) +SET_TARGET_PROPERTIES(${TARGET_INJECTED_BUNDLE_LIB} PROPERTIES + COMPILE_FLAGS -fPIC) +SET_TARGET_PROPERTIES(${TARGET_INJECTED_BUNDLE_LIB} PROPERTIES + LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both -Wl,--version-script=${PROJECT_SOURCE_DIR}/src/view/webkit/injected-bundle/${TARGET_INJECTED_BUNDLE_LIB}.map" + OUTPUT_NAME ${TARGET_INJECTED_BUNDLE_LIB} +) + +INSTALL(TARGETS ${TARGET_INJECTED_BUNDLE_LIB} + DESTINATION lib/ + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE +) + diff --git a/src/view/webkit/injected-bundle/injected_bundle_decryption_support.cpp b/src/view/webkit/injected-bundle/injected_bundle_decryption_support.cpp new file mode 100644 index 0000000..e33f221 --- /dev/null +++ b/src/view/webkit/injected-bundle/injected_bundle_decryption_support.cpp @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 injected_bundle_decryption_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + */ + +#include "injected_bundle_decryption_support.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +namespace InjectedBundle { +namespace { +const char * const SCHEME_FILE_SLASH = "file://"; +const char * const DATA_STRING = "data:"; +const char * const BASE64_STRING = ";base64,"; +const char QUESTION_MARK = '?'; +const char ASTERISK_MARK = '#'; +} + +//Implementation class +class DecryptionSupportImplementation +{ + private: + bool m_initialized; + + WrtDB::TizenAppId m_appId; + WrtDB::EncryptedFileList m_encryptedFiles; + bool m_isEncrypted; + std::set::iterator m_targetIt; + bool m_isPreload; + + + std::string getFilePath(const std::string& url) + { + std::string filePath = url; + + size_t pos = filePath.find_first_not_of(SCHEME_FILE_SLASH); + if (pos != std::string::npos) { + filePath = filePath.substr(pos - 1); + } + + pos = filePath.find_first_of(ASTERISK_MARK); + if (pos != std::string::npos) { + filePath = filePath.substr(0, pos); + } + + pos = filePath.find_first_of(QUESTION_MARK); + if (pos != std::string::npos) { + filePath = filePath.substr(0, pos); + } + + return filePath; + } + + int ssmDecrypt(const char* inBuf, int inSize, char** outBuf, int* outSize) + { + *outSize = ssa_decrypt_web_application(inBuf, inSize, outBuf, m_isPreload); + return *outSize; + } + + std::string doDecrypt(std::string filePath, int size) + { + struct stat buf; + if (0 == stat(filePath.c_str(), &buf)) { + const std::size_t fileSize = buf.st_size; + std::unique_ptr inChunk; + + FILE* fp = fopen(filePath.c_str(), "rb"); + if (NULL == fp) { + _E("Couldnot open file : %s", filePath.c_str()); + return std::string(); + } + + std::unique_ptr DecryptedString(new unsigned + char[fileSize]); + std::string pkgid(DPL::ToUTF8String(m_appId)); + + int writeCount = 0; + do { + unsigned char getDecSize[4]; + memset(getDecSize, 0x00, sizeof(getDecSize)); + + size_t readSize = fread(getDecSize, sizeof(unsigned char), sizeof(getDecSize), fp); + if (0 != readSize) { + unsigned int readBufSize = 0; + std::istringstream(std::string((char*)getDecSize)) >> readBufSize; + if (readBufSize == 0) { + _E("Failed to read resource"); + fclose(fp); + return std::string(); + } + inChunk.reset(new unsigned char[readBufSize]); + + size_t decReadSize = fread(inChunk.get(), sizeof(unsigned char), readBufSize, fp); + + if (0 != decReadSize) { + char *outChunk = NULL; + int outSize = 0; + if (0 > ssmDecrypt((char*)inChunk.get(), (int)decReadSize, &outChunk, &outSize)) + { + _E("Failed to get decrypted resource"); + fclose(fp); + return std::string(); + } + memcpy(DecryptedString.get() + writeCount, outChunk, outSize); + writeCount += outSize; + } + } + } while( 0 == std::feof(fp)); + fclose(fp); + memset(DecryptedString.get() + size, '\n', fileSize - size); + + BIO *bmem, *b64; + BUF_MEM *bptr; + + b64 = BIO_new(BIO_f_base64()); + bmem = BIO_new(BIO_s_mem()); + b64 = BIO_push(b64, bmem); + if (BIO_write(b64, DecryptedString.get(), fileSize) <= 0) { + _E("No data has been written"); + } + BIO_flush(b64); + BIO_get_mem_ptr(b64, &bptr); + + std::string base64Enc((char *)bptr->data, bptr->length - 1); + BIO_free_all(b64); + + return base64Enc; + } + return std::string(); + } + + public: + DecryptionSupportImplementation() : + m_initialized(false), + m_isEncrypted(false), + m_isPreload(false) + { + } + + void initialize(WrtDB::TizenAppId appId) + { + _D("called"); + m_initialized = true; + + m_appId = appId; + WrtDB::WidgetDAOReadOnly dao(m_appId); + dao.getEncryptedFileList(m_encryptedFiles); + if (!m_encryptedFiles.empty()) { + m_isEncrypted = true; + _D("encrypted application"); + } + + bool isPreload = false; + bool isUpdate = false; + pkgmgrinfo_pkginfo_h handle = NULL; + std::string tzPkgId = DPL::ToUTF8String(dao.getTizenPkgId()); + + if (PMINFO_R_OK != pkgmgrinfo_pkginfo_get_pkginfo(tzPkgId.c_str(), &handle)) { + _E("Can't get package information : %s", tzPkgId.c_str()); + return; + } + if (PMINFO_R_OK != pkgmgrinfo_pkginfo_is_preload(handle, &isPreload)) { + _E("Can't get package information : %s", tzPkgId.c_str()); + return; + } + if (PMINFO_R_OK != pkgmgrinfo_pkginfo_is_update(handle, &isUpdate)) { + _E("Can't get package information : %s", tzPkgId.c_str()); + return; + } + + if (isPreload && !isUpdate) { + m_isPreload = true; + _D("preload application"); + } + } + + void deinitialize(void) + { + _D("called"); + + m_encryptedFiles.clear(); + m_targetIt = m_encryptedFiles.end(); + m_isEncrypted = false; + m_appId = DPL::String(L""); + m_initialized = false; + } + + bool isNeedDecryption(std::string url) + { + if (!m_initialized) { + _E("not initialized"); + return false; + } + + if (0 != strncmp(url.c_str(), SCHEME_FILE_SLASH, strlen(SCHEME_FILE_SLASH))) { + return false; + } + + std::set::iterator it; + WrtDB::EncryptedFileInfo info; + std::string filePath = getFilePath(url); + info.fileName = DPL::FromUTF8String(filePath); + if (m_encryptedFiles.end() != (it = m_encryptedFiles.find(info))) { + _D(" info file name : %s", DPL::ToUTF8String(it->fileName).c_str()); + _D(" info file size : %d", it->fileSize); + m_targetIt = it; + return true; + } + return false; + } + + std::string decryptResource(std::string url) + { + if (!m_initialized) { + _E("not initialized"); + return std::string(); + } + + std::string filePath = getFilePath(url); + if (filePath != DPL::ToUTF8String(m_targetIt->fileName)) { + if (!isNeedDecryption(filePath)) { + return std::string(); + } + } + + std::string decryptString = + doDecrypt(DPL::ToUTF8String(m_targetIt->fileName), + m_targetIt->fileSize); + if (!decryptString.empty()) { + std::string destString = DATA_STRING; + + std::string mimeString = + DPL::ToUTF8String( + MimeTypeUtils::identifyFileMimeType( + DPL::FromUTF8String(url))); + + destString += mimeString; + destString += BASE64_STRING; + + decryptString.insert(0, destString); + } + return decryptString; + } +}; + +DecryptionSupport::DecryptionSupport() : + m_impl(new DecryptionSupportImplementation) +{ +} + +DecryptionSupport::~DecryptionSupport() +{ +} + +void DecryptionSupport::initialize(WrtDB::TizenAppId appId) +{ + m_impl->initialize(appId); +} + +void DecryptionSupport::deinitialize(void) +{ + m_impl->deinitialize(); +} + +bool DecryptionSupport::isNeedDecryption(std::string url) +{ + return m_impl->isNeedDecryption(url); +} + +std::string DecryptionSupport::decryptResource(std::string url) +{ + return m_impl->decryptResource(url); +} +} // namespace InjectedBundle diff --git a/src/view/webkit/injected-bundle/injected_bundle_decryption_support.h b/src/view/webkit/injected-bundle/injected_bundle_decryption_support.h new file mode 100644 index 0000000..0f3897e --- /dev/null +++ b/src/view/webkit/injected-bundle/injected_bundle_decryption_support.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 injected_bundle_decryption_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + */ +#ifndef INJECTED_BUNDLE_DECRYPTION_SUPPORT_H_ +#define INJECTED_BUNDLE_DECRYPTION_SUPPORT_H_ + +#include +#include +#include + +namespace InjectedBundle { +class DecryptionSupportImplementation; + +class DecryptionSupport +{ + public: + DecryptionSupport(); + virtual ~DecryptionSupport(); + void initialize(WrtDB::TizenAppId appId); + void deinitialize(void); + bool isNeedDecryption(std::string url); + std::string decryptResource(std::string url); + + private: + std::unique_ptr m_impl; +}; +} // namespace InjectedBundle + +#endif // INJECTED_BUNDLE_DECRYPTION_SUPPORT_H_ diff --git a/src/view/webkit/injected-bundle/injected_bundle_uri_handling.cpp b/src/view/webkit/injected-bundle/injected_bundle_uri_handling.cpp new file mode 100644 index 0000000..e89d115 --- /dev/null +++ b/src/view/webkit/injected-bundle/injected_bundle_uri_handling.cpp @@ -0,0 +1,379 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 injected_bundle_uri_handling.cpp + * @author Marcin Kaminski (marcin.ka@samsung.com) + * @version 1.0 + */ + +#include "injected_bundle_uri_handling.h" + +#include +#include +#include + +#include +#include +#include +// For dao creation (widget info fetching) +#include +// security checks for URI +#include +#include +#include +// URI localization +#include +// WARP check +#include +#include +// allow-navigation check +#include +#include + +namespace { +char const * const SCHEME_TYPE_FILE = "file"; +char const * const SCHEME_TYPE_WIDGET = "widget"; +char const * const SCHEME_TYPE_APP = "app"; +char const * const SCHEME_TYPE_HTTP = "http"; +char const * const PARAM_URL = "param:url"; +char const * const ACE_IGNORED_SCHEMA[] = { + "file://", + "widget://", +#if ENABLE(APP_SCHEME) + "app://", +#endif + "data:", + "tel:", + "sms:", + "mmsto:", + "mailto:", + 0 }; + +bool wildcardCompare(std::string wildcardString, std::string target) +{ + std::string re = wildcardString; + + // replace special character to meaning character + pcrecpp::RE("\\\\").GlobalReplace("\\\\\\\\", &re); + pcrecpp::RE("\\.").GlobalReplace("\\\\.", &re); + pcrecpp::RE("\\+").GlobalReplace("\\\\+", &re); + pcrecpp::RE("\\?").GlobalReplace("\\\\?", &re); + pcrecpp::RE("\\^").GlobalReplace("\\\\^", &re); + pcrecpp::RE("\\$").GlobalReplace("\\\\$", &re); + pcrecpp::RE("\\[").GlobalReplace("\\\\[", &re); + pcrecpp::RE("\\]").GlobalReplace("\\\\]", &re); + pcrecpp::RE("\\{").GlobalReplace("\\\\{", &re); + pcrecpp::RE("\\}").GlobalReplace("\\\\}", &re); + pcrecpp::RE("\\(").GlobalReplace("\\\\(", &re); + pcrecpp::RE("\\)").GlobalReplace("\\\\)", &re); + pcrecpp::RE("\\|").GlobalReplace("\\\\|", &re); + + // replace wildcard character to regex type + pcrecpp::RE("\\*").GlobalReplace(".*", &re); + + return pcrecpp::RE(re).FullMatch(target); +} + +bool checkWARP(const char *url, const DPL::String& tizenId) +{ + // ignore WARP in test mode + if (GlobalSettings::WarpTestModeEnabled()) { + return true; + } + + if (WarpIRI::isIRISchemaIgnored(url)) { + // scheme is not supported by WARP + return true; + } + + WrtDB::WidgetDAOReadOnly dao = WrtDB::WidgetDAOReadOnly(tizenId); + WrtDB::WidgetAccessInfoList widgetAccessInfoList; + dao.getWidgetAccessInfo(widgetAccessInfoList); + + // temporary solution for libiri parsing error + // This code will be removed + std::string urlstr = url; + size_t pos = urlstr.find_first_of("#?"); + if (pos != std::string::npos) { + urlstr = urlstr.substr(0, pos); + } + + return (static_cast(widgetAccessInfoList)).isRequiredIRI( + DPL::FromUTF8String(urlstr)); +} + +bool checkWhitelist(const char *url) +{ + if (url == NULL) { + return true; + } + + std::unique_ptr iri(iri_parse(url), iri_destroy); + if (!iri->scheme || !iri->host || strlen(iri->host) == 0) { + return true; + } + std::string scheme = iri->scheme; + std::string host = iri->host; + + if (scheme.find(SCHEME_TYPE_HTTP) == std::string::npos) { + return true; + } + + return false; +} + +bool checkAllowNavigation(const char *url, const DPL::String& tizenId) +{ + if (url == NULL) { + return true; + } + + std::unique_ptr iri(iri_parse(url), iri_destroy); + if (!iri->scheme || !iri->host || strlen(iri->host) == 0) { + return true; + } + std::string scheme = iri->scheme; + std::string host = iri->host; + + if (scheme.find(SCHEME_TYPE_HTTP) == std::string::npos) { + return true; + } + + WrtDB::WidgetDAOReadOnly dao = WrtDB::WidgetDAOReadOnly(tizenId); + WrtDB::WidgetAllowNavigationInfoList list; + dao.getWidgetAllowNavigationInfo(list); + + FOREACH(it, list) { + if (wildcardCompare(DPL::ToUTF8String(it->scheme), scheme) && + wildcardCompare(DPL::ToUTF8String(it->host), host)) + { + return true; + } + } + _E("deny"); + return false; +} + +bool preventSymlink(const std::string & url) +{ + if(0 != strncmp(url.c_str(), SCHEME_TYPE_FILE, strlen(SCHEME_TYPE_FILE))) + { + return true; + } + + if(url.size() >= strlen(SCHEME_TYPE_FILE) + 3) + { + std::string file = url.substr(strlen(SCHEME_TYPE_FILE) + 3); + struct stat st; + if(0 != stat(file.c_str(), &st)) return true; + return !S_ISLNK(st.st_mode); + } + else + { + return true; + } +} + +bool checkACE(const char* url, bool xhr, const DPL::String& tizenId) +{ + if (url) { + for (size_t i = 0; ACE_IGNORED_SCHEMA[i]; ++i) { + if (0 == strncmp(url, + ACE_IGNORED_SCHEMA[i], + strlen(ACE_IGNORED_SCHEMA[i]))) + { + return true; + } + } + } + + const char *devCapNamesMarkup = "externalNetworkAccess"; + const char *devCapNamesXHR = "XMLHttpRequest"; + + ace_request_t aceRequest; + + aceRequest.widget_handle = WrtDB::WidgetDAOReadOnly::getHandle(tizenId); + + // TODO! We should get session id from somewhere (outside Widget Process) + const std::string session = ""; + aceRequest.session_id = const_cast(session.c_str()); + aceRequest.feature_list.count = 0; + aceRequest.dev_cap_list.count = 1; + aceRequest.dev_cap_list.items = new ace_dev_cap_t[1]; + + if (xhr) { + aceRequest.dev_cap_list.items[0].name = + const_cast(devCapNamesXHR); + } else { + aceRequest.dev_cap_list.items[0].name = + const_cast(devCapNamesMarkup); + } + + aceRequest.dev_cap_list.items[0].param_list.count = 1; + aceRequest.dev_cap_list.items[0].param_list.items = new ace_param_t[1]; + aceRequest.dev_cap_list.items[0].param_list.items[0].name = + const_cast(PARAM_URL); + aceRequest.dev_cap_list.items[0].param_list.items[0].value = + const_cast(url); + + ace_check_result_t result = ACE_PRIVILEGE_DENIED; + ace_return_t ret = ace_check_access_ex(&aceRequest, &result); + + _D("Result is: %d", static_cast(result)); + + delete[] aceRequest.dev_cap_list.items[0].param_list.items; + delete[] aceRequest.dev_cap_list.items; + + return ACE_OK == ret && ACE_ACCESS_GRANTED == result; +} +} // namespace (anonymous) + +namespace InjectedBundleURIHandling { +bool processURI(const std::string& inputURI, + const DPL::String& tizenId, + WrtDB::WidgetSecurityModelVersion version) +{ + if (version == WrtDB::WidgetSecurityModelVersion::WIDGET_SECURITY_MODEL_V1) + { + if (!checkWARP(inputURI.c_str(), tizenId)) { + _E("Request was blocked by WARP: %s", inputURI.c_str()); + return false; + } + } + + // disable for performance + // if (!preventSymlink(inputURI)) { + // _W("Request for symlink is invalid: %s", inputURI.c_str()); + // return false; + //} + + return true; +} + +bool processURI(const DPL::String& inputURI, + const DPL::String& tizenId, + WrtDB::WidgetSecurityModelVersion version) +{ + DPL::OptionalString optionalUri(inputURI); + if (!optionalUri) { + _D("uri is empty"); + return true; + } + + std::string uri = DPL::ToUTF8String(inputURI); + return processURI(uri, tizenId, version); +} + +bool processMainResource(const DPL::String& inputURI, + const DPL::String& tizenId, + WrtDB::WidgetSecurityModelVersion version) +{ + DPL::OptionalString optionalUri(inputURI); + if (!optionalUri) { + _D("uri is empty"); + return true; + } + + std::string uri = DPL::ToUTF8String(inputURI); + if (version == + WrtDB::WidgetSecurityModelVersion::WIDGET_SECURITY_MODEL_V1) + { + if (!checkWARP(uri.c_str(), tizenId)) { + _E("Request was blocked by WARP: %s", uri.c_str()); + return false; + } + } else if (version == + WrtDB::WidgetSecurityModelVersion::WIDGET_SECURITY_MODEL_V2) + { +#if ENABLE(ALLOW_NAVIGATION) + if (!checkAllowNavigation(uri.c_str(), tizenId)) { + _E("Request was blocked by allow-navigation: %s", uri.c_str()); + return false; + } +#else + return false; +#endif + } + + // disable for performance + // if (!preventSymlink(uri)) { + // _W("Request for symlink is invalid: %s", uri.get().c_str()); + // return false; + // } + return true; +} + +bool processURIForPlugin(const char* url) +{ + return checkWhitelist(url); +} + +std::string localizeURI(const std::string& inputURI, const std::string& tizenId) +{ + if (inputURI.compare(0, strlen(SCHEME_TYPE_WIDGET), SCHEME_TYPE_WIDGET) && + inputURI.compare(0, strlen(SCHEME_TYPE_FILE), SCHEME_TYPE_FILE) && + inputURI.compare(0, strlen(SCHEME_TYPE_APP), SCHEME_TYPE_APP)) + { + _D("scheme doesn't need to localize"); + return inputURI; + } + + std::string localizedURI = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(tizenId, inputURI); + + if (localizedURI.empty()) { + return inputURI; + } else { + return std::string("file://") + localizedURI; + } +} + +DPL::OptionalString localizeURI(const DPL::String& inputURI, + const DPL::String& tizenId) +{ + std::string uri = DPL::ToUTF8String(inputURI); + const char* urlcstr = uri.c_str(); + const char *end = strstr(urlcstr, ":"); + if (!end) { + _W("no schema in link, return null"); + return DPL::OptionalString(); + } + std::string scheme(urlcstr, end); + +#if ENABLE(APP_SCHEME) + if (scheme != SCHEME_TYPE_WIDGET && scheme != SCHEME_TYPE_FILE && scheme != SCHEME_TYPE_APP) { +#else + if (scheme != SCHEME_TYPE_WIDGET && scheme != SCHEME_TYPE_FILE) { +#endif + _D("scheme doesn't need to localize"); + return DPL::OptionalString(inputURI); + } + + DPL::OptionalString found = + W3CFileLocalization::getFilePathInWidgetPackageFromUrl( + tizenId, + DPL::FromUTF8String(uri)); + + if (!found) { + // In this case, path doesn't need to localize. return input uri + _W("Path not found within current locale in current widget"); + return DPL::OptionalString(inputURI); + } else { + DPL::String uri(L"file://" + *found); + _D("Will load resource: %s", DPL::ToUTF8String(uri).c_str()); + return DPL::OptionalString(uri); + } +} +} // namespace InjectedBundleURIHandling diff --git a/src/view/webkit/injected-bundle/injected_bundle_uri_handling.h b/src/view/webkit/injected-bundle/injected_bundle_uri_handling.h new file mode 100644 index 0000000..b981c3d --- /dev/null +++ b/src/view/webkit/injected-bundle/injected_bundle_uri_handling.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 injected_bundle_uri_handling.h + * @author Marcin Kaminski (marcin.ka@samsung.com) + * @version 1.0 + */ +#ifndef INJECTED_BUNDLE_URI_HANDLING_H_ +#define INJECTED_BUNDLE_URI_HANDLING_H_ + +#include +#include +#include + +namespace InjectedBundleURIHandling { +bool processURI(const DPL::String& inputURI, + const DPL::String& tizenId, + WrtDB::WidgetSecurityModelVersion m_securityModelVersion); +bool processURI(const std::string& inputURI, + const DPL::String& tizenId, + WrtDB::WidgetSecurityModelVersion version); +bool processMainResource(const DPL::String& inputURI, + const DPL::String& tizenId, + WrtDB::WidgetSecurityModelVersion m_securityModelVersion); +bool processURIForPlugin(const char* url); +DPL::OptionalString localizeURI(const DPL::String& inputURI, + const DPL::String& tizenId); +std::string localizeURI(const std::string& inputURI, const std::string& tizenId); +} + +#endif // INJECTED_BUNDLE_URI_HANDLING_H_ diff --git a/src/view/webkit/injected-bundle/injected_bundle_viewmodes_support.cpp b/src/view/webkit/injected-bundle/injected_bundle_viewmodes_support.cpp new file mode 100644 index 0000000..a0a7b7b --- /dev/null +++ b/src/view/webkit/injected-bundle/injected_bundle_viewmodes_support.cpp @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 injected_bundle_viewmodes_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + */ + +#include "injected_bundle_viewmodes_support.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace InjectedBundle { +namespace { +const std::string VIEWMODE_TYPE_MAXIMIZED = "maximized"; +const std::string VIEWMODE_TYPE_FULLSCREEN = "fullscreen"; +const std::string VIEWMODE_TYPE_WINDOWED = "windowed"; + +typedef std::set SupportViewmodesSet; +SupportViewmodesSet g_supportViewmodes = {VIEWMODE_TYPE_MAXIMIZED, + VIEWMODE_TYPE_FULLSCREEN, + VIEWMODE_TYPE_WINDOWED}; +} + +//Implementation class +class ViewmodesSupportImplementation +{ + private: + typedef std::map ViewmodesMap; + typedef ViewmodesMap::iterator ViewmodesIt; + + bool m_initialized; + + WrtDB::TizenAppId m_appId; + WrtDB::WindowModeList m_modeList; + ViewmodesMap m_initialViewmodeMap; + ViewmodesMap m_currentViewmodeMap; + + bool isExisted(WKBundlePageRef page) + { + ViewmodesIt viewmodeIt = m_initialViewmodeMap.find(page); + if (viewmodeIt == m_initialViewmodeMap.end()) { + return false; + } + return true; + } + + std::string getChangedViewmode(void) + { + if (!m_currentViewmodeMap.empty()) { + ViewmodesIt curIt = m_currentViewmodeMap.begin(); + ViewmodesIt initIt = m_initialViewmodeMap.begin(); + if (curIt->second != initIt->second) { + return curIt->second; + } + } + return std::string(); + } + + bool isSupportViewmode(const std::string& mode) + { + if (g_supportViewmodes.find(mode) == g_supportViewmodes.end()) { + return false; + } + return true; + } + + public: + ViewmodesSupportImplementation(WrtDB::TizenAppId appId) : + m_initialized(false), + m_appId(appId) + { + WrtDB::WidgetDAOReadOnly dao(m_appId); + m_modeList = dao.getWindowModes(); + + m_initialized = true; + } + + void initialize(WKBundlePageRef page) + { + _D("initialize"); + if (!m_initialized) { + Assert(false); + } + + if (isExisted(page)) { + _W("This page is already initialized"); + return; + } + + // set initial viewmode from manifest + std::string initViewmode = VIEWMODE_TYPE_MAXIMIZED; + FOREACH(it, m_modeList) { + std::string mode = DPL::ToUTF8String(*it); + if (g_supportViewmodes.find(mode) != g_supportViewmodes.end()) { + initViewmode = mode; + } + } + m_initialViewmodeMap[page] = initViewmode; + + // In case of current viewmode of chrome is changed, + // set to changed viewmode + std::string currentViewmode = getChangedViewmode(); + if (currentViewmode.empty()) { + currentViewmode = initViewmode; + } + m_currentViewmodeMap[page] = currentViewmode; + + WKBundlePageSetViewMode(page, + WKStringCreateWithUTF8CString( + currentViewmode.c_str())); + } + + void deinitialize(WKBundlePageRef page) + { + _D("deinitialize"); + if (!m_initialized) { + Assert(false); + } + m_initialViewmodeMap.erase(page); + m_currentViewmodeMap.erase(page); + } + + void setViewmodes(WKBundlePageRef page, const std::string& mode) + { + if (!m_initialized) { + Assert(false); + } + + m_currentViewmodeMap[page] = mode; + WKBundlePageSetViewMode(page, + WKStringCreateWithUTF8CString( + mode.c_str())); + } + + void enterViewmodesAllPages(const std::string& mode) + { + _D("setViewmodesAllPages"); + if (!m_initialized) { + Assert(false); + } + if (!isSupportViewmode(mode)) { + _W("Wrong viewmode : %s", mode.c_str()); + return; + } + + FOREACH(it, m_currentViewmodeMap) { + setViewmodes(it->first, mode); + } + } + + void exitViewmodes(WKBundlePageRef page) + { + if (!m_initialized) { + Assert(false); + } + + std::string mode = m_initialViewmodeMap[page]; + m_currentViewmodeMap[page] = mode; + WKBundlePageSetViewMode(page, + WKStringCreateWithUTF8CString( + mode.c_str())); + } + + void exitViewmodesAllPages(void) + { + _D("exitViewmodesAllPages"); + if (!m_initialized) { + Assert(false); + } + + FOREACH(it, m_currentViewmodeMap) { + exitViewmodes(it->first); + } + } +}; + +ViewmodesSupport::ViewmodesSupport(WrtDB::TizenAppId appId) : + m_impl(new ViewmodesSupportImplementation(appId)) +{ +} + +ViewmodesSupport::~ViewmodesSupport() +{ +} + +void ViewmodesSupport::initialize(WKBundlePageRef page) +{ + m_impl->initialize(page); +} + +void ViewmodesSupport::deinitialize(WKBundlePageRef page) +{ + m_impl->deinitialize(page); +} + +void ViewmodesSupport::enterViewmodesAllPages(const std::string& mode) +{ + m_impl->enterViewmodesAllPages(mode); +} + +void ViewmodesSupport::exitViewmodesAllPages(void) +{ + m_impl->exitViewmodesAllPages(); +} +} // namespace InjectedBundle diff --git a/src/view/webkit/injected-bundle/injected_bundle_viewmodes_support.h b/src/view/webkit/injected-bundle/injected_bundle_viewmodes_support.h new file mode 100644 index 0000000..da1521b --- /dev/null +++ b/src/view/webkit/injected-bundle/injected_bundle_viewmodes_support.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 injected_bundle_viewmodes_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + */ +#ifndef INJECTED_BUNDLE_VIEWMODES_SUPPORT_H_ +#define INJECTED_BUNDLE_VIEWMODES_SUPPORT_H_ + +#include +#include + +#include + +namespace InjectedBundle { +class ViewmodesSupportImplementation; + +class ViewmodesSupport +{ + public: + ViewmodesSupport(WrtDB::TizenAppId appId); + virtual ~ViewmodesSupport(); + void initialize(WKBundlePageRef page); + void deinitialize(WKBundlePageRef page); + void enterViewmodesAllPages(const std::string& mode); + void exitViewmodesAllPages(void); + private: + std::unique_ptr m_impl; +}; +} // namespace InjectedBundle + +#endif // INJECTED_BUNDLE_VIEWMODES_SUPPORT_H_ \ No newline at end of file diff --git a/src/view/webkit/injected-bundle/page_global_context_container.cpp b/src/view/webkit/injected-bundle/page_global_context_container.cpp new file mode 100644 index 0000000..343fb03 --- /dev/null +++ b/src/view/webkit/injected-bundle/page_global_context_container.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 page_global_context_container.cpp + * @author Tomasz Iwanek (t.iwanek@smasung.com) + * @brief Declares container for global context that holds its references + */ +#include "page_global_context_container.h" + +#include + +PageGlobalContextContainer::PageGlobalContextContainer() +{ +} + +PageGlobalContextContainer::~PageGlobalContextContainer() +{ + FOREACH(iter, m_map) + { + JSGlobalContextRelease(iter->second); + } +} + +void PageGlobalContextContainer::insertContextForPage(WKBundlePageRef page, JSGlobalContextRef context) +{ + PageGlobalContext::iterator iter = m_map.find(page); + if(iter != m_map.end()) + { + JSGlobalContextRelease(m_map[page]); + } + JSGlobalContextRetain(context); + m_map[page] = context; +} + +void PageGlobalContextContainer::removeContextForPage(WKBundlePageRef page) +{ + PageGlobalContext::iterator iter = m_map.find(page); + if(iter != m_map.end()) + { + JSGlobalContextRelease(m_map[page]); + } + m_map.erase(iter); +} + +JSGlobalContextRef PageGlobalContextContainer::getContextForPage(WKBundlePageRef page) const +{ + return m_map.find(page)->second; +} + +PageGlobalContextContainer::const_iterator PageGlobalContextContainer::begin() const +{ + return m_map.begin(); +} +PageGlobalContextContainer::const_iterator PageGlobalContextContainer::find(WKBundlePageRef ref) const +{ + return m_map.find(ref); +} +PageGlobalContextContainer::const_iterator PageGlobalContextContainer::end() const +{ + return m_map.end(); +} diff --git a/src/view/webkit/injected-bundle/page_global_context_container.h b/src/view/webkit/injected-bundle/page_global_context_container.h new file mode 100644 index 0000000..1ef3499 --- /dev/null +++ b/src/view/webkit/injected-bundle/page_global_context_container.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 page_global_context_container.h + * @author Tomasz Iwanek (t.iwanek@smasung.com) + * @brief Declares container for global context that holds its references + */ +#ifndef PAGE_GLOBAL_CONTEXT_CONTAINER_H +#define PAGE_GLOBAL_CONTEXT_CONTAINER_H + +#include + +#include +#include + +/** + * @brief The PageGlobalContextContainer class + * + * Container for global contexts that increments reference for holded elements + */ +class PageGlobalContextContainer +{ +public: + typedef std::map PageGlobalContext; + typedef PageGlobalContext::iterator iterator; + typedef PageGlobalContext::const_iterator const_iterator; + typedef PageGlobalContext::value_type value_type; + + PageGlobalContextContainer(); + ~PageGlobalContextContainer(); + + PageGlobalContextContainer(const PageGlobalContextContainer&) = delete; + PageGlobalContextContainer& operator=(const PageGlobalContextContainer&) = delete; + + void insertContextForPage(WKBundlePageRef page, JSGlobalContextRef context); + void removeContextForPage(WKBundlePageRef page); + /** + * @brief getContextForPage gets context for given page + * @param page wk page + * Page should be valid for container. + * If you don't know if page is present in container use find + * + * @return context + */ + JSGlobalContextRef getContextForPage(WKBundlePageRef page) const; + + const_iterator begin() const; + const_iterator find(WKBundlePageRef ref) const; + const_iterator end() const; +private: + PageGlobalContext m_map; +}; + +#endif // PAGE_GLOBAL_CONTEXT_CONTAINER_H diff --git a/src/view/webkit/injected-bundle/wrt-injected-bundle.cpp b/src/view/webkit/injected-bundle/wrt-injected-bundle.cpp new file mode 100644 index 0000000..744422c --- /dev/null +++ b/src/view/webkit/injected-bundle/wrt-injected-bundle.cpp @@ -0,0 +1,1042 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 wrt-injected-bundle.cpp + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @brief Implementation file for injected bundle + */ +#include "wrt-injected-bundle.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 +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +// URI localization on WebProcess side +#include "injected_bundle_uri_handling.h" +#include "injected_bundle_decryption_support.h" +#include "injected_bundle_viewmodes_support.h" + +#include + +namespace { +const char SCHEME_HTTP[] = "http"; +const char SCHEME_HTTPS[] = "https"; +const char SCHEME_FILE[] = "file"; +const char SCHEME_FILE_SLASH[] = "file://"; +const char SCHEME_BOX_SLASH[] = "box://"; +const char BLANK_PAGE_URL[] = "about:blank"; +const char SRC_DOC_PAGE_URL[] = "about:srcdoc"; +const char HTML_MIME[] = "text/html"; +const char PHP_MIME[] = "application/x-php"; +const char WRT_WILL_SEND_REQUEST_LOG_ENABLE[] = "WRT_WILL_SEND_REQUEST_LOG_ENABLE"; +const std::size_t FILE_BUF_MAX_SIZE = 1024; // bytes +const std::size_t PLAIN_CHUNK_SIZE = 1008; // bytes +const unsigned int UID_ROOT = 0; +const unsigned int DEFAULT_PRIORITY = 0; +const char PRIVILEGE_APP_TYPE[] = "wgt"; +#if ENABLE(CORS_WHITELISTING) +const char * const warpAllowProtocolsForWildcard[] = { "http", "https" }; +#endif +} + +Bundle::Bundle(WKBundleRef bundle) : + m_bundle(bundle), + m_scale(0), + m_encodedBundle(""), + m_theme(""), + m_willRemoveContext(NULL), + m_securityModelVersion( + WrtDB::WidgetSecurityModelVersion::WIDGET_SECURITY_MODEL_V1), + m_initialized(false), + m_decryptionSupport(new InjectedBundle::DecryptionSupport()) +{ + Try { + LOG_PROFILE_START("Bundle attachToThread"); + WrtDB::WrtDatabase::attachToThreadRO(); + LOG_PROFILE_STOP("Bundle attachToThread"); + } Catch (DPL::DB::SqlConnection::Exception::Base) { + _E("## Db attach was failed! Terminate WebProcess by force. ##"); + exit(-1); + } +} + +Bundle::~Bundle() +{ + WrtDB::WrtDatabase::detachFromThread(); + + if (!m_pagesList.empty()) { + _E("There are not closed pages!"); + } + WKRelease(m_bundle); +} + +void Bundle::didCreatePageCallback( + WKBundleRef /*bundle*/, + WKBundlePageRef page, + const void* clientInfo) +{ + LOG_PROFILE_START("didCreatePageCallback"); + Bundle* This = static_cast(const_cast(clientInfo)); + This->didCreatePage(page); + LOG_PROFILE_STOP("didCreatePageCallback"); +} + +void Bundle::didReceiveMessageCallback( + WKBundleRef /*bundle*/, + WKStringRef messageName, + WKTypeRef messageBody, + const void *clientInfo) +{ + Bundle* bundle = static_cast(const_cast(clientInfo)); + bundle->didReceiveMessage(messageName, messageBody); +} + +void Bundle::willDestroyPageCallback( + WKBundleRef /*bundle*/, + WKBundlePageRef page, + const void* clientInfo) +{ + Bundle* This = static_cast(const_cast(clientInfo)); + This->willDestroyPage(page); +} + +void Bundle::didCreatePage(WKBundlePageRef page) +{ + if (!m_initialized) + { + _E("## Injected-bundle was not initialized! Terminate WebProcess by force. ##"); + exit(-1); + } + + auto mainFrame = WKBundlePageGetMainFrame(page); + auto context = WKBundleFrameGetJavaScriptContext(mainFrame); + m_pagesList.push_back(page); + m_pageGlobalContext.insertContextForPage(page, context); + _D("created Page : %p created JSContext : %p", page, context); + m_viewmodesSupport->initialize(page); + + WKBundlePageResourceLoadClient resourceLoadClient = { + kWKBundlePageResourceLoadClientCurrentVersion, /* version */ + this, /* clientinfo */ + 0, /* didInitiateLoadForResource */ + willSendRequestForFrameCallback, /* willSendRequestForFrame */ + 0, /* didReceiveResponseForResource */ + 0, /* didReceiveContentLengthForResource */ + 0, /* didFinishLoadForResource */ + 0, /* didFailLoadForResource */ + 0, /* shouldCacheResponse */ + 0, /* shouldUseCredentialStorage */ + }; + WKBundlePageSetResourceLoadClient(page, &resourceLoadClient); + + WKBundlePageLoaderClient loaderClient = { + kWKBundlePageLoaderClientCurrentVersion, + this, /* clientinfo */ + didStartProvisionalLoadForFrameCallback, /* didStartProvisionalLoadForFrame */ + 0, /* didReceiveServerRedirectForProvisionalLoadForFrame */ + 0, /* didFailProvisionalLoadWithErrorForFrame */ + didCommitLoadForFrameCallback, /* didCommitLoadForFrame */ + 0, /* didFinishDocumentLoadForFrame */ + 0, /* didFinishLoadForFrame */ + 0, /* didFailLoadWithErrorForFrame */ + 0, /* didSameDocumentNavigationForFrame */ + 0, /* didReceiveTitleForFrame */ + 0, /* didFirstLayoutForFrame */ + 0, /* didFirstVisuallyNonEmptyLayoutForFrame */ + didRemoveFrameFromHierarchyCallback, /* didRemoveFrameFromHierarchy */ + 0, /* didDisplayInsecureContentForFrame */ + 0, /* didRunInsecureContentForFrame */ + 0, /* didClearWindowObjectForFrame */ + 0, /* didCancelClientRedirectForFrame */ + 0, /* willPerformClientRedirectForFrame */ + 0, /* didHandleOnloadEventsForFrame */ + 0, /* didLayoutForFrame */ + 0, /* didNewFirstVisuallyNonEmptyLayout */ + 0, /* didDetectXSSForFrame */ + 0, /* shouldGoToBackForwardListItem */ + 0, /* globalObjectIsAvailableForFrame */ + 0, /* willDisconnectDOMWindowExtensionFromGlobalObject */ + 0, /* didReconnectDOMWindowExtensionToGlobalObject */ + 0, /* willDestroyGlobalObjectForDOMWindowExtension */ + 0, /* didFinishProgress */ + 0, /* shouldForceUniversalAccessFromLocalURL */ + 0, /* didReceiveIntentForFrame */ + 0, /* registerIntentServiceForFrame */ + 0, /* didLayout */ + 0, /* featuresUsedInPage */ + 0, /* willLoadURLRequest */ + 0, /* willLoadDataRequest */ + }; + + WKBundlePageSetPageLoaderClient(page, &loaderClient); + + + WKBundlePagePolicyClient policyClient = { + kWKBundlePagePolicyClientCurrentVersion, /* version */ + this, /* clientInfo */ + decidePolicyForNavigationActionCallback, /* decidePolicyForNavigationAction */ + decidePolicyForNewWindowActionCallback, /* decidePolicyForNavigationAction */ + decidePolicyForResponseCallback, /* decidePolicyForResponse */ + 0, /* unableToImplementPolicy */ + }; + WKBundlePageSetPolicyClient(page, &policyClient); +} + +void Bundle::willDestroyPage(WKBundlePageRef page) +{ + _D("Destroyed page : %p", page); + + auto context = m_pageGlobalContext.getContextForPage(page); + m_pagesList.remove(page); + m_pageGlobalContext.removeContextForPage(page); + m_pageContext[page].erase(context); + m_viewmodesSupport->deinitialize(page); + + PluginModule::unloadFrame(context); + PluginModule::stop(context); +} + +void Bundle::fixWKMessageArgs(std::string & argScale, + std::string & argEncodedBundle, + std::string & argTheme) +{ + if (argScale != "null" && argScale[0] == '_') { + argScale.erase(0, 1); + + std::stringstream ssScale(argScale); + ssScale >> m_scale; + } + + if (argEncodedBundle != "null" && argEncodedBundle[0] == '_') { + argEncodedBundle.erase(0, 1); + + m_encodedBundle = argEncodedBundle; + } + + if (argTheme != "null" && argTheme[0] == '_') { + argTheme.erase(0, 1); + + m_theme = argTheme; + } +} + +#if ENABLE(CORS_WHITELISTING) +void Bundle::bypassCORSforWARPAccessList(WrtDB::WidgetDAOReadOnly & dao) +{ + // bypassing CORS using origin whitelist + WrtDB::WidgetAccessInfoList WAList; + dao.getWidgetAccessInfo(WAList); + FOREACH(it, WAList) + { + const WrtDB::WidgetAccessInfo & access = *it; + WKURLRef url = WKURLCreateWithUTF8CString(DPL::ToUTF8String(access.strIRI).c_str()); + +#if ENABLE(APP_SCHEME) + std::string source = std::string("app://") + DPL::ToUTF8String(m_widgetTizenId) + "/"; +#else + std::string source = DPL::ToUTF8String(dao.getFullPath()); +#endif + + _D("WARP to WK whitelist position: %s for %s subDomains: %d", + source.c_str(), + DPL::ToUTF8String(access.strIRI).c_str(), + access.bSubDomains); + + WKStringRef wkSource = WKStringCreateWithUTF8CString(source.c_str()); + WKStringRef wkHost; + WKStringRef wkProtocol; + if(access.strIRI == L"*") + { + //wildcard force to explicitly say which protocol is used + // passed wkHost if empty means wildcard -> allow everything but protocol has to be set. + for(unsigned i = 0; i < sizeof(warpAllowProtocolsForWildcard) / sizeof(char*); i++) + { + wkHost = WKStringCreateWithUTF8CString(""); + wkProtocol = WKStringCreateWithUTF8CString(warpAllowProtocolsForWildcard[i]); + WKBundleAddOriginAccessWhitelistEntry(m_bundle, + wkSource, wkProtocol, wkHost, access.bSubDomains); + } + } + else + { + wkHost = WKURLCopyHostName(url); + wkProtocol = WKURLCopyScheme(url); + WKBundleAddOriginAccessWhitelistEntry(m_bundle, + wkSource, wkProtocol, wkHost, access.bSubDomains); + } + + WKRelease(wkHost); + WKRelease(wkProtocol); + WKRelease(wkSource); + } +} +#endif + +void Bundle::didReceiveMessage(WKStringRef messageName, WKTypeRef messageBody) +{ + _D("message name: %s", toString(messageName).c_str()); + if (WKStringIsEqualToUTF8CString(messageName, + Message::ToInjectedBundle::START)) + { + if (!messageBody || WKStringGetTypeID() != WKGetTypeID(messageBody)) { + _E("Wrong message format received, ignoring"); + return; + } + + std::string msgString = + toString(static_cast(messageBody)); + _D("message body: %s", msgString.c_str()); + // set information from ui process + std::stringstream ssMsg(msgString); + std::string argScale; + std::string argEncodedBundle; + std::string argTheme; + + std::string id; + ssMsg >> id; + m_widgetTizenId = DPL::FromASCIIString(id); + + ssMsg >> argScale; + ssMsg >> argEncodedBundle; + ssMsg >> argTheme; + + // ** Language tags setting completed ** + fixWKMessageArgs(argScale, argEncodedBundle, argTheme); + } else if (WKStringIsEqualToUTF8CString(messageName, + Message::ToInjectedBundle::SHUTDOWN)) + { + if (m_pagesList.empty()) { + _D("shutdown plugins"); + PluginModule::shutdown(); + } else { + _D("PluginModule shutdown ignored, there are still alive pages!"); + } + } + else if (WKStringIsEqualToUTF8CString(messageName, + Message::ToInjectedBundle::SET_CUSTOM_PROPERTIES)) + { + // set information from ui process + std::string msgString = + toString(static_cast(messageBody)); + _D("message body: %s", msgString.c_str()); + std::string argScale; + std::string argEncodedBundle; + std::string argTheme; + + std::stringstream ssMsg(msgString); + ssMsg >> argScale; + ssMsg >> argEncodedBundle; + ssMsg >> argTheme; + + fixWKMessageArgs(argScale, argEncodedBundle, argTheme); + + //apply for each context + PageGlobalContextContainer::const_iterator it = m_pageGlobalContext.begin(); + for (; it != m_pageGlobalContext.end(); ++it) { + PluginModule::setCustomProperties(it->second, + m_scale, + m_encodedBundle.c_str(), + m_theme.c_str()); + } + } else if (WKStringIsEqualToUTF8CString( + messageName, + Message::ToInjectedBundle::DISPATCH_JS_EVENT)) + { + _D("dispatch javascript event to created frames"); + using namespace WrtPlugins::W3C; + + // set information from ui process + std::string text = toString(static_cast(messageBody)); + int eventType; + SoftKeyboardChangeArgs softKeyboardArgs; + + std::stringstream ss(text); + ss >> eventType; + + if (eventType == SoftKeyboardChangeCustomEvent) + { + ss >> softKeyboardArgs.state; + ss >> softKeyboardArgs.width; + ss >> softKeyboardArgs.height; + } + + //apply for each context + PageGlobalContextContainer::const_iterator it = m_pageGlobalContext.begin(); + + for (; it != m_pageGlobalContext.end(); ++it) + { + if (eventType == SoftKeyboardChangeCustomEvent) + { + DispatchEventSupport::dispatchSoftKeyboardChangeEvent(it->second, + softKeyboardArgs.state, + softKeyboardArgs.width, + softKeyboardArgs.height); + } + } + } else if (WKStringIsEqualToUTF8CString( + messageName, + Message::ToInjectedBundle::INIT)) + { + if (!m_initialized) { + _D("initialize"); + std::string msgString = toString(static_cast(messageBody)); + m_widgetTizenId = DPL::FromASCIIString(msgString); + WrtDB::WidgetDAOReadOnly dao(m_widgetTizenId); + + // process pool - set app_privilige + //for only one time run + static bool first = true; + if (UID_ROOT == getuid() && first) { + first = false; + + using namespace WrtDB::GlobalConfig; + + std::string appPath; + std::string tzAppId = DPL::ToUTF8String(dao.getTizenAppId()); + std::string tzPkgId = DPL::ToUTF8String(dao.getTizenPkgId()); + DPL::OptionalString installedPath = dao.getWidgetInstalledPath(); + if (!installedPath) { + appPath = std::string(GetUserInstalledWidgetPath()) + "/" + + tzPkgId + GetUserWidgetExecPath() + "/" + tzAppId; + } else { + appPath = DPL::ToUTF8String(*installedPath) + + GetUserWidgetExecPath() + "/" + tzAppId; + } + + _D("set_app_smack_label(%s)", appPath.c_str()); + if (set_app_smack_label(appPath.c_str()) != 0) { + _E("set_app_smack_label() failed"); + } + + _D("perm_app_set_privilege(%s)", appPath.c_str()); + perm_app_set_privilege(tzPkgId.c_str(), PRIVILEGE_APP_TYPE, appPath.c_str()); + + // set process name + const int PR_NAME_LENGTH = 16; + std::string processName = tzAppId.substr(0, PR_NAME_LENGTH); + prctl(PR_SET_NAME, processName.c_str()); + } + + // add web process to cgroup (appId) to trace network + pid_t wpid = getpid(); + int ret = join_app_performance(DPL::ToUTF8String(dao.getTizenAppId()).c_str(), wpid); + if (ret != RESOURCED_ERROR_NONE) { + _D("fail to add web process(%d) to UI cgroup", wpid); + } else { + _D("add cgroup (%s), (%d)", DPL::ToUTF8String(dao.getTizenAppId()).c_str(), wpid); + } + + /* This type of message is received when widget is restarting + * (proably in other situation too). Widget restart can be + * called after system language change so language tags have to + * be recreated here. + * Do NOT MOVE LanguageTags reset before m_widgetHandle initialization + */ + // reset language tags (create new tags based on system locales) + LanguageTagsProviderSingleton::Instance().resetLanguageTags(); + DPL::OptionalString defaultLocale = dao.getDefaultlocale(); + if (!!defaultLocale) { + LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales( + *defaultLocale); + } + LanguageTags tags = + LanguageTagsProviderSingleton::Instance().getLanguageTags(); + _D("Current widget locales (language tags):"); + FOREACH(it, tags) { + _D("Locale: %s", DPL::ToUTF8String(*it).c_str()); + } + + _D("Preload PluginLogicSingleton"); + PluginModule::init(WrtDB::WidgetDAOReadOnly::getHandle(m_widgetTizenId)); + _D("Preload PluginLogicSingleton_end"); + + m_securityModelVersion = dao.getSecurityModelVersion(); +#if ENABLE(CORS_WHITELISTING) + bypassCORSforWARPAccessList(dao); +#endif + m_decryptionSupport->initialize(m_widgetTizenId); + m_viewmodesSupport.reset( + new InjectedBundle::ViewmodesSupport(m_widgetTizenId)); + m_initialized = true; + } else { + _D("already initalized"); + } + } else if (WKStringIsEqualToUTF8CString( + messageName, + Message::ToInjectedBundle::SET_XWINDOW_HANDLE)) + { + std::string msgString = + toString(static_cast(messageBody)); +#if 0 // sub mode disable + _D("set x window handle [%s]", msgString.c_str()); + IPCMessageSupport::setXwindowHandle(atoi(msgString.c_str())); +#else + _D("sub mode is disabled, set x window handle [NULL]"); +#endif + + } else if (WKStringIsEqualToUTF8CString( + messageName, + Message::ToInjectedBundle::SET_VIEWMODES)) + { + std::string msgBody = + toString(static_cast(messageBody)); + _D("set viewmode to [%s]", msgBody.c_str()); + if (msgBody == Message::ToInjectedBundle::SET_VIEWMODES_MSGBODY_EXIT) { + m_viewmodesSupport->exitViewmodesAllPages(); + } else { + m_viewmodesSupport->enterViewmodesAllPages(msgBody); + } + } + else if (WKStringIsEqualToUTF8CString(messageName, IPCMessageSupport::REPLY_ASYNC)) + { + using namespace IPCMessageSupport; + + std::string msgBody = toString(static_cast(messageBody)); + + if (msgBody.find_first_of('_') != std::string::npos) { + std::string strHandle = msgBody.substr(0, msgBody.find_first_of('_')); + std::string strBody = msgBody.substr(msgBody.find_first_of('_')+1); + + _D("handle: %s, , Body: %s", strHandle.c_str(), strBody.c_str()); + + int handle = atoi(strHandle.c_str()); + + AsyncConnectionPtr connection = AsyncConnectionManager::instance().getConnection(handle); + + if (connection) { + if (connection->replyCallback) { + _D("connection->replyCallback()"); + (connection->replyCallback)(handle, connection->data, strBody.c_str()); + } + + AsyncConnectionManager::instance().removeConnection(handle); + } else { + _D("Connection is not available. Ignored."); + } + } + } +} + +WKURLRequestRef Bundle::willSendRequestForFrameCallback( + WKBundlePageRef /*page*/, + WKBundleFrameRef /*frame*/, + uint64_t /*resourceIdentifier*/, + WKURLRequestRef request, + WKURLResponseRef /*response*/, + const void *clientInfo) +{ + Bundle* This = static_cast(const_cast(clientInfo)); + WKURLRequestRef ret = This->willSendRequestForFrame(request); + + return ret; +} + +void Bundle::didStartProvisionalLoadForFrameCallback( + WKBundlePageRef page, + WKBundleFrameRef frame, + WKTypeRef* /*userData*/, + const void *clientInfo) +{ + _D("called"); + Bundle* This = static_cast(const_cast(clientInfo)); + + if (This->m_pageGlobalContext.find(page) == This->m_pageGlobalContext.end()) { + return; + } + if (This->m_pageContext.count(page) == 0) { + return; + } + + JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame); + + ContextSet::iterator i = This->m_pageContext[page].find(context); + + if (i == This->m_pageContext[page].end()) { + _D("Initially attached frame"); + return; + } + + This->m_pageContext[page].erase(i); + This->m_willRemoveContext = context; +} + +void Bundle::didRemoveFrameFromHierarchyCallback( + WKBundlePageRef page, + WKBundleFrameRef frame, + WKTypeRef* /*userData*/, + const void *clientInfo) +{ + _D("called"); + Bundle* This = static_cast(const_cast(clientInfo)); + + if (This->m_pageContext.count(page) == 0) { + _D("his->m_pageContext.count(page) == 0"); + return; + } + + JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame); + + ContextSet::iterator i = This->m_pageContext[page].find(context); + + if (i == This->m_pageContext[page].end()) { + _W("Tried to unload frame which has never been loaded"); + return; + } + + This->m_pageContext[page].erase(i); + + PluginModule::unloadFrame(context); +} + +void Bundle::didFinishLoadForResourceCallback( + WKBundlePageRef /*page*/, + WKBundleFrameRef /*frame*/, + uint64_t /*resourceIdentifier*/, + const void* /*clientInfo*/) +{ + _D("called"); +} + +void Bundle::didCommitLoadForFrameCallback( + WKBundlePageRef page, + WKBundleFrameRef frame, + WKTypeRef* /*userData*/, + const void *clientInfo) +{ + _D("called"); + LOG_PROFILE_START("didCommitLoadForFrameCallback"); + Bundle* This = static_cast(const_cast(clientInfo)); + + WKURLRef url = WKBundleFrameCopyURL(frame); + + if (url == NULL) { + _W("url is NULL"); + return; + } + + if (This->m_willRemoveContext) { + PluginModule::unloadFrame(This->m_willRemoveContext); + This->m_willRemoveContext = NULL; + } + + JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame); + + This->m_pageContext[page].insert(context); + std::string urlStr = toString(url); + + if (WKBundleFrameIsMainFrame(frame)) { + _D("frame main frame"); + if(This->m_pageGlobalContext.find(page) != This->m_pageGlobalContext.end()) + { + _D("Previous context: %p", This->m_pageGlobalContext.getContextForPage(page)); + PluginModule::stop(This->m_pageGlobalContext.getContextForPage(page)); + } + _D("New context: %p", context); + //note that since we need old context for unloading plugins it must be sotred + //custom container take care of increamenting and decrementing references + This->m_pageGlobalContext.insertContextForPage(page, context); + } + + if (InjectedBundleURIHandling::processURIForPlugin(urlStr.c_str())){ + _D("start plugin"); + LOG_PROFILE_START("PluginModule start"); + PluginModule::start( + WrtDB::WidgetDAOReadOnly::getHandle(This->m_widgetTizenId), + context, + This->m_scale, + This->m_encodedBundle.c_str(), + This->m_theme.c_str() ); + LOG_PROFILE_STOP("PluginModule start"); + + PluginModule::loadFrame(context); + LOG_PROFILE_STOP("didCommitLoadForFrameCallback"); + } +} + +WKBundlePagePolicyAction Bundle::decidePolicyForNavigationActionCallback( + WKBundlePageRef page, + WKBundleFrameRef frame, + WKBundleNavigationActionRef navigationAction, + WKURLRequestRef request, + WKTypeRef* userData, + const void* clientInfo) +{ + _D("called"); + Bundle* This = static_cast(const_cast(clientInfo)); + return This->decidePolicyForAction(false, + page, + frame, + navigationAction, + request, + userData); +} + +WKBundlePagePolicyAction Bundle::decidePolicyForNewWindowActionCallback( + WKBundlePageRef page, + WKBundleFrameRef frame, + WKBundleNavigationActionRef navigationAction, + WKURLRequestRef request, + WKStringRef /*frameName*/, + WKTypeRef* userData, + const void* clientInfo) +{ + _D("called"); + Bundle* This = static_cast(const_cast(clientInfo)); + return This->decidePolicyForAction(true, + page, + frame, + navigationAction, + request, + userData); +} + +WKBundlePagePolicyAction Bundle::decidePolicyForResponseCallback( + WKBundlePageRef /* page */, + WKBundleFrameRef /* frame */, + WKURLResponseRef response, + WKURLRequestRef /* request */, + WKTypeRef* /* userData */, + const void* /* clientInfo */) +{ + _D("called"); + Assert(response); + WKStringRef contentTypeRef = WKURLResponseEflCopyContentType(response); + + std::string contentType = toString(contentTypeRef); + _D("contentTypeRef : %s", contentType.c_str()); + WKRelease(contentTypeRef); + + if (contentType == HTML_MIME) { + _D("Accepting HTML_MIME type"); + return WKBundlePagePolicyActionUse; + } + if (contentType == PHP_MIME) { + _D("Accepting php type"); + return WKBundlePagePolicyActionUse; + } + + return WKBundlePagePolicyActionPassThrough; +} + +WKURLRequestRef Bundle::willSendRequestForFrame(WKURLRequestRef request) +{ + static bool logEnable = (getenv(WRT_WILL_SEND_REQUEST_LOG_ENABLE) != NULL); + + WKURLRef wkUrl = WKURLRequestCopyURL(request); + WKStringRef wkStr = WKURLCopyString(wkUrl); + + std::string stdUrl = Bundle::toString(wkStr); + std::string localizedUrl; + + WKRelease(wkStr); + WKRelease(wkUrl); + + if (logEnable){ _D("willSendRequestForFrame : %s", stdUrl.c_str()); } + + std::string scheme = stdUrl.substr(0, stdUrl.find_first_of(':')); + +#if ENABLE(APP_SCHEME) + if (scheme == SCHEME_FILE) { + _E("File schema blocked for: %s", stdUrl.c_str()); + return NULL; + } +#endif + + // "about:blank"/"about:srcdoc" uri doesn't need uri processing. + if (stdUrl == BLANK_PAGE_URL || stdUrl == SRC_DOC_PAGE_URL) { + WKRetain(request); + return request; + } + + localizedUrl = InjectedBundleURIHandling::localizeURI(stdUrl, DPL::ToUTF8String(m_widgetTizenId)); + bool ret = InjectedBundleURIHandling::processURI(localizedUrl, m_widgetTizenId, m_securityModelVersion); + + if (!ret) { + _D("Not permitted resource: %s", localizedUrl.c_str()); + return NULL; + } + + // log disabled for performance + //LogDebug("URI processing result: " << result); + scheme = localizedUrl.substr(0, localizedUrl.find_first_of(':')); + + // Return value must contain details information of input + // WKURLRequestRef. Current webkit2 doesn't support api that + // copy WKURLRequestRef or change url only. Before webkit2 + // support api, callback return original WKURLRequestRef in the + // case of external scheme + + // external scheme also need to send message to UI process for + // checking roaming and security + + if (scheme == SCHEME_HTTP || scheme == SCHEME_HTTPS) { + if (logEnable){ _D("external scheme return original WKURLRequestRef"); } + WKRetain(request); + + return request; + } else { + std::string checkUrl = localizedUrl; + + if (m_decryptionSupport->isNeedDecryption(checkUrl)) { + std::string decryptString = + m_decryptionSupport->decryptResource(checkUrl); + + if (logEnable){ _D("return value : %s", decryptString.c_str()); } + + WKURLRef destUrl = + WKURLCreateWithUTF8CString(decryptString.c_str()); + WKURLRequestRef req = WKURLRequestCreateWithWKURL(destUrl); + WKRelease(destUrl); + + return req; + } + } + + WKURLRef newUrl = WKURLCreateWithUTF8CString(localizedUrl.c_str()); + WKURLRequestRef req = WKURLRequestCreateWithWKURL(newUrl); + WKRelease(newUrl); + + if (logEnable){ _D("return value : %s", localizedUrl.c_str()); } + + return req; +} + +WKBundlePagePolicyAction Bundle::decidePolicyForAction( + bool isNewWindow, + WKBundlePageRef /* page */, + WKBundleFrameRef frame, + WKBundleNavigationActionRef /* navigationAction */, + WKURLRequestRef request, + WKTypeRef* /* userData */) +{ + using namespace ViewModule; + using namespace ViewModule::SchemeActionMap; + + char const * const TIZEN_SCHEME = "tizen"; + + std::string request_uri = toString(request); + + _D("request uri : %s", request_uri.c_str()); + + // exception uri + if (request_uri == BLANK_PAGE_URL) { + return WKBundlePagePolicyActionUse; + } + + // in case of box scheme, unconditionally PassThrough should be returned + if (!request_uri.compare(0, 6, SCHEME_BOX_SLASH)) { + return WKBundlePagePolicyActionPassThrough; + } + + DPL::String dplUrl = DPL::FromUTF8String(request_uri); + bool ret = + InjectedBundleURIHandling::processMainResource(dplUrl, + m_widgetTizenId, + m_securityModelVersion); + if (!ret) { + std::string blockedUrl = DPL::ToUTF8String(dplUrl); + _D("URI is blocked: %s", blockedUrl.c_str()); + + // Send information about blocked URI to UIProcess + WKStringRef urlStr = WKStringCreateWithUTF8CString(blockedUrl.c_str()); + WKStringRef blockMessage = + WKStringCreateWithUTF8CString(Message::ToUIProcess::BLOCKED_URL); + WKBundlePostMessage(m_bundle, blockMessage, urlStr); + WKRelease(urlStr); + WKRelease(blockMessage); + return WKBundlePagePolicyActionPassThrough; + } + + // get scheme string + std::string request_scheme = getScheme(request_uri); + + // is tizen schem? + if (request_scheme == TIZEN_SCHEME) { + return WKBundlePagePolicyActionPassThrough; + } + + // scheme action + Scheme scheme(request_scheme); + Scheme::Type type = scheme.GetType(); + if (type < Scheme::FILE || type >= Scheme::COUNT) { + _D("Unknown scheme : %s", request_scheme.c_str()); + return WKBundlePagePolicyActionPassThrough; + } + + bool mainFrame = WKBundleFrameIsMainFrame(frame); + NavigationContext ctx = mainFrame ? TOP_LEVEL : FRAME_LEVEL; + if (isNewWindow) { + ctx = NEW_WINDOW; + } + + UriAction action = g_tizenActionMap[type][ctx]; + _D("Scheme type: %d, Navigation context: %d, Action: %d", + type, + ctx, + action); + + if (action != URI_ACTION_WRT) { + return WKBundlePagePolicyActionPassThrough; + } + + return WKBundlePagePolicyActionUse; +} + +std::string Bundle::toString(WKStringRef str) +{ + if (WKStringIsEmpty(str)) { + return ""; + } else { + size_t size = WKStringGetMaximumUTF8CStringSize(str); + + char buffer[size + 1]; + WKStringGetUTF8CString(str, buffer, sizeof(buffer)); + + return buffer; + } +} + +std::string Bundle::toString(WKURLRef url) +{ + WKStringRef urlStr = WKURLCopyString(url); + std::string str = toString(urlStr); + WKRelease(urlStr); + return str; +} + +std::string Bundle::toString(WKURLRequestRef req) +{ + WKURLRef reqUrl = WKURLRequestCopyURL(req); + std::string str = toString(reqUrl); + WKRelease(reqUrl); + return str; +} + +std::string Bundle::toString(WKErrorRef err) +{ + WKStringRef domErr = WKErrorCopyDomain(err); + WKStringRef desc = WKErrorCopyLocalizedDescription(err); + std::string str = toString(domErr) + "\n" + toString(desc); + WKRelease(domErr); + WKRelease(desc); + return str; +} + +std::string Bundle::getScheme(std::string uri) +{ + std::size_t found = uri.find(':'); + std::string str; + + if (found != std::string::npos) { + str = uri.substr(0, found); + } + + return str; +} + +static void vconfChangedHandler(keynode_t* key, void* data) +{ + _D("vconfChangedHandler"); + + DPL_UNUSED_PARAM(key); + DPL_UNUSED_PARAM(data); + + LanguageTagsProviderSingleton::Instance().resetLanguageTags(); +} + +extern "C" +{ +WK_EXPORT +void WKBundleInitialize(WKBundleRef bundle, + WKTypeRef) +{ + _D("Bundle initialized"); + + DPL::Event::GetMainEventDispatcherInstance().ResetCrossEventCallHandler(); + _D("ResetCrossEventCallHandler()"); + + static Bundle s_bundle(bundle); + + WKBundleClient client = { + kWKBundleClientCurrentVersion, + &s_bundle, + &Bundle::didCreatePageCallback, + &Bundle::willDestroyPageCallback, + 0, /* didInitializePageGroup */ + &Bundle::didReceiveMessageCallback, + 0 /* didReceiveMessageToPage */ + }; + WKBundleSetClient(bundle, &client); + + // process pool - restore process priority + if (UID_ROOT == getuid()) { + setpriority(PRIO_PROCESS, 0, DEFAULT_PRIORITY); + } + IPCMessageSupport::setWKBundleRef(bundle); + + // TODO: Move to Construtor(Bundle::Bundle) + // Add "vconf_ignore_key_changed(VCONFKEY_LANGSET, vconfChangedHandler);" in the destructor(Bundle::~Bundle) + vconf_notify_key_changed(VCONFKEY_LANGSET, vconfChangedHandler, NULL); +} +} diff --git a/src/view/webkit/injected-bundle/wrt-injected-bundle.h b/src/view/webkit/injected-bundle/wrt-injected-bundle.h new file mode 100644 index 0000000..39a292c --- /dev/null +++ b/src/view/webkit/injected-bundle/wrt-injected-bundle.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 wrt-injected-bundle.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @brief declare injected bundle + */ +#ifndef WRT_SRC_VIEW_WEBKIT_WRT_INJECTED_BUNDLE_H_ +#define WRT_SRC_VIEW_WEBKIT_WRT_INJECTED_BUNDLE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "page_global_context_container.h" + +extern "C" { +WK_EXPORT void WKBundleInitialize(WKBundleRef bundle, WKTypeRef); +} + +namespace InjectedBundle { +class DecryptionSupport; +class ViewmodesSupport; +} + +class Bundle +{ + public: + Bundle(WKBundleRef bundle); + ~Bundle(); + + Bundle(const Bundle&) = delete; + Bundle& operator=(const Bundle&) = delete; + + // WKBundleClient callback + static void didCreatePageCallback( + WKBundleRef bundle, + WKBundlePageRef page, + const void* clientInfo); + static void willDestroyPageCallback( + WKBundleRef bundle, + WKBundlePageRef page, + const void* clientInfo); + static void didReceiveMessageCallback( + WKBundleRef, + WKStringRef messageName, + WKTypeRef messageBody, + const void *clientInfo); + + private: + WKBundleRef m_bundle; + + typedef std::list PagesList; + PagesList m_pagesList; + typedef std::set ContextSet; + typedef std::map PageContextList; + PageContextList m_pageContext; + PageGlobalContextContainer m_pageGlobalContext; + DPL::String m_widgetTizenId; + double m_scale; + std::string m_encodedBundle; + std::string m_theme; + std::set m_loadedContext; + JSGlobalContextRef m_willRemoveContext; + WrtDB::WidgetSecurityModelVersion m_securityModelVersion; + bool m_initialized; + + std::unique_ptr m_decryptionSupport; + std::unique_ptr m_viewmodesSupport; + + // WKBundlePageResourceLoadClient callback + static WKURLRequestRef willSendRequestForFrameCallback( + WKBundlePageRef, + WKBundleFrameRef, + uint64_t resourceIdentifier, + WKURLRequestRef request, + WKURLResponseRef, + const void *clientInfo); + static void didFinishLoadForResourceCallback( + WKBundlePageRef page, + WKBundleFrameRef frame, + uint64_t resourceIdentifier, + const void* clientInfo); + + // WKBundlePageDidStartProvisionalLoadForFrame callback + static void didStartProvisionalLoadForFrameCallback( + WKBundlePageRef page, + WKBundleFrameRef frame, + WKTypeRef* userData, + const void *clientInfo); + + // WKBundlePageDidRemoveFrameFromHierarchy callback + static void didRemoveFrameFromHierarchyCallback( + WKBundlePageRef page, + WKBundleFrameRef frame, + WKTypeRef* userData, + const void *clientInfo); + + // WKBundlePageLoaderClient callback + static void didCommitLoadForFrameCallback( + WKBundlePageRef page, + WKBundleFrameRef frame, + WKTypeRef*, + const void *clientInfo); + + // WKBundlePageDecidePolicyForNavigationActionCallback + static WKBundlePagePolicyAction decidePolicyForNavigationActionCallback( + WKBundlePageRef page, + WKBundleFrameRef frame, + WKBundleNavigationActionRef navigationAction, + WKURLRequestRef request, + WKTypeRef* userData, + const void* clientInfo); + + // WKBundlePageDecidePolicyForNewWindowActionCallback + static WKBundlePagePolicyAction decidePolicyForNewWindowActionCallback( + WKBundlePageRef page, + WKBundleFrameRef frame, + WKBundleNavigationActionRef navigationAction, + WKURLRequestRef request, + WKStringRef frameName, + WKTypeRef* userData, + const void* clientInfo); + + // WKBundlePageDecidePolicyForResponseCallback + static WKBundlePagePolicyAction decidePolicyForResponseCallback( + WKBundlePageRef page, + WKBundleFrameRef frame, + WKURLResponseRef response, + WKURLRequestRef request, + WKTypeRef* userData, + const void* clientInfo); + + // WKBundleClient + void didCreatePage(WKBundlePageRef page); + void willDestroyPage(WKBundlePageRef page); + void didReceiveMessage( + WKStringRef messageName, + WKTypeRef messageBody); + + // WKBundlePageResourceLoadClient + WKURLRequestRef willSendRequestForFrame(WKURLRequestRef request); + WKBundlePagePolicyAction decidePolicyForAction( + bool isNewWindow, + WKBundlePageRef page, + WKBundleFrameRef frame, + WKBundleNavigationActionRef navigationAction, + WKURLRequestRef request, + WKTypeRef* userData); + + // basic + inline static std::string toString(WKStringRef str); + inline static std::string toString(WKURLRef url); + inline static std::string toString(WKURLRequestRef req); + inline static std::string toString(WKErrorRef err); + static std::string getScheme(std::string uri); + + bool isEncryptedResource(std::string Url, int &size); + std::string DecryptResource(std::string resource, int size); + + void fixWKMessageArgs(std::string & argScale, + std::string & argEncodedBundle, + std::string & argTheme); + +#if ENABLE(CORS_WHITELISTING) + void bypassCORSforWARPAccessList(WrtDB::WidgetDAOReadOnly &dao); +#endif +}; + +#endif // WRT_SRC_VIEW_WEBKIT_WRT_INJECTED_BUNDLE_H_ diff --git a/src/view/webkit/injected-bundle/wrt-injected-bundle.map b/src/view/webkit/injected-bundle/wrt-injected-bundle.map new file mode 100644 index 0000000..55fe5ea --- /dev/null +++ b/src/view/webkit/injected-bundle/wrt-injected-bundle.map @@ -0,0 +1,18 @@ +{ + global: + WKBundleInitialize; + _Jv_RegisterClasses; + __bss_end__; + __bss_start; + __bss_start__; + __cxa_finalize; + __end__; + __gmon_start__; + _bss_end__; + _edata; + _end; + _fini; + _init; + pthread_cancel; + local: *; +}; diff --git a/src/view/webkit/view_logic.cpp b/src/view/webkit/view_logic.cpp new file mode 100755 index 0000000..7454278 --- /dev/null +++ b/src/view/webkit/view_logic.cpp @@ -0,0 +1,2587 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic.cpp + * @author Pawel Sikorski (p.sikorsk@samsung.com) + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @author Yunchan Cho (yunchan.cho@samsung.com) + * @brief View logic for Webkit2 + */ +#include "view_logic.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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ORIENTATION_ENABLED +#include +#endif +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { +// IME State value +const char * const IME_STATE_ON = "on"; +const char * const IME_STATE_OFF = "off"; + +const char PROTOCOL_HANDLER_ASK_MSG[] = "Add protocol?"; +const char PROTOCOL_HANDLER_ASK_TITLE[] = "Add protocol"; +const char PROTOCOL_HANDLER_ASK_REMEMBER[] = "Remember dicision"; +const char CONTENT_HANDLER_ASK_MSG[] = "Add content?"; +const char CONTENT_HANDLER_ASK_TITLE[] = "Add content"; +const char CONTENT_HANDLER_AKS_REMEMBER[] = "Remember dicision"; + +const char* const DEFAULT_ENCODING = "UTF-8"; +#if ENABLE(CONTENT_SECURITY_POLICY) +const char* const DEFAULT_CSP_POLICY = + "default-src *; script-src 'self'; style-src 'self'; object-src 'none';"; +#endif +// SCHEME +const char * const SCHEME_BOX_SLASH = "box://"; +#ifdef ORIENTATION_ENABLED +const double ORIENTATION_THRESHOLD = 0.5; +#endif + +// Ewk Smart Class +const char* EWK_SMART_CLASS_USER_DATA = "__sc_userdata__"; +} // anonymous namespace + +std::map ViewLogic::m_ewkCallbacksMap = { + { "load,started", &ViewLogic::loadStartedCallback }, + { "load,finished", &ViewLogic::loadFinishedCallback }, + { "load,progress,started", &ViewLogic::loadProgressStartedCallback }, + { "load,progress", &ViewLogic::loadProgressCallback }, + { "load,progress,finished", &ViewLogic::loadProgressFinishedCallback }, + { "webprocess,crashed", &ViewLogic::processCrashedCallback }, + // WKPagePolicyClient + { "policy,navigation,decide", &ViewLogic::policyNavigationDecideCallback }, + { "policy,newwindow,decide", &ViewLogic::policyNewWindowDecideCallback }, + { "policy,response,decide", &ViewLogic::pageResponseDecideCallback }, + // WKPageContextMenuClient + { "contextmenu,customize", &ViewLogic::contextmenuCustomizeCallback }, + // EWK Notification Callback + { "notification,show", &ViewLogic::notificationShowCallback }, + { "notification,cancel", &ViewLogic::notificationCancelCallback }, + { "fullscreen,enterfullscreen", &ViewLogic::enterFullscreenCallback }, + { "fullscreen,exitfullscreen", &ViewLogic::exitFullscreenCallback }, + // IME Callback + // when ime start to be showed on the webview, + // this callback will be called + { "inputmethod,changed", &ViewLogic::imeChangedCallback }, + // this callback will be called + // when ime finishes to be showed on the webview + // "event_info" arg of this callback is always NULL point + // if web content should know size of ime, + // use "inputmethod,changed" instead of this. + // + { "editorclient,ime,opened", &ViewLogic::imeOpenedCallback }, + // when ime finished to be hidden, + // this callback will be called + { "editorclient,ime,closed", &ViewLogic::imeClosedCallback }, + // Custom handlers + { "protocolhandler,registration,requested", + &ViewLogic::protocolHandlerRegistrationCallback }, + { "protocolhandler,isregistered", + &ViewLogic::protocolHandlerIsRegisteredCallback }, + { "protocolhandler,unregistration,requested", + &ViewLogic::protocolHandlerUnregistrationCallback }, + { "contenthandler,registration,requested", + &ViewLogic::contentHandlerRegistrationCallback }, + { "contenthandler,isregistered", + &ViewLogic::contentHandlerIsRegisteredCallback }, + { "contenthandler,unregistration,requested", + &ViewLogic::contentHandlerUnregistrationCallback }, + { "request,certificate,confirm", + &ViewLogic::certificateConfirmRequestCallback }, + { "authentication,request", + &ViewLogic::authenticationRequestCallback }, + { "frame,rendered", + &ViewLogic::viewFrameRenderedCallback }, +#ifdef ORIENTATION_ENABLED + { "mediacontrol,rotate,horizontal", + &ViewLogic::mediacontrolRotateHorizontal }, + { "mediacontrol,rotate,vertical", + &ViewLogic::mediacontrolRotateVertical }, + { "mediacontrol,rotate,exit", + &ViewLogic::mediacontrolRotateExit }, +#endif + { "popup,reply,wait,start", + &ViewLogic::popupReplyWaitStart }, + { "popup,reply,wait,finish", + &ViewLogic::popupReplyWaitFinish }, + { "console,message", + &ViewLogic::consoleMessageCallback }, +#ifdef ORIENTATION_ENABLED + { "rotate,prepared", &ViewLogic::rotatePreparedCallback }, +#endif + { "video,hwoverlay,enabled", + &ViewLogic::enabledVideoHwOverlayCallback }, + { "video,hwoverlay,disabled", + &ViewLogic::disabledVideoHwOverlayCallback }, + { "vibrate", + &ViewLogic::vibrateCallback }, + { "cancel,vibration", + &ViewLogic::cancelVibrationCallback }, +}; + +ViewLogic::ViewLogic() : + m_ewkContext(0), + m_attachedToCustomHandlerDao(false), + m_currentEwkView(0), + m_closedEwkView(NULL), + m_window(NULL), + m_model(0), + m_cbs(new WRT::UserDelegates), + m_imeWidth(0), + m_imeHeight(0), + m_isBackgroundSupport(false), +#ifdef ORIENTATION_ENABLED + m_rotateAngle(0), + m_deferredRotateAngle( + ViewModule::OrientationSupport::DEFERRED_ORIENTATION_EMPTY), + m_orientationThresholdTimer(NULL), +#endif + m_isPopupReplyWait(false), + m_isFullscreenByPlatform(false), + m_category(0), + m_appsSupport(new ViewModule::AppsSupport()), + m_vibrationSupport(new ViewModule::VibrationSupport()), + m_webNotificationSupport(new ViewModule::WebNotificationSupport()) +{ + ApplicationLauncherSingleton::Instance().Touch(); +} + +ViewLogic::~ViewLogic() +{ + detachFromCustomHandlersDao(); +} + +bool ViewLogic::createView(Ewk_Context* context, Evas_Object* window) +{ + LogDebug("enter"); + if (!context || !window) { + return false; + } + + // theme setting + const char *theme = elm_theme_get(NULL); + if (theme) { + m_theme = theme; + LogDebug("theme is " << m_theme); + } + + // set members + m_ewkContext = context; + m_window = window; + + // TODO page group should be different per appid + // for support of multiple injected bundles on one web process + m_pageGroup = ewk_page_group_create(""); + + if (!createEwkView()) { + return false; + } + + return true; +} + +void ViewLogic::prepareView(WidgetModel* m, const std::string &startUrl, int category) +{ + LogDebug("View prepare"); + + Assert(m); + m_model = m; + m_startUrl = startUrl; + Assert(NULL != m_ewkContext); + Assert(m_window); + + m_category = category; + + ADD_PROFILING_POINT("initializeSupport", "start"); + initializeSupport(); + ADD_PROFILING_POINT("initializeSupport", "stop"); + ewkClientInit(m_currentEwkView); + ADD_PROFILING_POINT("prepareEwkView", "start"); + prepareEwkView(m_currentEwkView); + ADD_PROFILING_POINT("prepareEwkView", "stop"); + initializePluginLoading(); + initializeXwindowHandle(); +} + +struct _WidgetViewInfo{ + std::string url; + Evas_Object_Event_Cb callback; + Evas_Object* view; + Ecore_Timer* timeout; +}; + +void ViewLogic::showWidget() +{ + LogDebug("showing widget"); + AssertMsg(NULL != m_currentEwkView, "ewk_view not created at this point"); + std::string url = + ViewModule::UriSupport::getUri(m_model, m_startUrl); + if (url.empty()) { + LogError("Localized current URI doesn't exist"); + return; + } + LogDebug("url : " << url); + + //to delay ewk_view_url_set until resize callback was called + auto callback = [](void* data, Evas* e, Evas_Object* obj, void* eventInfo) -> void { + _WidgetViewInfo *info = static_cast<_WidgetViewInfo*>(data); + ewk_view_url_set(info->view, info->url.c_str()); + evas_object_event_callback_del(info->view, EVAS_CALLBACK_RESIZE, info->callback); + ecore_timer_del(info->timeout); + delete info; + }; + auto timeout = [](void* data) -> Eina_Bool { + _WidgetViewInfo *info = static_cast<_WidgetViewInfo*>(data); + ewk_view_url_set(info->view, info->url.c_str()); + evas_object_event_callback_del(info->view, EVAS_CALLBACK_RESIZE, info->callback); + delete info; + return ECORE_CALLBACK_CANCEL; + }; + + _WidgetViewInfo *info = new _WidgetViewInfo(); + info->url = url; + info->callback = callback; + info->view = m_currentEwkView; + //resize callback was not called until after 0.1 sec, called by timer to prevent blocking + info->timeout = ecore_timer_add(0.1, timeout, info); + evas_object_event_callback_add(m_currentEwkView, EVAS_CALLBACK_RESIZE, callback, info); + + if (m_cbs->setWebviewCallback) { + m_cbs->setWebviewCallback(m_currentEwkView); + } +} + +void ViewLogic::hideWidget() +{ + LogDebug("hiding widget"); + ViewModule::StorageSupport::deinitializeStorage(m_model); + m_appsSupport->deinitialize(); + m_vibrationSupport->deinitialize(); + m_webNotificationSupport->deinitialize(); + system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_FONT_TYPE); + + while (!m_ewkViewList.empty()) { + LogDebug("pop webview: " << m_ewkViewList.back()); + removeEwkView(m_ewkViewList.back()); + } + m_ewkViewList.clear(); +} + +void ViewLogic::suspendWidget() +{ + LogDebug("Pausing widget"); + Assert(m_model); + + if (!m_currentEwkView) { + LogWarning("Cannot suspend widget without view"); + } else { + // In case of idle-clock, web view has to be visible to support home edit mode + // and extra user scenario. + if (m_category != 1) { + setEwkViewInvisible(m_currentEwkView); + } + + FOREACH(it, m_ewkViewList) { + if (*it != m_currentEwkView) { + suspendWebkit(*it); + } + } + + suspendWebkit(m_currentEwkView); + } +} + +void ViewLogic::resumeWidget() +{ + LogDebug("Resume widget"); + Assert(m_model); + + if (m_currentEwkView) + { + setEwkViewVisible(m_currentEwkView); + + FOREACH(it, m_ewkViewList) { + if (*it != m_currentEwkView) { + resumeWebkit(*it); + } + } + + resumeWebkit(m_currentEwkView); + } +} + +void ViewLogic::resetWidgetFromSuspend() +{ + LogDebug("Reset widget from suspend"); + Assert(m_currentEwkView); + + if (m_isPopupReplyWait) { + setEwkViewVisible(m_currentEwkView); + + FOREACH(it, m_ewkViewList) { + if (*it != m_currentEwkView) { + resumeWebkit(*it); + } + } + + resumeWebkit(m_currentEwkView); + } +#if ENABLE(JAVASCRIPT_ONBEFOREUNLOAD_EVENT) + else { + setEwkViewVisible(m_currentEwkView); + + FOREACH(it, m_ewkViewList) { + if (*it != m_currentEwkView) { + resumeWebkit(*it); + } + } + + resumeWebkit(m_currentEwkView); + } +#endif + resetWidgetCommon(); +} + +void ViewLogic::resetWidgetFromResume() +{ + LogDebug("Reset widget from resume"); + + resetWidgetCommon(); +} + +void ViewLogic::resetWidgetCommon() +{ + Assert(m_currentEwkView); + + if (m_isPopupReplyWait) { + // Current WebProcess is blocked by some reason, js alert. + // This case "reset" event cannot pass to application(javascript layer). + // Free bundle data to use next "reset" event. + _D("Webkit is blocked. do resume"); + ApplicationDataSingleton::Instance().freeBundle(); + } else { + bool isSelfTarget = false; + std::string url = ViewModule::UriSupport::getUri(m_model, m_startUrl, &isSelfTarget); + + if (isSelfTarget) { + ViewLogicMessageSupport::setCustomProperties(m_ewkContext, NULL, + ApplicationDataSingleton::Instance().getEncodedBundle()); + DispatchEventSupport::dispatchAppControlEvent(m_currentEwkView); + } else { +#if ENABLE(JAVASCRIPT_ONBEFOREUNLOAD_EVENT) + initializePluginLoading(); + ewk_view_url_set(m_currentEwkView, url.c_str()); +#else + while (!m_ewkViewList.empty()) { + removeEwkView(m_ewkViewList.back()); + } + m_currentEwkView = NULL; + + createEwkView(); + ewkClientInit(m_currentEwkView); + prepareEwkView(m_currentEwkView); + + initializePluginLoading(); + + if (m_cbs->setWebviewCallback) { + m_cbs->setWebviewCallback(m_currentEwkView); + } + ewk_view_url_set(m_currentEwkView, url.c_str()); +#endif + } + } + + elm_win_activate(m_window); +} + +// keep this code to handle future requirement. +void ViewLogic::TimeTick(long time) +{ +#if 0 + LogDebug("throw time tick custom event"); + + std::stringstream script; + script << "var __event = document.createEvent(\"CustomEvent\");\n" + << "__event.initCustomEvent(\"timetick\", true, true);\n" + << "document.dispatchEvent(__event);\n" + << "\n" + << "for (var i=0; i < window.frames.length; i++)\n" + << "{ window.frames[i].document.dispatchEvent(__event); }"; + + if (true) + { + LogDebug("script : " << script.str()); + } + + if (ewk_view_script_execute(m_currentEwkView, script.str().c_str(), NULL, NULL) != EINA_TRUE) + { + LogDebug("ewk_view_script_execute returned FALSE!"); + } +#endif +} + +void ViewLogic::AmbientTick(long time) +{ + LogDebug("throw ambient time tick custom event"); + + std::stringstream script; + script << "var __event = document.createEvent(\"CustomEvent\");\n" + << "__event.initCustomEvent(\"timetick\", true, true);\n" + << "document.dispatchEvent(__event);\n" + << "\n" + << "for (var i=0; i < window.frames.length; i++)\n" + << "{ window.frames[i].document.dispatchEvent(__event); }"; + + if (true) + { + LogDebug("script : " << script.str()); + } + + if (ewk_view_script_execute(m_currentEwkView, script.str().c_str(), NULL, NULL) != EINA_TRUE) + { + LogDebug("ewk_view_script_execute returned FALSE!"); + } +} + +void ViewLogic::AmbientModeChanged(bool ambient_mode) +{ + LogDebug("throw ambient mode change custom event"); + + std::stringstream script; + script << "var __event = document.createEvent(\"CustomEvent\");\n" + << "var __detail = {};\n" + << "__event.initCustomEvent(\"ambientmodechanged\", true, true, __detail);\n" + << "__event.detail.ambientMode = " << (ambient_mode ? "true" : "false") << ";\n" + << "document.dispatchEvent(__event);\n" + << "\n" + << "for (var i=0; i < window.frames.length; i++)\n" + << "{ window.frames[i].document.dispatchEvent(__event); }"; + + if (true) + { + LogDebug("script : " << script.str()); + } + + if (ewk_view_script_execute(m_currentEwkView, script.str().c_str(), NULL, NULL) != EINA_TRUE) + { + LogDebug("ewk_view_script_execute returned FALSE!"); + } +} + + +void ViewLogic::backward() +{ + if (ewk_view_back_possible(m_currentEwkView)) { + ewk_view_back(m_currentEwkView); + } else { + if (1 >= m_ewkViewList.size()) { + // If there is no previous page, widget move to backgroud. + LogDebug("Widget move to backgroud"); + elm_win_lower(m_window); + } else { + // Back to previous webview + LogDebug("Widget move to previous webview"); + m_closedEwkView = m_currentEwkView; + ecore_idler_add(windowCloseIdlerCallback, this); + } + } +} + +void ViewLogic::reloadStartPage() +{ + LogDebug("Reload Start Page"); + // set preferred languages + std::string customHeaderString = ViewModule::CustomHeaderSupport::getValueByField(ViewModule::CustomHeaderSupport::ACCEPT_LANGUAGE); + if (!customHeaderString.empty()) { + LogDebug("preferred languages=[" << customHeaderString << "]"); + Eina_List* list = eina_list_append(NULL, customHeaderString.c_str()); + ewk_context_preferred_languages_set(list); + } + + ewk_context_resource_cache_clear(m_ewkContext); + ewk_view_reload_bypass_cache(m_currentEwkView); +} + +Evas_Object* ViewLogic::getCurrentWebview() +{ + LogDebug("get current webview"); + return m_currentEwkView; +} + +void ViewLogic::fireJavascriptEvent(int event, void* data) +{ + ViewLogicMessageSupport::dispatchJavaScriptEvent( + m_ewkContext, + static_cast(event), + data); +} + +void ViewLogic::setUserCallbacks(const WRT::UserDelegatesPtr& cbs) +{ + m_cbs = cbs; +} + +void ViewLogic::checkSyncMessageFromBundle( + const char* name, + const char* /*body*/, + char** returnData) +{ + LogDebug("didReceiveSynchronousMessage called"); + Assert(name); + + LogDebug("received : " << name); + if (!strcmp(name, Message::TizenScheme::GET_WINDOW_HANDLE)) { + if (m_window) { + Ecore_X_Window handle = elm_win_xwindow_get(m_window); + if (handle != 0) { + std::stringstream ss; + ss << handle; + std::string ret = ss.str(); + if (returnData) { + *returnData = strdup(ret.c_str()); + } + } else { + LogDebug("X window isn't exist"); + } + } + } +} + +void ViewLogic::checkAsyncMessageFromBundle(const char* name, const char* body) +{ + Assert(name); + _D("received : %s", name); + + if (!strcmp(name, Message::ToUIProcess::BLOCKED_URL)) { + // Currently WebProcess informs obly about blocked + // URI - URI localization and security chekcs are + // done by WebProcess itself (see: wrt-injected-bundle.cpp + // and bundle_uri_handling.cpp) + std::string msgBody = (body) ? (body) : ""; + if (!msgBody.empty() && m_cbs->blockedUrlPolicyCallback) { + m_cbs->blockedUrlPolicyCallback(msgBody); + m_blockedUri = msgBody; + } + } else if (!strcmp(name, Message::TizenScheme::CLEAR_ALL_COOKIES)) { + Ewk_Cookie_Manager* cookieManager = + ewk_context_cookie_manager_get(m_ewkContext); + if (!cookieManager) { + _E("Fail to get cookieManager"); + return; + } + ewk_cookie_manager_cookies_clear(cookieManager); + } else if (!strcmp(name, IPCMessageSupport::TIZEN_CHANGE_USERAGENT)) { + std::string msgBody = (body) ? (body) : ""; + + std::string strId = msgBody.substr(0, msgBody.find_first_of('_')); + std::string strBody = msgBody.substr(msgBody.find_first_of('_')+1); + _D("Id: %s , Body %s", strId.c_str(), strBody.c_str()); + + ewk_view_user_agent_set(m_currentEwkView, strBody.c_str()); + _D("get UA: %s", ewk_view_user_agent_get(m_currentEwkView)); + + IPCMessageSupport::replyAsyncMessageToWebProcess(m_ewkContext, + atoi(strId.c_str()), + "success"); + return; + } else if (!strcmp(name, IPCMessageSupport::TIZEN_DELETE_ALL_COOKIES)) { + std::string msgBody = (body) ? (body) : ""; + std::string strId = msgBody.substr(0, msgBody.find_first_of('_')); + std::string strBody = msgBody.substr(msgBody.find_first_of('_')+1); + + Ewk_Cookie_Manager* cookieManager = + ewk_context_cookie_manager_get(m_ewkContext); + if (!cookieManager) { + _E("Fail to get cookieManager"); + IPCMessageSupport::replyAsyncMessageToWebProcess( + m_ewkContext, + atoi(strId.c_str()), + "error"); + return; + } + ewk_cookie_manager_cookies_clear(cookieManager); + IPCMessageSupport::replyAsyncMessageToWebProcess(m_ewkContext, + atoi(strId.c_str()), + "success"); + return; + } else if (!strcmp(name, IPCMessageSupport::TIZEN_EXIT) || + !strcmp(name, IPCMessageSupport::TIZEN_HIDE)) + { + bool ret = + ViewModule::SchemeSupport::HandleTizenScheme(name, + m_window, + m_currentEwkView); + if (ret == false) { + _E("Fail to handle tizen scheme %s", name); + } + // Not need to send reply + return; + } else { + _W("Not defined message"); + } +} + +void ViewLogic::downloadData(const char* url) +{ + LogDebug("enter"); + if (!url) { + return; + } + m_appsSupport->downloadRequest(url, NULL, NULL); +} + +void ViewLogic::activateVibration(bool on, uint64_t time) +{ + LogDebug("enter vibrationTime=" << time); + if (on) { + m_vibrationSupport->startVibration(static_cast(time)); + } else { + m_vibrationSupport->stopVibration(); + } +} + +void ViewLogic::initializeSupport() +{ + // background support + if (m_model->SettingList.Get().getBackgroundSupport() + == BackgroundSupport_Enable) + { + LogDebug("Background support enabled, set process active"); + deviced_inform_active(getpid()); + m_isBackgroundSupport = true; + } + system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_FONT_TYPE, + systemSettingsChangedCallback, + this); + + ViewModule::StorageSupport::initializeStorage(m_model); + m_appsSupport->initialize(m_model, elm_win_xwindow_get(m_window)); + m_securityOriginSupport.reset(new ViewModule::SecurityOriginSupport(m_model)); + m_certificateSupport.reset(new ViewModule::CertificateSupport(m_model)); + m_privilegeSupport.reset(new ViewModule::PrivilegeSupport(m_model)); + m_webNotificationSupport->initialize(m_model->TzPkgId.Get()); +} + +void ViewLogic::initializePluginLoading() +{ + // inform wrt information for plugin loading to web process + ViewLogicMessageSupport::start( + m_ewkContext, + m_model->TizenId, + elm_config_scale_get(), + ApplicationDataSingleton::Instance().getEncodedBundle(), + m_theme.c_str()); +} + +void ViewLogic::initializeXwindowHandle() +{ + if (m_window) { + unsigned int handle = elm_win_xwindow_get(m_window); + ViewLogicMessageSupport::setXwindowHandle( + m_ewkContext, + handle); + } +} + +void ViewLogic::ewkClientInit(Evas_Object *wkView) +{ + AssertMsg(NULL != wkView, "ewk_view not created at this point"); + + FOREACH(it, m_ewkCallbacksMap) + { + evas_object_smart_callback_add( + wkView, + it->first.c_str(), + it->second, + this); + } + ewk_view_exceeded_database_quota_callback_set( + wkView, + exceededDatabaseQuotaCallback, + this); + ewk_view_exceeded_indexed_database_quota_callback_set( + wkView, + exceededIndexedDatabaseQuotaCallback, + this); + ewk_view_exceeded_local_file_system_quota_callback_set( + wkView, + exceededLocalFileSystemQuotaCallback, + this); + ewk_view_geolocation_permission_callback_set( + wkView, + geolocationPermissionRequestCallback, + this); + ewk_view_user_media_permission_callback_set( + wkView, + usermediaPermissionRequestCallback, + this); + ewk_view_notification_permission_callback_set( + wkView, + notificationPermissionRequestCallback, + this); + ea_object_event_callback_add(wkView, + EA_CALLBACK_BACK, + eaKeyCallback, + this); + ea_object_event_callback_add(wkView, + EA_CALLBACK_MORE, + eaKeyCallback, + this); + // Always register access object even application doesn't support + // accessibility. In case of accessibility isn't supported, efl_assist + // shows warning message by syspopup. + // initScreenReaderSupport is related method. (window_data.cpp) + elm_access_object_register(wkView, m_window); + // add callback to handle rotary event + eext_rotary_object_event_callback_add(wkView, rotaryCallback, this); + eext_rotary_object_event_activated_set(wkView, EINA_TRUE); +} + +void ViewLogic::ewkClientDeinit(Evas_Object *wkView) +{ + LogDebug("ewkClientDeinit"); + AssertMsg(NULL != wkView, "ewk_view not created at this point"); + + FOREACH(it, m_ewkCallbacksMap) + { + evas_object_smart_callback_del( + wkView, + it->first.c_str(), + it->second); + } + ewk_view_exceeded_database_quota_callback_set(wkView, NULL, NULL); + ewk_view_exceeded_indexed_database_quota_callback_set(wkView, NULL, NULL); + ewk_view_exceeded_local_file_system_quota_callback_set(wkView, NULL, NULL); + ewk_view_geolocation_permission_callback_set(wkView, NULL, NULL); + ewk_view_user_media_permission_callback_set(wkView, NULL, NULL); + ewk_view_notification_permission_callback_set(wkView, NULL, NULL); + ea_object_event_callback_del(wkView, + EA_CALLBACK_BACK, + eaKeyCallback); + ea_object_event_callback_del(wkView, + EA_CALLBACK_MORE, + eaKeyCallback); +#ifdef ORIENTATION_ENABLED + if (m_orientationThresholdTimer) { + ecore_timer_del(m_orientationThresholdTimer); + m_orientationThresholdTimer = NULL; + } +#endif + elm_access_object_unregister(wkView); +} + +bool ViewLogic::createEwkView() +{ + LogDebug("createEwkView"); + ADD_PROFILING_POINT("ewk_view_add_with_context", "start"); + Evas_Object* newEwkView = addEwkView(); + ADD_PROFILING_POINT("ewk_view_add_with_context", "stop"); + + if (!newEwkView) { + LogError("View creation failed"); + Wrt::Popup::PopupInvoker().showInfo( + "Info", "View creation failed", "close"); + return false; + } + + // set cookie policy + // even arguments pass the ewkContext, this API should be called + // after webkit Evas_Object is created + Ewk_Cookie_Manager *ewkCookieManager; + ewkCookieManager = + ewk_context_cookie_manager_get(m_ewkContext); + ewk_cookie_manager_accept_policy_set(ewkCookieManager, + EWK_COOKIE_ACCEPT_POLICY_ALWAYS); + + if (m_currentEwkView) { + setEwkViewInvisible(m_currentEwkView); + } + + LogDebug("push webview: " << newEwkView); + m_ewkViewList.push_back(newEwkView); + m_currentEwkView = newEwkView; + return true; +} + +Evas_Object* ViewLogic::addEwkView() +{ + LogDebug("enter"); + Assert(m_window); + Assert(m_ewkContext); + Assert(m_pageGroup); + + static Evas_Smart* evasSmart = NULL; + static Ewk_View_Smart_Class ewkViewClass = + EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("WRT_VIEW"); + + if (!evasSmart) { + ewk_view_smart_class_set(&ewkViewClass); + + // register webkit callbacks like window open/close + ewkViewClass.window_create = createWindowCallback; + ewkViewClass.window_close = closeWindowCallback; +#ifdef ORIENTATION_ENABLED + ewkViewClass.orientation_lock = orientationLockCallback; + ewkViewClass.orientation_unlock = orientationUnLockCallback; +#endif + + evasSmart = evas_smart_class_new(&ewkViewClass.sc); + if (!evasSmart) { + _D("no evas smart"); + return NULL; + } + } + Evas_Object *ewkView = ewk_view_smart_add( + evas_object_evas_get(m_window), evasSmart, m_ewkContext, m_pageGroup); + if (!ewkView) { + _D("no ewk view"); + return NULL; + } + + evas_object_data_set(ewkView, EWK_SMART_CLASS_USER_DATA, this); + return ewkView; +} + +void ViewLogic::prepareEwkView(Evas_Object *wkView) +{ + LogDebug("prepareEwkView called"); + Assert(wkView); + Ewk_Settings* settings = ewk_view_settings_get(wkView); + + // set user agent +#if ENABLE(CUSTOM_USER_AGENT_SUPPORT) + std::string customUserAgent = m_model->SettingList.Get().getUserAgent(); + if (!customUserAgent.empty()) { + LogDebug("Setting custom user agent as: " << customUserAgent); + ewk_view_user_agent_set(wkView, customUserAgent.c_str()); + } else +#endif // ENABLE(CUSTOM_USER_AGENT_SUPPORT) + { + LogDebug("Setting user agent as: default"); + ewk_view_user_agent_set(wkView, NULL); + std::string defaultUA = ewk_view_user_agent_get(wkView); + LogDebug("webkit's UA: " << defaultUA); + } + + // set custom header : language + using namespace ViewModule::CustomHeaderSupport; + std::string customHeaderString = getValueByField(ACCEPT_LANGUAGE); + if (!customHeaderString.empty()) { + LogDebug("custom field=[" << ACCEPT_LANGUAGE << "]"); + LogDebug("custom value=[" << customHeaderString << "]"); + Eina_List* list = eina_list_append(NULL, customHeaderString.c_str()); + ewk_context_preferred_languages_set(list); + } + + // webkit NPAPI plugins is always on in wrt + ewk_settings_plugins_enabled_set(settings, EINA_TRUE); + ewk_settings_javascript_enabled_set(settings, EINA_TRUE); + ewk_settings_loads_images_automatically_set(settings, EINA_TRUE); + // WRT should not fit web contents to device width automatically as default. + // Fitting to device width should be handled by web content using viewport meta tag. + ewk_settings_auto_fitting_set(settings, EINA_FALSE); + ewk_settings_autofill_password_form_enabled_set(settings, EINA_TRUE); + ewk_settings_form_candidate_data_enabled_set(settings, EINA_TRUE); + + evas_object_show(wkView); + + // Set transparent view only for idle clock category + // If normal webapp accessing browser using access tag, background color should be white. + if (m_category == 1) { + ewk_view_bg_color_set(wkView, 0, 0, 0, 0); + } else { + ewk_view_bg_color_set(wkView, 0, 0, 0, 255); + } + + std::string encoding = DEFAULT_ENCODING; + OptionalWidgetStartFileInfo fileInfo = + W3CFileLocalization::getStartFileInfo(m_model->TizenId); + if (!!fileInfo) { + std::string file_encoding = DPL::ToUTF8String((*fileInfo).encoding); + + if(EINA_TRUE == ewk_settings_is_encoding_valid( + file_encoding.c_str())){ + encoding = file_encoding; + _D("Found custom encoding in DB: %s", encoding.c_str()); + } + + } + _D("Setting encoding: %s", encoding.c_str()); + if (ewk_settings_default_text_encoding_name_set(settings,encoding.c_str())) { + _D("Encoding set properly"); + } else { + _E("Error while setting encoding"); + } + +#if ENABLE(CONTENT_SECURITY_POLICY) + if (m_model->SecurityModelVersion.Get() == + WrtDB::WidgetSecurityModelVersion::WIDGET_SECURITY_MODEL_V2) + { + // setting CSP policy rules + DPL::OptionalString policy = m_model->CspReportOnlyPolicy.Get(); + if (!!policy) { + LogDebug("CSP report only policy present in manifest: " << *policy); + ewk_view_content_security_policy_set( + wkView, + DPL::ToUTF8String(*policy).c_str(), + EWK_REPORT_ONLY); + } + + policy = m_model->CspPolicy.Get(); + if (!!policy) { + LogDebug("CSP policy present in manifest: " << *policy); + ewk_view_content_security_policy_set( + wkView, + DPL::ToUTF8String(*policy).c_str(), + EWK_ENFORCE_POLICY); + } else { + ewk_view_content_security_policy_set( + wkView, + DEFAULT_CSP_POLICY, + EWK_ENFORCE_POLICY); + } + } +#endif +} + +void ViewLogic::removeEwkView(Evas_Object *wkView) +{ + LogDebug("removeEwkView called"); + Assert(wkView); + Assert(0 != m_ewkViewList.size()); + + // unregister webview callbacks + ewkClientDeinit(wkView); + + // suspend NPAPI plugin - Not implemented by Webkit2 + // ewk_view_pause_or_resume_plugins(); + evas_object_del(wkView); + m_ewkViewList.remove(wkView); +} + +void ViewLogic::setEwkViewInvisible(Evas_Object *wkView) +{ + LogDebug("setEwkViewInvisible called"); + Assert(wkView); + + evas_object_hide(wkView); +} + +void ViewLogic::setEwkViewVisible(Evas_Object *wkView) +{ + LogDebug("setEwkViewVisible called"); + Assert(wkView); + + evas_object_show(wkView); +} + +void ViewLogic::resumeWebkit(Evas_Object *wkView) +{ + LogDebug("resumeWebkit : " << wkView); + Assert(wkView); + + ewk_view_page_visibility_set(wkView, EWK_PAGE_VISIBILITY_STATE_VISIBLE, false); + + if (!m_isBackgroundSupport) { + LogDebug("background support is disabled. resume view"); + ewk_view_resume(wkView); + ewk_view_foreground_set(wkView, true); + } else { + LogDebug("background support is enabled. skip resume view"); + } + + return; +} + +void ViewLogic::suspendWebkit(Evas_Object *wkView) +{ + LogDebug("suspendWebkit : " << wkView); + Assert(wkView); + + ewk_view_page_visibility_set(wkView, EWK_PAGE_VISIBILITY_STATE_HIDDEN, false); + + if (!m_isBackgroundSupport) { + LogDebug("background support is disabled. suspend view"); + ewk_view_suspend(wkView); + ewk_view_foreground_set(wkView, false); + } else { + LogDebug("background support is enabled. skip suspend view"); + } + + return; +} + +void ViewLogic::loadStartedCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + Assert(data); + + ViewLogic* This = static_cast(data); + if (This->m_cbs->loadStartedCallback) { + This->m_cbs->loadStartedCallback(obj, eventInfo); + } +} + +void ViewLogic::loadFinishedCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + Assert(data); + + ViewLogic* This = static_cast(data); + + // Fill id/password + const char* url = ewk_view_url_get(This->m_currentEwkView); + if (NULL == url || strlen(url) == 0) { + LogError("url is empty"); + return; + } + + if (This->m_cbs->loadFinishedCallback) { + This->m_cbs->loadFinishedCallback(obj, eventInfo); + } + + // set only encoded bundle + double scale = elm_config_scale_get(); + ViewLogicMessageSupport::setCustomProperties( + This->m_ewkContext, + &scale, + ApplicationDataSingleton::Instance().getEncodedBundle()); +} + +void ViewLogic::loadProgressStartedCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + Assert(data); + + ViewLogic* This = static_cast(data); + if (This->m_cbs->loadProgressStartedCallback) { + This->m_cbs->loadProgressStartedCallback(obj, eventInfo); + } +} + +void ViewLogic::loadProgressCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + Assert(data); + Assert(eventInfo); + + ViewLogic* This = static_cast(data); + double* progress = static_cast(eventInfo); + _D("progress = %f", *progress); + if (This->m_cbs->loadProgressCallback) { + This->m_cbs->loadProgressCallback(obj, eventInfo); + } +} + +void ViewLogic::loadProgressFinishedCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + Assert(data); + + ViewLogic* This = static_cast(data); + if (This->m_cbs->loadProgressFinishedCallback) { + This->m_cbs->loadProgressFinishedCallback(obj, eventInfo); + } +} + +void ViewLogic::processCrashedCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + Assert(data); + + ViewLogic* This = static_cast(data); + if (This->m_cbs->processCrashedCallback) { + This->m_cbs->processCrashedCallback(obj, eventInfo); + } + // This flag will be prevented exit() call in the Webkit side + if (NULL != eventInfo) { + *(static_cast(eventInfo)) = EINA_TRUE; + } +} + +Evas_Object* ViewLogic::createWindowCallback( + Ewk_View_Smart_Data* sd, + const Ewk_Window_Features* /*windowFeatures*/) +{ + LogDebug("createWindowCallback"); + ViewLogic* This = static_cast( + evas_object_data_get(sd->self, EWK_SMART_CLASS_USER_DATA)); + if (This == NULL) { + LogError("This is null"); + return NULL; + } + + // First, current webview should be handled by user callback + if (This->m_cbs->unsetWebviewCallback) { + This->m_cbs->unsetWebviewCallback(sd->self); + } + + // create new ewkview + This->createEwkView(); + Evas_Object* newEwkView = This->m_currentEwkView; + + // initialize new ewkview + This->ewkClientInit(newEwkView); + This->prepareEwkView(newEwkView); + + // Lastly, new webview should be handled by user callback + if (This->m_cbs->setWebviewCallback) { + This->m_cbs->setWebviewCallback(newEwkView); + } + return newEwkView; +} + +void ViewLogic::closeWindowCallback(Ewk_View_Smart_Data* sd) +{ + LogDebug("closeWindowCallback"); + ViewLogic* This = static_cast( + evas_object_data_get(sd->self, EWK_SMART_CLASS_USER_DATA)); + if (This == NULL) { + LogError("This is null"); + return; + } + This->m_closedEwkView = sd->self; + ecore_idler_add(windowCloseIdlerCallback, This); +} + +#ifdef ORIENTATION_ENABLED +Eina_Bool ViewLogic::orientationLockCallback(Ewk_View_Smart_Data *sd, int orientation) +{ + LogDebug("orientationLockCallback"); + ViewLogic* This = static_cast( + evas_object_data_get(sd->self, EWK_SMART_CLASS_USER_DATA)); + + // Screen.lockOrientation + if (This->m_orientationThresholdTimer) { + This->m_deferredRotateAngle = orientation; + + return EINA_TRUE; + } + + int winAngle = + ViewModule::OrientationSupport::getWinOrientationAngle(orientation); + if (!This->m_cbs->setOrientation.empty()) { + This->m_cbs->setOrientation(winAngle); + } + ewk_context_tizen_extensible_api_set( + This->m_ewkContext, + EWK_EXTENSIBLE_API_ROTATION_LOCK, + EINA_TRUE); + This->m_orientationThresholdTimer = + ecore_timer_add(ORIENTATION_THRESHOLD, + orientationThresholdTimerCallback, + This); + + return EINA_TRUE; +} + +void ViewLogic::orientationUnLockCallback(Ewk_View_Smart_Data *sd) +{ + LogDebug("orientationUnLockCallback"); + ViewLogic* This = static_cast( + evas_object_data_get(sd->self, EWK_SMART_CLASS_USER_DATA)); + + // Screen.unlockOrientation + if (This->m_orientationThresholdTimer) { + This->m_deferredRotateAngle = + ViewModule::OrientationSupport::DEFERRED_ORIENTATION_UNLOCK; + + return; + } + + if (This->m_model->SettingList.Get().getRotationValue() == + Screen_AutoRotation) + { + if (!This->m_cbs->setOrientation.empty()) { + This->m_cbs->setOrientation(OrientationAngle::Window::UNLOCK); + } + This->m_rotateAngle = 0; + ewk_context_tizen_extensible_api_set( + This->m_ewkContext, + EWK_EXTENSIBLE_API_ROTATION_LOCK, + EINA_FALSE); + } +} +#endif + +void ViewLogic::policyNavigationDecideCallback( + void* data, + Evas_Object* obj, + void* eventInfo) +{ + _D("called"); + + Assert(data); + Assert(obj); + Assert(eventInfo); + + ViewLogic* This = static_cast(data); + Ewk_Policy_Decision* policyDecision = + static_cast(eventInfo); + + // handle blocked url + const char* url = ewk_policy_decision_url_get(policyDecision); + + // call user delegate callback + if (This->m_cbs->policyNavigationDecideCallback) { + if(!This->m_cbs->policyNavigationDecideCallback(obj, eventInfo)) { + _D(" URI is blocked for DynamicBox"); + ewk_policy_decision_ignore(policyDecision); + return; + } + std::string navigationUri(url); + if (!navigationUri.compare(0, 6, SCHEME_BOX_SLASH)) { + ewk_policy_decision_ignore(policyDecision); + return; + } + } + + if (url && strlen(url) != 0) { + if (This->m_blockedUri == url) { + LogDebug("Blocked url = " << url); + This->m_blockedUri = std::string(); + ewk_policy_decision_ignore(policyDecision); + return; + } + } + + if (ViewModule::SchemeSupport::filterURIByScheme(policyDecision, + false, + This->m_window, + This->m_currentEwkView)) + { + LogDebug("use"); + ewk_policy_decision_use(policyDecision); + } else { + // check whether this is new empty window + const char* activeUrl = ewk_view_url_get(This->m_currentEwkView); + if (!activeUrl || 0 == strlen(activeUrl)) { + /* + * The view is empty and scheme has been handled externally. When + * user gets back from the external application he'd see blank page + * and won't be able to navigate back. This happens when window.open + * is used to handle schemes like sms/mms/mailto (for example in + * WAC web standards tests: WS-15XX). + * + * To solve the problem, the empty view is removed from the stack + * and the previous one is shown. This is not an elegant solution + * but we don't have a better one. + */ + LogDebug("Scheme has been handled externally. Removing empty view."); + if (ewk_view_back_possible(This->m_currentEwkView)) { + // go back to previous WKPage + ewk_view_back(This->m_currentEwkView); + } else { + // stop current WKPage + ewk_view_stop(This->m_currentEwkView); + This->m_closedEwkView = This->m_currentEwkView; + ecore_idler_add(windowCloseIdlerCallback, This); + } + } + + LogDebug("ignore"); + ewk_policy_decision_ignore(policyDecision); + } +} + +void ViewLogic::policyNewWindowDecideCallback( + void* data, + Evas_Object* /*obj*/, + void* eventInfo) +{ + LogDebug("policyNewWindowDecideCallback called"); + Assert(data); + ViewLogic* This = static_cast(data); + Assert(eventInfo); + Ewk_Policy_Decision* policyDecision = + static_cast(eventInfo); + + // handle blocked url + const char* url = ewk_policy_decision_url_get(policyDecision); + if (url && strlen(url) != 0) { + if (This->m_blockedUri == url) { + LogDebug("Blocked url = " << url); + This->m_blockedUri = std::string(); + ewk_policy_decision_ignore(policyDecision); + return; + } + } + + if (ViewModule::SchemeSupport::filterURIByScheme(policyDecision, + true, + This->m_window, + This->m_currentEwkView)) + { + ewk_policy_decision_use(policyDecision); + } else { + // scheme handled + ewk_policy_decision_ignore(policyDecision); + } +} + +void ViewLogic::pageResponseDecideCallback( + void* data, + Evas_Object* /*obj*/, + void* eventInfo) +{ + LogDebug("pageResponseDecideCallback called"); + Assert(data); + ViewLogic* This = static_cast(data); + Assert(eventInfo); + Ewk_Policy_Decision* policyDecision = + static_cast(eventInfo); + Ewk_Policy_Decision_Type policyDecisionType = + ewk_policy_decision_type_get(policyDecision); + + if (policyDecisionType == EWK_POLICY_DECISION_USE) { + LogDebug("use"); + ewk_policy_decision_use(policyDecision); + } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) { + LogDebug("download"); + ewk_policy_decision_suspend(policyDecision); + + // get uri information + const char* url = ewk_policy_decision_url_get(policyDecision); + if (NULL == url || strlen(url) == 0) { + LogDebug("url data is empty"); + ewk_policy_decision_use(policyDecision); + return; + } + LogDebug("url = [" << url << "]"); + + // get content information + const char* content = + ewk_policy_decision_response_mime_get(policyDecision); + LogDebug("content type = [" << content << "]"); + + // get cookie information + const char* cookie = ewk_policy_decision_cookie_get(policyDecision); + LogDebug("cookie = [" << cookie << "]"); + + LogDebug("Content not supported, will be opened in external app"); + This->m_appsSupport->downloadRequest( + url, + content, + cookie); + ewk_policy_decision_ignore(policyDecision); + } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) { + LogDebug("ignore"); + ewk_policy_decision_ignore(policyDecision); + } else { + LogDebug("Type isn't handled"); + ewk_policy_decision_ignore(policyDecision); + } +} + +void ViewLogic::contextmenuCustomizeCallback( + void* data, + Evas_Object* /*obj*/, + void* eventInfo) +{ + LogDebug("contextmenuCustomizeCallback called"); + Assert(data); + Assert(eventInfo); + ViewLogic* This = static_cast(const_cast(data)); + Ewk_Context_Menu* menu = static_cast(eventInfo); + if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) && + (This->m_model->SettingList.Get().getContextMenu() + == ContextMenu_Disable)) + { + LogDebug("ContextMenu Disable!!"); + for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) { + Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu, + idx); + Assert(item); + ewk_context_menu_item_remove(menu, item); + } + } else { + LogDebug("ContextMenu Enable!!"); + unsigned int menu_num = ewk_context_menu_item_count(menu); + unsigned int idx = 0; + do { + Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu, + idx); + if (!item) { + idx++; + continue; + } + Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item); + + switch (tag) { + case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW: + ewk_context_menu_item_remove(menu, item); + continue; + + case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW: + ewk_context_menu_item_remove(menu, item); + continue; + + case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW: + ewk_context_menu_item_remove(menu, item); + continue; + + case EWK_CONTEXT_MENU_ITEM_OPEN_MEDIA_IN_NEW_WINDOW: + ewk_context_menu_item_remove(menu, item); + continue; + + case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB: + ewk_context_menu_item_remove(menu, item); + continue; + + case EWK_CONTEXT_MENU_ITEM_TAG_DOWNLOAD_IMAGE_TO_DISK: + ewk_context_menu_item_remove(menu, item); + continue; + + default: + idx++; + break; + } + } while (idx < menu_num); + } +} + +Eina_Bool ViewLogic::geolocationPermissionRequestCallback( + Evas_Object* /*obj*/, + Ewk_Geolocation_Permission_Request* geolocationPermissionRequest, + void* userData) +{ + Assert(userData); + Assert(geolocationPermissionRequest); + ViewLogic* This = static_cast(userData); + + DPL::OptionalBool ret = + This->m_privilegeSupport->getPrivilegeStatus(ViewModule::PrivilegeSupport::Privilege::LOCATION); + if (!!ret) { + ewk_geolocation_permission_reply(geolocationPermissionRequest, (*ret) ? EINA_TRUE : EINA_FALSE); + return EINA_TRUE; + } + + ViewModule::GeolocationSupport::GeoLocationData geoData; + geoData.data = userData; + geoData.permissionRequest = geolocationPermissionRequest; + geoData.pkgId = This->m_model->TzPkgId.Get(); + + ViewModule::GeolocationSupport::geolocationPermissionRequest( + This->m_currentEwkView, + This->m_securityOriginSupport->getSecurityOriginDAO(), + &geoData, + This->m_model->TizenId); + + return EINA_TRUE; +} + +void ViewLogic::notificationShowCallback( + void* data, + Evas_Object* /*obj*/, + void* eventInfo) +{ + Assert(eventInfo); + Ewk_Notification* ewkNotification = + static_cast(eventInfo); + ViewModule::WebNotificationDataPtr notiData( + new ViewModule::WebNotificationData(ewkNotification)); + + _D("notification id : %u", notiData->getEwkNotiId()); + _D("notification iconURL : %s", notiData->getIconUrl()); + _D("notification title : %s", notiData->getTitle()); + _D("notification body : %s", notiData->getBody()); + + Assert(data); + ViewLogic* This = static_cast(data); + if (This->m_webNotificationSupport->show(notiData)) { + ewk_notification_showed(This->m_ewkContext, notiData->getEwkNotiId()); + } +} + +void ViewLogic::notificationCancelCallback( + void* data, + Evas_Object* obj, + void* eventInfo) +{ + Assert(eventInfo); + uint64_t ewkNotiId = *static_cast(eventInfo); + + Assert(data); + ViewLogic* This = static_cast(data); + Ewk_Notification* ewkNotification = + static_cast( + This->m_webNotificationSupport->hide(ewkNotiId)); + if (ewkNotification) { + Assert(obj); + Eina_List* list = NULL; + list = eina_list_append(list, ewkNotification); + ewk_view_notification_closed(obj, list); + eina_list_free(list); + } +} + +Eina_Bool ViewLogic::notificationPermissionRequestCallback( + Evas_Object* obj, + Ewk_Notification_Permission_Request* request, + void* userData) +{ + LogDebug("called"); + Assert(userData); + ViewLogic* This = static_cast(userData); + + Assert(request); + ViewModule::WebNotificationPermissionSupport::permissionRequest( + This->m_currentEwkView, + This->m_securityOriginSupport->getSecurityOriginDAO(), + request); + return EINA_TRUE; +} + +// Fullscreen API callbacks +void ViewLogic::enterFullscreenCallback( + void* data, + Evas_Object* obj, + void* eventInfo) +{ + _D("called"); + + Assert(data); + + ViewLogic* This = static_cast(data); + ViewLogicMessageSupport::setViewmodes( + This->m_ewkContext, + "fullscreen"); + + if (eventInfo) { + This->m_isFullscreenByPlatform = + *static_cast(eventInfo) == EINA_TRUE; + } + if (This->m_cbs->enterFullscreenCallback) { + This->m_cbs->enterFullscreenCallback(obj, eventInfo); + } +} + +void ViewLogic::exitFullscreenCallback( + void* data, + Evas_Object* obj, + void* eventInfo) +{ + _D("called"); + + Assert(data); + + ViewLogic* This = static_cast(data); + ViewLogicMessageSupport::setViewmodes( + This->m_ewkContext, + Message::ToInjectedBundle::SET_VIEWMODES_MSGBODY_EXIT); + + This->m_isFullscreenByPlatform = false; + if (This->m_cbs->exitFullscreenCallback) { + This->m_cbs->exitFullscreenCallback(obj, eventInfo); + } +} + +void ViewLogic::enabledVideoHwOverlayCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + Assert(data); + + ViewLogic* This = static_cast(data); + if (This->m_cbs->enableVideoHwOverlayCallback) { + This->m_cbs->enableVideoHwOverlayCallback(obj, eventInfo); + } +} + +void ViewLogic::disabledVideoHwOverlayCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + Assert(data); + + ViewLogic* This = static_cast(data); + if (This->m_cbs->disableVideoHwOverlayCallback) { + This->m_cbs->disableVideoHwOverlayCallback(obj, eventInfo); + } +} + +void ViewLogic::imeChangedCallback( + void* data, + Evas_Object* /*obj*/, + void* eventInfo) +{ + LogDebug("enter"); + Assert(data); + Assert(eventInfo); + ViewLogic* This = static_cast(data); + Eina_Rectangle *rect = static_cast(eventInfo); + This->m_imeWidth = rect->w; + This->m_imeHeight = rect->h; +} + +void ViewLogic::imeOpenedCallback( + void* data, + Evas_Object* /*obj*/, + void* /*eventInfo*/) +{ + LogDebug("enter"); + Assert(data); + ViewLogic* This = static_cast(data); + + using namespace WrtPlugins::W3C; + SoftKeyboardChangeArgs args; + args.state = IME_STATE_ON; + args.width = This->m_imeWidth; + args.height = This->m_imeHeight; + This->fireJavascriptEvent( + static_cast(SoftKeyboardChangeCustomEvent), + &args); +} + +void ViewLogic::imeClosedCallback( + void* data, + Evas_Object* /*obj*/, + void* /*eventInfo*/) +{ + LogDebug("enter"); + Assert(data); + ViewLogic* This = static_cast(data); + + using namespace WrtPlugins::W3C; + SoftKeyboardChangeArgs args; + args.state = IME_STATE_OFF; + This->fireJavascriptEvent( + static_cast(SoftKeyboardChangeCustomEvent), + &args); +} + +Eina_Bool ViewLogic::usermediaPermissionRequestCallback( + Evas_Object* /*obj*/, + Ewk_User_Media_Permission_Request* request, + void* userData) +{ + LogDebug("called"); + Assert(userData); + ViewLogic* This = static_cast(userData); + + DPL::OptionalBool ret = + This->m_privilegeSupport->getPrivilegeStatus(ViewModule::PrivilegeSupport::Privilege::MEDIACAPTURE); + if (!!ret) { + ewk_user_media_permission_reply(request, (*ret) ? EINA_TRUE : EINA_FALSE); + return EINA_TRUE; + } + + ViewModule::UsermediaSupport::usermediaPermissionRequest( + This->m_currentEwkView, + This->m_securityOriginSupport->getSecurityOriginDAO(), + request, + This->m_model->TizenId); + return EINA_TRUE; +} + +// helper method +CustomHandlerDB::CustomHandlerPtr getCustomHandlerFromData(void* data) +{ + Assert(data); + Ewk_Custom_Handlers_Data* handler = + static_cast(data); + CustomHandlerDB::CustomHandlerPtr customHandler( + new CustomHandlerDB::CustomHandler()); + const char* base_url = ewk_custom_handlers_data_base_url_get(handler); + if (base_url) { + LogDebug("base url: " << base_url); + customHandler->base_url = DPL::FromASCIIString(string(base_url)); + } + const char* url = ewk_custom_handlers_data_url_get(handler); + if (url) { + LogDebug("url: " << url); + customHandler->url = DPL::FromASCIIString(string(url)); + } + const char* target = ewk_custom_handlers_data_target_get(handler); + if (target) { + LogDebug("target: " << target); + customHandler->target = DPL::FromASCIIString(string(target)); + } + const char* title = ewk_custom_handlers_data_title_get(handler); + if (title) { + LogDebug("title: " << title); + customHandler->title = DPL::FromASCIIString(string(title)); + } + return customHandler; +} + +void ViewLogic::attachToCustomHandlersDao() +{ + if (!m_attachedToCustomHandlerDao) { + CustomHandlerDB::Interface::attachDatabaseRW(); + } +} + +void ViewLogic::detachFromCustomHandlersDao() +{ + if (m_attachedToCustomHandlerDao) { + CustomHandlerDB::Interface::detachDatabase(); + } +} + +const int protocolWhiteListLenth = 15; +char const * const protocolWhiteList[protocolWhiteListLenth] = { + "irc", + "geo", + "mailto", + "magnet", + "mms", + "news", + "nntp", + "sip", + "sms", + "smsto", + "ssh", + "tel", + "urn", + "webcal", + "xmpp" +}; + +const int contentBlackListLenth = 14; +char const * const contentBlackList[contentBlackListLenth] = { + "application/x-www-form-urlencoded", + "application/xhtml+xml", + "application/xml", + "image/gif", + "image/jpeg", + "image/png", + "image/svg+xml", + "multipart/x-mixed-replace", + "text/cache-manifest", + "text/css", + "text/html", + "text/ping", + "text/plain", + "text/xml" +}; + +/** + * Saves user's response from popup to custom handler. Saves Yes/No and remember + * state. + * @param response + * @param customHandler + */ +void saveUserResponse(Wrt::Popup::PopupResponse response, + CustomHandlerDB::CustomHandlerPtr customHandler) +{ + switch (response) { + case Wrt::Popup::YES_DO_REMEMBER: + LogDebug("User allowed, remember"); + customHandler->user_decision = + static_cast + (CustomHandlerDB::Agreed | CustomHandlerDB::DecisionSaved); + break; + case Wrt::Popup::YES_DONT_REMEMBER: + LogDebug("User allowed, don't remember"); + customHandler->user_decision = CustomHandlerDB::Agreed; + break; + case Wrt::Popup::NO_DO_REMEMBER: + LogDebug("User didn't allow, remember"); + customHandler->user_decision = + static_cast + (CustomHandlerDB::Declined | CustomHandlerDB::DecisionSaved); + break; + case Wrt::Popup::NO_DONT_REMEMBER: + LogDebug("User didn't allow, don't remember"); + customHandler->user_decision = CustomHandlerDB::Declined; + break; + } +} + +//TODO registration, checking if registered and unregistration can be done in +//common functions for both types of handlers. Only white and black lists +//have to be separated +//TODO attach database only one at the start (not in every callback?) +void ViewLogic::protocolHandlerRegistrationCallback(void* data, + Evas_Object* /*obj*/, + void* eventInfo) +{ + Assert(data); + LogDebug("enter"); + CustomHandlerDB::CustomHandlerPtr customHandler = + getCustomHandlerFromData(eventInfo); + + std::string scheme = DPL::ToUTF8String(customHandler->target); + if (scheme.empty()) { + LogError("No scheme provided"); + //TODO what about securityError? + return; + } + bool matched = false; + //scheme on whiteList + for (int i = 0; i < protocolWhiteListLenth; ++i) { + if (0 == strcmp(protocolWhiteList[i], scheme.c_str())) { + LogDebug("Match found, protocol can be handled"); + matched = true; + } + } + if (!matched) { + //starts with web+ and have at least 5 chars (lowercase ASCII) + if (strncmp("web+", scheme.c_str(), 4) || scheme.length() < 5) { + LogWarning("Scheme neither on whitelist nor starts with \"web+\""); + //throw SecurityException + return; + } + int l = 4; + char c = scheme[l]; + while (c != '\0') { + if (c < 'a' || c > 'z') { + LogWarning("Wrong char inside scheme. " + << "Only lowercase ASCII letters accepted"); + //throw SecurityException + return; + } + c = scheme[++l]; + } + } + + ViewLogic* This = static_cast(data); + LogDebug("Creating handlers dao"); + This->attachToCustomHandlersDao(); + CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId); + CustomHandlerDB::CustomHandlerPtr handler = + handlersDao.getProtocolHandler(customHandler->target, + customHandler->url, + customHandler->base_url); + if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) { + LogDebug("Protocol already registered - nothing to do"); + } else { + LogDebug("Protocol handler not found"); + Wrt::Popup::PopupResponse response = + GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup:: + YES_DO_REMEMBER : + Wrt::Popup::PopupInvoker().askYesNoCheckbox( + PROTOCOL_HANDLER_ASK_TITLE, + PROTOCOL_HANDLER_ASK_MSG, + PROTOCOL_HANDLER_ASK_REMEMBER); + saveUserResponse(response, customHandler); + if (customHandler->user_decision == CustomHandlerDB::Declined) { + return; + } + if (customHandler->user_decision & CustomHandlerDB::Agreed) { + //TODO remove old default handler somehow from appsvc + LogDebug("Registering appservice entry"); + int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW, + NULL, + DPL::ToUTF8String( + customHandler->target).c_str(), + DPL::ToUTF8String(This->m_model-> + TizenId).c_str()); + if (APPSVC_RET_OK != ret) { + LogWarning("Appsvc entry failed: " << ret); + //no database change + return; + } + } + handlersDao.registerProtocolHandler(*(customHandler.get())); + + LogDebug("Protocal saved"); + } + + This->detachFromCustomHandlersDao(); +} + +void ViewLogic::protocolHandlerIsRegisteredCallback(void* data, + Evas_Object* /*obj*/, + void* eventInfo) +{ + LogDebug("enter"); + CustomHandlerDB::CustomHandlerPtr customHandler = getCustomHandlerFromData( + eventInfo); + ViewLogic* This = static_cast(data); + LogDebug("Creating handlers dao"); + This->attachToCustomHandlersDao(); + CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId); + CustomHandlerDB::CustomHandlerPtr handler = + handlersDao.getProtocolHandler(customHandler->target, + customHandler->url, + customHandler->base_url); + if (handler) { + if (handler->user_decision & CustomHandlerDB::Agreed) { + ewk_custom_handlers_data_result_set( + static_cast(eventInfo), + EWK_CUSTOM_HANDLERS_REGISTERED); + } else { + ewk_custom_handlers_data_result_set( + static_cast(eventInfo), + EWK_CUSTOM_HANDLERS_DECLINED); + } + } else { + ewk_custom_handlers_data_result_set( + static_cast(eventInfo), + EWK_CUSTOM_HANDLERS_NEW); + } + This->detachFromCustomHandlersDao(); +} + +void ViewLogic::protocolHandlerUnregistrationCallback(void* data, + Evas_Object* /*obj*/, + void* eventInfo) +{ + LogDebug("enter"); + CustomHandlerDB::CustomHandlerPtr customHandler = + getCustomHandlerFromData(eventInfo); + ViewLogic* This = static_cast(data); + LogDebug("Creating handlers dao"); + This->attachToCustomHandlersDao(); + CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId); + CustomHandlerDB::CustomHandlerPtr handlerCheck = + handlersDao.getProtocolHandler(customHandler->target, + customHandler->url, + customHandler->base_url); + This->detachFromCustomHandlersDao(); + if (handlerCheck) { + if (handlerCheck->user_decision & CustomHandlerDB::Agreed) { + int ret = appsvc_unset_defapp( + DPL::ToUTF8String(This->m_model->TizenId).c_str()); + if (APPSVC_RET_OK != ret) { + LogWarning("Failed to unregister appsvc entry"); + return; + } + } + //if appsvc ok change custom_handlers_db + handlersDao.unregisterProtocolHandler(customHandler->target, + customHandler->url, + customHandler->base_url); + } else { + LogDebug("Nothing to unregister"); + } +} + +void ViewLogic::contentHandlerRegistrationCallback(void* data, + Evas_Object* /*obj*/, + void* eventInfo) +{ + Assert(data); + LogDebug("enter"); + CustomHandlerDB::CustomHandlerPtr customHandler = + getCustomHandlerFromData(eventInfo); + + std::string mimeType = DPL::ToUTF8String(customHandler->target); + if (mimeType.empty()) { + LogError("No mimeType provided."); + return; + } + for (int i = 0; i < contentBlackListLenth; ++i) { + if (0 == strcmp(contentBlackList[i], mimeType.c_str())) { + LogWarning("mimeType blacklisted"); + //throw SecurityException + return; + } + } + + ViewLogic* This = static_cast(data); + LogDebug("Creating handlers dao"); + This->attachToCustomHandlersDao(); + CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId); + CustomHandlerDB::CustomHandlerPtr handler = + handlersDao.getContentHandler(customHandler->target, + customHandler->url, + customHandler->base_url); + if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) { + LogDebug("Protocol already registered - nothing to do"); + } else { + LogDebug("Protocol handler not found"); + Wrt::Popup::PopupResponse response = + GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup:: + YES_DO_REMEMBER : + Wrt::Popup::PopupInvoker().askYesNoCheckbox( + CONTENT_HANDLER_ASK_TITLE, + CONTENT_HANDLER_ASK_MSG, + CONTENT_HANDLER_AKS_REMEMBER); + saveUserResponse(response, customHandler); + if (customHandler->user_decision == CustomHandlerDB::Declined) { + return; + } + if (customHandler->user_decision & CustomHandlerDB::Agreed) { + //TODO remove old default handler somehow from appsvc + LogDebug("Registering appservice entry"); + int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW, + DPL::ToUTF8String( + customHandler->target).c_str(), + NULL, + DPL::ToUTF8String(This->m_model-> + TizenId).c_str()); + if (APPSVC_RET_OK != ret) { + LogWarning("Appsvc entry failed: " << ret); + return; + } + } + handlersDao.registerContentHandler(*(customHandler.get())); + LogDebug("Content saved"); + } + This->detachFromCustomHandlersDao(); +} + +void ViewLogic::contentHandlerIsRegisteredCallback(void* data, + Evas_Object* /*obj*/, + void* eventInfo) +{ + LogDebug("enter"); + CustomHandlerDB::CustomHandlerPtr customHandler = + getCustomHandlerFromData(eventInfo); + ViewLogic* This = static_cast(data); + LogDebug("Creating handlers dao"); + + This->attachToCustomHandlersDao(); + CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId); + CustomHandlerDB::CustomHandlerPtr handler = + handlersDao.getContentHandler(customHandler->target, + customHandler->url, + customHandler->base_url); + if (handler) { + if (handler->user_decision & CustomHandlerDB::Agreed) { + ewk_custom_handlers_data_result_set( + static_cast(eventInfo), + EWK_CUSTOM_HANDLERS_REGISTERED); + } else { + ewk_custom_handlers_data_result_set( + static_cast(eventInfo), + EWK_CUSTOM_HANDLERS_DECLINED); + } + } else { + ewk_custom_handlers_data_result_set( + static_cast(eventInfo), + EWK_CUSTOM_HANDLERS_NEW); + } + This->detachFromCustomHandlersDao(); +} + +void ViewLogic::contentHandlerUnregistrationCallback(void* data, + Evas_Object* /*obj*/, + void* eventInfo) +{ + LogDebug("enter"); + CustomHandlerDB::CustomHandlerPtr customHandler = + getCustomHandlerFromData(eventInfo); + ViewLogic* This = static_cast(data); + LogDebug("Creating handlers dao"); + This->attachToCustomHandlersDao(); + CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId); + CustomHandlerDB::CustomHandlerPtr handlerCheck = + handlersDao.getContentHandler(customHandler->target, + customHandler->url, + customHandler->base_url); + This->detachFromCustomHandlersDao(); + if (handlerCheck) { + if (handlerCheck->user_decision & CustomHandlerDB::Agreed) { + int ret = appsvc_unset_defapp( + DPL::ToUTF8String(This->m_model->TizenId).c_str()); + if (APPSVC_RET_OK != ret) { + LogWarning("Failed to unregister mime handler from appsvc"); + return; + } + } + handlersDao.unregisterContentHandler(customHandler->target, + customHandler->url, + customHandler->base_url); + } else { + LogDebug("Nothing to unregister"); + } +} + +void ViewLogic::didRunJavaScriptCallback( + Evas_Object* /*obj*/, + const char* result, + void* /*userData*/) +{ + LogDebug("didRunJavaScriptCallback called"); + LogDebug("result = " << result); +} + +void ViewLogic::eaKeyCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + Assert(data); + Assert(obj); + + ViewLogic* This = static_cast(data); + + Ea_Callback_Type keyType = + static_cast(reinterpret_cast(eventInfo)); + + LogDebug("Key = [" << keyType << "]"); + + std::string keyName; + if (keyType == EA_CALLBACK_BACK) { + Assert(obj); + // Call fullscreen exit API + // In case of fullscreen is entered by platform(default video tag), + // automatically exit fullscreen when backkey is selected + if (This->m_isFullscreenByPlatform) { + ewk_view_fullscreen_exit(obj); + return; + } + + // Call text selection clear API + // In case of current state is selection mode, + // application doesn't need to handle back key + if (EINA_TRUE == ewk_view_text_selection_clear(obj)) { + return; + } + keyName = KeyName::BACK; + } else if (keyType == EA_CALLBACK_MORE) { + keyName = KeyName::MENU; + } else { + return; + } + + if (This->m_model->SettingList.Get().getHWkeyEvent() == HWkeyEvent_Enable) + { + DispatchEventSupport::dispatchHwKeyEvent(obj, keyName); + } + if (This->m_cbs->keyCallback) { + This->m_cbs->keyCallback(obj, eventInfo); + } + + return; +} + +Eina_Bool ViewLogic::rotaryCallback(void* /*data*/, Evas_Object *obj, Eext_Rotary_Event_Info *info) +{ + Assert(obj); + + std::stringstream script; + + script << "var __event = document.createEvent(\"CustomEvent\");\n" + << "var __detail = {};\n" + << "__event.initCustomEvent(\"rotarydetent\", true, true, __detail);\n" + << "__event.detail.direction = \"" << (info->direction == EEXT_ROTARY_DIRECTION_CLOCKWISE ? "CW" : "CCW") << "\";\n" + << "document.dispatchEvent(__event);\n" + << "\n" + << "for (var i=0; i < window.frames.length; i++)\n" + << "{ window.frames[i].document.dispatchEvent(__event); }"; + + // just for debugging + LogDebug("script :\n" << script.str()); + + if (ewk_view_script_execute(obj, script.str().c_str(), NULL, NULL) != EINA_TRUE) + { + LogWarning("ewk_view_script_execute returned FALSE!"); + } + + return true; +} + +Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data) +{ + LogDebug("closeIdlerCallback"); + ViewLogic* This = static_cast(data); + This->windowClose(); + return ECORE_CALLBACK_CANCEL; +} + +Eina_Bool ViewLogic::exceededDatabaseQuotaCallback(Evas_Object* obj, + Ewk_Security_Origin* origin, + const char* , + unsigned long long , + void* data) +{ + LogDebug("exceededDatabaseQuotaCallback called"); + Assert(data); + ViewLogic* This = static_cast(data); + ViewModule::WebStorageSupport::createPermissionRequest( + This->m_currentEwkView, + This->m_securityOriginSupport->getSecurityOriginDAO(), + obj, + origin, + ewk_view_exceeded_database_quota_reply); + return EINA_TRUE; +} + +Eina_Bool ViewLogic::exceededIndexedDatabaseQuotaCallback(Evas_Object* obj, + Ewk_Security_Origin* origin, + long long , + void* data) +{ + LogDebug("exceededIndexedDatabaseQuotaCallback called"); + Assert(data); + ViewLogic* This = static_cast(data); + ViewModule::WebStorageSupport::createPermissionRequest( + This->m_currentEwkView, + This->m_securityOriginSupport->getSecurityOriginDAO(), + obj, + origin, + ewk_view_exceeded_indexed_database_quota_reply); + return EINA_TRUE; +} + +Eina_Bool ViewLogic::exceededLocalFileSystemQuotaCallback(Evas_Object* obj, + Ewk_Security_Origin* origin, + long long , + void* data) +{ + LogDebug("exceededLocalFileSystemQuotaCallback called"); + Assert(data); + ViewLogic* This = static_cast(data); + ViewModule::WebStorageSupport::createPermissionRequest( + This->m_currentEwkView, + This->m_securityOriginSupport->getSecurityOriginDAO(), + obj, + origin, + ewk_view_exceeded_local_file_system_quota_reply); + return EINA_TRUE; +} + +void ViewLogic::certificateConfirmRequestCallback( + void* data, + Evas_Object* /*obj*/, + void* eventInfo) +{ + LogDebug("certificateConfirmRequestCallback called"); + + Assert(data); + ViewLogic* This = static_cast(data); + Assert(eventInfo); + ViewModule::CertificateConfirmSupport::certificatePermissionRequest( + This->m_currentEwkView, + This->m_certificateSupport->getCertificateDAO(), + eventInfo); +} + +void ViewLogic::authenticationRequestCallback( + void* data, + Evas_Object* /*obj*/, + void* eventInfo) +{ + LogDebug("authenticationRequestCallback called"); + Assert(data); + Assert(eventInfo); + + ViewLogic* This = static_cast(data); + const char* url = ewk_view_url_get(This->m_currentEwkView); + if (!url || strlen(url) == 0) { + Ewk_Auth_Request* authRequest = static_cast(eventInfo); + ewk_auth_request_cancel(authRequest); + return; + } + ViewModule::AuthenticationRequestSupport::authenticationRequest( + This->m_currentEwkView, + url, + eventInfo); +} + +void ViewLogic::viewFrameRenderedCallback( + void* data, + Evas_Object* obj, + void* eventInfo) +{ + _D("enter"); + + Assert(data); + ViewLogic* This = static_cast(data); + + if (This->m_cbs->frameRenderedCallback) { + This->m_cbs->frameRenderedCallback(obj, eventInfo); + } +} + +#ifdef ORIENTATION_ENABLED +void ViewLogic::mediacontrolRotateHorizontal(void* data, + Evas_Object* obj, + void* /*eventInfo*/) +{ + LogDebug("mediacontrolRotateHorizontal called"); + Assert(data); + Assert(obj); + ViewLogic* This = static_cast(data); + ViewModule::OrientationSupport::setEwkOrientation( + obj, + OrientationAngle::W3C::Landscape::PRIMARY); + if (This->m_cbs->orientationLockCallback) { + This->m_cbs->orientationLockCallback(OrientationAngle::Window::Landscape::PRIMARY); + } +} + +void ViewLogic::mediacontrolRotateVertical(void* data, + Evas_Object* obj, + void* /*eventInfo*/) +{ + LogDebug("mediacontrolRotateVertical called"); + Assert(data); + Assert(obj); + ViewLogic* This = static_cast(data); + ViewModule::OrientationSupport::setEwkOrientation( + obj, + OrientationAngle::W3C::Portrait::PRIMARY); + if (This->m_cbs->orientationLockCallback) { + This->m_cbs->orientationLockCallback(OrientationAngle::Window::Portrait::PRIMARY); + } +} + +void ViewLogic::mediacontrolRotateExit(void* data, + Evas_Object* obj, + void* /*eventInfo*/) +{ + LogDebug("mediacontrolRotateExit called"); + Assert(data); + Assert(obj); + ViewLogic* This = static_cast(data); + + int w3cAngle = 0; + int winAngle = 0; + if (This->m_rotateAngle == 0) { + // application hasn't call orientation lock + WidgetSettingScreenLock screenLock = + This->m_model->SettingList.Get().getRotationValue(); + if (screenLock == Screen_Portrait) { + w3cAngle = OrientationAngle::W3C::Portrait::PRIMARY; + winAngle = OrientationAngle::Window::Portrait::PRIMARY; + } else if (screenLock == Screen_Landscape) { + w3cAngle = OrientationAngle::W3C::Landscape::PRIMARY; + winAngle = OrientationAngle::Window::Landscape::PRIMARY; + } else if (screenLock == Screen_AutoRotation) { + if (This->m_cbs->orientationLockCallback) { + This->m_cbs->orientationLockCallback(OrientationAngle::Window::UNLOCK); + } + return; + } + } else { + // Restore previous orientation + w3cAngle = + ViewModule::OrientationSupport::getW3COrientationAngle( + This->m_rotateAngle); + winAngle = + ViewModule::OrientationSupport::getWinOrientationAngle( + This->m_rotateAngle); + } + + ViewModule::OrientationSupport::setEwkOrientation(obj, w3cAngle); + if (This->m_cbs->orientationLockCallback) { + This->m_cbs->orientationLockCallback(winAngle); + } + +} + +Eina_Bool ViewLogic::orientationThresholdTimerCallback(void* data) +{ + LogDebug("orientationThresholdTimerCallback"); + ViewLogic* This = static_cast(data); + + if (This->m_deferredRotateAngle == + ViewModule::OrientationSupport::DEFERRED_ORIENTATION_EMPTY) + { + // There is no defered orientation API call + This->m_orientationThresholdTimer = NULL; + return ECORE_CALLBACK_CANCEL; + } + + if (This->m_deferredRotateAngle != This->m_rotateAngle) { + This->m_rotateAngle = This->m_deferredRotateAngle; + int w3cAngle = 0; + int winAngle = 0; + if (This->m_rotateAngle == 0) { + WidgetSettingScreenLock screenLock = + This->m_model->SettingList.Get().getRotationValue(); + if (screenLock == Screen_Portrait) { + w3cAngle = OrientationAngle::W3C::Portrait::PRIMARY; + winAngle = OrientationAngle::Window::Portrait::PRIMARY; + } else if (screenLock == Screen_Landscape) { + w3cAngle = OrientationAngle::W3C::Landscape::PRIMARY; + winAngle = OrientationAngle::Window::Landscape::PRIMARY; + } else if (screenLock == Screen_AutoRotation) { + if (This->m_cbs->orientationLockCallback) { + This->m_cbs->orientationLockCallback(OrientationAngle::Window::UNLOCK); + } + This->m_orientationThresholdTimer = NULL; + return ECORE_CALLBACK_CANCEL; + } + } else { + // Restore previous orientation + w3cAngle = + ViewModule::OrientationSupport::getW3COrientationAngle( + This->m_rotateAngle); + winAngle = + ViewModule::OrientationSupport::getWinOrientationAngle( + This->m_rotateAngle); + } + + ViewModule::OrientationSupport::setEwkOrientation( + This->m_currentEwkView, + w3cAngle); + if (This->m_cbs->orientationLockCallback) { + This->m_cbs->orientationLockCallback(winAngle); + } + This->m_deferredRotateAngle = + ViewModule::OrientationSupport::DEFERRED_ORIENTATION_EMPTY; + return ECORE_CALLBACK_RENEW; + } + + This->m_orientationThresholdTimer = NULL; + return ECORE_CALLBACK_CANCEL; +} +#endif + +void ViewLogic::popupReplyWaitStart(void* data, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + Assert(data); + + ViewLogic* This = static_cast(data); + This->m_isPopupReplyWait = true; + if (This->m_cbs->popupReplyWaitStartCallback) { + This->m_cbs->popupReplyWaitStartCallback(obj, eventInfo); + } +} + +void ViewLogic::popupReplyWaitFinish(void* data, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + Assert(data); + + ViewLogic* This = static_cast(data); + This->m_isPopupReplyWait = false; + if (This->m_cbs->popupReplyWaitFinishCallback) { + This->m_cbs->popupReplyWaitFinishCallback(obj, eventInfo); + } +} + +void ViewLogic::consoleMessageCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + Assert(data); + + ViewLogic* This = static_cast(data); + if (This->m_cbs->consoleMessageCallback) { + This->m_cbs->consoleMessageCallback(obj, eventInfo); + } +} + +#ifdef ORIENTATION_ENABLED +void ViewLogic::rotatePreparedCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + Assert(data); + + ViewLogic* This = static_cast(data); + if (This->m_cbs->rotatePreparedCallback) { + This->m_cbs->rotatePreparedCallback(obj, eventInfo); + } +} +#endif + +void ViewLogic::windowClose() +{ + LogDebug("windowClose"); + AssertMsg(m_closedEwkView, "no closed webview"); + + if (1 >= m_ewkViewList.size()) { + if (m_cbs->processExitCallback) { + m_cbs->processExitCallback(m_closedEwkView, NULL); + } + } else { + // call user callbacks + if (m_cbs->unsetWebviewCallback) { + m_cbs->unsetWebviewCallback(m_currentEwkView); + } + removeEwkView(m_closedEwkView); + + // get latest ewkView + m_currentEwkView = m_ewkViewList.back(); + + setEwkViewVisible(m_currentEwkView); + + // show ewkView + if (m_cbs->setWebviewCallback) { + m_cbs->setWebviewCallback(m_currentEwkView); + } + } +} + +void ViewLogic::systemSettingsChangedCallback(system_settings_key_e key, + void* data) +{ + LogDebug("systemSettingsChanged"); + LogDebug("System setting Key is [" << key << "]"); + + Assert(data); + ViewLogic* This = static_cast(data); + + if (SYSTEM_SETTINGS_KEY_FONT_TYPE == key) { + if (!This->m_currentEwkView) { + LogError("ewkView isn't initialized"); + return; + } + ewk_view_use_settings_font(This->m_currentEwkView); + } else { + LogError("Unregister system callback is called"); + } +} + +void ViewLogic::vibrateCallback(void* data, Evas_Object* /*obj*/, void* eventInfo) +{ + ViewLogic* This = static_cast(data); + unsigned* vibrationTime = static_cast(eventInfo); + This->activateVibration(true, static_cast(*vibrationTime)); +} + +void ViewLogic::cancelVibrationCallback(void* data, Evas_Object* /*obj*/, void* /*eventInfo*/) +{ + ViewLogic* This = static_cast(data); + This->activateVibration(false, 0); +} + + diff --git a/src/view/webkit/view_logic.h b/src/view/webkit/view_logic.h new file mode 100644 index 0000000..452960d --- /dev/null +++ b/src/view/webkit/view_logic.h @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @brief Declaration file for view logic for Webkit2 + */ + +#ifndef VIEW_LOGIC_H_ +#define VIEW_LOGIC_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +namespace ViewModule { +class CertificateSupport; +class PrivilegeSupport; +class SecurityOriginSupport; +class WebNotificationSupport; +} + +class ViewLogic : public ViewModule::IViewModule +{ + public: + ViewLogic(); + virtual ~ViewLogic(); + + // IViewModule Impl + bool createView(Ewk_Context* context, + Evas_Object* window); + void destroyWebView(); + void prepareView(WidgetModel* m, const std::string &startUrl, int category); + void showWidget(); + void hideWidget(); + void suspendWidget(); + void resumeWidget(); + void resetWidgetFromSuspend(); + void resetWidgetFromResume(); + void TimeTick(long time); + void AmbientTick(long time); + void AmbientModeChanged(bool ambient_mode); + void backward(); + void reloadStartPage(); + Evas_Object* getCurrentWebview(); + void fireJavascriptEvent(int event, void* data); + void setUserCallbacks(const WRT::UserDelegatesPtr& cbs); + void checkSyncMessageFromBundle( + const char* name, + const char* body, + char** returnData); + void checkAsyncMessageFromBundle( + const char* name, + const char* body); + void downloadData(const char* url); + void activateVibration(bool on, uint64_t time); + + + private: + void initializeSupport(); + void initializePluginLoading(); + void initializeXwindowHandle(); + void resetWidgetCommon(); + + // EwkView operations + Evas_Object* addEwkView(); + void ewkClientInit(Evas_Object *wkView); + void ewkClientDeinit(Evas_Object *wkView); + bool createEwkView(); + void prepareEwkView(Evas_Object *wkView); + void removeEwkView(Evas_Object *wkView); + void setEwkViewVisible(Evas_Object *wkView); + void setEwkViewInvisible(Evas_Object *wkView); + void resumeWebkit(Evas_Object *wkView); + void suspendWebkit(Evas_Object *wkView); + + // WKPageLoaderClient + static void loadStartedCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + static void loadFinishedCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + static void loadProgressStartedCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + static void loadProgressCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + static void loadProgressFinishedCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + static void processCrashedCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + + // EWK Callback + static Evas_Object* createWindowCallback( + Ewk_View_Smart_Data *sd, + const Ewk_Window_Features *window_features); + static void closeWindowCallback(Ewk_View_Smart_Data *sd); + + // EWK PolicyDecide Callback + static void policyNavigationDecideCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + static void policyNewWindowDecideCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + static void pageResponseDecideCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + + // EWK ContextMenu Callback + static void contextmenuCustomizeCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + + // EWK Geolocation Callback + static Eina_Bool geolocationPermissionRequestCallback( + Evas_Object* obj, + Ewk_Geolocation_Permission_Request* geolocationPermissionRequest, + void* userData); + + // EWK Notification Callback + static void notificationShowCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + static void notificationCancelCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + static Eina_Bool notificationPermissionRequestCallback( + Evas_Object* obj, + Ewk_Notification_Permission_Request* request, + void* userData); + +#ifdef ORIENTATION_ENABLED + // EWK Orientation Callback + static Eina_Bool orientationLockCallback( + Ewk_View_Smart_Data *smartData, + int orientations); + + static void orientationUnLockCallback( + Ewk_View_Smart_Data *smartData); +#endif + // EWK Fullscreen API callbacks + static void enterFullscreenCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + static void exitFullscreenCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + + static void enabledVideoHwOverlayCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + + static void disabledVideoHwOverlayCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + + // EWK IME Change/Show/Hide Callback + static void imeChangedCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + static void imeOpenedCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + static void imeClosedCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + + // EWK Usermedia Callback + static Eina_Bool usermediaPermissionRequestCallback( + Evas_Object* obj, + Ewk_User_Media_Permission_Request* request, + void* userData); + + // custom content/scheme handlers + static void protocolHandlerRegistrationCallback(void* data, + Evas_Object* obj, + void* eventInfo); + static void protocolHandlerIsRegisteredCallback(void* data, + Evas_Object* obj, + void* eventInfo); + static void protocolHandlerUnregistrationCallback(void* data, + Evas_Object* obj, + void* eventInfo); + + static void contentHandlerRegistrationCallback(void* data, + Evas_Object* obj, + void* eventInfo); + static void contentHandlerIsRegisteredCallback(void* data, + Evas_Object* obj, + void* eventInfo); + static void contentHandlerUnregistrationCallback(void* data, + Evas_Object* obj, + void* eventInfo); + static Eina_Bool exceededDatabaseQuotaCallback(Evas_Object* obj, + Ewk_Security_Origin* origin, + const char* databaseName, + unsigned long long expectedQuota, + void* data); + static Eina_Bool exceededIndexedDatabaseQuotaCallback(Evas_Object* obj, + Ewk_Security_Origin* origin, + long long expectedQuota, + void* data); + static Eina_Bool exceededLocalFileSystemQuotaCallback(Evas_Object* obj, + Ewk_Security_Origin* origin, + long long expectedQuota, + void* data); + static void certificateConfirmRequestCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + + static void authenticationRequestCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + + static void viewFrameRenderedCallback( + void* data, + Evas_Object* obj, + void* eventInfo); + +#ifdef ORIENTATION_ENABLED + static void mediacontrolRotateHorizontal(void* data, + Evas_Object* obj, + void* eventInfo); + static void mediacontrolRotateVertical(void* data, + Evas_Object* obj, + void* eventInfo); + static void mediacontrolRotateExit(void* data, + Evas_Object* obj, + void* eventInfo); +#endif + static void popupReplyWaitStart(void* data, + Evas_Object* obj, + void* eventInfo); + static void popupReplyWaitFinish(void* data, + Evas_Object* obj, + void* eventInfo); + static void consoleMessageCallback(void* data, + Evas_Object* obj, + void* eventInfo); + +#ifdef ORIENTATION_ENABLED + static void rotatePreparedCallback(void* data, Evas_Object* obj, void* eventInfo); +#endif + + void attachToCustomHandlersDao(); + void detachFromCustomHandlersDao(); + + // JS execute callback + static void didRunJavaScriptCallback( + Evas_Object* obj, + const char* result, + void* userData); + + // event callback + static void eaKeyCallback(void* data, + Evas_Object* obj, + void* eventInfo); + + // rotary event callback + static Eina_Bool rotaryCallback(void *data, + Evas_Object *obj, + Eext_Rotary_Event_Info *rotary_info); + + // idler callback + static Eina_Bool windowCloseIdlerCallback(void *data); + +#ifdef ORIENTATION_ENABLED + // timer callback + static Eina_Bool orientationThresholdTimerCallback(void* data); +#endif + + // window + void windowClose(void); + + // system settings + static void systemSettingsChangedCallback(system_settings_key_e key, void* data); + + // vibration callback + static void vibrateCallback(void* data, Evas_Object* obj, void* eventInfo); + static void cancelVibrationCallback(void* data, Evas_Object* obj, void* eventinfo); + + Ewk_Context* m_ewkContext; + bool m_attachedToCustomHandlerDao; + std::list m_ewkViewList; + Evas_Object* m_currentEwkView; + Evas_Object* m_closedEwkView; + Evas_Object* m_window; + WidgetModel* m_model; + std::string m_blockedUri; + std::string m_theme; + std::string m_startUrl; + WRT::UserDelegatesPtr m_cbs; + size_t m_imeWidth; + size_t m_imeHeight; + bool m_isBackgroundSupport; +#ifdef ORIENTATION_ENABLED + int m_rotateAngle; + int m_deferredRotateAngle; + Ecore_Timer* m_orientationThresholdTimer; +#endif + // TODO: change name to m_isWebkitBlocked + bool m_isPopupReplyWait; + Ewk_Page_Group* m_pageGroup; + bool m_isFullscreenByPlatform; + int m_category; + + std::unique_ptr m_appsSupport; + std::unique_ptr m_vibrationSupport; + std::unique_ptr m_securityOriginSupport; + std::unique_ptr m_certificateSupport; + std::unique_ptr m_privilegeSupport; + std::unique_ptr m_webNotificationSupport; + + static std::map m_ewkCallbacksMap; +}; + +#endif //VIEW_LOGIC_H_ diff --git a/src/view/webkit/view_logic_authentication_request_support.cpp b/src/view/webkit/view_logic_authentication_request_support.cpp new file mode 100644 index 0000000..9e3c65c --- /dev/null +++ b/src/view/webkit/view_logic_authentication_request_support.cpp @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_authentication_request_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ + +#include "view_logic_authentication_request_support.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace ViewModule { +namespace { + +const char* const EVAS_SMART_CALLBACK_CLICKED = "clicked"; +const char* const EVAS_SMART_CALLBACK_CHANGED = "changed"; +const char* const EVAS_SMART_CALLBACK_PREEDIT_CHANGED = "preedit,changed"; +const char* const EVAS_SMART_CALLBACK_FOCUSED = "focused"; +const char* const EVAS_SMART_CALLBACK_UNFOCUSED = "unfocused"; +const char* const ELM_SIGNAL_ERASER_CLICKED = "elm,eraser,clicked"; +const char* const ELM_SIGNAL_STATE_GUIDETEXT_HIDE = "elm,state,guidetext,hide"; +const char* const ELM_SIGNAL_STATE_ERASER_SHOW = "elm,state,eraser,show"; +const char* const ELM_SIGNAL_STATE_HIDE_SHOW = "elm,state,eraser,hide"; +const char* const ELM_SWALLOW_CONTENT = "elm.swallow.content"; +const char* const ELM_SWALLOW_LABEL = "elm.swallow.label"; +const char* const ELM_SWALLOW_IDFIELD = "elm.swallow.idfield"; +const char* const ELM_SWALLOW_PASSWDFIELD = "elm.swallow.pwfield"; + +const char* const GROUP_NAME_AUTHENTICATION_REQUEST_POPUP = + "authRequestPopup"; +const char* const THEME_EDITFIELD = "editfield"; +const char* const THEME_DEFAULT = "default"; + +const char* const STYLE_POPUP_BUTTON_DEFAULT = "popup_button/default"; +const char* const STYLE_DEFAULT_EDITFIELD = + "DEFAULT='font_size=34 color=#808080 ellipsis=1'"; + +const char* const PART_IDFIELD_TEXT = "elm.swallow.idtext"; +const char* const PART_PASSWORDFIELD_TEXT = "elm.swallow.pwtext"; +const char* const PART_BUTTON1 = "button1"; +const char* const PART_BUTTON2 = "button2"; + +const char* const ELM = "elm"; +const char* const TITLE_TEXT = "title,text"; +const char* const LAYOUT = "layout"; +const char* const ERASER = "eraser"; +const char* const WIDGET_NAME_POPUP = "elm_popup"; +const char* const WIDGET_NAME_NAVIFRAME = "elm_naviframe"; + +const char* const AUTHENTICATION_REQUEST_TITLE_TEXT = + "Authentication Requested"; +const char* const AUTHENTICATION_REQUEST_BODY_PRETEXT = + "A username and password are being requested by "; +const char* const AUTHENTICATION_REQUEST_BODY_MIDDLETEXT = + ". The site says: "; + +const char* const TEXT_DOUBLE_QUOTATION_MARKS = " \""; +const char* const TEXT_ID_FIELD = " User Name: "; +const char* const TEXT_PASSWORD_FIELD = " Password: "; +const char* const TEXT_OK = "Ok"; +const char* const TEXT_CANCEL = "Cancel"; + +struct authenticationData { + Ewk_Auth_Request* m_authRequest; + std::string m_bodyText; + Evas_Object* m_navi; + Evas_Object* m_idEdit; + Evas_Object* m_pwEdit; +}; + +// function declare +void askUserInformation(authenticationData* authData); +void loginAuthentication(authenticationData* authData); +void cancelAuthentication(authenticationData* authData); +Evas_Object* getEvasObjectByWidgetName(Evas_Object* obj, const char* name); +Evas_Object* createEdit(Evas_Object* parent, bool isIdEdit = false); +void eaKeyCallback(void* data, Evas_Object* obj, void* eventInfo); +void buttonClickedCallback(void* data, Evas_Object* obj, void* eventInfo); +void editActivatedCallback(void* data, Evas_Object* obj, void* eventInfo); + +void askUserInformation(authenticationData* authData) +{ + Evas_Object* popup = elm_popup_add(authData->m_navi); + evas_object_size_hint_weight_set(popup, + EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(popup, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_object_part_text_set(popup, + TITLE_TEXT, + AUTHENTICATION_REQUEST_TITLE_TEXT); + + Evas_Object* label = elm_label_add(popup); + evas_object_size_hint_weight_set(label, + EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + + elm_label_line_wrap_set(label , ELM_WRAP_WORD); + elm_object_text_set(label, authData->m_bodyText.c_str()); + + authData->m_idEdit = createEdit(popup, true); + authData->m_pwEdit = createEdit(popup); + + Evas_Object* popupLayout = elm_layout_add(popup); + elm_layout_file_set(popupLayout, + WRT_EDJ_PATH, + GROUP_NAME_AUTHENTICATION_REQUEST_POPUP); + evas_object_size_hint_weight_set(popupLayout, + EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + /* FIXME : The text should be translated. */ + edje_object_part_text_set(elm_layout_edje_get(popupLayout), + PART_IDFIELD_TEXT, + TEXT_ID_FIELD); + edje_object_part_text_set(elm_layout_edje_get(popupLayout), + PART_PASSWORDFIELD_TEXT, + TEXT_PASSWORD_FIELD); + + elm_object_part_content_set(popupLayout, ELM_SWALLOW_LABEL, label); + elm_object_part_content_set(popupLayout, + ELM_SWALLOW_IDFIELD, + authData->m_idEdit); + + elm_object_part_content_set(popupLayout, + ELM_SWALLOW_PASSWDFIELD, + authData->m_pwEdit); + + elm_object_content_set(popup, popupLayout); + + Evas_Object* lButton = elm_button_add(popup); + elm_object_text_set(lButton, TEXT_OK); + elm_object_style_set(lButton, STYLE_POPUP_BUTTON_DEFAULT); + elm_object_part_content_set(popup, PART_BUTTON1, lButton); + evas_object_smart_callback_add(lButton, + EVAS_SMART_CALLBACK_CLICKED, + buttonClickedCallback, + static_cast(authData)); + + Evas_Object* rButton= elm_button_add(popup); + elm_object_text_set(rButton, TEXT_CANCEL); + elm_object_style_set(rButton, STYLE_POPUP_BUTTON_DEFAULT); + elm_object_part_content_set(popup, PART_BUTTON2, rButton); + evas_object_smart_callback_add(rButton, + EVAS_SMART_CALLBACK_CLICKED, + buttonClickedCallback, + static_cast(authData)); + + evas_object_show(popup); +} + +void loginAuthentication(authenticationData* authData) +{ + _D("called"); + + Assert(authData); + + const char* id = elm_entry_entry_get(authData->m_idEdit); + const char* pw = elm_entry_entry_get(authData->m_pwEdit); + ewk_auth_request_authenticate(authData->m_authRequest, const_cast(id), const_cast(pw)); + + Evas_Object* popup = getEvasObjectByWidgetName(authData->m_idEdit, "elm_popup"); + if (popup) { + evas_object_hide(popup); + evas_object_del(popup); + } +} + +void cancelAuthentication(authenticationData* authData) +{ + _D("called"); + + Assert(authData); + + ewk_auth_request_cancel(authData->m_authRequest); + + Evas_Object* popup = getEvasObjectByWidgetName(authData->m_idEdit, "elm_popup"); + if (popup) { + evas_object_hide(popup); + evas_object_del(popup); + } +} + +Evas_Object* getEvasObjectByWidgetName(Evas_Object* obj, const char* name) +{ + Assert(obj); + Evas_Object* current = elm_object_parent_widget_get(obj); + while (strcmp(elm_object_widget_type_get(current), name)) { + current = elm_object_parent_widget_get(current); + if (!current) { + return NULL; + } + } + return current; +} + +Evas_Object* createEdit(Evas_Object* parent, bool isIdEdit) +{ + Evas_Object* edit = ea_editfield_add(parent, EA_EDITFIELD_SCROLL_SINGLELINE); + elm_entry_cnp_mode_set(edit, ELM_CNP_MODE_PLAINTEXT); + //elm_object_style_set(edit, "editfield/password/popup"); + elm_entry_single_line_set(edit, EINA_TRUE); + elm_entry_scrollable_set(edit, EINA_TRUE); + elm_entry_prediction_allow_set(edit, EINA_FALSE); + elm_object_signal_emit(edit, "elm,action,hide,search_icon", ""); + elm_entry_autocapital_type_set(edit, ELM_AUTOCAPITAL_TYPE_NONE); + + if (isIdEdit) { + evas_object_smart_callback_add(edit, "activated", editActivatedCallback, NULL); + } else { + elm_entry_password_set(edit, EINA_TRUE); + elm_entry_input_panel_layout_set(edit, ELM_INPUT_PANEL_LAYOUT_PASSWORD); + } + + return edit; +} + +void eaKeyCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + DPL_UNUSED_PARAM(obj); + DPL_UNUSED_PARAM(eventInfo); + + Assert(data); + + authenticationData* authData = static_cast(data); + cancelAuthentication(authData); +} + +void buttonClickedCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + DPL_UNUSED_PARAM(eventInfo); + + Assert(data); + Assert(obj); + + authenticationData* authData = static_cast(data); + Evas_Object* popup = getEvasObjectByWidgetName(obj, WIDGET_NAME_POPUP); + + bool allow = !strcmp(TEXT_OK, elm_object_text_get(obj)); + if (allow) { + const char* id = elm_entry_entry_get(authData->m_idEdit); + const char* pw = elm_entry_entry_get(authData->m_pwEdit); + ewk_auth_request_authenticate(authData->m_authRequest, + const_cast(id), + const_cast(pw)); + } else { + ewk_auth_request_cancel(authData->m_authRequest); + } + evas_object_hide(popup); + evas_object_del(popup); + delete authData; +} + +void editActivatedCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + DPL_UNUSED_PARAM(eventInfo); + DPL_UNUSED_PARAM(data); + + Assert(obj); + elm_object_focus_set(obj, EINA_TRUE); +} +} // namespace + +void AuthenticationRequestSupport::authenticationRequest( + Evas_Object* webview, + std::string url, + void* data) +{ + _D("authenticationRequest called"); + authenticationData* authData = new authenticationData(); + Assert(webview); + authData->m_navi = getEvasObjectByWidgetName(webview, "elm_naviframe"); + + Assert(data); + authData->m_authRequest = (Ewk_Auth_Request*)data; + + // create body text + // TODO : The text should be translated + const char* authRealm = ewk_auth_request_realm_get(authData->m_authRequest); + if (authRealm != NULL) { + authData->m_bodyText = + std::string(AUTHENTICATION_REQUEST_BODY_PRETEXT) + + std::string(url) + + std::string(AUTHENTICATION_REQUEST_BODY_MIDDLETEXT) + + std::string(TEXT_DOUBLE_QUOTATION_MARKS) + + std::string(authRealm) + + std::string(TEXT_DOUBLE_QUOTATION_MARKS); + } + + ewk_auth_request_suspend(authData->m_authRequest); + + // ask to user + askUserInformation(authData); +} +} // namespace ViewModule diff --git a/src/view/webkit/view_logic_authentication_request_support.h b/src/view/webkit/view_logic_authentication_request_support.h new file mode 100644 index 0000000..26a649f --- /dev/null +++ b/src/view/webkit/view_logic_authentication_request_support.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_authentication_request_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ + +#ifndef VIEW_LOGIC_AUTHENTICATION_REQUEST_SUPPORT_H_ +#define VIEW_LOGIC_AUTHENTICATION_REQUEST_SUPPORT_H_ + +#include +#include + +namespace ViewModule { +namespace AuthenticationRequestSupport { +void authenticationRequest( + Evas_Object* webview, + std::string url, + void* data); +} // namespace AuthenticationSupport +} // namespace ViewModule + +#endif // VIEW_LOGIC_AUTHENTICATION_REQUEST_SUPPORT_H_ diff --git a/src/view/webkit/view_logic_certificate_confirm_support.cpp b/src/view/webkit/view_logic_certificate_confirm_support.cpp new file mode 100644 index 0000000..2c3343f --- /dev/null +++ b/src/view/webkit/view_logic_certificate_confirm_support.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_certificate_confirm_support.cpp + * @author Leerang Song (leerang.song@samsung.com) + */ + +#include "view_logic_certificate_confirm_support.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ViewModule { +namespace CertificateConfirmSupport { +using namespace CertificateDB; +using namespace ViewModule::CertificateSupportUtil; + +namespace { + +// function declare +void askUserForCertificatePermission( + Evas_Object* window, + PermissionData* data); +void setPermissionResult(PermissionData* permData, Result result); +static void popupCallback(void* data, Evas_Object* obj, void* eventInfo); +static void eaKeyCallback(void* data, Evas_Object* obj, void* eventInfo); + +void askUserForCertificatePermission( + Evas_Object* window, + PermissionData* data) +{ + LogDebug("askUserForCertificatePermission called"); + Ewk_Certificate_Policy_Decision* certificatePolicyDecision = + static_cast(data->m_data); + Assert(certificatePolicyDecision); + + std::string msg = std::string(WRT_POP_CERTIFICATE_PERMISSION) + + " " + ewk_certificate_policy_decision_url_get(certificatePolicyDecision); + Evas_Object* popup = createPopup(window, + msg.c_str(), + WRT_BODY_REMEMBER_PREFERENCE, + popupCallback, + eaKeyCallback, + data); + + if (popup == NULL) { + LogError("Fail to create popup object"); + delete data; + return; + } else { + evas_object_show(popup); + } +} + +void setPermissionResult(PermissionData* permData, Result result) +{ + Assert(permData); + Ewk_Certificate_Policy_Decision* certificatePolicyDecision = + static_cast(permData->m_data); + + if (result != RESULT_UNKNOWN) { + permData->m_certiDao->setCertificateData(permData->m_certiData, result); + } + + Eina_Bool ret = (result == RESULT_ALLOW_ALWAYS || result == RESULT_ALLOW_ONCE) ? EINA_TRUE : EINA_FALSE; + ewk_certificate_policy_decision_allowed_set(certificatePolicyDecision, ret); +} + +void popupCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + Assert(data); + Assert(obj); + + DPL_UNUSED_PARAM(eventInfo); + + PermissionData* permData = static_cast(data); + setPermissionResult(permData, getResult(obj)); + delete permData; + + Evas_Object* popup = getPopup(obj); + evas_object_hide(popup); + evas_object_del(popup); +} + +void eaKeyCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + Assert(data); + Assert(obj); + + DPL_UNUSED_PARAM(eventInfo); + + PermissionData* permData = static_cast(data); + setPermissionResult(permData, RESULT_DENY_ONCE); + delete permData; + + evas_object_hide(obj); + evas_object_del(obj); +} +} // namespace + +void certificatePermissionRequest( + Evas_Object* window, + CertificateDB::CertificateDAO* certificateDAO, + void* data) +{ + LogDebug("certificationPermissionRequest called"); + Assert(certificateDAO); + Assert(data); + + Ewk_Certificate_Policy_Decision* certificatePolicyDecision = + static_cast(data); + ewk_certificate_policy_decision_suspend(certificatePolicyDecision); + Assert(certificatePolicyDecision); + + CertificateData certificateData( + DPL::FromUTF8String( + ewk_certificate_policy_decision_certificate_pem_get( + certificatePolicyDecision))); + + // check cache database + Result result = certificateDAO->getResult(certificateData); + + if (RESULT_ALLOW_ONCE == result || RESULT_ALLOW_ALWAYS == result) { + LogDebug("allow"); + ewk_certificate_policy_decision_allowed_set( + certificatePolicyDecision, + EINA_TRUE); + return; + } else if (RESULT_DENY_ONCE == result || RESULT_DENY_ALWAYS == result) { + LogDebug("Deny"); + ewk_certificate_policy_decision_allowed_set( + certificatePolicyDecision, + EINA_FALSE); + return; + } + // ask to user + PermissionData* permissionData = + new PermissionData(certificateDAO, + certificateData, + certificatePolicyDecision); + askUserForCertificatePermission(window, permissionData); + return; +} +} +} // namespace ViewModule diff --git a/src/view/webkit/view_logic_certificate_confirm_support.h b/src/view/webkit/view_logic_certificate_confirm_support.h new file mode 100755 index 0000000..8bd42ba --- /dev/null +++ b/src/view/webkit/view_logic_certificate_confirm_support.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_certificate_confirm_support.h + * @author Leerang Song (leerang.song@samsung.com) + */ + +#ifndef VIEW_LOGIC_CERTIFICATE_CONFIRM_SUPPORT_H_ +#define VIEW_LOGIC_CERTIFICATE_CONFIRM_SUPPORT_H_ + +#include +#include + +namespace CertificateDB { +class CertificateDAO; +} + +namespace ViewModule { +namespace CertificateConfirmSupport { +void certificatePermissionRequest( + Evas_Object* window, + CertificateDB::CertificateDAO* certificateDAO, + void* data); +} +} // namespace ViewModule + +#endif diff --git a/src/view/webkit/view_logic_geolocation_support.cpp b/src/view/webkit/view_logic_geolocation_support.cpp new file mode 100644 index 0000000..8176fbe --- /dev/null +++ b/src/view/webkit/view_logic_geolocation_support.cpp @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_geolocation_support.cpp + * @author Grzegorz Krawczyk (g.krawczyk@samsung.com) + */ + +#include "view_logic_geolocation_support.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOCATION_PRIVACY "http://tizen.org/privilege/location" + +namespace ViewModule { +namespace GeolocationSupport { +using namespace SecurityOriginDB; +using namespace ViewModule::SecurityOriginSupportUtil; + +namespace { +// function declare +void askUserForGeolocationPermission( + Evas_Object* window, + PermissionData* data); +void setPermissionResult(PermissionData* permData, Result result); +static void popupCallback(void* data, Evas_Object* obj, void* eventInfo); +static void eaKeyCallback(void* data, Evas_Object* obj, void* eventInfo); + +void askUserForGeolocationPermission( + Evas_Object* window, + PermissionData* data) +{ + LogDebug("askUserForGeolocationPermission called"); + std::string origin = DPL::ToUTF8String(data->m_originData.origin.host); + if (origin.empty()) { + origin = "local"; + } + std::string appname; + char* name = NULL; + if (app_get_name(&name) == APP_ERROR_NONE) { + appname = name; + free(name); + } else { + appname = "application"; + } + + std::string body = + WrtText::replacePS({WRT_POP_GEOLOCATION_PERMISSION, appname, origin}); + Evas_Object* popup = createPopup(window, + body.c_str(), + WRT_BODY_REMEMBER_PREFERENCE, + popupCallback, + eaKeyCallback, + data); + + if (popup == NULL) { + LogError("Fail to create popup object"); + delete data; + return; + } else { + evas_object_show(popup); + } +} + +void setPermissionResult(PermissionData* permData, Result result) +{ + Assert(permData); + if (result != RESULT_UNKNOWN) { + permData->m_originDao->setSecurityOriginData(permData->m_originData, result); + } + + Ewk_Geolocation_Permission_Request* permissionRequest = + static_cast(permData->m_data); + Eina_Bool ret = (result == RESULT_ALLOW_ALWAYS || result == RESULT_ALLOW_ONCE) ? EINA_TRUE : EINA_FALSE; + + std::string package_id = DPL::ToUTF8String(permData->m_pkgId); + const char *privacy_list[] = { + LOCATION_PRIVACY, + "\0" + }; + + LogDebug("packageId " << package_id.c_str()); + int privacy_ret = privacy_manager_client_install_privacy(package_id.c_str(), privacy_list, false); + LogDebug("privacy manager ret val: " << privacy_ret); + + ewk_geolocation_permission_reply(permissionRequest, ret); +} + +void popupCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + Assert(obj); + Assert(data); + + DPL_UNUSED_PARAM(eventInfo); + + PermissionData* permData = static_cast(data); + setPermissionResult(permData, getResult(obj)); + delete permData; + + Evas_Object* popup = getPopup(obj); + +// disable help popup in the Wearable. +// application manager is not exist in Wearble Setting App +#if 0 + if (isNeedHelpPopup(popup)) { + ViewModule::HelpPopupSupport::showClearDefaultPopup(popup); + } +#endif + evas_object_hide(popup); + evas_object_del(popup); +} + +void eaKeyCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + DPL_UNUSED_PARAM(eventInfo); + + Assert(data); + Assert(obj); + + PermissionData* permData = static_cast(data); + Evas_Object* popup = getPopup(obj); + setPermissionResult(permData, RESULT_DENY_ONCE); + + delete permData; + evas_object_hide(popup); + evas_object_del(popup); +} +} // namespace + + +bool hasPrivilege(DPL::String tizenId) +{ + bool ret = false; + + WrtDB::WidgetDAOReadOnly widgetDao(tizenId); + std::list widgetPrivilege = widgetDao.getWidgetPrivilege(); + FOREACH(it, widgetPrivilege) { + if (!DPL::ToUTF8String(*it).compare("http://tizen.org/privilege/location")) { + LogDebug("Find privilege."); + ret = true; + } + } + + return ret; +} + +void geolocationPermissionRequest( + Evas_Object* window, + SecurityOriginDB::SecurityOriginDAO* securityOriginDAO, + void* data, + DPL::String tizenId) +{ + LogDebug("called"); + + Assert(securityOriginDAO); + Assert(data); + GeoLocationData *geoData = static_cast(data); + Ewk_Geolocation_Permission_Request* permissionRequest = + static_cast(geoData->permissionRequest); + + const Ewk_Security_Origin* ewkOrigin = + ewk_geolocation_permission_request_origin_get( + permissionRequest); + Assert(ewkOrigin); + + SecurityOriginData securityOriginData( + WrtDB::FEATURE_GEOLOCATION, + Origin( + DPL::FromUTF8String(ewk_security_origin_protocol_get(ewkOrigin)), + DPL::FromUTF8String(ewk_security_origin_host_get(ewkOrigin)), + ewk_security_origin_port_get(ewkOrigin))); + + // check cache database + Result result = securityOriginDAO->getResult(securityOriginData); + if (RESULT_ALLOW_ONCE == result || RESULT_ALLOW_ALWAYS == result) { + LogDebug("allow"); + ewk_geolocation_permission_reply(permissionRequest, EINA_TRUE); + return; + } else if (RESULT_DENY_ONCE == result || RESULT_DENY_ALWAYS == result) { + LogDebug("deny"); + ewk_geolocation_permission_reply(permissionRequest, EINA_FALSE); + return; + } + + DPL::String pkgId = geoData->pkgId; + + // ask to user + PermissionData* permissionData = + new PermissionData(securityOriginDAO, + securityOriginData, + permissionRequest, + pkgId); + + // check whether geolocation privilege is exist or not. + // if privilege is not exist, set to deny without popup + if (!hasPrivilege(tizenId)) { + LogDebug("App no privilege. set to deny"); + setPermissionResult(permissionData, RESULT_DENY_ONCE); + delete permissionData; + return; + } + + // suspend geolocation + ewk_geolocation_permission_request_suspend(permissionRequest); + + askUserForGeolocationPermission(window, permissionData); + return; +} +} // namespace GeolocationSupport +} // namespace ViewModule diff --git a/src/view/webkit/view_logic_geolocation_support.h b/src/view/webkit/view_logic_geolocation_support.h new file mode 100644 index 0000000..6ac1d9d --- /dev/null +++ b/src/view/webkit/view_logic_geolocation_support.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_geolocation_support.h + * @author Grzegorz Krawczyk (g.krawczyk@samsung.com) + */ + +#ifndef VIEW_LOGIC_GEOLOCATION_SUPPORT_H_ +#define VIEW_LOGIC_GEOLOCATION_SUPPORT_H_ + +#include +#include +#include +#include +#include + +namespace SecurityOriginDB { +class SecurityOriginDAO; +} + +namespace ViewModule { +namespace GeolocationSupport { + +typedef struct { + void* data; + Ewk_Geolocation_Permission_Request* permissionRequest; + DPL::String pkgId; +}GeoLocationData; + +void geolocationPermissionRequest( + Evas_Object* window, + SecurityOriginDB::SecurityOriginDAO* securityOriginDAO, + void* data, + DPL::String tizenId); +} // namespace GeolocationSupport +} // namespace ViewModule + +#endif diff --git a/src/view/webkit/view_logic_message_support.cpp b/src/view/webkit/view_logic_message_support.cpp new file mode 100644 index 0000000..38b4e7e --- /dev/null +++ b/src/view/webkit/view_logic_message_support.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_message_support.cpp + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @author Yunchan Cho (yunchan.cho@samsung.com) + * @brief View logic message support - implementation + */ +#include "view_logic_message_support.h" + +#include +#include +#include +#include +#include + +namespace ViewLogicMessageSupport { +void init(Ewk_Context* ewkContext, const std::string& tizenId) +{ + const char* name = Message::ToInjectedBundle::INIT; + const char* msg = tizenId.c_str(); + + ewk_context_message_post_to_injected_bundle(ewkContext, name, msg); +} + +void start(Ewk_Context* ewkContext, + const DPL::String& tizenId, + double scale, + const char *encodedBundle, + const char *theme) +{ + std::stringstream ssMsg; + + std::string id = DPL::ToUTF8String(tizenId); + ssMsg << id << " "; + + ssMsg << "_" << scale << " "; + + if (encodedBundle) { + ssMsg << "_" << encodedBundle << " "; + } else { + ssMsg << "null" << " "; + } + + if (theme) { + ssMsg << "_" << theme; + } else { + ssMsg << "null"; + } + + std::string msgString = ssMsg.str(); + + const char* msg = msgString.c_str(); + const char* name = Message::ToInjectedBundle::START; + + ewk_context_message_post_to_injected_bundle(ewkContext, name, msg); +} + +void shutdown(Ewk_Context* ewkContext) +{ + const char* name = Message::ToInjectedBundle::SHUTDOWN; + ewk_context_message_post_to_injected_bundle(ewkContext, name, name); +} + +void setCustomProperties( + Ewk_Context* ewkContext, + double* scale, + const char* encodedBundle, + const char* theme) +{ + std::stringstream ssMsg; + + if (scale) { + ssMsg << "_" << *scale << " "; + } else { + ssMsg << "null" << " "; + } + + if (encodedBundle) { + ssMsg << "_" << encodedBundle << " "; + } else { + ssMsg << "null" << " "; + } + + if (theme) { + ssMsg << "_" << theme; + } else { + ssMsg << "null"; + } + + std::string msgString = ssMsg.str(); + + const char* msg = msgString.c_str(); + const char* name = Message::ToInjectedBundle::SET_CUSTOM_PROPERTIES; + + ewk_context_message_post_to_injected_bundle(ewkContext, name, msg); +} + +void dispatchJavaScriptEvent( + Ewk_Context* ewkContext, + WrtPlugins::W3C::CustomEventType eventType, + void *data) +{ + using namespace WrtPlugins::W3C; + std::stringstream str; + str << eventType; + + // if needed, arguments for event should be set here + if (eventType == SoftKeyboardChangeCustomEvent) { + if (data) { + SoftKeyboardChangeArgs* args = + static_cast(data); + str << " " << args->state; + str << " " << args->width; + str << " " << args->height; + } + } + + std::string msgString = str.str(); + const char* msg = msgString.c_str(); + const char* name = Message::ToInjectedBundle::DISPATCH_JS_EVENT; + + ewk_context_message_post_to_injected_bundle(ewkContext, name, msg); +} + +void setXwindowHandle(Ewk_Context* ewkContext, const unsigned int handle) +{ + const char* name = Message::ToInjectedBundle::SET_XWINDOW_HANDLE; + std::stringstream ssMsg; + ssMsg << handle; + std::string msgString = ssMsg.str(); + const char* msg = msgString.c_str(); + + ewk_context_message_post_to_injected_bundle(ewkContext, name, msg); +} + +void setViewmodes(Ewk_Context* ewkContext, const char* msg) +{ + const char* name = Message::ToInjectedBundle::SET_VIEWMODES; + ewk_context_message_post_to_injected_bundle(ewkContext, name, msg); +} +} // namespace ViewLogicMessageSupport diff --git a/src/view/webkit/view_logic_message_support.h b/src/view/webkit/view_logic_message_support.h new file mode 100644 index 0000000..341fa54 --- /dev/null +++ b/src/view/webkit/view_logic_message_support.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_message_support.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @author Yunchan Cho (yunchan.cho@samsung.com) + * @brief View logic message support - declaration + */ +#ifndef VIEW_LOGIC_MESSAGE_SUPPORT_H_ +#define VIEW_LOGIC_MESSAGE_SUPPORT_H_ + +#include +#include +#include +#include + +namespace ViewLogicMessageSupport { +void init(Ewk_Context* ewkContext, + const std::string& tizenId); +void start(Ewk_Context* ewkContext, + const DPL::String& tizenId, + double scale, + const char *encodedBundle, + const char *theme); +void shutdown(Ewk_Context* ewkContext); +void setCustomProperties( + Ewk_Context* ewkContext, + double* scale = NULL, + const char* encodedBundle = NULL, + const char* theme = NULL); +void dispatchJavaScriptEvent( + Ewk_Context* ewkContext, + WrtPlugins::W3C::CustomEventType eventType, + void* data); +void setXwindowHandle(Ewk_Context* ewkContext, const unsigned int handle); +void setViewmodes(Ewk_Context* ewkContext, const char* msg); +} // namespace ViewLogicMessageSupport + +#endif // VIEW_LOGIC_MESSAGE_SUPPORT_H_ diff --git a/src/view/webkit/view_logic_orientation_support.cpp b/src/view/webkit/view_logic_orientation_support.cpp new file mode 100644 index 0000000..9e4bbe2 --- /dev/null +++ b/src/view/webkit/view_logic_orientation_support.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_orientation_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + */ + + #include "view_logic_orientation_support.h" + +#include +#include + +#include +#include + +namespace ViewModule { + +int OrientationSupport::getWinOrientationAngle(int ewkOrientation) +{ + int angle; + if (ewkOrientation & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) { + angle = OrientationAngle::Window::Portrait::PRIMARY; + } else if (ewkOrientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) { + angle = OrientationAngle::Window::Landscape::PRIMARY; + } else if (ewkOrientation & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) { + angle = OrientationAngle::Window::Portrait::SECONDARY; + } else if (ewkOrientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY) { + angle = OrientationAngle::Window::Landscape::SECONDARY; + } else { + LogDebug("Wrong orientation value is passed"); + Assert(false); + } + return angle; +} + +int OrientationSupport::getW3COrientationAngle(int ewkOrientation) +{ + int angle; + if (ewkOrientation & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) { + angle = OrientationAngle::W3C::Portrait::PRIMARY; + } else if (ewkOrientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) { + angle = OrientationAngle::W3C::Landscape::PRIMARY; + } else if (ewkOrientation & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) { + angle = OrientationAngle::W3C::Portrait::SECONDARY; + } else if (ewkOrientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY) { + angle = OrientationAngle::W3C::Landscape::SECONDARY; + } else { + LogDebug("Wrong orientation value is passed"); + Assert(false); + } + return angle; +} + +void OrientationSupport::setEwkOrientation(Evas_Object* ewk, + int angle) +{ + LogDebug("setOrientation called"); + ewk_view_orientation_send(ewk, angle); +} +} // ViewModule diff --git a/src/view/webkit/view_logic_orientation_support.h b/src/view/webkit/view_logic_orientation_support.h new file mode 100644 index 0000000..2512afc --- /dev/null +++ b/src/view/webkit/view_logic_orientation_support.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_orientation_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + */ + +#ifndef VIEW_LOGIC_ORIENTATION_SUPPORT_H_ +#define VIEW_LOGIC_ORIENTATION_SUPPORT_H_ + +#include + +namespace ViewModule { +namespace OrientationSupport { +const int DEFERRED_ORIENTATION_EMPTY = -1; +const int DEFERRED_ORIENTATION_UNLOCK = 0; + +int getWinOrientationAngle(int ewkOrientation); +int getW3COrientationAngle(int ewkOrientation); +void setEwkOrientation(Evas_Object* ewk, int angle); +} // namespace OrientationSupport +} // namespace ViewModule + +#endif // VIEW_LOGIC_ORIENTATION_SUPPORT_H_ \ No newline at end of file diff --git a/src/view/webkit/view_logic_scheme_support.cpp b/src/view/webkit/view_logic_scheme_support.cpp new file mode 100644 index 0000000..eace982 --- /dev/null +++ b/src/view/webkit/view_logic_scheme_support.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_scheme_support.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#include "view_logic_scheme_support.h" + +#include +#include +#include +#include +#include +#include + +namespace ViewModule { +namespace { +char const * const TIZEN_SCHEME = "tizen"; +char const * const TIZEN_EXIT = "tizen://exit"; +char const * const TIZEN_HIDE = "tizen://hide"; +char const * const TIZEN_CHANGE_USERAGNET = "tizen://changeUA"; + +static Eina_Bool exitAppIdlerCallback(void* /*data*/) +{ + elm_exit(); + return ECORE_CALLBACK_CANCEL; +} +} // namespace + +bool SchemeSupport::HandleTizenScheme(const char* uri, + Evas_Object* window, + Evas_Object* wkView) +{ + if (!uri) { + _W("Empty uri"); + return false; + } + if (!window) { + _W("Empty window data"); + return false; + } + + if (strncmp(uri, TIZEN_EXIT, strlen(TIZEN_EXIT)) == 0) { + _D("%s : exit", uri); + ecore_idle_enterer_before_add(exitAppIdlerCallback, NULL); + return true; + } else if (strncmp(uri, TIZEN_HIDE, strlen(TIZEN_HIDE)) == 0) { + _D("%s : hide", uri); + elm_win_lower(window); + return true; + } else if (strncmp(uri, + TIZEN_CHANGE_USERAGNET, + strlen(TIZEN_CHANGE_USERAGNET)) == 0) + { + _D("%s : change UA", uri); + const char* userAgentString = strstr(uri, "="); + if (NULL == userAgentString) { + _W("UA string is NULL"); + } else { + userAgentString++; + _D("Setting custom user agent as: %s", userAgentString); + ewk_view_user_agent_set(wkView, userAgentString); + } + return true; + } + return false; +} + +bool SchemeSupport::filterURIByScheme(Ewk_Policy_Decision* policyDecision, + bool newWindow, + Evas_Object* window, + Evas_Object* wkView) +{ + _D("called"); + Assert(policyDecision); + + const char* url = ewk_policy_decision_url_get(policyDecision); + if (NULL == url) { + // URI is null + // There is no reason, security by scheme block null uri + return true; + } + + bool mainFrame = + ewk_frame_is_main_frame(ewk_policy_decision_frame_get(policyDecision)); + + using namespace ViewModule::SchemeActionMap; + if (HandleTizenScheme(url, window, wkView)) { + _D("Scheme is tizen scheme"); + return false; + } + + NavigationContext ctx; + ctx = (mainFrame ? TOP_LEVEL : FRAME_LEVEL); + if (newWindow) { + // In case of Tizen, + // policy of new window should be applied, + // regardless level of this frame + ctx = NEW_WINDOW; + } + + return SchemeActionMap::HandleUri(url, ctx); +} +} // namespace ViewModule + diff --git a/src/view/webkit/view_logic_scheme_support.h b/src/view/webkit/view_logic_scheme_support.h new file mode 100644 index 0000000..1c2cb64 --- /dev/null +++ b/src/view/webkit/view_logic_scheme_support.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_scheme_support.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#ifndef VIEW_LOGIC_SCHEME_SUPPORT_H_ +#define VIEW_LOGIC_SCHEME_SUPPORT_H_ + +#include +#include +#include +#include + +namespace ViewModule { +namespace SchemeSupport { +bool HandleTizenScheme(const char* uri, + Evas_Object* window, + Evas_Object* wkView); +bool filterURIByScheme(Ewk_Policy_Decision* policyDecision, + bool newWindow, + Evas_Object* window, + Evas_Object* wkView); +} // SchemeSupport +} // namespace ViewModule +#endif // VIEW_LOGIC_SCHEME_SUPPORT_H_ diff --git a/src/view/webkit/view_logic_user_agent_support.cpp b/src/view/webkit/view_logic_user_agent_support.cpp new file mode 100644 index 0000000..120b283 --- /dev/null +++ b/src/view/webkit/view_logic_user_agent_support.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_user_agent_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + */ + +#include "view_logic_user_agent_support.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace ViewModule { +namespace { +#if ENABLE(CUSTOM_USER_AGENT_SUPPORT) +void setCustomUA(std::string customUA); +#endif // ENABLE(CUSTOM_USER_AGENT_SUPPORT) +bool setAppInfo(WidgetModel* model, Evas_Object* wkView); +void printUA(Evas_Object* wkView); + +#if ENABLE(CUSTOM_USER_AGENT_SUPPORT) +bool setCustomUA(WidgetModel* model, Evas_Object* wkView) +{ + std::string customUserAgent = model->SettingList.Get().getUserAgent(); + if (customUserAgent.empty()) { + return false; + } else { + ewk_view_user_agent_set(wkView, customUserAgent.c_str()); + return true; + } + return false; +} +#endif // ENABLE(CUSTOM_USER_AGENT_SUPPORT) + +bool setAppInfo(WidgetModel* model, Evas_Object* wkView) +{ + std::string appInfo; // appname/appversion + char* name = NULL; + if (app_get_name(&name) == APP_ERROR_NONE) { + appInfo = name; + free(name); + } else { + _W("Fail to get app name"); + if (name) { + free(name); + } + return false; + } + + DPL::OptionalString version = model->Version.Get(); + if (!!version) { + std::string versionStr = DPL::ToUTF8String(*version); + if (versionStr.empty()) { + // version is empty + // skip to set version field + } else { + appInfo += "/"; + appInfo += versionStr; + } + } + if (ewk_view_application_name_for_user_agent_set(wkView, appInfo.c_str()) + == EINA_TRUE) + { + // verify + const char* info = + ewk_view_application_name_for_user_agent_get(wkView); + if (!info || !strlen(info) || appInfo != info) { + _W("Fail to verify app info in the UA"); + return false; + } + return true; + } else { + _W("Fail to set app info to UA"); + return false; + } + return true; +} + +void printUA(Evas_Object* wkView) +{ + const char* ua = ewk_view_user_agent_get(wkView); + _D("%s", ua); +} +} // anonymous namespace + +void UserAgentSupport::setUserAgent(WidgetModel* model, Evas_Object* wkView) +{ + Assert(model); + Assert(wkView); + +#if ENABLE(CUSTOM_USER_AGENT_SUPPORT) + // set custom UA + if (setCustomUA(model, wkView)) { + printUA(wkView); + return; + } +#endif // ENABLE(CUSTOM_USER_AGENT_SUPPORT) + + // In case of default UA, add appname/appversion + if (setAppInfo(model, wkView)) { + printUA(wkView); + } else { + // default UA + printUA(wkView); + } + return; +} + +} // ViewModule diff --git a/src/view/webkit/view_logic_user_agent_support.h b/src/view/webkit/view_logic_user_agent_support.h new file mode 100644 index 0000000..1bb7643 --- /dev/null +++ b/src/view/webkit/view_logic_user_agent_support.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_user_agent_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + */ + +#ifndef VIEW_LOGIC_USER_AGENT_SUPPORT_H_ +#define VIEW_LOGIC_USER_AGENT_SUPPORT_H_ + +#include + +class WidgetModel; + +namespace ViewModule { +namespace UserAgentSupport { +void setUserAgent(WidgetModel* model, Evas_Object* wkView); +} // namespace UserAgentSupport +} // namespace ViewModule + +#endif // VIEW_LOGIC_USER_AGENT_SUPPORT_H_ \ No newline at end of file diff --git a/src/view/webkit/view_logic_usermedia_support.cpp b/src/view/webkit/view_logic_usermedia_support.cpp new file mode 100644 index 0000000..aceae83 --- /dev/null +++ b/src/view/webkit/view_logic_usermedia_support.cpp @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_usermedia_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ + +#include "view_logic_usermedia_support.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace ViewModule { +using namespace SecurityOriginDB; +using namespace ViewModule::SecurityOriginSupportUtil; +namespace { +// function declare +void askUserForUsermediaPermission(Evas_Object* window, PermissionData* data); +static void popupCallback(void* data, Evas_Object* obj, void* eventInfo); +void setPermissionResult(PermissionData* permData, Result result); +static void eaKeyCallback(void* data, Evas_Object* obj, void* eventInfo); + +void askUserForUsermediaPermission(Evas_Object* window, PermissionData* data) +{ + LogDebug("called"); + std::string origin = DPL::ToUTF8String(data->m_originData.origin.host); + if (origin.empty()) { + origin = "local"; + } + std::string appname; + char* name = NULL; + if (app_get_name(&name) == APP_ERROR_NONE) { + appname = name; + free(name); + } else { + appname = "application"; + } + + std::string body = + WrtText::replacePS({WRT_POP_USERMEDIA_PERMISSION, appname, origin}); + + Evas_Object* popup = createPopup(window, + body.c_str(), + WRT_BODY_REMEMBER_PREFERENCE, + popupCallback, + eaKeyCallback, + data); + + if (popup == NULL) { + LogError("Fail to create popup object"); + delete data; + return; + } else { + evas_object_show(popup); + } +} + +void eaKeyCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + LogDebug("called"); + DPL_UNUSED_PARAM(eventInfo); + + Assert(data); + Assert(obj); + + PermissionData* permData = static_cast(data); + Evas_Object* popup = getPopup(obj); + setPermissionResult(permData, RESULT_DENY_ONCE); + + delete permData; + evas_object_hide(popup); + evas_object_del(popup); +} + +void popupCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + LogDebug("called"); + + Assert(obj); + Assert(data); + + DPL_UNUSED_PARAM(eventInfo); + + PermissionData* permData = static_cast(data); + setPermissionResult(permData, getResult(obj)); + delete permData; + + Evas_Object* popup = getPopup(obj); + + evas_object_hide(popup); + evas_object_del(popup); +} + +void setPermissionResult(PermissionData* permData, Result result) +{ + Assert(permData); + if (result != RESULT_UNKNOWN) { + permData->m_originDao->setSecurityOriginData(permData->m_originData, result); + } + + Ewk_User_Media_Permission_Request* permissionRequest = + static_cast(permData->m_data); + + Eina_Bool ret = (result == RESULT_ALLOW_ALWAYS || result == RESULT_ALLOW_ONCE) ? EINA_TRUE : EINA_FALSE; + + ewk_user_media_permission_reply(permissionRequest, ret); +} +} // namespace + + +bool hasPrivilege(DPL::String tizenId) +{ + bool ret = false; + + WrtDB::WidgetDAOReadOnly widgetDao(tizenId); + std::list widgetPrivilege = widgetDao.getWidgetPrivilege(); + FOREACH(it, widgetPrivilege) { + if (!DPL::ToUTF8String(*it).compare("http://tizen.org/privilege/mediacapture")) { + LogDebug("Find privilege."); + ret = true; + } + } + + return ret; +} + +void UsermediaSupport::usermediaPermissionRequest(Evas_Object* window, + SecurityOriginDAO* securityOriginDAO, + void* data, + DPL::String tizenId) +{ + LogDebug("called"); + Assert(securityOriginDAO); + Assert(data); + + Ewk_User_Media_Permission_Request* permissionRequest = + static_cast(data); + + const Ewk_Security_Origin* ewkOrigin = + ewk_user_media_permission_request_origin_get(permissionRequest); + Assert(ewkOrigin); + + SecurityOriginData securityOriginData( + WrtDB::FEATURE_USER_MEDIA, + Origin( + DPL::FromUTF8String(ewk_security_origin_protocol_get(ewkOrigin)), + DPL::FromUTF8String(ewk_security_origin_host_get(ewkOrigin)), + ewk_security_origin_port_get(ewkOrigin))); + + // In case of usermedia ewk doesn't support origin data + // cache data also only store allow data by privilege + Result result = securityOriginDAO->getResult(securityOriginData); + if (RESULT_ALLOW_ONCE == result || RESULT_ALLOW_ALWAYS == result) { + LogDebug("allow"); + ewk_user_media_permission_reply(permissionRequest, EINA_TRUE); + return; + } else if (RESULT_DENY_ONCE == result || RESULT_DENY_ALWAYS == result) { + LogDebug("deny"); + ewk_user_media_permission_reply(permissionRequest, EINA_FALSE); + return; + } + + // ask to user + PermissionData* permissionData = + new PermissionData(securityOriginDAO, + securityOriginData, + permissionRequest); + + // check recorder privilege is exist or not. if privilege is not exist, set to deny without popup + if (!hasPrivilege(tizenId)) { + LogDebug("App no privilege. set to deny"); + + permissionData->m_originDao->setSecurityOriginData(permissionData->m_originData, RESULT_DENY_ONCE); + + Ewk_User_Media_Permission_Request* permissionRequest = + static_cast(permissionData->m_data); + + ewk_user_media_permission_request_set(permissionRequest, EINA_FALSE); + + delete permissionData; + return; + } + + ewk_user_media_permission_request_suspend(permissionRequest); + + askUserForUsermediaPermission(window, permissionData); + return; +} +} // namespace ViewModule diff --git a/src/view/webkit/view_logic_usermedia_support.h b/src/view/webkit/view_logic_usermedia_support.h new file mode 100644 index 0000000..2320246 --- /dev/null +++ b/src/view/webkit/view_logic_usermedia_support.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_usermedia_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ + +#ifndef VIEW_LOGIC_USERMEDIA_SUPPORT_H_ +#define VIEW_LOGIC_USERMEDIA_SUPPORT_H_ + +#include +#include + +//Forward declarations +namespace SecurityOriginDB { +class SecurityOriginDAO; +} + +namespace ViewModule { +namespace UsermediaSupport { +void usermediaPermissionRequest( + Evas_Object* window, + SecurityOriginDB::SecurityOriginDAO* securityOriginDAO, + void* data, + DPL::String tizenId); +} // namespace UsermediaSupport +} // namespace ViewModule + +#endif // VIEW_LOGIC_USERMEDIA_SUPPORT_H_ \ No newline at end of file diff --git a/src/view/webkit/view_logic_web_notification_data.cpp b/src/view/webkit/view_logic_web_notification_data.cpp new file mode 100644 index 0000000..8ef96da --- /dev/null +++ b/src/view/webkit/view_logic_web_notification_data.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_web_notification_data.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + * + */ + +#include "view_logic_web_notification_data.h" + +#include +#include +#include + +namespace ViewModule { +WebNotificationData::WebNotificationData(Ewk_Notification* ewkNotification) : + m_notificaionId(0), + m_data(ewkNotification) +{} + +WebNotificationData::~WebNotificationData() +{} + +int WebNotificationData::getNotiId() +{ + return m_notificaionId; +} + +void WebNotificationData::setNotiId(const int notiId) +{ + m_notificaionId = notiId; +} + +uint64_t WebNotificationData::getEwkNotiId() +{ + return ewk_notification_id_get(m_data); +} + +const char* WebNotificationData::getIconUrl() +{ + return ewk_notification_icon_url_get(m_data); +} + +const char* WebNotificationData::getTitle() +{ + return ewk_notification_title_get(m_data); +} + +const char* WebNotificationData::getBody() +{ + return ewk_notification_body_get(m_data); +} + +Ewk_Notification* WebNotificationData::getData() +{ + return m_data; +} +} //namespace ViewModule diff --git a/src/view/webkit/view_logic_web_notification_data.h b/src/view/webkit/view_logic_web_notification_data.h new file mode 100644 index 0000000..9c53fca --- /dev/null +++ b/src/view/webkit/view_logic_web_notification_data.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_web_notification_data.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + * + */ + +#ifndef VIEW_LOGIC_WEB_NOTIFICATION_DATA_H_ +#define VIEW_LOGIC_WEB_NOTIFICATION_DATA_H_ + +#include +#include +#include +#include + +namespace ViewModule { +class WebNotificationData +{ + public: + WebNotificationData(Ewk_Notification* ewkNotification); + virtual ~WebNotificationData(); + + int getNotiId(void); + void setNotiId(const int notiId); + uint64_t getEwkNotiId(void); + const char* getIconUrl(void); + const char* getTitle(void); + const char* getBody(void); + Ewk_Notification* getData(void); + + private: + int m_notificaionId; + Ewk_Notification* m_data; +}; +typedef std::shared_ptr WebNotificationDataPtr; +} // namespace ViewModule +#endif // VIEW_LOGIC_WEB_NOTIFICATION_DATA_H_ diff --git a/src/view/webkit/view_logic_web_notification_permission_support.cpp b/src/view/webkit/view_logic_web_notification_permission_support.cpp new file mode 100644 index 0000000..b1d135d --- /dev/null +++ b/src/view/webkit/view_logic_web_notification_permission_support.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_web_notification_permission_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @brief Implementation file of web Notification permission API + */ + +#include "view_logic_web_notification_permission_support.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace ViewModule { +namespace WebNotificationPermissionSupport { +using namespace SecurityOriginDB; +using namespace ViewModule::SecurityOriginSupportUtil; + +namespace { +// Function declare +bool askUserPermission(Evas_Object* parent, PermissionData* data); +void setPermissionResult(PermissionData* permData, Result result); +static void popupCallback(void* data, Evas_Object* obj, void* eventInfo); +static void eaKeyCallback(void* data, Evas_Object* obj, void* eventInfo); + +bool askUserPermission(Evas_Object* parent, PermissionData* data) +{ + _D("called"); + std::string origin = DPL::ToUTF8String(data->m_originData.origin.host); + if (origin.empty()) { + origin = "local"; + } + std::string appname; + char* name = NULL; + if (app_get_name(&name) == APP_ERROR_NONE) { + appname = name; + free(name); + } else { + appname = "application"; + } + + std::string body = + WrtText::replacePS({WRT_POP_WEB_NOTIFICATION_PERMISSION, + appname, + origin}); + Evas_Object* popup = createPopup(parent, + body.c_str(), + WRT_BODY_REMEMBER_PREFERENCE, + popupCallback, + eaKeyCallback, + data); + if (popup == NULL) { + delete data; + return false; + } else { + evas_object_show(popup); + } + return true; +} + +void setPermissionResult(PermissionData* permData, Result result) +{ + Assert(permData); + if (result != RESULT_UNKNOWN) { + permData->m_originDao->setSecurityOriginData(permData->m_originData, result); + } + + Ewk_Notification_Permission_Request* permissionRequest = + static_cast(permData->m_data); + Eina_Bool ret = (result == RESULT_ALLOW_ALWAYS || result == RESULT_ALLOW_ONCE) ? EINA_TRUE : EINA_FALSE; + ewk_notification_permission_reply(permissionRequest, ret); +} + +void popupCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + Assert(data); + Assert(obj); + + DPL_UNUSED_PARAM(eventInfo); + + PermissionData* permData = static_cast(data); + setPermissionResult(permData, getResult(obj)); + delete permData; + + Evas_Object* popup = getPopup(obj); + if (isNeedHelpPopup(popup)) { + ViewModule::HelpPopupSupport::showClearDefaultPopup(popup); + } + evas_object_hide(popup); + evas_object_del(popup); +} + +void eaKeyCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + Assert(data); + Assert(obj); + + DPL_UNUSED_PARAM(eventInfo); + + PermissionData* permData = static_cast(data); + setPermissionResult(permData, RESULT_DENY_ONCE); + delete permData; + + evas_object_hide(obj); + evas_object_del(obj); +} +} // anonymous namespace + +void permissionRequest( + Evas_Object* parent, + SecurityOriginDAO* securityOriginDAO, + void* data) +{ + Assert(securityOriginDAO); + Assert(data); + Ewk_Notification_Permission_Request* request = + static_cast(data); + const Ewk_Security_Origin* ewkOrigin = + ewk_notification_permission_request_origin_get(request); + Assert(ewkOrigin); + + SecurityOriginData securityOriginData( + WrtDB::FEATURE_WEB_NOTIFICATION, + Origin( + DPL::FromUTF8String(ewk_security_origin_protocol_get(ewkOrigin)), + DPL::FromUTF8String(ewk_security_origin_host_get(ewkOrigin)), + ewk_security_origin_port_get(ewkOrigin))); + + // check cache database + Result result = securityOriginDAO->getResult(securityOriginData); + if (RESULT_ALLOW_ONCE == result || RESULT_ALLOW_ALWAYS == result) { + _D("allow"); + ewk_notification_permission_reply(request, EINA_TRUE); + return; + } else if (RESULT_DENY_ONCE == result || RESULT_DENY_ALWAYS == result) { + _D("deny"); + ewk_notification_permission_reply(request, EINA_FALSE); + return; + } + + // ask to user + PermissionData* permissionData = + new PermissionData(securityOriginDAO, + securityOriginData, + request); + + // suspend notification + ewk_notification_permission_request_suspend(request); + if (!askUserPermission(parent, permissionData)) { + _W("Fail to create user permission popup"); + ewk_notification_permission_reply(request, RESULT_DENY_ONCE); + } + return; +} +} // namespace WebNotificationPermissionSupport +} //namespace ViewModule diff --git a/src/view/webkit/view_logic_web_notification_permission_support.h b/src/view/webkit/view_logic_web_notification_permission_support.h new file mode 100644 index 0000000..22bb21c --- /dev/null +++ b/src/view/webkit/view_logic_web_notification_permission_support.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_web_notification_permission_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @brief Header file of web Notification permission API + */ + +#ifndef VIEW_LOGIC_WEB_NOTIFICATION_PERMISSION_SUPPORT_H_ +#define VIEW_LOGIC_WEB_NOTIFICATION_PERMISSION_SUPPORT_H_ + +#include + +//Forward declarations +namespace SecurityOriginDB { +class SecurityOriginDAO; +} + +namespace ViewModule { +namespace WebNotificationPermissionSupport { +void permissionRequest( + Evas_Object* parent, + SecurityOriginDB::SecurityOriginDAO* securityOriginDAO, + void* data); +} // namespace WebNotificationPermissionSupport +} // namespace ViewModule +#endif // VIEW_LOGIC_WEB_NOTIFICATION_PERMISSION_SUPPORT_H_ + diff --git a/src/view/webkit/view_logic_web_notification_support.cpp b/src/view/webkit/view_logic_web_notification_support.cpp new file mode 100644 index 0000000..5800610 --- /dev/null +++ b/src/view/webkit/view_logic_web_notification_support.cpp @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_web_notification_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @brief Implementation file of web Notification API used by ViewLogic + */ + +#include "view_logic_web_notification_support.h" +#include "view_logic_web_notification_data.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace ViewModule { +namespace { +const char* PATTERN_CHECK_EXTERNAL = "^http(s)?://\\w+.*$"; + +// Function declare +bool isExternalUri(const std::string &uri); +size_t curlWriteData(void* ptr, size_t size, size_t nmemb, FILE* stream); + +bool isExternalUri(const std::string &uri) +{ + pcrecpp::RE_Options pcreOpt; + pcreOpt.set_caseless(true); + pcrecpp::RE re(PATTERN_CHECK_EXTERNAL, pcreOpt); + + return re.FullMatch(uri); +} + +size_t curlWriteData(void* ptr, size_t size, size_t nmemb, FILE* stream) +{ + size_t written = fwrite(ptr, size, nmemb, stream); + return written; +} +} // anonymous namespace + +// Implementation class +class WebNotificationSupportImplementation +{ + private: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, InitError) + DECLARE_EXCEPTION_TYPE(Base, NotificationShowError) + DECLARE_EXCEPTION_TYPE(Base, DownloadImageError) + }; + + bool m_initialized; + std::string m_persistentPath; + + typedef std::map NotiMap; + typedef std::map::iterator NotiMapIt; + NotiMap m_notiDataMap; + + std::string createDownloadPath(const std::string& iconUrl) + { + // Make valid filename + // If there is already exist filename, rename to "filename_%d" + + std::string downloadPath = m_persistentPath; + std::string fileName = iconUrl.substr(iconUrl.rfind('/') + 1); + _D("fileName from URL: %s", fileName.c_str()); + std::string rename = fileName; + unsigned int renameSuffixNb = 0; + while (0 == access((m_persistentPath + rename).c_str(), F_OK)) { + std::ostringstream suffixOstr; + suffixOstr.str(""); + suffixOstr << fileName << "_" << renameSuffixNb++; + + rename = fileName; + rename.insert(rename.find('.'), suffixOstr.str()); + } + + downloadPath += rename; + _D("Valid file path : %s", downloadPath.c_str()); + return downloadPath; + } + + std::string downloadImage(const std::string& iconUrl) + { + if (iconUrl.empty()) { + _W("Icon url is empty"); + return std::string(); + } + std::string downloadPath = createDownloadPath(iconUrl); + + // Download image by curl + FILE *fp = NULL; + CURL *curl = NULL; + + Try { + curl = curl_easy_init(); + if (NULL == curl) { + _W("fail to curl_easy_init"); + Throw(Exception::InitError); + } + fp = fopen(downloadPath.c_str(), "wb"); + if (fp == NULL) { + _W("fail to open"); + Throw(Exception::InitError); + } + + curl_easy_setopt(curl, CURLOPT_URL, iconUrl.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &curlWriteData); + + CURLcode err = curl_easy_perform(curl); + if (0 != err) { + _W("fail to curl_easy_perform: %d", err); + Throw(Exception::DownloadImageError); + } + fclose(fp); + curl_easy_cleanup(curl); + } Catch(DPL::Exception) { + fclose(fp); + curl_easy_cleanup(curl); + return std::string(); + } + _D("Download success"); + return downloadPath; + } + + int showNotification(WebNotificationDataPtr notiData) + { + Assert(notiData); + notification_h noti_h = NULL; + int error = NOTIFICATION_ERROR_NONE; + + Try { + // create notification + noti_h = notification_new( + NOTIFICATION_TYPE_NOTI, + NOTIFICATION_GROUP_ID_DEFAULT, + NOTIFICATION_PRIV_ID_NONE); + if (!noti_h) { + _E("Fail to notification_new"); + Throw(Exception::NotificationShowError); + } + + // set notification title + error = notification_set_text( + noti_h, + NOTIFICATION_TEXT_TYPE_TITLE, + notiData->getTitle(), + NULL, + NOTIFICATION_VARIABLE_TYPE_NONE); + if (error != NOTIFICATION_ERROR_NONE) { + _E("Fail to set title"); + Throw(Exception::NotificationShowError); + } + + // set notification content + error = notification_set_text( + noti_h, + NOTIFICATION_TEXT_TYPE_CONTENT, + notiData->getBody(), + NULL, + NOTIFICATION_VARIABLE_TYPE_NONE); + if (error != NOTIFICATION_ERROR_NONE) { + _E("Fail to set content: %d", error); + Throw(Exception::NotificationShowError); + } + + //check uri is "http", https" or not + if (notiData->getIconUrl()) { + std::string iconPath; + if (isExternalUri(notiData->getIconUrl())) { + //download image from url + iconPath = downloadImage(notiData->getIconUrl()); + } + + //set image + // If fail to download external image, skip to set image. + // In this case, set to default package image. + if (!iconPath.empty()) { + error = notification_set_image( + noti_h, + NOTIFICATION_IMAGE_TYPE_ICON, + iconPath.c_str()); + if (error != NOTIFICATION_ERROR_NONE) { + _E("Fail to free notification: %d", error); + Throw(Exception::NotificationShowError); + } + } + } + + // insert notification + int privId = NOTIFICATION_PRIV_ID_NONE; + error = notification_insert(noti_h, &privId); + if (error != NOTIFICATION_ERROR_NONE) { + _E("Fail to insert notification : %d", error); + Throw(Exception::NotificationShowError); + } + _D("ewkId=[%u], notiId=[%d]", notiData->getEwkNotiId(), privId); + + if (noti_h) { + error = notification_free(noti_h); + if (error != NOTIFICATION_ERROR_NONE) { + _E("Fail to free notification : %d", error); + Throw(Exception::NotificationShowError); + } + noti_h = NULL; + } + notiData->setNotiId(privId); + } Catch(Exception::NotificationShowError) { + notification_free(noti_h); + noti_h = NULL; + return false; + } Catch(DPL::Exception) { + _E("Fail to show notification"); + return false; + } + return true; + } + + bool hideNotification(uint64_t ewkNotiId) + { + int error = NOTIFICATION_ERROR_NONE; + NotiMapIt it = m_notiDataMap.find(ewkNotiId); + error = + notification_delete_by_priv_id(NULL, + NOTIFICATION_TYPE_NOTI, + it->second->getNotiId()); + if (error == NOTIFICATION_ERROR_NONE) { + _D("Success to hide"); + return true; + } else if (error == NOTIFICATION_ERROR_NOT_EXIST_ID) { + _D("Success to hide. Not exist noti"); + return true; + } else { + _W("Error to hide : %d", error); + return false; + } + } + + // manage noti data + bool isExistData(uint64_t ewkNotiId) + { + if (m_notiDataMap.find(ewkNotiId) == m_notiDataMap.end()) { + return false; + } + return true; + } + + void insertData(WebNotificationDataPtr notiData) + { + m_notiDataMap[notiData->getEwkNotiId()] = notiData; + } + + void removeData(uint64_t ewkNotiId) + { + m_notiDataMap.erase(ewkNotiId); + } + + WebNotificationDataPtr getData(uint64_t ewkNotiId) + { + return m_notiDataMap.find(ewkNotiId)->second; + } + + public: + WebNotificationSupportImplementation() : + m_initialized(false) + { + } + + void initialize(WrtDB::TizenPkgId pkgId) + { + // icon download path + // /opt/apps/tizen_id/data + '/' + filename + m_persistentPath = + WrtDB::WidgetConfig::GetWidgetPersistentStoragePath(pkgId) + '/'; + _D("path %s", m_persistentPath.c_str()); + m_initialized = true; + } + + void deinitialize(void) + { + _D("called"); + m_initialized = false; + } + + bool show(WebNotificationDataPtr notiData) + { + Assert(m_initialized); + if (isExistData(notiData->getEwkNotiId())) { + // Web Notifications (http://www.w3.org/TR/notifications/) + // 4.7 Replacing a notification + // 3. If old is in the list of pending notifications, queue a + // task to replace old with new, in the same position, in the + // list of pending notifications, and fire an event named + // close on old. + // 4. Otherwise, queue a task to replace old with new, in the + // same position, in the list of active notifications, fire + // an event named close on old, and fire an event named show + // on new. + hideNotification(notiData->getEwkNotiId()); + removeData(notiData->getEwkNotiId()); + } + if (showNotification(notiData)) { + insertData(notiData); + return true; + } + return false; + } + + void* hide(uint64_t ewkNotiId) + { + Assert(m_initialized); + if (!isExistData(ewkNotiId)) { + _W("Noti isn't exist"); + return NULL; + } + if (!hideNotification(ewkNotiId)) { + return NULL; + } + WebNotificationDataPtr data = getData(ewkNotiId); + removeData(ewkNotiId); + return static_cast(data->getData()); + } +}; + +WebNotificationSupport::WebNotificationSupport() : + m_impl(new WebNotificationSupportImplementation()) +{ +} + +WebNotificationSupport::~WebNotificationSupport() +{ +} + +void WebNotificationSupport::initialize(WrtDB::TizenAppId appId) +{ + m_impl->initialize(appId); +} + +void WebNotificationSupport::deinitialize(void) +{ + m_impl->deinitialize(); +} + +bool WebNotificationSupport::show(WebNotificationDataPtr notiData) +{ + return m_impl->show(notiData); +} + +void* WebNotificationSupport::hide(uint64_t ewkNotiId) +{ + return m_impl->hide(ewkNotiId); +} +} //namespace ViewModule diff --git a/src/view/webkit/view_logic_web_notification_support.h b/src/view/webkit/view_logic_web_notification_support.h new file mode 100644 index 0000000..893e771 --- /dev/null +++ b/src/view/webkit/view_logic_web_notification_support.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_web_notification_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @brief Header file of web Notification API used by ViewLogic + */ + +#ifndef VIEW_LOGIC_WEB_NOTIFICATION_SUPPORT_H_ +#define VIEW_LOGIC_WEB_NOTIFICATION_SUPPORT_H_ + +#include +#include +#include "view_logic_web_notification_data.h" + +namespace ViewModule { +class WebNotificationSupportImplementation; +class WebNotificationSupport +{ + public: + WebNotificationSupport(); + virtual ~WebNotificationSupport(); + void initialize(WrtDB::TizenPkgId pkgId); + void deinitialize(void); + + bool show(WebNotificationDataPtr notiData); + void* hide(uint64_t ewkNotiId); + + private: + std::unique_ptr m_impl; +}; +} // namespace ViewModule +#endif /* VIEW_LOGIC_WEB_NOTIFICATION_H_ */ diff --git a/src/view/webkit/view_logic_web_storage_support.cpp b/src/view/webkit/view_logic_web_storage_support.cpp new file mode 100644 index 0000000..3c64340 --- /dev/null +++ b/src/view/webkit/view_logic_web_storage_support.cpp @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_web_storage_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ + +#include "view_logic_web_storage_support.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ViewModule { +using namespace SecurityOriginDB; +using namespace ViewModule::SecurityOriginSupportUtil; + +namespace { +struct WebStoragePermissionData { + WebStorageSupport::ewkQuotaReply m_replyEAPI; + Evas_Object* m_ewkView; + WebStoragePermissionData(WebStorageSupport::ewkQuotaReply replyEAPI, + Evas_Object* ewkView) : + m_replyEAPI(replyEAPI), + m_ewkView(ewkView) + {} +}; + +// function declare +void askUserForWebStorageCreatePermission( + Evas_Object* window, + PermissionData* data); +void setPermissionResult(PermissionData* permData, Result result); +static void popupCallback(void* data, Evas_Object* obj, void* eventInfo); +static void eaKeyCallback(void* data, Evas_Object* obj, void* eventInfo); + +void askUserForWebStorageCreatePermission( + Evas_Object* window, + PermissionData* data) +{ + _D("called"); + std::string origin = DPL::ToUTF8String(data->m_originData.origin.host); + if (origin.empty()) { + origin = "local"; + } + std::string appname; + char* name = NULL; + if (app_get_name(&name) == APP_ERROR_NONE) { + appname = name; + free(name); + } else { + appname = "application"; + } + + std::string body = + WrtText::replacePS({WRT_POP_WEB_STORAGE_PERMISSION, appname, origin}); + Evas_Object* popup = createPopup(window, + body.c_str(), + WRT_BODY_REMEMBER_PREFERENCE, + popupCallback, + eaKeyCallback, + data); + + if (popup == NULL) { + _E("Fail to create popup object"); + delete data; + return; + } else { + evas_object_show(popup); + } +} + +void setPermissionResult(PermissionData* permData, Result result) +{ + Assert(permData); + WebStoragePermissionData* webStoragePermissionData = + static_cast(permData->m_data); + + if (result != RESULT_UNKNOWN) { + permData->m_originDao->setSecurityOriginData(permData->m_originData, result); + } + Eina_Bool ret = (result == RESULT_ALLOW_ALWAYS || result == RESULT_ALLOW_ONCE) ? EINA_TRUE : EINA_FALSE; + webStoragePermissionData->m_replyEAPI(webStoragePermissionData->m_ewkView, ret); +} + +void popupCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + Assert(data); + Assert(obj); + + DPL_UNUSED_PARAM(eventInfo); + + PermissionData* permData = static_cast(data); + setPermissionResult(permData, getResult(obj)); + WebStoragePermissionData* webStoragePermissionData = + static_cast(permData->m_data); + delete webStoragePermissionData; + delete permData; + + Evas_Object* popup = getPopup(obj); + if (isNeedHelpPopup(popup)) { + ViewModule::HelpPopupSupport::showClearDefaultPopup(popup); + } + evas_object_hide(popup); + evas_object_del(popup); +} + +void eaKeyCallback(void* data, Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + Assert(data); + Assert(obj); + + DPL_UNUSED_PARAM(eventInfo); + + PermissionData* permData = static_cast(data); + setPermissionResult(permData, RESULT_DENY_ONCE); + + WebStoragePermissionData* webStoragePermissionData = + static_cast(permData->m_data); + delete webStoragePermissionData; + delete permData; + + evas_object_hide(obj); + evas_object_del(obj); +} +} // namespace + +void WebStorageSupport::createPermissionRequest( + Evas_Object* window, + SecurityOriginDB::SecurityOriginDAO* securityOriginDAO, + Evas_Object* ewkView, + Ewk_Security_Origin* ewkOrigin, + ewkQuotaReply replyEAPI) +{ + _D("called"); + Assert(securityOriginDAO); + Assert(ewkOrigin); + Assert(ewkView); + SecurityOriginData securityOriginData( + WrtDB::FEATURE_WEB_DATABASE, + Origin( + DPL::FromUTF8String(ewk_security_origin_protocol_get(ewkOrigin)), + DPL::FromUTF8String(ewk_security_origin_host_get(ewkOrigin)), + ewk_security_origin_port_get(ewkOrigin))); + + // check cache database + Result result = securityOriginDAO->getResult(securityOriginData); + if (result != RESULT_UNKNOWN) { + Eina_Bool ret = + (result == RESULT_ALLOW_ALWAYS || result == RESULT_ALLOW_ONCE) ? + EINA_TRUE : EINA_FALSE; + replyEAPI(ewkView, ret); + return; + } + + // ask to user + WebStoragePermissionData* webStoragePermissionData = + new WebStoragePermissionData(replyEAPI, ewkView); + PermissionData* permissionData = + new PermissionData(securityOriginDAO, + securityOriginData, + webStoragePermissionData); + askUserForWebStorageCreatePermission(window, permissionData); + return; +} +} // namespace ViewModule diff --git a/src/view/webkit/view_logic_web_storage_support.h b/src/view/webkit/view_logic_web_storage_support.h new file mode 100644 index 0000000..845f591 --- /dev/null +++ b/src/view/webkit/view_logic_web_storage_support.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 view_logic_web_storage_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ + +#ifndef VIEW_LOGIC_WEB_STORAGE_SUPPORT_H_ +#define VIEW_LOGIC_WEB_STORAGE_SUPPORT_H_ + +#include +#include +#include +#include + +namespace SecurityOriginDB { +class SecurityOriginDAO; +} + +namespace ViewModule { +namespace WebStorageSupport { +typedef void (*ewkQuotaReply)(Evas_Object* ewkView, Eina_Bool allow); +bool isNeedPermissionRequest(void); +void createPermissionRequest( + Evas_Object* window, + SecurityOriginDB::SecurityOriginDAO* securityOriginDAO, + Evas_Object* ewkView, + Ewk_Security_Origin* ewkOrigin, + ewkQuotaReply replyEAPI); + +} // namespace WebStorageSupport +} // namespace ViewModule + +#endif // VIEW_LOGIC_WEB_STORAGE_SUPPORT_H_ diff --git a/src/wrt-client/CMakeLists.txt b/src/wrt-client/CMakeLists.txt new file mode 100644 index 0000000..32f5cc6 --- /dev/null +++ b/src/wrt-client/CMakeLists.txt @@ -0,0 +1,93 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +SET(TARGET_WRT_CLIENT "wrt-client") + +SET(WRT_CLIENT_SRCS + ${PROJECT_SOURCE_DIR}/src/wrt-client/window_data.cpp + ${PROJECT_SOURCE_DIR}/src/wrt-client/client_command_line_parser.cpp + ${PROJECT_SOURCE_DIR}/src/wrt-client/client_ide_support.cpp + ${PROJECT_SOURCE_DIR}/src/wrt-client/client_orientation_support.cpp + ${PROJECT_SOURCE_DIR}/src/wrt-client/client_submode_support.cpp + ${PROJECT_SOURCE_DIR}/src/wrt-client/splash_screen_support.cpp + ${PROJECT_SOURCE_DIR}/src/wrt-client/wrt-client.cpp + ${PROJECT_SOURCE_DIR}/src/wrt-launchpad-daemon/src/process_pool.c +) + +PKG_CHECK_MODULES(CLIENT_DEP + ail + capi-appfw-application + capi-appfw-watch-application + appcore-watch + dpl-wrt-dao-ro + wrt-popup-wrt-runner + appsvc + efl-assist + libsystemd-daemon + pkgmgr-info + capi-system-device + REQUIRED +) + +IF(JOURNAL_LOG_SUPPORT) + PKG_CHECK_MODULES(JOURNAL_LOG_DEP journal REQUIRED) +ENDIF(JOURNAL_LOG_SUPPORT) + +INCLUDE_DIRECTORIES( + ${PROJECT_SOURCE_DIR}/src/wrt-client + ${PROJECT_SOURCE_DIR}/src/api_new + ${PROJECT_SOURCE_DIR}/src/domain + ${PROJECT_SOURCE_DIR}/src/wrt-launchpad-daemon/include + ${CLIENT_DEP_INCLUDE_DIRS} + ${SMACK_LABELING_SUPPORT_INCLUDES} + ${JOURNAL_LOG_DEP_INCLUDE_DIRS} +) + +ADD_DEFINITIONS("-fPIE") + +SET(TARGET_WRT_CLIENT_SRCS + ${WRT_CLIENT_SRCS} +) + +ADD_EXECUTABLE(${TARGET_WRT_CLIENT} ${TARGET_WRT_CLIENT_SRCS}) + +SET_TARGET_PROPERTIES(${TARGET_WRT_CLIENT} PROPERTIES + COMPILE_DEFINITIONS LOG_TAG="${LOG_TAG}") + +SET(TARGET_WRT_CLIENT_LIBS + ${CLIENT_DEP_LIBRARIES} + ${TARGET_CORE_MODULE_LIB} + ${SMACK_LABELING_SUPPORT_STATIC} + ${PROF_LIB} + "-lcap" + "-pie" + ${JOURNAL_LOG_DEP_LIBRARIES} +) + +TARGET_LINK_LIBRARIES(${TARGET_WRT_CLIENT} + ${TARGET_WRT_CLIENT_LIBS} +) + +SET_TARGET_PROPERTIES(${TARGET_WRT_CLIENT} PROPERTIES + LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both -Wl,--version-script=${PROJECT_SOURCE_DIR}/wrt-engine.map" + BUILD_WITH_INSTALL_RPATH ON + INSTALL_RPATH_USE_LINK_PATH ON +) + +SET_TARGET_PROPERTIES(${TARGET_WRT_CLIENT} PROPERTIES + COMPILE_FLAGS "-include profiling_util.h" ) + +INSTALL(TARGETS ${TARGET_WRT_CLIENT} DESTINATION bin) + diff --git a/src/wrt-client/DESCRIPTION b/src/wrt-client/DESCRIPTION new file mode 100644 index 0000000..dd6f294 --- /dev/null +++ b/src/wrt-client/DESCRIPTION @@ -0,0 +1 @@ +The official WRT command-line interface diff --git a/src/wrt-client/client_command_line_parser.cpp b/src/wrt-client/client_command_line_parser.cpp new file mode 100644 index 0000000..fbb31d7 --- /dev/null +++ b/src/wrt-client/client_command_line_parser.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 client_command_line_parser.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ + +#include "client_command_line_parser.h" + +#include +#include +#include + +#include +#include +#include + +namespace ClientModule { +namespace { + +std::string parseIdField(int argc, char **argv) +{ + if (argv[0] == NULL) { + return ""; + } + + std::string arg = argv[0]; + if (arg.empty()) { + return ""; + } + + if (arg.find("wrt-client") != std::string::npos) { + if (argc <= 1) { + return ""; + } + + arg = argv[1]; + + if (arg == "-h" || arg == "--help") { + return ""; + } else if (arg == "-l" || + arg == "--launch" || + arg == "-t" || + arg == "--tizen") + { + if (argc != 3) { + return ""; + } + return argv[2]; + } else { + return ""; + } + } else { + std::size_t pos = arg.find_last_of('/'); + if (pos != std::string::npos) { + arg = arg.erase(0, pos + 1); + } + return arg; + } +} + +DPL::OptionalUInt getIndex(const std::string& tizenId) +{ + std::size_t pos = + tizenId.find(WrtDB::AppControlPrefix::PROCESS_PREFIX); + if (pos != std::string::npos) { + std::string index = tizenId.substr(pos); + index.erase(strlen(WrtDB::AppControlPrefix::PROCESS_PREFIX)); + std::stringstream s(index); + unsigned int appControlIndex; + s >> appControlIndex; + return appControlIndex; + } + return DPL::OptionalUInt(); +} + +std::string removeIndex(const std::string& tizenId) +{ + std::string id = tizenId; + std::size_t pos = + id.find(WrtDB::AppControlPrefix::PROCESS_PREFIX); + if (pos != std::string::npos) { + id.erase(pos); + } + return id; +} +} + +std::string CommandLineParser::getTizenId(int argc, char **argv) +{ + std::string id = parseIdField(argc, argv); + if (id.empty()) { + return ""; + } + return removeIndex(id); +} + +DPL::OptionalUInt CommandLineParser::getAppControlIndex(int argc, char **argv) +{ + std::string id = parseIdField(argc, argv); + if (id.empty()) { + return DPL::OptionalUInt(); + } + return getIndex(id); +} +} // ClientModule diff --git a/src/wrt-client/client_command_line_parser.h b/src/wrt-client/client_command_line_parser.h new file mode 100644 index 0000000..615e442 --- /dev/null +++ b/src/wrt-client/client_command_line_parser.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 client_command_line_parser.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ +#ifndef CLIENT_COMMAND_LINE_PARSER_H_ +#define CLIENT_COMMAND_LINE_PARSER_H_ + +#include + +namespace ClientModule { +namespace CommandLineParser { +std::string getTizenId(int argc, char **argv); +DPL::OptionalUInt getAppControlIndex(int argc, char **argv); +} // CommandLineParser +} // ClientModule +#endif // CLIENT_COMMAND_LINE_PARSER_H_ \ No newline at end of file diff --git a/src/wrt-client/client_ide_support.cpp b/src/wrt-client/client_ide_support.cpp new file mode 100644 index 0000000..1f37739 --- /dev/null +++ b/src/wrt-client/client_ide_support.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 client_ide_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ + +#include "client_ide_support.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace ClientModule { +namespace { +const char* const KEY_DEBUG = "debug"; +const char* const KEY_PORT = "port"; +const char* const VALUE_TRUE = "true"; + +const char* const CONSOLE_MESSAGE_LOG_TAG = "ConsoleMessage"; +} + +bool IDESupport::getDebugMode(bundle* b) +{ + if (!b) { + LogWarning("bundle is empty"); + return false; + } + + const char* value = bundle_get_val(b, KEY_DEBUG); + if (value != NULL && !strcmp(value, VALUE_TRUE)) { + return true; + } else { + return false; + } +} + +bool IDESupport::sendReply(bundle* b, unsigned int portNum) +{ + bundle* request = NULL; + if (appsvc_create_result_bundle(b, &request) != APPSVC_RET_OK) { + LogWarning("Fail to create result bundle"); + return false; + } + + char port[10] = {0,}; + sprintf(port, "%u", portNum); + if (appsvc_add_data(request, KEY_PORT, port) != APPSVC_RET_OK) { + LogWarning("Fail to add data"); + bundle_free(request); + return false; + } + + if (appsvc_send_result(request, APPSVC_RES_OK) != APPSVC_RET_OK) { + LogWarning("Fail to send result"); + bundle_free(request); + return false; + } + + bundle_free(request); + return true; +} + +void IDESupport::consoleMessage(int level, const char* format, ...) +{ + va_list args; + va_start(args, format); + switch (level) { + case ConsoleLogLevel::Debug: + ALOG_VA(LOG_DEBUG, CONSOLE_MESSAGE_LOG_TAG, format, args); + break; + case ConsoleLogLevel::Warning: + ALOG_VA(LOG_WARN, CONSOLE_MESSAGE_LOG_TAG, format, args); + break; + case ConsoleLogLevel::Error: + ALOG_VA(LOG_ERROR, CONSOLE_MESSAGE_LOG_TAG, format, args); + break; + default: + ALOG_VA(LOG_DEBUG, CONSOLE_MESSAGE_LOG_TAG, format, args); + break; + } + va_end(args); +} +} // ClientModule diff --git a/src/wrt-client/client_ide_support.h b/src/wrt-client/client_ide_support.h new file mode 100644 index 0000000..e52c1d1 --- /dev/null +++ b/src/wrt-client/client_ide_support.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 client_ide_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + */ +#ifndef CLIENT_IDE_SUPPORT_H_ +#define CLIENT_IDE_SUPPORT_H_ + +#include + +namespace ClientModule { +namespace IDESupport { +bool getDebugMode(bundle* b); +bool sendReply(bundle* b, unsigned int portNum); +void consoleMessage(int level, const char* format, ...); +} // IDESupport +} // ClientModule +#endif // CLIENT_IDE_SUPPORT_H_ \ No newline at end of file diff --git a/src/wrt-client/client_orientation_support.cpp b/src/wrt-client/client_orientation_support.cpp new file mode 100644 index 0000000..846cdeb --- /dev/null +++ b/src/wrt-client/client_orientation_support.cpp @@ -0,0 +1,278 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file client_orientation_support.cpp + * @author Grzegorz Rynkowski (g.rynkowski@samsung.com) + * @brief source file to support window orientation of web application + */ + +#include "client_orientation_support.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ClientModule { + +namespace { +const char* const WM_ROTATION_CHANGED_CALLBACK = "wm,rotation,changed"; +const int ANGLE_PORTRAIT = 0; +const int ANGLE_LANDSCAPE = 270; +} + +OrientationSupport::OrientationSupport(const WindowDataPtr& windowData, + const WRT::RunnableWidgetObjectPtr& widget) + : m_windowData(windowData), + m_widget(widget), + m_rotationAngle(0) +{ +} + +void OrientationSupport::setWindowOrientation(int angle) +{ + Assert(m_windowData); + m_windowData->setOrientation(angle); +} + +void OrientationSupport::setInitialWindowOrientation( + WidgetSettingScreenLock rotationValue) +{ + switch(rotationValue) { + case Screen_AutoRotation: + break; + case Screen_Landscape: + setWindowOrientation(OrientationAngle::Window::Landscape::PRIMARY); + break; + case Screen_Portrait: + default: + setWindowOrientation(OrientationAngle::Window::Portrait::PRIMARY); + break; + } +} + +bool OrientationSupport::setAutoRotation() +{ + Assert(m_windowData); + Evas_Object* window = m_windowData->getEvasObject(Layer::WINDOW); + + if (elm_win_wm_rotation_supported_get(window)) { + const int rots[4] = {OrientationAngle::Window::Portrait::PRIMARY, + OrientationAngle::Window::Portrait::SECONDARY, + OrientationAngle::Window::Landscape::PRIMARY, + OrientationAngle::Window::Landscape::SECONDARY}; + elm_win_wm_rotation_available_rotations_set(window, rots, 4); + registerRotationCallback(&OrientationSupport::autoRotationCallback, this); +#if USE(WEBKIT_MANUAL_ROTATION) + m_rotationAngle = elm_win_rotation_get(window); +#endif + return true; + } + return false; +} + +#if USE(WEBKIT_MANUAL_ROTATION) +void OrientationSupport::setRotationDone(void) +{ + _D("called"); + + Assert(m_windowData); + Evas_Object* win = m_windowData->getEvasObject(Layer::WINDOW); + Assert(win); + if (EINA_TRUE == elm_win_wm_rotation_manual_rotation_done_get(win)) { + elm_win_wm_rotation_manual_rotation_done(win); + } +} + +void OrientationSupport::setManualRotation(bool enable) +{ + _D("called"); + + Assert(m_windowData); + Evas_Object* win = m_windowData->getEvasObject(Layer::WINDOW); + + Assert(win); + elm_win_wm_rotation_manual_rotation_done_set(win, enable ? EINA_TRUE : EINA_FALSE); +} +#endif + +bool OrientationSupport::isOrientationPrepared(WidgetSettingScreenLock rotationValue) +{ + _D("called"); + + Assert(m_windowData); + Evas_Object* win = m_windowData->getEvasObject(Layer::WINDOW); + Assert(win); + int currentAngle = elm_win_rotation_get(win); + if (currentAngle == -1) { + _E("elm_win_rotation_get failed"); + Assert(false); + } + + switch(rotationValue) { + case Screen_Landscape: + return currentAngle == ANGLE_LANDSCAPE; + case Screen_Portrait: + return currentAngle == ANGLE_PORTRAIT; + case Screen_AutoRotation: + default: + return true; + } +} + +void OrientationSupport::registerRotationCallback(const Evas_Smart_Cb callback, + const void *data) +{ + Assert(m_windowData); + Evas_Object* window = m_windowData->getEvasObject(Layer::WINDOW); + _D("add rotation callback: %s (%p)", WM_ROTATION_CHANGED_CALLBACK, callback); + evas_object_smart_callback_add(window, + WM_ROTATION_CHANGED_CALLBACK, + callback, + data); + m_registeredCallbacks.push_back( + Callback(WM_ROTATION_CHANGED_CALLBACK, callback)); +} + +void OrientationSupport::unregisterRotationCallback(const Evas_Smart_Cb callback) +{ + FOREACH(it, m_registeredCallbacks) + { + if (it->second == callback) { + Assert(m_windowData); + Evas_Object* win = m_windowData->getEvasObject(Layer::WINDOW); + Assert(win); + _D("remove rotation callback: %s (%p)", WM_ROTATION_CHANGED_CALLBACK, callback); + evas_object_smart_callback_del(win, it->first.c_str(), it->second); + m_registeredCallbacks.erase(it); + return; + } + } +} + +void OrientationSupport::unregisterRotationCallbacks() +{ + Assert(m_windowData); + Evas_Object* wkView = m_windowData->getEvasObject(Layer::WINDOW); + FOREACH(it, m_registeredCallbacks) + { + _D("remove rotation callback: %s (%p)", it->first.c_str(), it->second); + evas_object_smart_callback_del(wkView, it->first.c_str(), it->second); + } +} + +void OrientationSupport::setEwkInitialOrientation( + WidgetSettingScreenLock rotationValue) +{ + Assert(m_widget); + + Evas_Object* obj = m_widget->GetCurrentWebview(); + switch(rotationValue) { + case Screen_Landscape: + ewk_view_orientation_send(obj, + OrientationAngle::W3C::Landscape::PRIMARY); + break; + case Screen_Portrait: + case Screen_AutoRotation: + default: + ewk_view_orientation_send(obj, + OrientationAngle::W3C::Portrait::PRIMARY); + break; + } +} + +void OrientationSupport::rotatePrepared(Evas_Object* obj) +{ + _D("rotatePrepared"); + Assert(m_windowData); + int winAngle = elm_win_rotation_get( + m_windowData->getEvasObject(Layer::WINDOW)); + int w3cAngle; + + switch(winAngle) { + case OrientationAngle::Window::Portrait::PRIMARY: + w3cAngle = OrientationAngle::W3C::Portrait::PRIMARY; + break; + case OrientationAngle::Window::Portrait::SECONDARY: + w3cAngle = OrientationAngle::W3C::Portrait::SECONDARY; + break; + case OrientationAngle::Window::Landscape::PRIMARY: + w3cAngle = OrientationAngle::W3C::Landscape::PRIMARY; + break; + case OrientationAngle::Window::Landscape::SECONDARY: + w3cAngle = OrientationAngle::W3C::Landscape::SECONDARY; + break; + default: + _W("unknown angle"); + return; + } + ewk_view_orientation_send(obj, w3cAngle); +} + +void OrientationSupport::updateRotationAngle(void) +{ + Evas_Object* win = m_windowData->getEvasObject(Layer::WINDOW); + int newAngle = elm_win_rotation_get(win); + if (newAngle == -1) { + _W("elm_win_rotation_get failed"); + return; + } + +#if USE(WEBKIT_MANUAL_ROTATION) + if (EINA_FALSE == elm_win_wm_rotation_manual_rotation_done_get(win)) { + _D("Rotate by platform"); + m_rotationAngle = newAngle; + return; + } + + if ((m_rotationAngle + newAngle) % 180 == 0) + { + _D("Rotate by wrt"); + // In case of rotate 180 degress, setRotationDone by WRT instead of webkit. + // Webkit doesn't call "rotate,prepared" callback. + setRotationDone(); + } + m_rotationAngle = newAngle; +#endif +} + +//static +void OrientationSupport::autoRotationCallback(void* data, + Evas_Object* obj, + void* event) +{ + DPL_UNUSED_PARAM(obj); + DPL_UNUSED_PARAM(event); + _D("entered"); + OrientationSupport* This = static_cast(data); + Assert(This->m_widget); + This->rotatePrepared(This->m_widget->GetCurrentWebview()); + This->updateRotationAngle(); +} + +void OrientationSupport::resetOrientation() +{ + Assert(m_widget); + rotatePrepared(m_widget->GetCurrentWebview()); + updateRotationAngle(); +} + +} // namespace ClientModule diff --git a/src/wrt-client/client_orientation_support.h b/src/wrt-client/client_orientation_support.h new file mode 100644 index 0000000..081bf61 --- /dev/null +++ b/src/wrt-client/client_orientation_support.h @@ -0,0 +1,75 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file client_orientation_support.h + * @author Grzegorz Rynkowski (g.rynkowski@samsung.com) + * @brief header file to support window orientation of web application + */ + +#ifndef CLIENT_ORIENTATION_SUPPORT_H_ +#define CLIENT_ORIENTATION_SUPPORT_H_ + +#include +#include +#include + +#include +#include +#include +#include + +#include "window_data.h" + +namespace ClientModule { + +class OrientationSupport { + public: + OrientationSupport(const WindowDataPtr& windowData, + const WRT::RunnableWidgetObjectPtr& widget); + + void setInitialWindowOrientation(WidgetSettingScreenLock rotationValue); + void setEwkInitialOrientation(WidgetSettingScreenLock rotationValue); + bool setAutoRotation(); +#if USE(WEBKIT_MANUAL_ROTATION) + void setRotationDone(void); + void setManualRotation(bool enable); +#endif + bool isOrientationPrepared(WidgetSettingScreenLock rotationValue); + + void registerRotationCallback(const Evas_Smart_Cb callback, const void *data); + void unregisterRotationCallback(const Evas_Smart_Cb callback); + void unregisterRotationCallbacks(); + void resetOrientation(); + + private: + void setWindowOrientation(int angle); + void rotatePrepared(Evas_Object* obj); + void updateRotationAngle(void); + static void autoRotationCallback(void* data, Evas_Object* obj, void* event); + + WindowDataPtr m_windowData; + WRT::RunnableWidgetObjectPtr m_widget; + // TODO: separate by base class(OrientationManualRotationSupport) + int m_rotationAngle; + + typedef std::pair Callback; + typedef std::vector CallbacksList; + CallbacksList m_registeredCallbacks; +}; + +} // namespace ClientModule +#endif // CLIENT_ORIENTATION_SUPPORT_H_ diff --git a/src/wrt-client/client_submode_support.cpp b/src/wrt-client/client_submode_support.cpp new file mode 100644 index 0000000..e65718c --- /dev/null +++ b/src/wrt-client/client_submode_support.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 client_submode_support.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + */ + +#include "client_submode_support.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +namespace ClientModule { +namespace { +const unsigned int EMPTY = 0; +const unsigned int INLINE_MODE = 1; +const unsigned int TRANSIENT_WINDOW = 1 << 1; +} + + //Implementation class +class SubmodeSupportImplementation +{ + private: + bool m_initialized; + WrtDB::TizenAppId m_appId; + unsigned int m_mode; + + void setMode(const int mode) + { + m_mode |= mode; + } + + bool getMode(const int mode) + { + return m_mode & mode; + } + + static Eina_Bool destoryCallback(void* data, int /*type*/, void* event) + { + _D("called"); + Ecore_X_Window callerId = reinterpret_cast(data); + + Assert(event); + Ecore_X_Event_Window_Hide* ev = + static_cast(event); + + if(ev->win == callerId) { + elm_exit(); + } + return ECORE_CALLBACK_CANCEL; + } + + public: + SubmodeSupportImplementation() : + m_initialized(false), + m_mode(EMPTY) + { + } + + void initialize(WrtDB::TizenAppId appId) + { + _D("called"); + + m_appId = appId; + WrtDB::WidgetDAOReadOnly dao(m_appId); + WrtDB::WidgetAppControlList widgetApplicationControlList; + dao.getAppControlList(widgetApplicationControlList); + FOREACH(it, widgetApplicationControlList) { + if (it->disposition == + WrtDB::WidgetAppControl::Disposition::INLINE) + { + _D("disposition"); + setMode(INLINE_MODE); + } + } + + m_initialized = true; + } + + void deinitialize(void) + { + _D("called"); + m_initialized = false; + } + + bool isInlineMode(void) + { + return getMode(INLINE_MODE); + } + + bool isNeedTerminateOnSuspend(void) + { + if (isInlineMode()) { + return !getMode(TRANSIENT_WINDOW); + } + return false; + } + + bool transientWindow(Ecore_X_Window calleeId) + { + _D("called"); + if (!m_initialized) { + _E("not initialized"); + return false; + } + + bundle* b = ApplicationDataSingleton::Instance().getBundle(); + if (!b) { + _W("Service data is empty"); + return false; + } + const char* callerIdPtr = bundle_get_val(b, "__APP_SVC_K_WIN_ID__"); + if (callerIdPtr) { + Ecore_X_Window callerId = atoi(callerIdPtr); + _D("Caller x handle = %u", callerId); + ecore_x_icccm_transient_for_set(calleeId, callerId); + ecore_x_window_client_manage(callerId); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, + destoryCallback, + reinterpret_cast(callerId)); + setMode(TRANSIENT_WINDOW); + } else { + _W("Service data is empty"); + return false; + } + + return true; + } +}; + +SubmodeSupport::SubmodeSupport() : + m_impl(new SubmodeSupportImplementation()) +{ +} + +SubmodeSupport::~SubmodeSupport() +{ +} + +void SubmodeSupport::initialize(WrtDB::TizenAppId appId) +{ + m_impl->initialize(appId); +} + +void SubmodeSupport::deinitialize(void) +{ + m_impl->deinitialize(); +} + +bool SubmodeSupport::isInlineMode(void) +{ + return m_impl->isInlineMode(); +} + +bool SubmodeSupport::isNeedTerminateOnSuspend(void) +{ + return m_impl->isNeedTerminateOnSuspend(); +} + +bool SubmodeSupport::transientWindow(Ecore_X_Window calleeId) +{ + return m_impl->transientWindow(calleeId); +} +} // namespace ClientModule diff --git a/src/wrt-client/client_submode_support.h b/src/wrt-client/client_submode_support.h new file mode 100644 index 0000000..4fdcf66 --- /dev/null +++ b/src/wrt-client/client_submode_support.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 client_submode_support.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + */ + +#ifndef CLIENT_SUBMODE_SUPPORT_H_ +#define CLIENT_SUBMODE_SUPPORT_H_ + +#include +#include + +#include + +namespace ClientModule { +class SubmodeSupportImplementation; +class SubmodeSupport +{ + public: + SubmodeSupport(); + virtual ~SubmodeSupport(); + void initialize(WrtDB::TizenAppId appId); + void deinitialize(void); + bool isInlineMode(void); + bool isNeedTerminateOnSuspend(void); + bool transientWindow(Ecore_X_Window win); + + private: + std::unique_ptr m_impl; +}; +} // namespace ClientModule +#endif // CLIENT_SUBMODE_SUPPORT_H_ \ No newline at end of file diff --git a/src/wrt-client/process_pool/smack_labeling_support.cpp b/src/wrt-client/process_pool/smack_labeling_support.cpp new file mode 100644 index 0000000..187fed2 --- /dev/null +++ b/src/wrt-client/process_pool/smack_labeling_support.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 smack_labeling_support.cpp + * @author Tae-Jeong Lee (taejeong.lee@samsung.com) + * @version 0.1 + * @brief API to support smack labeling for whole threads in a process. + */ + +#include "smack_labeling_support.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SMACK_LABEL_LEN 255 +#define FILE_MAX_LEN 1024 +#define MAX_RETRY_CNT 1000 +#define UID_ROOT 0 + +static char s_smack_label[SMACK_LABEL_LEN + 1] = {0,}; +static int s_waiting_task_cnt = 0; + +static int smack_set_label_for_tid(const char *label) +{ + int len, fd, ret; + char curren_path[FILE_MAX_LEN + 1] = {0,}; + + len = strnlen(label, SMACK_LABEL_LEN + 1); + + if (len > SMACK_LABEL_LEN) + { + return -1; + } + + snprintf(curren_path, sizeof(curren_path), "/proc/%d/attr/current", (int)syscall(__NR_gettid)); + + fd = open(curren_path, O_WRONLY); + + if (fd < 0) + { + return -1; + } + + ret = write(fd, label, len); + close(fd); + + return (ret < 0) ? -1 : 0; +} + +static void SIGUSR1_handler(int /*signo*/) +{ + if (smack_set_label_for_tid(s_smack_label) != 0) + { + LogError("## [tid:" << syscall(__NR_gettid) << "] smack_set_label_for_tid() failed! ##"); + } + s_waiting_task_cnt--; +} + +static int set_SIGUSR1_handler() +{ + if (signal(SIGUSR1, SIGUSR1_handler) == SIG_ERR) + { + LogError("## signal(SIGUSR1, SIGUSR1_handler) failed! ##"); + return -1; + } + + return 0; +} + +static int set_SIGUSR1_to_default() +{ + if (signal(SIGUSR1, SIG_DFL) == SIG_ERR) + { + LogError("## signal(SIGUSR1, SIG_ERR) failed! ##"); + return -1; + } + + return 0; +} + +static int send_SIGUSR1_to_threads() +{ + int ret; + DIR *dir; + struct dirent entry, *result; + char proc_self_task_path[FILE_MAX_LEN + 1] = {0, }; + + sprintf(proc_self_task_path, "/proc/self/task"); + + dir = opendir(proc_self_task_path); + + if (dir) + { + for (ret = readdir_r(dir, &entry, &result); + result != NULL && ret == 0; + ret = readdir_r(dir, &entry, &result)) + { + if (strncmp(entry.d_name, ".", 2) == 0 || + strncmp(entry.d_name, "..", 3) == 0) + { + continue; + } + + s_waiting_task_cnt++; + if (syscall(__NR_tkill, atoi(entry.d_name), SIGUSR1) != 0) + { + LogError("## tkill(" << atoi(entry.d_name) << "SIGUSR1) failed! ##"); + s_waiting_task_cnt--; + } + } + + closedir(dir); + } + else + { + LogError("## opendir(\"/proc/self/task\") failed! ##"); + return -1; + } + + return 0; +} + +int set_app_smack_label(const char* app_path) +{ + assert(s_waiting_task_cnt == 0); + + if (UID_ROOT != getuid() || app_path == NULL) + { + LogError("## parameter error! ##"); + return -1; + } + + // set SIGUSR1 signal handler + if (set_SIGUSR1_handler() != 0) + { + return -1; + } + + // get smack label from app_path + char *smack_label = NULL; + + if (smack_lgetlabel(app_path, &smack_label, SMACK_LABEL_EXEC) != 0) + { + LogError("## smack_lgetlabel() failed! ##"); + goto err_set_app_smack_label; + } + + if (smack_label) + { + strncpy(s_smack_label, smack_label, sizeof(s_smack_label)); + s_smack_label[SMACK_LABEL_LEN] = '\0'; + + free(smack_label); + smack_label = NULL; + } + else + { + LogError("## smack_label is NULL! ##"); + strcpy(s_smack_label, ""); + } + + if (send_SIGUSR1_to_threads() != 0) + { + LogError("## send_SIGUSR1_to_threads() timeout! ##"); + goto err_set_app_smack_label; + } + + // wait for labeling on each tasks + int i; + + for (i=0; s_waiting_task_cnt && i < MAX_RETRY_CNT; i++) + { + usleep(100); // 0.1ms + } + + if (i == MAX_RETRY_CNT) + { + LogError("## set_app_smack_label() timeout! ##"); + } + + // set SIGUSR1 signal defualt handler + set_SIGUSR1_to_default(); + + return 0; + +err_set_app_smack_label: + s_waiting_task_cnt = 0; + set_SIGUSR1_to_default(); + + return -1; +} + + diff --git a/src/wrt-client/process_pool/smack_labeling_support.h b/src/wrt-client/process_pool/smack_labeling_support.h new file mode 100644 index 0000000..09ef1a5 --- /dev/null +++ b/src/wrt-client/process_pool/smack_labeling_support.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 smack_labeling_support.h + * @author Tae-Jeong Lee (taejeong.lee@samsung.com) + * @version 0.1 + * @brief API to support smack labeling for whole threads in a process. + */ + +#ifndef SMACK_LABELING_SUPPORT_H +#define SMACK_LABELING_SUPPORT_H + +int set_app_smack_label(const char* app_path); + +#endif // SMACK_LABELING_SUPPORT_H diff --git a/src/wrt-client/splash_screen_support.cpp b/src/wrt-client/splash_screen_support.cpp new file mode 100644 index 0000000..c5c1924 --- /dev/null +++ b/src/wrt-client/splash_screen_support.cpp @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 splash_screen_support.cpp + * @author Andrzej Surdej (a.surdej@samsung.com) + * @brief Implementation file for splash screen support + */ + +#include "splash_screen_support.h" +#include + +const short SPLASH_SCREEN_LAYER = 10; +const double SPLASH_SCREEN_MAXIUM_TIMER = 5.0; // sec +const double SPLASH_SCREEN_BUFFER_TIMER = 0.5; // sec +const int INDICATOR_H = 60; + +static void evas_object_reposition(Evas_Object* obj, int x, int y, int w, int h) +{ + evas_object_resize(obj,w, h); + evas_object_move(obj, x, y); +} + +SplashScreenSupport::SplashScreenSupport(Evas_Object* parent, const char* image_path, bool indicator, bool landscape) : + m_parent(parent), + m_splashScreen(NULL), + m_splashScreenBg(NULL), + m_timer(NULL), + m_deviceWidth(0), + m_deviceHeight(0), + m_imageWidth(0), + m_imageHeight(0), + m_initialized(false), + m_isShowing(false), + m_indicator(indicator) +{ + LogDebug("enter"); + + if (!m_parent || !image_path) + { + LogError("Invalid parameter"); + return; + } + + // create evas object + m_splashScreenBg = evas_object_rectangle_add(evas_object_evas_get(m_parent)); + evas_object_color_set(m_splashScreenBg, 255, 255, 255, 255); + + m_splashScreen = elm_image_add(m_splashScreenBg); + elm_image_no_scale_set(m_splashScreen, EINA_FALSE); + + if (elm_image_file_set(m_splashScreen, image_path, NULL)) + { + // check animation + if (elm_image_animated_available_get(m_splashScreen)) + { + elm_image_animated_set(m_splashScreen, EINA_TRUE); + elm_image_animated_play_set(m_splashScreen, EINA_FALSE); + } + + // get contents area + Evas_Coord x, y, w, h; + evas_object_geometry_get(m_parent, &x, &y, &w, &h); + + m_deviceWidth = (w < h) ? w : h; + m_deviceHeight = (w > h) ? w : h; + + if (!landscape) + { + x = 0; + y = 0; + w = m_deviceWidth; + h = m_deviceHeight; + +// there are no indicator space in wearable device +#if 0 + if (m_indicator) + { + int indicator_h = INDICATOR_H * elm_config_scale_get(); + + y += indicator_h; + h -= indicator_h; + } +#endif + } + else + { + x = 0; + y = 0; + w = m_deviceHeight; + h = m_deviceWidth; + } + + // fit to width + elm_image_object_size_get(m_splashScreen, &m_imageWidth, &m_imageHeight); + + if (m_imageWidth == 0 || m_imageHeight == 0) + { + LogError("Splash screen image size error!"); + + m_imageWidth = w; + m_imageHeight = h; + } + + double ratio_win = (double)w/h; + double ratio_image = (double)m_imageWidth/m_imageHeight; + + // set evas position + evas_object_reposition(m_splashScreenBg, x, y, w, h); + evas_object_reposition(m_splashScreen, x, y, w, h); + + double scaled_image_w = w; + double scaled_image_h = (w/ratio_image); + + Evas_Object* imageObject = elm_image_object_get(m_splashScreen); + + if (ratio_image <= ratio_win) + { + evas_object_image_fill_set(imageObject, 0, 0-((scaled_image_h-h)/2), scaled_image_w, scaled_image_h); + evas_object_reposition(imageObject, x, y, w, h); + } + else + { + evas_object_image_fill_set(imageObject, 0, 0, scaled_image_w, scaled_image_h); + evas_object_reposition(imageObject, 0, y+(h-scaled_image_h)/2, scaled_image_w, scaled_image_h); + } + + m_initialized = true; + } +} + +SplashScreenSupport::~SplashScreenSupport() +{ + LogDebug("enter"); + + if (m_initialized) + { + evas_object_del(m_splashScreen); + evas_object_del(m_splashScreenBg); + } + + if (m_timer) + { + ecore_timer_del(m_timer); + m_timer = NULL; + } +} + +Eina_Bool SplashScreenSupport::timerCallback(void *data) +{ + LogDebug("enter"); + + SplashScreenSupport* This = static_cast(data); + + if (This->isShowing()) + { + This->stopSplashScreen(); + } + + return ECORE_CALLBACK_CANCEL; +} + +void SplashScreenSupport::startSplashScreen() +{ + LogDebug("splashImageOn"); + + if (m_initialized) + { + if (elm_image_animated_get(m_splashScreen) == EINA_TRUE) + { + elm_image_animated_play_set(m_splashScreen, EINA_TRUE); + } + + evas_object_layer_set(m_splashScreenBg, SPLASH_SCREEN_LAYER); + evas_object_layer_set(m_splashScreen, SPLASH_SCREEN_LAYER); + + evas_object_show(m_splashScreenBg); + evas_object_show(m_splashScreen); + + m_isShowing = true; + + if (m_timer) + { + ecore_timer_del(m_timer); + } + + m_timer = ecore_timer_add(SPLASH_SCREEN_MAXIUM_TIMER, timerCallback, this); + } +} + + +void SplashScreenSupport::stopSplashScreenBuffered() +{ + if (m_isShowing) + { + if (m_timer) + { + ecore_timer_del(m_timer); + } + + m_timer = ecore_timer_add(SPLASH_SCREEN_BUFFER_TIMER, timerCallback, this); + } +} + +void SplashScreenSupport::stopSplashScreen() +{ + LogDebug("splashImageOff"); + + if (m_isShowing) + { + if (elm_image_animated_get(m_splashScreen) == EINA_TRUE) + { + elm_image_animated_play_set(m_splashScreen, EINA_FALSE); + } + + evas_object_hide(m_splashScreen); + evas_object_hide(m_splashScreenBg); + + evas_object_del(m_splashScreen); + evas_object_del(m_splashScreenBg); + + m_initialized = false; + m_isShowing = false; + + if (m_timer) + { + ecore_timer_del(m_timer); + m_timer = NULL; + } + } +} + +bool SplashScreenSupport::isShowing() +{ + return m_isShowing; +} + +void SplashScreenSupport::resizeSplashScreen() +{ + if (m_initialized && m_isShowing) + { + int x, y, w, h; + int angle = elm_win_rotation_get(m_parent); + + if (angle == 0 || angle == 180) + { + x = 0; + y = 0; + w = m_deviceWidth; + h = m_deviceHeight; +// there are no indicator space in wearable device +#if 0 + if (m_indicator) + { + int indicator_h = INDICATOR_H * elm_config_scale_get(); + + y += indicator_h; + h -= indicator_h; + } +#endif + } + else + { + x = 0; + y = 0; + w = m_deviceHeight; + h = m_deviceWidth; + } + + // fit to width + double ratio_win = (double)w/h; + double ratio_image = (double)m_imageWidth/m_imageHeight; + + evas_object_reposition(m_splashScreenBg, x, y, w, h); + evas_object_reposition(m_splashScreen, x, y, w, h); + + double scaled_image_w = w; + double scaled_image_h = (w/ratio_image); + + Evas_Object* imageObject = elm_image_object_get(m_splashScreen); + + if (ratio_image <= ratio_win) + { + evas_object_image_fill_set(imageObject, 0, 0-((scaled_image_h-h)/2), scaled_image_w, scaled_image_h); + evas_object_reposition(imageObject, x, y, w, h); + } + else + { + evas_object_image_fill_set(imageObject, 0, 0, scaled_image_w, scaled_image_h); + evas_object_reposition(imageObject, 0, y+(h-scaled_image_h)/2, scaled_image_w, scaled_image_h); + } + + } +} diff --git a/src/wrt-client/splash_screen_support.h b/src/wrt-client/splash_screen_support.h new file mode 100644 index 0000000..553b863 --- /dev/null +++ b/src/wrt-client/splash_screen_support.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 splash_screen_support.h + * @author Andrzej Surdej (a.surdej@samsung.com) + * @brief Header file for supporting splash screen handling + */ + +#ifndef WRT_SPLASH_SCREEN_SUPPORT_H +#define WRT_SPLASH_SCREEN_SUPPORT_H + +#include +#include + +class SplashScreenSupport +{ + public: + SplashScreenSupport(Evas_Object* parent, const char* image_path, bool indicator = true, bool landscape = false); + ~SplashScreenSupport(); + + void startSplashScreen(); + void stopSplashScreen(); + void stopSplashScreenBuffered(); + bool isShowing(); + void resizeSplashScreen(); + static Eina_Bool timerCallback(void *data); + + private: + Evas_Object* m_parent; + Evas_Object* m_splashScreen; + Evas_Object* m_splashScreenBg; + Ecore_Timer* m_timer; + + int m_deviceWidth; + int m_deviceHeight; + int m_imageWidth; + int m_imageHeight; + + bool m_initialized; + bool m_isShowing; + bool m_indicator; +}; + +#endif /* WRT_SPLASH_SCREEN_SUPPORT_H */ diff --git a/src/wrt-client/widget_state.h b/src/wrt-client/widget_state.h new file mode 100644 index 0000000..1dcbd61 --- /dev/null +++ b/src/wrt-client/widget_state.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 core_module.cpp + * @author Przemyslaw Ciezkowski (p.ciezkowski@samsung.com) + * @version 1.0 + * @brief File contains declaration of WidgetState enum. + */ + +#ifndef WIDGET_STATE_H +#define WIDGET_STATE_H + +/** + * @brief State of widget + * + * This enumerator describes a state that widget is in. + * Notice, that not all combinations of state changes are correct. + * In current architecture, only following state changes are corrent and can + * occur: + * + * oldState: WidgetState_Stopped -> newState: WidgetState_Authorizing + * oldState: WidgetState_Authorizing -> newState: WidgetState_Running + * oldState: WidgetState_Authorizing -> newState: WidgetState_Stopped + * oldState: WidgetState_Running -> newState: WidgetState_Stopped + * oldState: WidgetState_Running -> newState: WidgetState_Suspended + * oldState: WidgetState_Suspended -> newState: WidgetState_Running + * oldState: WidgetState_Stopped -> newState: WidgetState_Uninstalling + * + * WidgetState_Stopped - Widget is in stopped state. No view is currently + * attached to WidgetModel. + * WidgetState_Authorizing - Widget is in authorizing state. No view is + * currently attached to WidgetModel. + * WidgetState_Running - Widget is in running state. There is a view + * attached to WidgetModel. + * WidgetState_Suspended - Widget is in running state but its java script has + * been suspended. There is a view attached to + * WidgetModel. + * WidgetState_Uninstalling - Widget is currently being uninstalled. + * WidgetState_Running_Nested_Loop - Widget has created nested loop. We cannot + * close widget in this state. We must wait until + * widget will be in WidgetState_Running + */ +enum WidgetState +{ + WidgetState_Stopped, + WidgetState_Authorizing, + WidgetState_Running, + WidgetState_Suspended, + WidgetState_Uninstalling, + WidgetState_Running_Nested_Loop +}; + +#endif /* WIDGET_STATE_H */ + diff --git a/src/wrt-client/window_data.cpp b/src/wrt-client/window_data.cpp new file mode 100644 index 0000000..fedcdba --- /dev/null +++ b/src/wrt-client/window_data.cpp @@ -0,0 +1,457 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 window_data.cpp + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @version 1.0 + * @brief Window data class implementation + */ +#include "window_data.h" + +#include +#include +#include + +#include +#include + +namespace { +const unsigned int UID_ROOT = 0; +const char* const DELETE_REQUEST = "delete,request"; +const char* const PROFILE_CHANGED = "profile,changed"; +const char* const DESKTOP_ICON_PATH = + "/opt/share/icons/default/small/tizenScmgz.png"; +const char* const USER_DATA_KEY = "__WRT_DATA_KEY__"; +const std::string DESKTOP_PROFILE("desktop"); +const int PROGRESS_H = 10; +} // anonymous namespace + +WindowData::WindowData(AppCategory category, unsigned long pid, bool manualInit) : + m_win(NULL), + m_bg(NULL), + m_conformant(NULL), + m_topLayout(NULL), + m_naviframe(NULL), + m_mainLayout(NULL), + m_progressbar(NULL), + m_initialized(false), + m_currentViewModeFullScreen(false), + m_category(category) +{ + m_win = createWindow(pid); + + if (!manualInit) { + init(); + } +} + +WindowData::~WindowData() +{ + LogDebug(""); + evas_object_del(m_win); +} + +void WindowData::init() +{ + AssertMsg(m_win != NULL, "m_win is null"); + + if (m_initialized == true) { + LogDebug("Already initilized"); + return; + } + + m_bg = createBg(m_win); + evas_object_show(m_bg); + m_conformant = createConformant(m_win); + evas_object_show(m_conformant); + m_topLayout = createTopLayout(m_conformant); + evas_object_show(m_topLayout); + m_naviframe = createNaviframe(m_topLayout); + evas_object_show(m_naviframe); + m_mainLayout = createMainLayout(m_naviframe); + evas_object_show(m_mainLayout); + m_focus = createFocus(m_mainLayout); + evas_object_show(m_focus); + m_progressbar = createProgressBar(m_win, m_mainLayout); + evas_object_show(m_progressbar); + + if(m_category == APP_CATEGORY_IDLE_CLOCK){ + toggleTransparent(true); + } + + m_initialized = true; +} + +void WindowData::postInit() +{ + AssertMsg(m_win != NULL, "m_win is null"); + AssertMsg(m_initialized, "Not init"); + + // postInit should called after process permission is changed to app + if (UID_ROOT == getuid()) { + Assert(!"Cannot do with root permission"); + } + elm_win_indicator_mode_set(m_win, ELM_WIN_INDICATOR_SHOW); +} + +bool WindowData::initScreenReaderSupport(bool isSupportAccessibility) +{ + LogDebug("called"); + AssertMsg(m_win != NULL, "x window is Null"); + return ea_screen_reader_support_set( + m_win, + isSupportAccessibility ? EINA_TRUE : EINA_FALSE); +} + +void WindowData::initTheme(void) +{ + const Eina_List* list = elm_theme_list_get(NULL); + if (!list) { + LogWarning("elm_theme_list_get fail"); + return; + } + + const char* theme = static_cast(eina_list_data_get(list)); + if (!theme) { + LogWarning("eina_list_data_get fail"); + return; + } + + char* path = elm_theme_list_item_path_get(theme, NULL); + if (!path) { + LogWarning("elm_theme_list_item_path_get fail"); + return; + } + + Eina_Bool isExist = edje_file_group_exists(path, "*"); + if (!isExist) { + LogDebug("theme path: " << path); + } + if (path) { + free(path); + } + + return; +} + +Evas_Object* WindowData::getEvasObject(Layer layer) +{ + EvasObjectDataIt it = m_evasObjectData.find(layer); + if (it == m_evasObjectData.end()) { + return NULL; + } + return it->second; +} + +void WindowData::setWebview(Evas_Object* webview) +{ + elm_object_part_content_set(m_focus, "elm.swallow.content", webview); + elm_object_focus_set(m_focus, EINA_TRUE); +} + +void WindowData::unsetWebview() +{ + elm_object_part_content_unset(m_focus, "elm.swallow.content"); +} + +void WindowData::smartCallbackAdd( + Layer layer, + const char* event, + Evas_Smart_Cb callback, + const void* data) +{ + Evas_Object* obj = getEvasObject(layer); + if (!obj) { + LogError("Fail to get Evas_Object"); + return; + } + evas_object_smart_callback_add(obj, event, callback, data); + return; +} + +void WindowData::smartCallbackDel( + Layer layer, + const char* event, + Evas_Smart_Cb callback) +{ + Evas_Object* obj = getEvasObject(layer); + if (!obj) { + LogError("Fail to get Evas_Object"); + return; + } + evas_object_smart_callback_del(obj, event, callback); +} + +void WindowData::signalEmit(Layer layer, + const char* emission, + const char* source) +{ + Evas_Object* obj = getEvasObject(layer); + if (!obj) { + LogError("Fail to get Evas_Object"); + return; + } + edje_object_signal_emit(elm_layout_edje_get(obj), emission, source); +} + +void WindowData::setViewMode(bool fullscreen, bool backbutton) +{ + LogDebug("fullscreen: " << fullscreen); + LogDebug("backbutton: " << backbutton); + + m_currentViewModeFullScreen = fullscreen; + toggleIndicator(fullscreen); +} + +void WindowData::setOrientation(int angle) +{ + LogDebug("setOrientation"); + Assert(m_win); + elm_win_wm_rotation_preferred_rotation_set(m_win, angle); +} + +void WindowData::toggleFullscreen(bool fullscreen) +{ + toggleIndicator(fullscreen || m_currentViewModeFullScreen); +} + +void WindowData::toggleTransparent(bool transparent) +{ + if (transparent) { + edje_object_signal_emit(elm_layout_edje_get(m_mainLayout), + "show,transparent,signal", + ""); + evas_object_render_op_set(m_bg, EVAS_RENDER_COPY); + } else { + edje_object_signal_emit(elm_layout_edje_get(m_mainLayout), + "hide,transparent,signal", + ""); + evas_object_render_op_set(m_bg, EVAS_RENDER_BLEND); + } +} + +void WindowData::updateProgress(double value) +{ + int x, y, w, h; + evas_object_geometry_get(m_mainLayout, &x, &y, &w, &h); + evas_object_resize(m_progressbar, + static_cast(w * value), + static_cast(PROGRESS_H * elm_config_scale_get())); +} + +void WindowData::setEvasObjectData(Layer layer, Evas_Object* obj) +{ + m_evasObjectData[layer] = obj; +} + +Evas_Object* WindowData::createWindow(unsigned long pid) +{ + ADD_PROFILING_POINT("elm_win_add", "start"); + Evas_Object* window = NULL; + LogDebug("Category: " << m_category); + switch (m_category) { + case APP_CATEGORY_IDLE_CLOCK: + { + std::ostringstream name; + name << pid; + // should I add return value of watch_app_get_elm_win() function? + // there are no error handling code of caller function. + watch_app_get_elm_win(&window); + elm_win_alpha_set(window, EINA_TRUE); + evas_object_render_op_set(window, EVAS_RENDER_COPY); + evas_object_show(window); + } + break; + default: + elm_config_accel_preference_set("opengl:depth24:stencil8"); + window = elm_win_add(NULL, "wrt-widget", ELM_WIN_BASIC); + break; + } + + ADD_PROFILING_POINT("elm_win_add", "stop"); + ecore_x_window_prop_property_set( + elm_win_xwindow_get(window), + ECORE_X_ATOM_NET_WM_PID, + ECORE_X_ATOM_CARDINAL, 32, &pid, 1); + elm_win_conformant_set(window, EINA_TRUE); + + // use vsync of system for animator + ecore_x_vsync_animator_tick_source_set(elm_win_xwindow_get(window)); + + int w, h; + ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h); + evas_object_resize(window, w, h); + elm_win_autodel_set(window, EINA_TRUE); + evas_object_smart_callback_add(window, + DELETE_REQUEST, + winDeleteRequestCallback, + this); + evas_object_smart_callback_add(window, + PROFILE_CHANGED, + winProfileChangedCallback, + this); + setEvasObjectData(Layer::WINDOW, window); + return window; +} + +Evas_Object* WindowData::createBg(Evas_Object* parent) +{ + AssertMsg(parent != NULL, "Parent is null"); + Evas_Object* obj = evas_object_rectangle_add(evas_object_evas_get(parent)); + evas_object_color_set(obj, 0, 0, 0, 0); + evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_win_resize_object_add(parent, obj); + evas_object_render_op_set(obj, EVAS_RENDER_BLEND); + setEvasObjectData(Layer::BG, obj); + return obj; +} + +Evas_Object* WindowData::createConformant(Evas_Object* parent) +{ + AssertMsg(parent != NULL, "Parent is null"); + Evas_Object* obj = elm_conformant_add(parent); + evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_win_resize_object_add(parent, obj); + setEvasObjectData(Layer::CONFORMANT, obj); + return obj; +} + +Evas_Object* WindowData::createTopLayout(Evas_Object* parent) +{ + AssertMsg(parent != NULL, "Parent is null"); + Evas_Object* obj = elm_layout_add(parent); + elm_layout_theme_set(obj, "layout", "application", "default"); + evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_content_set(parent, obj); + setEvasObjectData(Layer::TOP_LAYOUT, obj); + return obj; +} + +Evas_Object* WindowData::createNaviframe(Evas_Object* parent) +{ + AssertMsg(parent != NULL, "Parent is null"); + Evas_Object* obj = elm_naviframe_add(parent); + evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_part_content_set(parent, "elm.swallow.content", obj); + setEvasObjectData(Layer::NAVIFRAME, obj); + return obj; +} + +Evas_Object* WindowData::createMainLayout(Evas_Object* parent) +{ + AssertMsg(parent != NULL, "Parent is null"); + Evas_Object* obj = elm_layout_add(parent); + elm_layout_file_set(obj, WRT_EDJ_PATH, "web-application"); + evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + ADD_PROFILING_POINT("elm_naviframe_item_push", "start"); + Elm_Object_Item* naviIt = + elm_naviframe_item_push( + parent, // Evas_Object* obj + NULL, // const char* title_label + NULL, // Evas_Object* prev_btn + NULL, // Evas_Object* next_btn + obj, // Evas_Object* content + NULL); // const char* item_style + ADD_PROFILING_POINT("elm_naviframe_item_push", "stop"); + elm_naviframe_item_title_enabled_set(naviIt, EINA_FALSE, EINA_FALSE); + elm_naviframe_item_pop_cb_set(naviIt, naviframeItemPopCallback, NULL); + setEvasObjectData(Layer::MAIN_LAYOUT, obj); + return obj; +} + +Evas_Object* WindowData::createFocus(Evas_Object* parent) +{ + AssertMsg(parent != NULL, "Parent is null"); + // ewkview isn't elementary widget style. This is reason why ewkview focus + // doesn't restore after focus-out and focus-in. To support focus restore + // for ewkview, WRT add selectable elementary(button) to manage focus + Evas_Object* obj = elm_button_add(parent); + elm_theme_extension_add(NULL, WRT_EDJ_PATH); + elm_object_style_set(obj, "wrt"); + elm_object_part_content_set(parent, "elm.swallow.content", obj); + evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_access_object_unregister(obj); + setEvasObjectData(Layer::FOCUS, obj); + return obj; +} + +Evas_Object* WindowData::createProgressBar(Evas_Object* window, Evas_Object* parent) +{ + AssertMsg(parent != NULL, "Parent is null"); + Evas_Object* obj = evas_object_rectangle_add(evas_object_evas_get(window)); + evas_object_color_set(obj, 91, 166, 255, 255); + elm_object_part_content_set(parent, "elm.swallow.progress", obj); + evas_object_resize(obj, 0, 0); + setEvasObjectData(Layer::PROGRESSBAR, obj); + return obj; +} + +void WindowData::toggleIndicator(bool fullscreen) +{ + LogDebug("fullscreen=" << (fullscreen ? "true" : "false")); + + if (!fullscreen) { + elm_win_indicator_opacity_set(m_win, ELM_WIN_INDICATOR_OPAQUE); + } else { + elm_win_indicator_opacity_set(m_win, ELM_WIN_INDICATOR_TRANSPARENT); + } +} + +void WindowData::winDeleteRequestCallback(void* data, + Evas_Object* /*obj*/, + void* /*eventInfo*/) +{ + DPL_UNUSED_PARAM(data); + LogDebug("call"); + elm_exit(); +} + +void WindowData::winProfileChangedCallback(void *data, + Evas_Object* /*obj*/, + void* /*eventInfo*/) +{ + LogDebug("winProfileChangedCallback"); + if (data == NULL) { + return; + } + WindowData* This = static_cast(data); + const char* profile = elm_config_profile_get(); + + if (DESKTOP_PROFILE == profile) { + elm_win_indicator_mode_set(This->m_win, ELM_WIN_INDICATOR_HIDE); + // set desktop icon + Evas_Object* icon = + evas_object_image_add(evas_object_evas_get(This->m_win)); + evas_object_image_file_set(icon, DESKTOP_ICON_PATH, NULL); + elm_win_icon_object_set(This->m_win, icon); + } +} + +Eina_Bool WindowData::naviframeItemPopCallback(void* /*data*/, + Elm_Object_Item* /*it*/) +{ + LogDebug("naviframeItemPopCallback"); + // This return value makes naviframe not to perform a pop operation + // about this item. + return EINA_FALSE; +} + diff --git a/src/wrt-client/window_data.h b/src/wrt-client/window_data.h new file mode 100644 index 0000000..228bd03 --- /dev/null +++ b/src/wrt-client/window_data.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 window_data.h + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @version 1.0 + * @brief Window data header file. + */ + +#ifndef WINDOW_INITIALIZE_H_ +#define WINDOW_INITIALIZE_H_ + +#include +#include +#include +#include + +#include +#include + +enum class Layer { + WINDOW = 0, + BG = 1, + CONFORMANT = 2, + TOP_LAYOUT = 3, + NAVIFRAME = 4, + MAIN_LAYOUT = 5, + FOCUS = 6, + PROGRESSBAR = 7 +}; + +enum AppCategory { + APP_CATEGORY_NORMAL = 0, + APP_CATEGORY_IDLE_CLOCK +}; + +class WindowData : private DPL::Noncopyable +{ + public: + explicit WindowData(AppCategory category, unsigned long pid, bool manualInit = false); + virtual ~WindowData(); + + void init(); + void postInit(); + bool initScreenReaderSupport(bool isSupportAccessibility); + void initTheme(void); + + Evas_Object* getEvasObject(Layer layer); + void setWebview(Evas_Object* evas_object); + void unsetWebview(); + + void smartCallbackAdd( + Layer layer, + const char* event, + Evas_Smart_Cb callback, + const void* data); + void smartCallbackDel( + Layer layer, + const char* event, + Evas_Smart_Cb callback); + void signalEmit(Layer layer, const char* emission, const char* source); + + void setViewMode(bool fullscreen, bool backbutton); + void setOrientation(int angle); + void toggleFullscreen(bool fullscreen); + void toggleTransparent(bool transparent); + void updateProgress(double value); + + private: + Evas_Object* m_win; + Evas_Object* m_bg; + Evas_Object* m_conformant; + Evas_Object* m_topLayout; + Evas_Object* m_naviframe; + Evas_Object* m_mainLayout; + Evas_Object* m_focus; + Evas_Object* m_progressbar; + bool m_initialized; + bool m_currentViewModeFullScreen; + AppCategory m_category; + + typedef std::map EvasObjectData; + typedef std::map::iterator EvasObjectDataIt; + EvasObjectData m_evasObjectData; + void setEvasObjectData(Layer layer, Evas_Object* obj); + + Evas_Object* createWindow(unsigned long pid); + Evas_Object* createBg(Evas_Object* parent); + Evas_Object* createConformant(Evas_Object* parent); + Evas_Object* createTopLayout(Evas_Object* parent); + Evas_Object* createNaviframe(Evas_Object* parent); + Evas_Object* createMainLayout(Evas_Object* parent); + Evas_Object* createFocus(Evas_Object* parent); + Evas_Object* createProgressBar(Evas_Object* window, Evas_Object* parent); + + void toggleIndicator(bool fullscreen); + static void winDeleteRequestCallback(void* data, + Evas_Object* obj, + void* eventInfo); + static void winProfileChangedCallback(void* data, + Evas_Object* obj, + void* eventInfo); + static Eina_Bool naviframeItemPopCallback(void *data, + Elm_Object_Item *it); + }; + +typedef std::shared_ptr WindowDataPtr; + +#endif /* WINDOW_INITIALIZE_H_ */ diff --git a/src/wrt-client/wrt-client.cpp b/src/wrt-client/wrt-client.cpp new file mode 100755 index 0000000..6e55482 --- /dev/null +++ b/src/wrt-client/wrt-client.cpp @@ -0,0 +1,1707 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "wrt-client.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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "client_command_line_parser.h" +#include "client_ide_support.h" +#ifdef ORIENTATION_ENABLED +#include "client_orientation_support.h" +#endif +#include +#include "client_submode_support.h" +#include "splash_screen_support.h" + +#ifdef JOURNAL_LOG_SUPPORT + #include +#endif + +//W3C PACKAGING enviroment variable name +#define W3C_DEBUG_ENV_VARIABLE "DEBUG_LOAD_FINISH" + +// window signal callback +const char *EDJE_SHOW_PROGRESS_SIGNAL = "show,progress,signal"; +const char *EDJE_HIDE_PROGRESS_SIGNAL = "hide,progress,signal"; +const char *EDJE_1X1_RATIO_SIGNAL = "1x1,ratio,signal"; +const std::string VIEWMODE_TYPE_FULLSCREEN = "fullscreen"; +const std::string VIEWMODE_TYPE_MAXIMIZED = "maximized"; +const std::string VIEWMODE_TYPE_WINDOWED = "windowed"; +char const* const ELM_SWALLOW_CONTENT = "elm.swallow.content"; +const char* const BUNDLE_PATH = "/usr/lib/libwrt-injected-bundle.so"; +const char* const MESSAGE_NAME_INITIALIZE = "ToInjectedBundle::INIT"; +const unsigned int UID_ROOT = 0; + +// process pool +const char* const DUMMY_PROCESS_PATH = "/usr/bin/wrt_launchpad_daemon_candidate"; +static Ewk_Context* s_preparedEwkContext = NULL; +static WindowData* s_preparedWindowData = NULL; +static int app_argc = 0; +static char** app_argv = NULL; +static bool s_processPoolDisabled = false; +static int s_clientFd = -1; +static const float s_processPoolLaunchDelayedWaitTime = 5.0f; +static const float s_processPoolLaunchFinishedWaitTime = 0.35f; +static const float s_firstFrameRenderedDelayWaitTime = 2.0f; +// env +const char* const HOME = "HOME"; +const char* const APP_HOME_PATH = "/opt/home/app"; +const char* const ROOT_HOME_PATH = "/opt/home/root"; +const char* const WRT_CONSOLE_LOG_ENABLE = "WRT_CONSOLE_LOG_ENABLE"; + +const char* CATEGORY_IDLE_CLOCK = "com.samsung.wmanager.WATCH_CLOCK"; +const char* CATEGORY_WEARABLE_CLOCK = "http://tizen.org/category/wearable_clock"; + +WrtClient::WrtClient(int argc, char **argv) : + Application(argc, argv, "wrt-client", false), + DPL::TaskDecl(this), + m_launched(false), + m_initializing(false), + m_initialized(false), + m_debugMode(false), + m_isWatchApp(false), + m_returnStatus(ReturnStatus::Succeeded), + m_widgetState(WidgetState::WidgetState_Stopped), + m_initialViewMode(VIEWMODE_TYPE_MAXIMIZED), + m_currentViewMode(VIEWMODE_TYPE_MAXIMIZED), + m_isWebkitFullscreen(false), + m_processPoolLaunchDelayedTimer(NULL), + m_processPoolLaunchFinishedTimer(NULL), + m_firstFrameRenderedDelayTimer(NULL), +#if USE(WEBKIT_MANUAL_ROTATION) + m_isWebkitHandleManualRotationDone(false), +#endif + m_submodeSupport(new ClientModule::SubmodeSupport()) +{ + Touch(); + + m_tizenId = ClientModule::CommandLineParser::getTizenId(argc, argv); + + LogDebug("m_tizenId : " << m_tizenId); + + if (m_tizenId.empty()) { + showHelpAndQuit(); + } + + AppCategory type = checkAppCategory(); + LogDebug("Category: " << type); + if( type == APP_CATEGORY_IDLE_CLOCK ) { + m_isWatchApp = true; + } else { + m_isWatchApp = false; + } + + LogDebug("App Created"); +} + +WrtClient::~WrtClient() +{ + LogDebug("App Finished"); +} + +WrtClient::ReturnStatus::Type WrtClient::getReturnStatus() const +{ + return m_returnStatus; +} + +void WrtClient::OnStop() +{ + LogDebug("Stopping Dummy Client"); +} + +void WrtClient::OnCreate() +{ + LogDebug("On Create"); + ADD_PROFILING_POINT("OnCreate callback", "point"); + + setTimeoutForLaunchDelayedStatus(); + setTimeoutFirstFrameRenderedDelay(); + + ewk_init(); +} + +void WrtClient::OnResume() +{ + if (m_widgetState != WidgetState_Suspended) { + LogWarning("Widget is not suspended, resuming was skipped"); + return; + } + + m_widget->Resume(); + m_widgetState = WidgetState_Running; +} + +void WrtClient::OnPause() +{ + if (m_widgetState != WidgetState_Running) { + LogWarning("Widget is not running to be suspended"); + return; + } + if (m_submodeSupport->isNeedTerminateOnSuspend()) { + LogDebug("Current mode cannot support suspend"); + elm_exit(); + return; + } + m_widget->Suspend(); + m_widgetState = WidgetState_Suspended; + + //FIX.ME This code should be rearranged. + device_set_brightness_from_settings(0); +} + +// appcore does not send low memory event to remove sluggish issue. +// Add callback to vconf to get low memory event. +static void vconf_lowmem_handler(keynode_t* key, void* data); + +void WrtClient::OnReset(bundle *b) +{ + LogDebug("OnReset"); + + // bundle argument is freed after OnReset() is returned + // So bundle duplication is needed + ApplicationDataSingleton::Instance().setBundle(bundle_dup(b)); + ApplicationDataSingleton::Instance().setEncodedBundle(b); + + if (true == m_initializing) { + LogDebug("can not handle reset event"); + return; + } + if (true == m_launched) { + if (m_widgetState == WidgetState_Stopped) { + LogError("Widget is not running to be reset"); + return; + } + m_widget->Reset(); +#ifdef ORIENTATION_ENABLED + m_orientationSupport->resetOrientation(); +#endif + m_widgetState = WidgetState_Running; + } else { + setDebugMode(b); + setStep(); + } + +// appcore does not send low memory event to remove sluggish issue. +// Add callback to vconf to get low memory event. +#if 0 + // low memory callback set + appcore_set_event_callback( + APPCORE_EVENT_LOW_MEMORY, + WrtClient::appcoreLowMemoryCallback, + this); +#else + // register low memory changed callback + vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, vconf_lowmem_handler, this); +#endif +} + +void WrtClient::OnTimeTick(watch_time_h watch_time) +{ + time_t time; + int ret = watch_time_get_utc_timestamp(watch_time, &time); + + if (!ret) { + LogDebug("time : " << time); + m_widget->TimeTick(time); + } else { + LogDebug("Fail to get utc time. skip send tick event"); + } +} + +void WrtClient::OnAmbientTick(watch_time_h watch_time) +{ + time_t time; + int ret = watch_time_get_utc_timestamp(watch_time, &time); + if (!ret) { + LogDebug("time : " << time); + m_widget->AmbientTick(time); + } else { + LogDebug("Fail to get utc time. skip send ambient tick event"); + } +} + +void WrtClient::OnAmbientChanged(bool ambient_mode) +{ + m_widget->AmbientModeChanged(ambient_mode); +} + +void WrtClient::OnTerminate() +{ + LogDebug("Wrt Shutdown now"); + shutdownStep(); + //FIX.ME This code should be rearranged. + device_set_brightness_from_settings(0); +} + +void WrtClient::showHelpAndQuit() +{ + printf("Usage: wrt-client [OPTION]... [WIDGET: ID]...\n" + "launch widgets.\n" + "Mandatory arguments to long options are mandatory for short " + "options too.\n" + " -h, --help show this help\n" + " -l, --launch " + "launch widget with given tizen ID\n" + " -t, --tizen " + "launch widget with given tizen ID\n" + "\n"); + + Quit(); +} + +void WrtClient::setStep() +{ + LogDebug("setStep"); + + AddStep(&WrtClient::initStep); + AddStep(&WrtClient::launchStep); + AddStep(&WrtClient::showStep); + AddStep(&WrtClient::shutdownStep); + + m_initializing = true; + + DPL::Event::ControllerEventHandler::PostEvent(NextStepEvent()); +} + +void WrtClient::setDebugMode(bundle* b) +{ + m_debugMode = ClientModule::IDESupport::getDebugMode(b); + LogDebug("debug mode : " << m_debugMode); +} + +void WrtClient::OnEventReceived(const NextStepEvent& /*event*/) +{ + size_t count = GetStepCount(); + LogDebug("Step Count : " << count); + + if (count) { + LogDebug("Executing next step"); + NextStep(); + } +} + +void WrtClient::initStep() +{ + LogDebug(""); + if (WRT::CoreModuleSingleton::Instance().Init()) { + m_initialized = true; + } else { + m_returnStatus = ReturnStatus::Failed; + switchToShutdownStep(); + return; + } + + DPL::Event::ControllerEventHandler::PostEvent(NextStepEvent()); +} + +void WrtClient::loadStartedCallback(Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + DPL_UNUSED_PARAM(obj); + DPL_UNUSED_PARAM(eventInfo); + +#if USE(WEBKIT_SHOW_PROGRESS_BAR_EARLIER) + if (m_settingList->getProgressBarPresence() == ProgressBar_Enable || + m_initialViewMode == VIEWMODE_TYPE_WINDOWED) + { + m_windowData->signalEmit(Layer::MAIN_LAYOUT, + EDJE_SHOW_PROGRESS_SIGNAL, + ""); + m_windowData->updateProgress(0); + } +#endif +} + +void WrtClient::loadFinishedCallback(Evas_Object* obj, void* eventInfo) +{ + Assert(obj); + + DPL_UNUSED_PARAM(eventInfo); + + ADD_PROFILING_POINT("loadFinishedCallback", "start"); + + // Splash screen + if (m_splashScreen && m_splashScreen->isShowing()) + { + m_splashScreen->stopSplashScreenBuffered(); + } + + LogDebug("Post result of launch"); + + //w3c packaging test debug (message on 4>) + const char * makeScreen = getenv(W3C_DEBUG_ENV_VARIABLE); + if (makeScreen != NULL && strcmp(makeScreen, "1") == 0) { + FILE* doutput = fdopen(4, "w"); + if(doutput) + { + fprintf(doutput, "didFinishLoadForFrameCallback: ready\n"); + fclose(doutput); + } + } + + LogDebug("Launch succesfull"); + + m_launched = true; + m_initializing = false; + setlinebuf(stdout); + ADD_PROFILING_POINT("loadFinishedCallback", "stop"); + printf("launched\n"); + fflush(stdout); + + if (m_debugMode) { + unsigned int portNum = + ewk_view_inspector_server_start(obj, 0); + LogDebug("Port for inspector : " << portNum); + bool ret = ClientModule::IDESupport::sendReply( + ApplicationDataSingleton::Instance().getBundle(), + portNum); + if (!ret) { + LogWarning("Fail to send reply"); + } + } + + ApplicationDataSingleton::Instance().freeBundle(); +} + +void WrtClient::loadProgressStartedCallback(Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + DPL_UNUSED_PARAM(obj); + DPL_UNUSED_PARAM(eventInfo); + +#if !USE(WEBKIT_SHOW_PROGRESS_BAR_EARLIER) + if (m_settingList->getProgressBarPresence() == ProgressBar_Enable || + m_initialViewMode == VIEWMODE_TYPE_WINDOWED) + { + m_windowData->signalEmit(Layer::MAIN_LAYOUT, + EDJE_SHOW_PROGRESS_SIGNAL, + ""); + m_windowData->updateProgress(0); + } +#endif +} + +void WrtClient::loadProgressCallback(Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + DPL_UNUSED_PARAM(obj); + + if (m_settingList->getProgressBarPresence() == ProgressBar_Enable || + m_initialViewMode == VIEWMODE_TYPE_WINDOWED) + { + Assert(eventInfo); + double* progress = static_cast(eventInfo); + m_windowData->updateProgress(*progress); + } +} + +void WrtClient::loadProgressFinishedCallback(Evas_Object* obj, void* eventInfo) +{ + _D("called"); + + DPL_UNUSED_PARAM(obj); + DPL_UNUSED_PARAM(eventInfo); + + if (m_settingList->getProgressBarPresence() == ProgressBar_Enable || + m_initialViewMode == VIEWMODE_TYPE_WINDOWED) + { + m_windowData->signalEmit(Layer::MAIN_LAYOUT, + EDJE_HIDE_PROGRESS_SIGNAL, + ""); + } +} + +void WrtClient::processExitCallback(Evas_Object* obj, void* eventInfo) +{ + _D("process exit"); + + DPL_UNUSED_PARAM(obj); + DPL_UNUSED_PARAM(eventInfo); + + elm_exit(); +} + +void WrtClient::processCrashedCallback(Evas_Object* obj, void* eventInfo) +{ + LogError("webProcess crashed"); + + DPL_UNUSED_PARAM(obj); + DPL_UNUSED_PARAM(eventInfo); + + switchToShutdownStep(); +} + +void WrtClient::enterFullscreenCallback(Evas_Object* obj, void* eventInfo) +{ + DPL_UNUSED_PARAM(obj); + DPL_UNUSED_PARAM(eventInfo); + + // enter fullscreen + m_windowData->toggleFullscreen(true); + m_currentViewMode = VIEWMODE_TYPE_FULLSCREEN; + m_isWebkitFullscreen = true; +} + +void WrtClient::exitFullscreenCallback(Evas_Object* obj, void* eventInfo) +{ + DPL_UNUSED_PARAM(obj); + DPL_UNUSED_PARAM(eventInfo); + + // exit fullscreen + m_windowData->toggleFullscreen(false); + m_currentViewMode = m_initialViewMode; + m_isWebkitFullscreen = false; +} + +void WrtClient::enableVideoHwOverlayCallback(Evas_Object* obj, void* eventInfo) +{ + LogDebug("called"); + + Assert(obj); + + DPL_UNUSED_PARAM(eventInfo); + + ewk_view_bg_color_set(obj, 0, 0, 0, 0); + m_windowData->toggleTransparent(true); +} + +void WrtClient::disableVideoHwOverlayCallback(Evas_Object* obj, void* eventInfo) +{ + LogDebug("called"); + + Assert(obj); + + DPL_UNUSED_PARAM(eventInfo); + + m_windowData->toggleTransparent(false); + ewk_view_bg_color_set(obj, 0, 0, 0, 255); +} + +void WrtClient::popupReplyWaitStartCallback(Evas_Object* obj, void* eventInfo) +{ + DPL_UNUSED_PARAM(obj); + DPL_UNUSED_PARAM(eventInfo); + +#ifdef ORIENTATION_ENABLED +#if USE(WEBKIT_MANUAL_ROTATION) + m_orientationSupport->setManualRotation(false); + ewk_context_tizen_extensible_api_set(s_preparedEwkContext, + EWK_EXTENSIBLE_API_PRERENDERING_FOR_ROTATION, + EINA_FALSE); +#endif +#endif +} + +void WrtClient::popupReplyWaitFinishCallback(Evas_Object* obj, void* eventInfo) +{ + DPL_UNUSED_PARAM(obj); + DPL_UNUSED_PARAM(eventInfo); + +#ifdef ORIENTATION_ENABLED +#if USE(WEBKIT_MANUAL_ROTATION) + m_orientationSupport->setManualRotation(true); + ewk_context_tizen_extensible_api_set(s_preparedEwkContext, + EWK_EXTENSIBLE_API_PRERENDERING_FOR_ROTATION, + EINA_TRUE); +#endif +#endif +} + +void WrtClient::frameRenderedCallback(Evas_Object* obj, void* eventInfo) +{ + DPL_UNUSED_PARAM(obj); + DPL_UNUSED_PARAM(eventInfo); + +#ifdef ORIENTATION_ENABLED +#if USE(WEBKIT_MANUAL_ROTATION) + if (m_isWebkitHandleManualRotationDone == false) { + _D("start manual roatation"); + m_orientationSupport->setManualRotation(true); + m_isWebkitHandleManualRotationDone = true; + ewk_context_tizen_extensible_api_set(s_preparedEwkContext, + EWK_EXTENSIBLE_API_PRERENDERING_FOR_ROTATION, + EINA_TRUE); + } +#endif +#endif + + static bool isFirstCalled = true; + if (!isFirstCalled) { + return; + } + isFirstCalled = false; + +#ifdef JOURNAL_LOG_SUPPORT + journal_appcore_app_fully_loaded(const_cast(m_tizenId.c_str())); +#endif + + LogDebug("first frame has been made"); + // send status to process pool server + // this should be done only one time! + if (m_processPoolLaunchDelayedTimer) { + // timer for checking delay launch is not expired yet + // so wrt-client stops the timer + unsetTimeout(&m_processPoolLaunchDelayedTimer); + // start timer for waiting several seconds after load is finished + // now this is 1 second + setTimeoutForLaunchFinishedStatus(); + } + + // check if window is already showed, or not + if (m_firstFrameRenderedDelayTimer) { + // this case means that frame rendered callback is not delayed + unsetTimeout(&m_firstFrameRenderedDelayTimer); + LogDebug("window show!"); + // show window + evas_object_show(m_windowData->getEvasObject(Layer::WINDOW)); + } +} + +void WrtClient::blockedUrlPolicyCallback (const std::string& blockedUrl) +{ + // block this page and open it in browser + _D("Request was blocked : %s", blockedUrl.c_str()); + + m_launched = true; + m_initializing = false; + + app_control_h app_control = NULL; + app_control_create(&app_control); + app_control_set_operation(app_control, APP_CONTROL_OPERATION_VIEW); + app_control_set_uri(app_control, blockedUrl.c_str()); + + if(APP_CONTROL_ERROR_NONE != app_control_send_launch_request(app_control, NULL, NULL)) { + _E("Failed to run app_control"); + } + + app_control_destroy(app_control); + return; +} + +void WrtClient::launchStep() +{ + ADD_PROFILING_POINT("launchStep", "start"); + LogDebug("Launching widget ..."); + + ADD_PROFILING_POINT("getRunnableWidgetObject", "start"); + m_widget = WRT::CoreModuleSingleton::Instance() + .getRunnableWidgetObject(m_tizenId); + ADD_PROFILING_POINT("getRunnableWidgetObject", "stop"); + + if (!m_widget) { + LogError("RunnableWidgetObject is NULL, stop launchStep"); + switchToShutdownStep(); + elm_exit(); + return; + } + + if (m_widgetState == WidgetState_Running) { + LogWarning("Widget already running, stop launchStep"); + switchToShutdownStep(); + return; + } + + if (m_widgetState == WidgetState_Authorizing) { + LogWarning("Widget already authorizing, stop launchStep"); + switchToShutdownStep(); + return; + } + + m_dao.reset(new WrtDB::WidgetDAOReadOnly(DPL::FromASCIIString(m_tizenId))); + WrtDB::WidgetSettings widgetSettings; + m_dao->getWidgetSettings(widgetSettings); + m_settingList.reset(new WidgetSettingList(widgetSettings)); + m_submodeSupport->initialize(DPL::FromASCIIString(m_tizenId)); + + DPL::OptionalString defloc = m_dao->getDefaultlocale(); + if (!!defloc) { + LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales( + *defloc); + } + + setInitialViewMode(); + + LocalizationSetting::SetLanguageChangedCallback( + languageChangedCallback, this); + + AppCategory type = APP_CATEGORY_NORMAL; + if (m_isWatchApp) { + type = APP_CATEGORY_IDLE_CLOCK; + } + + ADD_PROFILING_POINT("CreateWindow", "start"); + + LogDebug("Category: " << type); + if( type == APP_CATEGORY_IDLE_CLOCK ){ + std::unique_ptr idleClockStr(vconf_get_str(VCONFKEY_WMS_CLOCKS_SET_IDLE), std::free); + std::string pkgid = DPL::ToUTF8String(m_dao->getTizenPkgId()); + if( idleClockStr.get() == NULL || strcmp(idleClockStr.get(), pkgid.c_str()) != 0 ){ + LogError("Does not allowed to launch idle clock app"); + switchToShutdownStep(); + return; + } + m_windowData.reset(new WindowData(type, static_cast(getpid()), true)); + if( s_preparedWindowData != NULL ){ + delete s_preparedWindowData; + s_preparedWindowData = NULL; + } + }else{ + if (s_preparedWindowData == NULL) { + s_preparedWindowData = new WindowData(type, static_cast(getpid()), true); + } + m_windowData.reset(s_preparedWindowData); + s_preparedWindowData = NULL; + } + ADD_PROFILING_POINT("CreateWindow", "stop"); + if (!m_windowData->initScreenReaderSupport( + m_settingList->getAccessibility() == Accessibility_Enable)) + { + LogWarning("Fail to set screen reader support set"); + } + +#ifdef ORIENTATION_ENABLED + // rotate window to initial value + initWindowOrientation(); +#endif + + WRT::UserDelegatesPtr cbs(new WRT::UserDelegates); + + ADD_PROFILING_POINT("Create splash screen", "start"); + DPL::OptionalString splashImgSrc = m_dao->getSplashImgSrc(); + if (!!splashImgSrc) + { + m_splashScreen.reset( + new SplashScreenSupport( + m_windowData->getEvasObject(Layer::WINDOW), + (DPL::ToUTF8String(*splashImgSrc)).c_str(), + m_currentViewMode != VIEWMODE_TYPE_FULLSCREEN, + m_settingList->getRotationValue() == Screen_Landscape)); + m_splashScreen->startSplashScreen(); + evas_object_show(this->m_windowData->getEvasObject(Layer::WINDOW)); + } + ADD_PROFILING_POINT("Create splash screen", "stop"); + + DPL::OptionalString startUrl = W3CFileLocalization::getStartFile(m_dao); +#if USE(WEB_PROVIDER_EXCEPTION_IN_EWK_CONTEXT) + ewk_context_tizen_extensible_api_set(s_preparedEwkContext, EWK_EXTENSIBLE_API_MEDIA_VOLUME_CONTROL, EINA_TRUE); +#endif + if (!m_widget->PrepareView( + DPL::ToUTF8String(*startUrl), + m_windowData->getEvasObject(Layer::WINDOW), + s_preparedEwkContext, type)) + { + switchToShutdownStep(); + return; + } + +#ifdef ORIENTATION_ENABLED + // send rotate information to ewk + m_orientationSupport->setEwkInitialOrientation( + m_settingList->getRotationValue()); +#endif + + //you can't show window with splash screen before PrepareView + //ewk_view_add_with_context() in viewLogic breaks window + m_windowData->init(); + m_windowData->postInit(); + + // only for gear3 product + DPL::OptionalString value = m_dao->getPropertyValue(L"view-compat"); + if (!!value && value == L"square") { + m_windowData->signalEmit(Layer::MAIN_LAYOUT, EDJE_1X1_RATIO_SIGNAL, ""); + } + + // sub-mode support + if (m_submodeSupport->isInlineMode()) { + if (m_submodeSupport->transientWindow( + elm_win_xwindow_get( + m_windowData->getEvasObject(Layer::WINDOW)))) + { + LogDebug("Success to set submode"); + } else { + LogWarning("Fail to set submode"); + } + } + m_windowData->smartCallbackAdd(Layer::FOCUS, + "focused", + focusedCallback, + this); + m_windowData->smartCallbackAdd(Layer::FOCUS, + "unfocused", + unfocusedCallback, + this); + + WrtDB::WidgetLocalizedInfo localizedInfo = + W3CFileLocalization::getLocalizedInfo(m_dao); + std::string name = ""; + if (!!localizedInfo.name) { + name = DPL::ToUTF8String(*(localizedInfo.name)); + } + elm_win_title_set(m_windowData->getEvasObject(Layer::WINDOW), + name.c_str()); + + initializeWindowModes(); + + m_widgetState = WidgetState_Authorizing; + if (!m_widget->CheckBeforeLaunch()) { + LogError("CheckBeforeLaunch failed, stop launchStep"); + switchToShutdownStep(); + return; + } + LogDebug("Widget launch accepted. Entering running state"); + m_widgetState = WidgetState_Running; + + cbs->loadProgressStartedCallback = DPL::Bind(&WrtClient::loadProgressStartedCallback, this); + cbs->loadProgressCallback = DPL::Bind(&WrtClient::loadProgressCallback, this); + cbs->loadProgressFinishedCallback = DPL::Bind(&WrtClient::loadProgressFinishedCallback, this); + cbs->loadStartedCallback = DPL::Bind(&WrtClient::loadStartedCallback, this); + cbs->loadFinishedCallback = DPL::Bind(&WrtClient::loadFinishedCallback, this); + cbs->setWebviewCallback = DPL::Bind(&WrtClient::setLayout, this); + cbs->unsetWebviewCallback = DPL::Bind(&WrtClient::unsetLayout, this); + cbs->processExitCallback = DPL::Bind(&WrtClient::processExitCallback, this); + cbs->processCrashedCallback = DPL::Bind(&WrtClient::processCrashedCallback, this); + cbs->enterFullscreenCallback = DPL::Bind(&WrtClient::enterFullscreenCallback, this); + cbs->exitFullscreenCallback = DPL::Bind(&WrtClient::exitFullscreenCallback, this); +#ifdef ORIENTATION_ENABLED + cbs->orientationLockCallback = DPL::Bind(&WrtClient::setWindowOrientation, this); +#endif + cbs->keyCallback = DPL::Bind(&WrtClient::keyCallback, this); + cbs->consoleMessageCallback = DPL::Bind(&WrtClient::consoleMessageCallback, this); +#ifdef ORIENTATION_ENABLED + cbs->rotatePreparedCallback = DPL::Bind(&WrtClient::rotatePreparedCallback, this); +#endif + cbs->enableVideoHwOverlayCallback = DPL::Bind(&WrtClient::enableVideoHwOverlayCallback, this); + cbs->disableVideoHwOverlayCallback = DPL::Bind(&WrtClient::disableVideoHwOverlayCallback, this); + cbs->popupReplyWaitStartCallback = DPL::Bind(&WrtClient::popupReplyWaitStartCallback, this); + cbs->popupReplyWaitFinishCallback = DPL::Bind(&WrtClient::popupReplyWaitFinishCallback, this); + cbs->frameRenderedCallback = DPL::Bind(&WrtClient::frameRenderedCallback, this); + cbs->blockedUrlPolicyCallback = DPL::Bind(&WrtClient::blockedUrlPolicyCallback, this); + + m_widget->SetUserDelegates(cbs); + +#ifdef ORIENTATION_ENABLED + if (m_orientationSupport->isOrientationPrepared(m_settingList->getRotationValue())) { + DPL::Event::ControllerEventHandler::PostEvent(NextStepEvent()); + } else { + m_orientationSupport->registerRotationCallback(initialOrientationCheckCallback, this); + } +#else + DPL::Event::ControllerEventHandler::PostEvent(NextStepEvent()); +#endif + ADD_PROFILING_POINT("launchStep", "stop"); +} + +void WrtClient::showStep() +{ + _D("Show widget ..."); + m_widget->Show(); +} + +void WrtClient::switchToShutdownStep() +{ + _D("switchToShutdownStep"); + + SwitchToStep(&WrtClient::shutdownStep); + DPL::Event::ControllerEventHandler::PostEvent(NextStepEvent()); +} + +void WrtClient::initializeWindowModes() +{ + Assert(m_windowData); + bool backbutton = + (m_settingList->getBackButtonPresence() == BackButton_Enable || + m_initialViewMode == VIEWMODE_TYPE_WINDOWED); + m_windowData->setViewMode(m_currentViewMode == VIEWMODE_TYPE_FULLSCREEN, + backbutton); +} + +void WrtClient::sendLaunchStatusToPoolServer(LaunchStatus status) +{ + if (s_processPoolDisabled) { + return; + } + if( s_clientFd == -1 ){ + LogDebug("Does not connected with pool server"); + return; + } + + int ret = 0; + int value = static_cast(status); + ret = send(s_clientFd, &value, sizeof(int), 0); + if (ret == -1 || ret != sizeof(int)) { + LogError("failed to send status : " << value); + } else { + LogDebug("sent status to pool server : " << value); + } + + if (s_clientFd != -1) { + close(s_clientFd); + s_clientFd = -1; + } +} + +void WrtClient::setTimeoutForLaunchDelayedStatus() +{ + LogDebug("enter"); + + if (s_processPoolDisabled) { + return; + } + + static int s_isFirstAccessed = true; + if (!s_isFirstAccessed) { + // this function can be access only one time + return; + } + + s_isFirstAccessed = false; + + // start launch status timer for responding to pool server + m_processPoolLaunchDelayedTimer = + ecore_timer_add( + s_processPoolLaunchDelayedWaitTime, + processPoolLaunchDelayedTimerCallback, this); +} + +void WrtClient::setTimeoutForLaunchFinishedStatus() +{ + LogDebug("enter"); + + if (s_processPoolDisabled) { + return; + } + + static int s_isFirstAccessed = true; + if (!s_isFirstAccessed) { + // this function can be access only one time + return; + } + + s_isFirstAccessed = false; + + // start launch status timer for responding to pool server + m_processPoolLaunchFinishedTimer = + ecore_timer_add( + s_processPoolLaunchFinishedWaitTime, + processPoolLaunchFinishedTimerCallback, this); +} + +void WrtClient::setTimeoutFirstFrameRenderedDelay() +{ + LogDebug("enter"); + + static int s_isFirstAccessed = true; + if (!s_isFirstAccessed) { + // this function can be access only one time + return; + } + s_isFirstAccessed = false; + + m_firstFrameRenderedDelayTimer = + ecore_timer_add( + s_firstFrameRenderedDelayWaitTime, + firstFrameRenderedDelayTimerCallback, this); +} + +void WrtClient::unsetTimeout(Ecore_Timer** timer) +{ + LogDebug("enter"); + + if (!timer || !(*timer)) { + return; + } + + ecore_timer_del(*timer); + *timer = NULL; +} + +Eina_Bool WrtClient::naviframeBackButtonCallback(void* data, + Elm_Object_Item* /*it*/) +{ + LogDebug("BackButtonCallback"); + Assert(data); + + WrtClient* This = static_cast(data); + This->m_widget->Backward(); + return EINA_FALSE; +} + +int WrtClient::appcoreLowMemoryCallback(void* /*data*/) +{ + LogDebug("appcoreLowMemoryCallback"); + //WrtClient* This = static_cast(data); + + // TODO call RunnableWidgetObject API regarding low memory + // The API should be implemented + + // temporary solution because we have no way to get ewk_context from runnable object. + if (s_preparedEwkContext) + { + ewk_context_resource_cache_clear(s_preparedEwkContext); + ewk_context_notify_low_memory(s_preparedEwkContext); + } + + return 0; +} + +void WrtClient::setInitialViewMode(void) +{ + Assert(m_dao); + WrtDB::WindowModeList windowModes = m_dao->getWindowModes(); + FOREACH(it, windowModes) { + std::string viewMode = DPL::ToUTF8String(*it); + switch(viewMode[0]) { + case 'f': + if (viewMode == VIEWMODE_TYPE_FULLSCREEN) { + m_initialViewMode = viewMode; + m_currentViewMode = m_initialViewMode; + break; + } + break; + case 'm': + if (viewMode == VIEWMODE_TYPE_MAXIMIZED) { + m_initialViewMode = viewMode; + m_currentViewMode = m_initialViewMode; + break; + } + break; + case 'w': + if (viewMode == VIEWMODE_TYPE_WINDOWED) { + m_initialViewMode = viewMode; + m_currentViewMode = m_initialViewMode; + break; + } + break; + default: + break; + } + } +} + +#ifdef ORIENTATION_ENABLED +void WrtClient::initWindowOrientation(void) +{ + Assert(m_windowData); + + m_orientationSupport.reset( + new ClientModule::OrientationSupport(m_windowData, m_widget)); + m_orientationSupport->setInitialWindowOrientation( + m_settingList->getRotationValue()); + if (!m_orientationSupport->setAutoRotation()) { + LogError("Fail to set rotation callback"); + } else { + m_orientationSupport->registerRotationCallback(autoRotationCallback, + this); + } +} + +void WrtClient::deinitWindowOrientation(void) +{ + Assert(m_orientationSupport); + + m_orientationSupport->unregisterRotationCallbacks(); + m_orientationSupport.reset(); +} + +void WrtClient::setWindowOrientation(int angle) +{ + Assert(m_windowData); + m_windowData->setOrientation(angle); +} +#endif + +void WrtClient::keyCallback(Evas_Object* obj, void* eventInfo) +{ + Ea_Callback_Type keyType = static_cast(reinterpret_cast(eventInfo)); + + // TODO: Remove keycallback when application moves to suspend + if (m_widgetState == WidgetState_Suspended) { + // Key event is faster than resume event + _W("Application is not ready to handle key"); + return; + } + if (m_settingList->getBackButtonPresence() == BackButton_Enable + || m_initialViewMode == VIEWMODE_TYPE_WINDOWED) + { + // windowed UX - hosted application + if (keyType == EA_CALLBACK_BACK) { + if (m_isWebkitFullscreen) { + ewk_view_fullscreen_exit(obj); + } else { + m_widget->Backward(); + } + } else if (keyType == EA_CALLBACK_MORE) { + // UX isn't confirmed + } + } +} + +void WrtClient::consoleMessageCallback(Evas_Object* obj, void* eventInfo) +{ + DPL_UNUSED_PARAM(obj); + + static bool logEnable = (getenv(WRT_CONSOLE_LOG_ENABLE) != NULL); + +#ifdef TIZEN_RELEASE_TYPE_ENG + // override logEnable value to true + logEnable = true; +#endif + + if (m_debugMode || logEnable) { + Assert(eventInfo); + 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; + + ConsoleLogLevel 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 = ConsoleLogLevel::Debug; + break; + case EWK_CONSOLE_MESSAGE_LEVEL_WARNING: + level = ConsoleLogLevel::Warning; + break; + case EWK_CONSOLE_MESSAGE_LEVEL_ERROR: + level = ConsoleLogLevel::Error; + break; + default: + level = ConsoleLogLevel::Debug; + break; + } + ClientModule::IDESupport::consoleMessage( + level, + "%s", + buf.str().c_str()); + } +} + +#ifdef ORIENTATION_ENABLED +void WrtClient::rotatePreparedCallback(Evas_Object* obj, void* eventInfo) +{ + DPL_UNUSED_PARAM(obj); + DPL_UNUSED_PARAM(eventInfo); + +#if USE(WEBKIT_MANUAL_ROTATION) + _D("Rotate by webkit"); + m_orientationSupport->setRotationDone(); +#endif +} +#endif + +void WrtClient::setLayout(Evas_Object* webview) +{ + LogDebug("add new webkit buffer to window"); + Assert(webview); + m_windowData->setWebview(webview); + evas_object_show(webview); +} + +void WrtClient::unsetLayout(Evas_Object* webview) +{ + LogDebug("remove current webkit buffer from window"); + Assert(webview); + evas_object_hide(webview); + m_windowData->unsetWebview(); +} + +void WrtClient::shutdownStep() +{ + LogDebug("Closing Wrt connection ..."); + + // to avoid call handler after destroy context, unregister callback + vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, vconf_lowmem_handler); + + // unset timers before process shutdownStep. + unsetTimeout(&m_processPoolLaunchFinishedTimer); + unsetTimeout(&m_processPoolLaunchDelayedTimer); + unsetTimeout(&m_firstFrameRenderedDelayTimer); + + if (m_widget && m_widgetState) { + m_widgetState = WidgetState_Stopped; + Abort(); + // (un)focusCallback MUST be detached before hiding widget starts + m_windowData->smartCallbackDel(Layer::FOCUS, + "focused", + focusedCallback); + m_windowData->smartCallbackDel(Layer::FOCUS, + "unfocused", + unfocusedCallback); + m_widget->Hide(); + // AutoRotation use m_widget pointer internally. + // It must be unset before m_widget is released. + m_submodeSupport->deinitialize(); +#ifdef ORIENTATION_ENABLED + deinitWindowOrientation(); +#endif + m_widget.reset(); + ewk_object_unref(s_preparedEwkContext); + WRT::CoreModuleSingleton::Instance().Terminate(); + } + + m_initialized = false; + m_windowData.reset(); + Quit(); +} + +#ifdef ORIENTATION_ENABLED +void WrtClient::autoRotationCallback(void* data, + Evas_Object* obj, + void* event) +{ + DPL_UNUSED_PARAM(obj); + DPL_UNUSED_PARAM(event); + LogDebug("entered"); + Assert(data); + WrtClient* This = static_cast(data); + // Splash screen + if (This->m_splashScreen && This->m_splashScreen->isShowing()) { + This->m_splashScreen->resizeSplashScreen(); + } + + This->rotatePrepared(This->m_widget->GetCurrentWebview()); +} + +void WrtClient::initialOrientationCheckCallback(void* data, Evas_Object* obj, void* event) +{ + _D("entered"); + + DPL_UNUSED_PARAM(obj); + DPL_UNUSED_PARAM(event); + + Assert(data); + WrtClient* This = static_cast(data); + if (This->m_orientationSupport->isOrientationPrepared(This->m_settingList->getRotationValue())) { + _D("initial orientation is ready"); + This->m_orientationSupport->unregisterRotationCallback(initialOrientationCheckCallback); + This->DPL::Event::ControllerEventHandler::PostEvent(NextStepEvent()); + } +} +#endif + +void WrtClient::focusedCallback(void* data, + Evas_Object* /*obj*/, + void* /*eventInfo*/) +{ + LogDebug("entered"); + Assert(data); + WrtClient* This = static_cast(data); + elm_object_focus_set(This->m_widget->GetCurrentWebview(), EINA_TRUE); +} + +void WrtClient::unfocusedCallback(void* data, + Evas_Object* /*obj*/, + void* /*eventInfo*/) +{ + LogDebug("entered"); + Assert(data); + WrtClient* This = static_cast(data); + elm_object_focus_set(This->m_widget->GetCurrentWebview(), EINA_FALSE); +} + +static void _timeout_cb(void* /*data*/, Evas_Object *obj, void* /*event_info*/) +{ + evas_object_del(obj); +} + +void WrtClient::fireLanguageChangePopup(float delay){ + Evas_Object *popup; + popup = elm_popup_add(m_windowData->getEvasObject(Layer::WINDOW)); + elm_object_style_set(popup, "toast"); + elm_popup_orient_set(popup, ELM_POPUP_ORIENT_BOTTOM); + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_part_text_set(popup,"elm.text", WRT_BODY_LOADING_ING); + evas_object_smart_callback_add(popup, "timeout", _timeout_cb, NULL); + elm_popup_timeout_set(popup, delay); + evas_object_show(popup); +} + +int WrtClient::languageChangedCallback(void *eventInfo, void *data) +{ + LogDebug("Language Changed"); + DPL_UNUSED_PARAM(eventInfo); + + if (!data) { + return 0; + } + WrtClient* wrtClient = static_cast(data); + if (!(wrtClient->m_dao)) { + return 0; + } + + // reset function fetches system locales and recreates language tags + LanguageTagsProviderSingleton::Instance().resetLanguageTags(); + // widget default locales are added to language tags below + DPL::OptionalString defloc = wrtClient->m_dao->getDefaultlocale(); + if (!!defloc) { + LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales( + *defloc); + } + + if (wrtClient->m_launched && + wrtClient->m_widgetState != WidgetState_Stopped) + { + AppCategory type = wrtClient->checkAppCategory(); + + if (wrtClient->m_widgetState == WidgetState_Running || type == APP_CATEGORY_IDLE_CLOCK) { + // 1. In case of IDLE_CLOCK app reload page + // 2. Running app(foreground) reload page + wrtClient->fireLanguageChangePopup(2.0); + wrtClient->m_widget->ReloadStartPage(); + } else if (wrtClient->m_widgetState == WidgetState_Suspended) { + // 3. Suspended app(background) exit + elm_exit(); + } + } + return 0; +} + +Eina_Bool processPoolFdCallback(void* /*data*/, Ecore_Fd_Handler *handler) +{ + int fd = ecore_main_fd_handler_fd_get(handler); + + if (fd == -1) + { + LogDebug("ECORE_FD_GET"); + exit(-1); + } + + if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR)) + { + LogDebug("ECORE_FD_ERROR"); + close(fd); + exit(-1); + } + + if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ)) + { + LogDebug("ECORE_FD_READ"); + app_pkt_t* pkt = (app_pkt_t*) malloc(sizeof(char) * AUL_SOCK_MAXBUFF); + if (pkt == NULL) { + LogError("malloc is failed"); + exit(-1); + } + memset(pkt, 0, AUL_SOCK_MAXBUFF); + + int recv_ret = recv(fd, pkt, AUL_SOCK_MAXBUFF, 0); + + if (recv_ret == -1) + { + LogDebug("recv error!"); + exit(-1); + } + ecore_main_fd_handler_del(handler); + + LogDebug("recv_ret : " << recv_ret << ", pkt->len : " << pkt->len); + process_pool_launchpad_main_loop(pkt, app_argv[0], &app_argc, &app_argv); + free(pkt); + + // escape from blocked position of process pool + ecore_main_loop_quit(); + } + + return ECORE_CALLBACK_CANCEL; +} + +Eina_Bool WrtClient::processPoolLaunchDelayedTimerCallback(void* data) +{ + LogDebug("enter"); + WrtClient* This = static_cast(data); + This->sendLaunchStatusToPoolServer(LAUNCH_STATUS_DELAYED); + This->m_processPoolLaunchDelayedTimer = NULL; + return ECORE_CALLBACK_CANCEL; +} + +Eina_Bool WrtClient::processPoolLaunchFinishedTimerCallback(void* data) +{ + LogDebug("enter"); + WrtClient* This = static_cast(data); + This->sendLaunchStatusToPoolServer(LAUNCH_STATUS_FINISHED); + This->m_processPoolLaunchFinishedTimer = NULL; + return ECORE_CALLBACK_CANCEL; +} + +Eina_Bool WrtClient::firstFrameRenderedDelayTimerCallback(void* data) +{ + LogDebug("enter"); + WrtClient* This = static_cast(data); + + // window should be showed for more fast interation with user + if (This->m_windowData) { + evas_object_show(This->m_windowData->getEvasObject(Layer::WINDOW)); + } + This->m_firstFrameRenderedDelayTimer = NULL; + return ECORE_CALLBACK_CANCEL; +} + +bool WrtClient::watch_app_create(int width, int height, void *data) +{ + LogDebug("enter : width("<(data); + This->OnTimeTick(watch_time); +#endif +} + +void WrtClient::app_ambient_tick(watch_time_h watch_time, void *data) +{ + LogDebug("enter"); + WrtClient *This = static_cast(data); + This->OnAmbientTick(watch_time); +} + +void WrtClient::app_ambient_changed(bool ambient_mode, void *data) +{ + LogDebug("enter"); + + WrtClient *This = static_cast(data); + // To render web application on ambient mode + if (ambient_mode) { + This->OnResume(); + } else { + This->OnPause(); + } + + This->OnAmbientChanged(ambient_mode); +} + +int WrtClient::Exec() +{ + int result = 0; + if (!m_isWatchApp) { + result = Application::Exec(); + } else { + LogDebug("Starting watch application framework..."); + watch_app_lifecycle_callback_s callback; + callback.create = watch_app_create; + callback.terminate = app_terminate; + callback.pause = app_pause; + callback.resume = app_resume; + callback.app_control = app_control; + callback.time_tick = app_time_tick; + callback.ambient_tick = app_ambient_tick; + callback.ambient_changed = app_ambient_changed; + + result = watch_app_main(m_argc, m_argv, &callback, this); + LogDebug("Exited application framework"); + } + return result; +} + +void WrtClient::Quit() +{ + ewk_shutdown(); + DPL::Application::Quit(); +} + +// appcore does not send low memory event to remove sluggish issue. +// Add callback to vconf to get low memory event. +static void vconf_lowmem_handler(keynode_t* key, void* /*data*/) +{ + LogDebug("VCONFKEY_SYSMAN_LOW_MEMORY vconf-key was changed!"); + + int val = vconf_keynode_get_int(key); + + if (val < VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) + { + return; + } + + if (s_preparedEwkContext) + { + LogDebug("call resource cache clear!"); + ewk_context_resource_cache_clear(s_preparedEwkContext); + ewk_context_notify_low_memory(s_preparedEwkContext); + } + + return; +} + +void set_env() +{ +#ifndef TIZEN_PUBLIC + setenv("COREGL_FASTPATH", "1", 1); +#endif + setenv("CAIRO_GL_COMPOSITOR", "msaa", 1); + setenv("CAIRO_GL_LAZY_FLUSHING", "yes", 1); + setenv("ELM_IMAGE_CACHE", "0", 1); + + char * evas_socket_engine = getenv("WRT_ECORE_EVAS_EXTN_SOCKET_ENGINE"); + if( evas_socket_engine != NULL ) + setenv("ECORE_EVAS_EXTN_SOCKET_ENGINE", evas_socket_engine, 1); +} + +int WrtClient::checkAppCategoryCallback(const char *name, void* result) +{ + if (!strcmp(name, CATEGORY_IDLE_CLOCK) || !strcmp(name, CATEGORY_WEARABLE_CLOCK)) { + LogDebug("idle clock: " << name); + *(static_cast(result)) = APP_CATEGORY_IDLE_CLOCK; + return -1; + } + + return 0; +} + +AppCategory WrtClient::checkAppCategory() +{ + int ret = 0; + AppCategory result = APP_CATEGORY_NORMAL; + pkgmgrinfo_appinfo_h handle; + ret = pkgmgrinfo_appinfo_get_appinfo(m_tizenId.c_str(), &handle); + if (ret != PMINFO_R_OK) { + return result; + } + ret = pkgmgrinfo_appinfo_foreach_category( + handle, checkAppCategoryCallback, (void*) &result); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_appinfo_destroy_appinfo(handle); + return result; + } + + pkgmgrinfo_appinfo_destroy_appinfo(handle); + return result; +} + +int main(int argc, + char *argv[]) +{ + // process pool - store arg's value + app_argc = argc; + app_argv = argv; + + // check process pool feature + if (getenv("WRT_PROCESS_POOL_DISABLE")) { + s_processPoolDisabled = true; + } + + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + ADD_PROFILING_POINT("main-entered", "point"); + + // Set log tagging + DPL::Log::LogSystemSingleton::Instance().SetTag("WRT"); + + // Set environment variables + set_env(); + + if (argc > 1 && argv[1] != NULL && !strcmp(argv[1], "-d")) + { + LogDebug("Entered dummy process mode"); + sprintf(argv[0], "%s", DUMMY_PROCESS_PATH); + + // Set 'root' home directory + setenv(HOME, ROOT_HOME_PATH, 1); + + LogDebug("Prepare ewk_context"); + appcore_set_i18n("wrt-client", NULL); + ewk_set_arguments(argc, argv); + setenv("WRT_LAUNCHING_PERFORMANCE", "1", 1); + s_preparedEwkContext = ewk_context_new_with_injected_bundle_path(BUNDLE_PATH); + + if (s_preparedEwkContext == NULL) + { + LogDebug("Creating webkit context was failed!"); + exit(-1); + } + + LogDebug("Prepare window_data"); + // Temporarily change HOME path to app + // This change is needed for getting elementary profile + // /opt/home/app/.elementary/config/mobile/base.cfg + std::string backupEnv = getenv(HOME); + if (backupEnv.empty()) { + // If getenv return "NULL", set empty string + backupEnv = ""; + } + setenv(HOME, APP_HOME_PATH, 1); + LogDebug("elm_init()"); + elm_init(argc, argv); + setenv(HOME, backupEnv.c_str(), 1); + + LogDebug("WindowData()"); + s_preparedWindowData = new WindowData(APP_CATEGORY_NORMAL, static_cast(getpid())); + s_preparedWindowData->initTheme(); + s_clientFd = __connect_process_pool_server(); + if (s_clientFd == -1) { + LogDebug("Connecting process_pool_server was failed!"); + } + Ecore_Fd_Handler* fdHandler = + ecore_main_fd_handler_add( + s_clientFd, + static_cast(ECORE_FD_READ|ECORE_FD_ERROR), + processPoolFdCallback, NULL, NULL, NULL); + + if (fdHandler == NULL) + { + LogDebug("fd_handler is NULL"); + exit(-1); + } + + setpriority(PRIO_PROCESS, 0, 0); + + LogDebug("dummy process temporary main loop begin"); + ecore_main_loop_begin(); + LogDebug("dummy process temporary main loop end"); + + std::string tizenId = + ClientModule::CommandLineParser::getTizenId(argc, argv); + + // CapabilitySupport + std::string pluginProcessPath = + ClientModule::SecuritySupport::getPluginProcessSoftLinkPath(tizenId); + + if (pluginProcessPath.empty()) { + LogError("Failed to get plugin process path"); + exit(-1); + } + + setenv("PLUGIN_PROCESS_EXECUTABLE_PATH_FOR_PROCESS_POOL", + pluginProcessPath.c_str(), 1); + LogDebug("PLUGIN_PROCESS_EXECUTABLE_PATH_FOR_PROCESS_POOL = " << + pluginProcessPath); + + ewk_context_message_post_to_injected_bundle( + s_preparedEwkContext, + MESSAGE_NAME_INITIALIZE, + tizenId.c_str()); + } else { + // This code is to fork a web process without exec. + std::string tizenId = + ClientModule::CommandLineParser::getTizenId(argc, argv); + + if (!tizenId.empty()) { + if (UID_ROOT == getuid()) { + // Drop root permission + // Only launch web application by console command case has root permission + if (!ClientModule::SecuritySupport::setAppPrivilege(tizenId)) { + LogError("Fail to set app privilege : [" << tizenId << "]"); + exit(-1); + } + } + + LogDebug("Launching by fork mode"); + // Language env setup + appcore_set_i18n("wrt-client", NULL); + ewk_set_arguments(argc, argv); + setenv("WRT_LAUNCHING_PERFORMANCE", "1", 1); + + // CapabilitySupport + std::string pluginProcessPath = + ClientModule::SecuritySupport::getPluginProcessSoftLinkPath(tizenId); + + if (pluginProcessPath.empty()) { + LogError("Failed to get plugin process path"); + exit(-1); + } + + setenv("PLUGIN_PROCESS_EXECUTABLE_PATH", + pluginProcessPath.c_str(), 1); + LogDebug("PLUGIN_PROCESS_EXECUTABLE_PATH = " << + pluginProcessPath); + + s_preparedEwkContext = ewk_context_new_with_injected_bundle_path( + BUNDLE_PATH); + + if (s_preparedEwkContext == NULL) + { + LogDebug("Creating webkit context was failed!"); + Wrt::Popup::PopupInvoker().showInfo("Error", "Creating webkit context was failed.", "OK"); + exit(-1); + } + + // plugin init + ewk_context_message_post_to_injected_bundle( + s_preparedEwkContext, + MESSAGE_NAME_INITIALIZE, + tizenId.c_str()); + } + } + + // Output on stdout will be flushed after every newline character, + // even if it is redirected to a pipe. This is useful for running + // from a script and parsing output. + // (Standard behavior of stdlib is to use full buffering when + // redirected to a pipe, which means even after an end of line + // the output may not be flushed). + setlinebuf(stdout); + + WrtClient app(app_argc, app_argv); + + ADD_PROFILING_POINT("Before appExec", "point"); + int ret = app.Exec(); + LogDebug("App returned: " << ret); + ret = app.getReturnStatus(); + LogDebug("WrtClient returned: " << ret); + elm_shutdown(); + return ret; + } + UNHANDLED_EXCEPTION_HANDLER_END +} diff --git a/src/wrt-client/wrt-client.h b/src/wrt-client/wrt-client.h new file mode 100755 index 0000000..a214259 --- /dev/null +++ b/src/wrt-client/wrt-client.h @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef WRT_CLIENT_H +#define WRT_CLIENT_H + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "widget_state.h" +#include "window_data.h" + +DECLARE_GENERIC_EVENT_0(NextStepEvent) + +namespace ClientModule { +class SubmodeSupport; +class OrientationSupport; +} +class SplashScreenSupport; +namespace WrtDB { +class WidgetDAOReadOnly; +} +class WidgetSettingList; + +class WrtClient : + public DPL::Application, + private DPL::Event::Controller::Type>, + public DPL::TaskDecl +{ + public: + WrtClient(int argc, + char **argv); + virtual ~WrtClient(); + + class ReturnStatus + { + public: + enum Type + { + Failed = -1, + Succeeded = 0 + }; + }; + + ReturnStatus::Type getReturnStatus() const; + virtual int Exec(); + virtual void Quit(); + static std::string getTizenIdFromArgument(int argc, char **argv); + + protected: + virtual void OnStop(); + virtual void OnCreate(); + virtual void OnResume(); + virtual void OnPause(); + virtual void OnReset(bundle *b); + virtual void OnTerminate(); + virtual void OnTimeTick(watch_time_h watch_time); + virtual void OnAmbientTick(watch_time_h watch_time); + virtual void OnAmbientChanged(bool ambient_mode); + + void setStep(); + + private: + enum LaunchStatus { + LAUNCH_STATUS_FAIL = -2, + LAUNCH_STATUS_DELAYED = -1, + LAUNCH_STATUS_FINISHED, + }; + + void showHelpAndQuit(); + void setDebugMode(bundle* b); + void initializeWindowModes(); + AppCategory checkAppCategory(); + + // Process Pool + void sendLaunchStatusToPoolServer(LaunchStatus status); + void setTimeoutForLaunchDelayedStatus(); + void setTimeoutForLaunchFinishedStatus(); + void setTimeoutFirstFrameRenderedDelay(); + void unsetTimeout(Ecore_Timer** timer); + void fireLanguageChangePopup(float delay); + + // Events + virtual void OnEventReceived(const NextStepEvent& event); + + // static Callback + static Eina_Bool naviframeBackButtonCallback(void* data, + Elm_Object_Item* it); + static int appcoreLowMemoryCallback(void* data); + static int languageChangedCallback(void *data, void *tmp); +#ifdef ORIENTATION_ENABLED + static void autoRotationCallback(void* data, Evas_Object* obj, void* event); + static void initialOrientationCheckCallback(void* data, Evas_Object* obj, void* event); +#endif + static void focusedCallback(void* data, + Evas_Object* obj, + void* eventInfo); + static void unfocusedCallback(void* data, + Evas_Object* obj, + void* eventInfo); + static Eina_Bool processPoolFdCallback(void* data, Ecore_Fd_Handler *handler); + static Eina_Bool processPoolLaunchDelayedTimerCallback(void* data); + static Eina_Bool processPoolLaunchFinishedTimerCallback(void* data); + static Eina_Bool firstFrameRenderedDelayTimerCallback(void* data); + static int checkAppCategoryCallback(const char* name, void* result); + + //view-mode + void setInitialViewMode(); + +#ifdef ORIENTATION_ENABLED + //orientation + void setWindowOrientation(int angle); + void initWindowOrientation(); + void deinitWindowOrientation(); +#endif + + // hwkey + void keyCallback(Evas_Object* obj, void* eventInfo); + + void consoleMessageCallback(Evas_Object* obj, void* eventInfo); +#ifdef ORIENTATION_ENABLED + void rotatePreparedCallback(Evas_Object* obj, void* eventInfo); +#endif + + // launching steps + void initStep(); + void launchStep(); + void shutdownStep(); + void showStep(); + void switchToShutdownStep(); + void loadStartedCallback(Evas_Object* obj, void* eventInfo); + void loadFinishedCallback(Evas_Object* obj, void* eventInfo); + void loadProgressStartedCallback(Evas_Object* obj, void* eventInfo); + void loadProgressCallback(Evas_Object* obj, void* eventInfo); + void loadProgressFinishedCallback(Evas_Object* obj, void* eventInfo); + void processExitCallback(Evas_Object* obj, void* eventInfo); + void processCrashedCallback(Evas_Object* obj, void* eventInfo); + void enterFullscreenCallback(Evas_Object* obj, void* eventInfo); + void exitFullscreenCallback(Evas_Object* obj, void* eventInfo); + void enableVideoHwOverlayCallback(Evas_Object* obj, void* eventInfo); + void disableVideoHwOverlayCallback(Evas_Object* obj, void* eventInfo); + void setLayout(Evas_Object* newBuffer); + void unsetLayout(Evas_Object* currentBuffer); + void popupReplyWaitStartCallback(Evas_Object* obj, void* eventInfo); + void popupReplyWaitFinishCallback(Evas_Object* obj, void* eventInfo); + void frameRenderedCallback(Evas_Object* obj, void* eventInfo); + void blockedUrlPolicyCallback(const std::string& blockedUrl) ; + + // watchcore integration + static bool watch_app_create(int width, int height, void *data); + static void app_time_tick(watch_time_h watch_time, void *data); + static void app_ambient_tick(watch_time_h watch_time, void *data); + static void app_ambient_changed(bool ambient_mode, void *data); + + // Private data + std::string m_tizenId; + + bool m_launched; + bool m_initializing; + bool m_initialized; + bool m_debugMode; + bool m_isWatchApp; + ReturnStatus::Type m_returnStatus; + WRT::RunnableWidgetObjectPtr m_widget; + WrtDB::WidgetDAOReadOnlyPtr m_dao; + WidgetSettingListPtr m_settingList; + WidgetState m_widgetState; + WindowDataPtr m_windowData; + std::unique_ptr m_splashScreen; + std::string m_initialViewMode; + std::string m_currentViewMode; + bool m_isWebkitFullscreen; + Ecore_Timer* m_processPoolLaunchDelayedTimer; + Ecore_Timer* m_processPoolLaunchFinishedTimer; + Ecore_Timer* m_firstFrameRenderedDelayTimer; + +#if USE(WEBKIT_MANUAL_ROTATION) + bool m_isWebkitHandleManualRotationDone; +#endif + std::unique_ptr m_submodeSupport; +#ifdef ORIENTATION_ENABLED + std::unique_ptr m_orientationSupport; +#endif +}; + +#endif // WRT_CLIENT_H diff --git a/src/wrt-launcher/CMakeLists.txt b/src/wrt-launcher/CMakeLists.txt new file mode 100644 index 0000000..1babcd8 --- /dev/null +++ b/src/wrt-launcher/CMakeLists.txt @@ -0,0 +1,59 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +SET(LAUNCHER "wrt-launcher") + +SET(LAUNCHER_SRCS + wrt-launcher.cpp +) + +PKG_CHECK_MODULES(LAUNCHER_PKGS + dpl-efl + dpl-db-efl + dpl-wrt-dao-rw + dpl-wrt-dao-ro + capi-appfw-app-manager + capi-appfw-application + appsvc + REQUIRED +) + +INCLUDE_DIRECTORIES(${LAUNCHER_PKGS_INCLUDE_DIRS}) + +ADD_DEFINITIONS("-fPIE") + +ADD_EXECUTABLE(${LAUNCHER} + ${LAUNCHER_SRCS} +) + +TARGET_LINK_LIBRARIES(${LAUNCHER} + ${LAUNCHER_PKGS_LIBRARIES} +) + +SET_TARGET_PROPERTIES(${LAUNCHER} PROPERTIES + COMPILE_DEFINITIONS LOG_TAG="${LOG_TAG}") + +SET_TARGET_PROPERTIES(${LAUNCHER} PROPERTIES + LINK_FLAGS "-Wl,--as-needed -pie -Wl,--hash-style=both -Wl,--version-script=${PROJECT_SOURCE_DIR}/wrt-engine.map" + BUILD_WITH_INSTALL_RPATH ON + INSTALL_RPATH_USE_LINK_PATH ON +) + +INSTALL(TARGETS ${LAUNCHER} + DESTINATION bin + PERMISSIONS OWNER_READ + OWNER_WRITE + OWNER_EXECUTE +) diff --git a/src/wrt-launcher/wrt-launcher.cpp b/src/wrt-launcher/wrt-launcher.cpp new file mode 100644 index 0000000..5ee064c --- /dev/null +++ b/src/wrt-launcher/wrt-launcher.cpp @@ -0,0 +1,470 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TIMEOUT_DEFAULT 10 +#define ROOT_DEFAULT_UID 0 +#define ROOT_DEFAULT_GID 0 +#define WEBAPP_DEFAULT_UID 5000 +#define WEBAPP_DEFAULT_GID 5000 +#define LOGGING_DEFAULT_GID 6509 +#define RETURN_ERROR -1 +#define BUF_SIZE 1024 + +static const char *program; + +class DBConnection +{ + public: + void AttachDatabase() + { + WrtDB::WrtDatabase::attachToThreadRW(); + } + + void DetachDatabase() + { + WrtDB::WrtDatabase::detachFromThread(); + } +}; + +static std::unique_ptr g_dbConnection; + +static bool attachDbConnection() +{ + if (NULL == g_dbConnection.get()) { + Try { + g_dbConnection.reset(new DBConnection()); + g_dbConnection->AttachDatabase(); + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + LogDebug("Fail to connect DB"); + return false; + } + } + return true; +} + +static bool display_widget_info() +{ + if (!attachDbConnection()) { + return false; + } + + WidgetDAOReadOnlyList widgetList; + + Try { + widgetList = WrtDB::WidgetDAOReadOnly::getWidgetList(); + } Catch (WrtDB::WidgetDAOReadOnly::Exception::DatabaseError) { + LogError("Fail to get WidgetList"); + return false; + } + + printf("%3s %32s %16s %64s %16s %24s\n", + "No", "Name", "Version", "GUID", "Package ID", "App ID"); + printf("%3s %32s %16s %64s %16s %24s\n", + "--", "--", "----", "-------", "-----", "-----"); + + int number = 1; + const char *null_str = "[NULL]"; + FOREACH(dao, widgetList) { + Try { + + WrtDB::WidgetGUID guid = (*dao)->getGUID(); + DPL::OptionalString version = (*dao)->getVersion(); + WrtDB::TizenAppId appid = (*dao)->getTizenAppId(); + WrtDB::TizenPkgId pkgid = (*dao)->getTizenPkgId(); + + /*get WidgetName*/ + DPL::OptionalString widget_name; + DPL::OptionalString dl = (*dao)->getDefaultlocale(); + WrtDB::WidgetLocalizedInfo localizedInfo; + if (!dl) { + DPL::String languageTag(L""); + localizedInfo = (*dao)->getLocalizedInfo(languageTag); + } else { + localizedInfo = (*dao)->getLocalizedInfo(*dl); + } + + widget_name = localizedInfo.name; + /*end get WidgetName*/ + + std::string widget_name_disp; + if (!!widget_name) + widget_name_disp = DPL::ToUTF8String(*widget_name); + + std::string version_disp; + if (!!version) + version_disp = DPL::ToUTF8String(*version); + + std::string guid_disp; + if (!!guid) + guid_disp = DPL::ToUTF8String(*guid); + + std::string pkgid_disp; + pkgid_disp = DPL::ToUTF8String(pkgid); + + std::string appid_disp; + appid_disp = DPL::ToUTF8String(appid); + + printf("%3i %32s %16s %64s %16s %24s\n", + number++, + widget_name_disp.empty() ? null_str : widget_name_disp.c_str(), + version_disp.c_str(), + guid_disp.empty() ? null_str : guid_disp.c_str(), + pkgid_disp.empty() ? null_str : pkgid_disp.c_str(), + appid_disp.empty() ? null_str : appid_disp.c_str()); + + } Catch (WrtDB::WidgetDAOReadOnly::Exception::WidgetNotExist) { + LogError("Installed application list is updated"); + } + } + + return true; +} + +static void print_help(FILE *stream, int /*exit_code*/) +{ + fprintf(stream, "Usage : %s [ ... ]\n", program); + fprintf( + stream, + " -h --help Display this usage information.\n" + " -l --list Display installed widgets list\n" + " -s [tizen application ID] --start Launch widget with tizen application ID\n" + " -k [tizen application ID] --kill Kill widget with tizen application ID\n" + " -r [tizen application ID] --is-running Check whether widget is running by tizen application ID,\n" + " If widget is running, 0(zero) will be returned.\n" + " -d --debug Activate debug mode\n" + " -t [second] --timeout Set timeout of response from widget in debug mode\n" + " if you emit this option, 5 seconds is set in debug mode\n" + ); +} + +extern "C" int app_control_to_bundle(app_control_h app_control, bundle** data); + +static void app_control_ReplyCallback(app_control_h /*request*/, + app_control_h reply, + app_control_result_e /*result*/, + void* data) +{ + Ecore_Timer* app_control_Timer = static_cast(data); + if (app_control_Timer != NULL) { + ecore_timer_del(app_control_Timer); + } + + bundle* b = NULL; + app_control_to_bundle(reply, &b); + const char* port = appsvc_get_data(b, "port"); + if (port != NULL && strlen(port) > 0) { + printf("port: %s\n", port); + printf("result: %s\n", "launched"); + } else { + printf("result: %s\n", "failed"); + } + ecore_main_loop_quit(); + return; +} + +static Eina_Bool timerCallback(void* /*data*/) +{ + printf("result: %s\n", "failed"); + ecore_main_loop_quit(); + return EINA_FALSE; +} + +int main(int argc, char* argv[]) +{ + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + // TODO: replace to use secure_log.h + DPL::Log::LogSystemSingleton::Instance().SetTag("WRT-LAUNCHER"); + + int next_opt, opt_idx = 0; + int timeout = TIMEOUT_DEFAULT; + char applicationId[BUF_SIZE] = ""; + char temp_arg[BUF_SIZE] = ""; + char pid[6] = ""; + char op = '\0'; + bool isDebugMode = false; + bool dispHelp = false; + bool dispList = false; + Ecore_Timer* app_control_Timer = NULL; + + app_control_h app_control = NULL; + int ret = APP_CONTROL_ERROR_NONE; + + program = argv[0]; + + static struct option long_options[] = { + { "help", no_argument, 0, 'h' }, + { "list", no_argument, 0, 'l' }, + { "start", required_argument, 0, 's' }, + { "kill", required_argument, 0, 'k' }, + { "is-running", required_argument, 0, 'r' }, + { "debug", no_argument, 0, 'd' }, + { "timeout", required_argument, 0, 't' }, + { 0, 0, 0, 0 } + }; + + if (argv[1] == NULL) { + /* exit if any argument doesn't exist */ + print_help(stdout, 0); + return -1; + } + + if (ROOT_DEFAULT_UID == geteuid()) { + if (RETURN_ERROR == setuid(ROOT_DEFAULT_UID)) { + perror("Fail to set uid"); + } + } + if (ROOT_DEFAULT_GID == getegid()) { + if (RETURN_ERROR == setgid(ROOT_DEFAULT_GID)) { + perror("Fail to set gid"); + } + } + + do { + next_opt = getopt_long(argc, + argv, + "hls:k:r:dt:v:c:i:m:", + long_options, + &opt_idx); + + switch (next_opt) { + case 'h': + if (!dispHelp) { + print_help(stdout, 0); + dispHelp = true; + } + break; + + case 'l': + if (dispList) { + break; + } + if (!display_widget_info()) { + printf("Fail to display the list of installed widgets"); + return -1; + } + dispList = true; + break; + + case 's': + case 'k': + case 'r': + strncpy(temp_arg, optarg, BUF_SIZE); + temp_arg[BUF_SIZE-1] = '\0'; + op = next_opt; + break; + + case 't': + timeout = atoi(optarg); + if (timeout < 0) { + timeout = TIMEOUT_DEFAULT; + } + break; + + case 'd': + isDebugMode = true; + break; + + case -1: + break; + + default: + print_help(stdout, 0); + break; + } + } while (next_opt != -1); + + if ((op == 's') || (op == 'k') || (op == 'r')) { + std::string temp; + + if (NULL == g_dbConnection.get()) { + Try { + g_dbConnection.reset(new DBConnection()); + g_dbConnection->AttachDatabase(); + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + LogDebug("Fail to connect DB"); + return -1; + } + } + DPL::OptionalString normal_str = DPL::FromUTF8String(temp_arg); + WrtDB::NormalizeAndTrimSpaceString(normal_str); + std::string normal_arg = DPL::ToUTF8String(*normal_str); + + WidgetDAOReadOnlyList widgetList = + WrtDB::WidgetDAOReadOnly::getWidgetList(); + FOREACH(dao, widgetList) { + WrtDB::TizenAppId tizenAppId = (*dao)->getTizenAppId(); + if (!strcmp(DPL::ToUTF8String(tizenAppId).c_str(), + normal_arg.c_str())) + { + temp = DPL::ToUTF8String(tizenAppId); + break; + } + } + if (!temp.empty()) { + strncpy(applicationId, temp.c_str(), BUF_SIZE); + applicationId[BUF_SIZE-1] = '\0'; + } else { + printf("result: %s\n", "failed"); + return -1; + } + } + + if (op == 's') { + if (strlen(applicationId) <= 0) { + printf("result: %s\n", "failed"); + return -1; + } + + // create app_control + ret = app_control_create(&app_control); + if (APP_CONTROL_ERROR_NONE != ret && NULL == app_control) { + printf("result: %s\n", "failed"); + return -1; + } + + // set package + ret = app_control_set_app_id(app_control, applicationId); + if (APP_CONTROL_ERROR_NONE != ret) { + printf("result: %s\n", "failed"); + app_control_destroy(app_control); + return -1; + } + + if (true == isDebugMode) { + // set debug mode + ret = app_control_add_extra_data(app_control, "debug", "true"); + if (APP_CONTROL_ERROR_NONE != ret) { + LogError("Fail to set debug mode [" << ret << "]"); + app_control_destroy(app_control); + return -1; + } + + // set pid + snprintf(pid, sizeof(pid), "%d", getpid()); + ret = app_control_add_extra_data(app_control, "pid", pid); + if (APP_CONTROL_ERROR_NONE != ret) { + LogError("Fail to set pid [" << ret << "]"); + app_control_destroy(app_control); + return -1; + } + + ecore_init(); + app_control_Timer = ecore_timer_add(timeout, timerCallback, NULL); + ret = app_control_send_launch_request(app_control, + app_control_ReplyCallback, + app_control_Timer); + } else { + ret = app_control_send_launch_request(app_control, NULL, NULL); + } + + if (APP_CONTROL_ERROR_NONE != ret) { + printf("result: %s\n", ""); + app_control_destroy(app_control); + return -1; + } + + app_control_destroy(app_control); + + if (true == isDebugMode) { + // wait response from callee + ecore_main_loop_begin(); + return 0; + } else { + // This text should be showed for IDE + printf("result: %s\n", "launched"); + } + return 0; + } else if (op == 'k') { + bool isRunning = false; + + //checks whether the application is running + ret = app_manager_is_running(applicationId, &isRunning); + if (APP_MANAGER_ERROR_NONE != ret) { + printf("result: %s\n", "failed"); + return -1; + } + + if (true == isRunning) { + // get app_context for running application + // app_context must be released with app_context_destroy + app_context_h appCtx = NULL; + ret = app_manager_get_app_context(applicationId, &appCtx); + if (APP_MANAGER_ERROR_NONE != ret) { + printf("result: %s\n", "failed"); + return -1; + } + + // terminate app_context_h + ret = app_manager_terminate_app(appCtx); + if (APP_MANAGER_ERROR_NONE != ret) { + printf("result: %s\n", "failed"); + app_context_destroy(appCtx); + return -1; + } else { + printf("result: %s\n", "killed"); + app_context_destroy(appCtx); + return 0; + } + } else { + printf("result: %s\n", "App isn't running"); + return 0; + } + } else if (op == 'r') { + bool isRunning = false; + ret = app_manager_is_running(applicationId, &isRunning); + + if (APP_MANAGER_ERROR_NONE != ret) { + printf("result: %s\n", "failed"); + return -1; + } + + if (true == isRunning) { + printf("result: %s\n", "running"); + return 0; + } else { + printf("result: %s\n", "not running"); + return -1; + } + } + + return 0 ; + } + UNHANDLED_EXCEPTION_HANDLER_END +} + diff --git a/src/wrt-launchpad-daemon/CMakeLists.txt b/src/wrt-launchpad-daemon/CMakeLists.txt new file mode 100644 index 0000000..912a5b8 --- /dev/null +++ b/src/wrt-launchpad-daemon/CMakeLists.txt @@ -0,0 +1,81 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# @file CMakeLists.txt +# @author Tae-Jeong Lee (taejeong.lee@samsung.com) +# @version 0.1 +# + +SET(WRT_LAUNCH_PAD_NAME "wrt_launchpad_daemon") + +ADD_DEFINITIONS("-DSHARE_PREFIX=\"/usr/share/aul\"") +ADD_DEFINITIONS("-DUSE_POOL_FOR_FIRST_LAUNCH") + +PKG_CHECK_MODULES(WRT_LAUNCH_PAD_DEPS + aul + dlog + app-checker + bundle + dbus-glib-1 + glib-2.0 + libsmack + libprivilege-control + x11 + sqlite3 + libsystemd-daemon + REQUIRED +) + +SET(WRT_LAUNCH_PAD_INCLUDE_DIRS + ${PROJECT_SOURCE_DIR}/src/wrt-launchpad-daemon/include + ${PROJECT_SOURCE_DIR}/src/wrt-launchpad-daemon/legacy + ${PROJECT_SOURCE_DIR}/src/wrt-launchpad-daemon/feature + ${WRT_LAUNCH_PAD_DEPS_INCLUDE_DIRS} +) + +INCLUDE_DIRECTORIES(${WRT_LAUNCH_PAD_INCLUDE_DIRS}) + +ADD_DEFINITIONS("-fPIE") + +#build executable +ADD_EXECUTABLE( ${WRT_LAUNCH_PAD_NAME} + src/app_sock.c + src/simple_util.c + launchpad_src/launchpad.c + launchpad_src/util_x.c + src/process_pool.c +) + +#link libraries +TARGET_LINK_LIBRARIES( ${WRT_LAUNCH_PAD_NAME} + ${WRT_LAUNCH_PAD_DEPS_LIBRARIES} + ${CMAKE_DL_LIBS} + "-lcap" + "-pie" +) + +#target properties +SET_TARGET_PROPERTIES(${WRT_LAUNCH_PAD_NAME} PROPERTIES + COMPILE_DEFINITIONS LOG_TAG="${LOG_TAG}") + +SET_TARGET_PROPERTIES(${TWRT_LAUNCH_PAD_NAME} PROPERTIES + LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both -Wl,--version-script=${PROJECT_SOURCE_DIR}/src/wrt-launchpad-daemon/${WRT_LAUNCH_PAD_NAME}.map" + BUILD_WITH_INSTALL_RPATH ON + INSTALL_RPATH_USE_LINK_PATH ON +) + +#install +INSTALL(TARGETS ${WRT_LAUNCH_PAD_NAME} DESTINATION bin) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/legacy/preload_list_wrt.txt DESTINATION /usr/share/aul ) diff --git a/src/wrt-launchpad-daemon/feature/preexec.h b/src/wrt-launchpad-daemon/feature/preexec.h new file mode 100644 index 0000000..584db6a --- /dev/null +++ b/src/wrt-launchpad-daemon/feature/preexec.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef PREEXEC_ACTIVATE + +#include +#include +#define PREEXEC_FILE SHARE_PREFIX "/preexec_list.txt" + +static int preexec_initialized = 0; + +GSList *preexec_list = NULL; + +typedef struct _preexec_list_t { + char *pkg_type; + char *so_path; + int (*dl_do_pre_exe)(char *, char *); + void *handle; +} preexec_list_t; + +static void __preexec_list_free() +{ + GSList *iter = NULL; + preexec_list_t *type_t; + + for (iter = preexec_list; iter != NULL; iter = g_slist_next(iter)) { + type_t = iter->data; + if (type_t) { + if (type_t->pkg_type) { + free(type_t->pkg_type); + } + if (type_t->so_path) { + free(type_t->so_path); + } + if (type_t->handle) { + dlclose(type_t->handle); + } + free(type_t); + } + } + g_slist_free(preexec_list); + return; +} + +static inline void __preexec_init(int argc, char **argv) +{ + void *handle = NULL; + FILE *preexec_file; + char *saveptr = NULL; + char line[MAX_LOCAL_BUFSZ] = { 0, }; + char *type = NULL; + char *sopath = NULL; + char *symbol = NULL; + int (*func)(char *, char *) = NULL; + preexec_list_t *type_t = NULL; + + // warning: unused parameter + argc = argc; + argv = argv; + + preexec_file = fopen(PREEXEC_FILE, "rt"); + if (preexec_file == NULL) { + _E("no preexec\n"); + return; + } + + _D("preexec start\n"); + + while (fgets(line, MAX_LOCAL_BUFSZ, preexec_file) > (char*)0) { + /* Parse each line */ + if (line[0] == '#' || line[0] == '\0') { + continue; + } + + type = strtok_r(line, ":\f\n\r\t\v ", &saveptr); + if (type == NULL) { + continue; + } + sopath = strtok_r(NULL, ",\f\n\r\t\v ", &saveptr); + if (sopath == NULL) { + continue; + } + symbol = strtok_r(NULL, ",\f\n\r\t\v ", &saveptr); + if (symbol == NULL) { + continue; + } + + type_t = (preexec_list_t *) calloc(1, sizeof(preexec_list_t)); + if (type_t == NULL) { + _E("no available memory\n"); + __preexec_list_free(); + fclose(preexec_file); + return; + } + + handle = dlopen(sopath, RTLD_NOW); + if (handle == NULL) { + free(type_t); + continue; + } + _D("preexec %s %s# - handle : %x\n", type, sopath, handle); + + func = dlsym(handle, symbol); + if (func == NULL) { + _E("failed to get symbol type:%s path:%s\n", + type, sopath); + free(type_t); + dlclose(handle); + handle = NULL; + continue; + } + + type_t->pkg_type = strdup(type); + if (type_t->pkg_type == NULL) { + _E("no available memory\n"); + free(type_t); + dlclose(handle); + handle = NULL; + __preexec_list_free(); + fclose(preexec_file); + return; + } + type_t->so_path = strdup(sopath); + if (type_t->so_path == NULL) { + _E("no available memory\n"); + free(type_t->pkg_type); + free(type_t); + dlclose(handle); + handle = NULL; + __preexec_list_free(); + fclose(preexec_file); + return; + } + type_t->handle = handle; + type_t->dl_do_pre_exe = func; + + preexec_list = g_slist_append(preexec_list, (void *)type_t); + } + + fclose(preexec_file); + preexec_initialized = 1; +} + +static inline void __preexec_run(const char *pkg_type, const char *pkg_name, + const char *app_path) +{ + GSList *iter = NULL; + preexec_list_t *type_t; + + if (!preexec_initialized) { + return; + } + + for (iter = preexec_list; iter != NULL; iter = g_slist_next(iter)) { + type_t = iter->data; + if (type_t) { + if (!strcmp(pkg_type, type_t->pkg_type)) { + if (type_t->dl_do_pre_exe != NULL) { + type_t->dl_do_pre_exe((char *)pkg_name, + (char *)app_path); + _D("called dl_do_pre_exe() type: %s", + pkg_type); + } else { + _E("no symbol for this type: %s", + pkg_type); + } + } + } + } +} + +#else + +static inline void __preexec_init(int argc, char **argv) +{} + +static inline void __preexec_run(const char *pkg_type, const char *pkg_name, + const char *app_path) +{} + +#endif diff --git a/src/wrt-launchpad-daemon/include/access_control.h b/src/wrt-launchpad-daemon/include/access_control.h new file mode 100644 index 0000000..6d6a520 --- /dev/null +++ b/src/wrt-launchpad-daemon/include/access_control.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ACCESS_CONTROL_H_ +#define __ACCESS_CONTROL_H_ + +#ifdef DAC_ACTIVATE + +#include +#include + + +#define INHOUSE_UID 5000 + +static int __add_smack_rule(const char* subject, const char* object, const char *access){ + int ret = 0; + struct smack_accesses *rules = NULL; + + if( (ret = smack_accesses_new(&rules)) != 0 ){ + _E("error smack_accesses_new %d", ret); + return -1; + } + if( (ret = smack_accesses_add(rules, subject, object, access)) != 0){ + _E("error smack_accesses_add %d", ret); + goto end;; + } + if( (ret = smack_accesses_apply(rules)) != 0){ + _E("error smack_accesses_apply %d", ret); + } + +end: + smack_accesses_free(rules); + return ret; +} + +static inline int __set_access(const char* pkg_name, + const char* pkg_type, + const char* app_path) +{ + return perm_app_set_privilege(pkg_name, pkg_type, app_path); +} + +#else + +static inline int __set_access(const char* pkg_name, + const char* pkg_type, + const char* app_path) +{ + return 0; +} + +#endif + +#endif //__ACCESS_CONTROL_H_ + diff --git a/src/wrt-launchpad-daemon/include/app_signal.h b/src/wrt-launchpad-daemon/include/app_signal.h new file mode 100644 index 0000000..d27990a --- /dev/null +++ b/src/wrt-launchpad-daemon/include/app_signal.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __APP_DBUS_H__ +#define __APP_DBUS_H__ + +#include +#include +#include + +#define AUL_DBUS_PATH "/aul/dbus_handler" +#define AUL_DBUS_SIGNAL_INTERFACE "org.tizen.aul.signal" +#define AUL_DBUS_APPDEAD_SIGNAL "app_dead" +#define AUL_DBUS_APPLAUNCH_SIGNAL "app_launch" + + +#define SYSTEM_BUS_NAME "org.tizen.system.deviced" +#define SYSTEM_OBJECT_PATH "/Org/Tizen/System/DeviceD/PmQos" +#define SYSTEM_INTERFACE_NAME "org.tizen.system.deviced.PmQos" +#define SYSTEM_METHOD_NAME "WebappLaunch" + +#define DBUS_WRT_OBJECT_PATH "/Org/Tizen/Runtime/WRT" +#define DBUS_WRT_INTERFACE_NAME "org.tizen.runtime.wrt.status" +#define DBUS_WRT_SIGNAL_READYDONE "READYDONE" + +#endif diff --git a/src/wrt-launchpad-daemon/include/app_sock.h b/src/wrt-launchpad-daemon/include/app_sock.h new file mode 100644 index 0000000..c9ca402 --- /dev/null +++ b/src/wrt-launchpad-daemon/include/app_sock.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __APP_PKT_H_ +#define __APP_PKT_H_ + +#include +#ifndef __USE_GNU +#define __USE_GNU +#endif +#include +#include + +// forward declare +struct ucred; + +enum app_cmd { + APP_START, + APP_OPEN, + APP_RESUME, + APP_RESUME_BY_PID, + APP_TERM_BY_PID, + APP_RESULT, + APP_START_RES, + APP_CANCEL, + APP_KILL_BY_PID, + APP_ADD_HISTORY, + APP_RUNNING_INFO, + APP_RUNNING_INFO_RESULT, + APP_IS_RUNNING, + APP_KEY_EVENT, + APP_KEY_RESERVE, + APP_KEY_RELEASE, + APP_STATUS_UPDATE, + APP_RELEASED, + APP_RUNNING_LIST_UPDATE +}; + +#define AUL_SOCK_PREFIX "/tmp/alaunch" +#define AUL_SOCK_MAXBUFF 65535 +#define LAUNCHPAD_PID -1 +#define WRT_LAUNCHPAD_PID -3 +#define ELOCALLAUNCH_ID 128 + +typedef struct _app_pkt_t { + int cmd; + int len; + unsigned char data[1]; +} app_pkt_t; + +int __create_server_sock(int pid); +int __create_client_sock(int pid); +int __app_send_raw(int pid, int cmd, unsigned char *kb_data, int datalen); +app_pkt_t *__app_recv_raw(int fd, int *clifd, struct ucred *cr); +app_pkt_t *__app_send_cmd_with_result(int pid, int cmd); + +#endif + diff --git a/src/wrt-launchpad-daemon/include/aul_util.h b/src/wrt-launchpad-daemon/include/aul_util.h new file mode 100644 index 0000000..813d071 --- /dev/null +++ b/src/wrt-launchpad-daemon/include/aul_util.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AUL_UTIL_H_ +#define __AUL_UTIL_H_ + +#define AUL_UTIL_PID -2 + +#define MAX_PACKAGE_STR_SIZE 512 +#define MAX_PACKAGE_APP_PATH_SIZE 512 +#define MAX_RUNNING_APP_INFO 512 + +typedef struct _app_status_info_t { + char appid[MAX_PACKAGE_STR_SIZE]; + char app_path[MAX_PACKAGE_APP_PATH_SIZE]; + int status; + int pid; +} app_status_info_t; + +struct amdmgr { + struct appinfomgr *af; /* appinfo manager */ + struct cginfo *cg; /* cgroup infomation */ +}; + +int _add_app_status_info_list(char *appid, int pid); +int _update_app_status_info_list(int pid, int status); +int _remove_app_status_info_list(int pid); + +#endif + diff --git a/src/wrt-launchpad-daemon/include/config.h b/src/wrt-launchpad-daemon/include/config.h new file mode 100644 index 0000000..dd2b4c5 --- /dev/null +++ b/src/wrt-launchpad-daemon/include/config.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LAUNCHPAD_CONFIG_H_ +#define __LAUNCHPAD_CONFIG_H_ + +#define LAUNCHPAD_LOG +#define DAC_ACTIVATE +#define PRELOAD_ACTIVATE +#define PREEXEC_ACTIVATE +/*#define GL_ACTIVATE*/ +/*#define HEAPDGB_ACTIVATE*/ +/*#define PERF_ACTIVATE*/ + +#endif // __LAUNCHPAD_CONFIG_H_ \ No newline at end of file diff --git a/src/wrt-launchpad-daemon/include/execute_on_whole_thread_util.h b/src/wrt-launchpad-daemon/include/execute_on_whole_thread_util.h new file mode 100644 index 0000000..fde4e68 --- /dev/null +++ b/src/wrt-launchpad-daemon/include/execute_on_whole_thread_util.h @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 execute_on_whole_thread_util.h + * @author Tae-Jeong Lee (taejeong.lee@samsung.com) + * @version 1.0 + */ + +#ifndef __EXECUTE_ON_WHOLE_THREAD_UTIL_H__ +#define __EXECUTE_ON_WHOLE_THREAD_UTIL_H__ + +#include +#include +#include +#include +#include + +// define +#define _EXEC_FILE_MAX_LEN 1024 +#define _EXEC_MAX_RETRY_CNT 1000 + +// typedef +typedef void (*exec_func_t)(); + +// static variable +static exec_func_t _s_exec_func = NULL; +static sighandler_t _s_prev_handler = NULL; +static int _s_exec_waiting_task_cnt = 0; + +// internal function +static void _exec_signal_handler(int signum) +{ + (void) signum; + + if (_s_exec_func) + { + _s_exec_func(); + } + + _s_exec_waiting_task_cnt--; +} + +static int _set_exec_signal_handler(int signum) +{ + sighandler_t ret; + + ret = signal(signum, _exec_signal_handler); + + if (ret == SIG_ERR) + { + return -1; + } + else + { + _s_prev_handler = ret; + } + + return 0; +} + +static int _restore_signal_handler(int signum) +{ + if (_s_prev_handler) + { + if (signal(signum, _s_prev_handler) == SIG_ERR) + { + return -1; + } + + _s_prev_handler = NULL; + } + else + { + if (signal(signum, SIG_DFL) == SIG_ERR) + { + return -1; + } + } + + return 0; +} + +static int _send_signal_to_whole_thread(int signum) +{ + int ret; + DIR *dir; + struct dirent entry, *result; + char proc_self_task_path[_EXEC_FILE_MAX_LEN + 1] = {0, }; + + sprintf(proc_self_task_path, "/proc/self/task"); + + dir = opendir(proc_self_task_path); + + if (dir) + { + for (ret = readdir_r(dir, &entry, &result); + result != NULL && ret == 0; + ret = readdir_r(dir, &entry, &result)) + { + if (strncmp(entry.d_name, ".", 2) == 0 || + strncmp(entry.d_name, "..", 3) == 0) + { + continue; + } + + _s_exec_waiting_task_cnt++; + if (syscall(__NR_tkill, atoi(entry.d_name), signum) != 0) + { + // syscall failed + _s_exec_waiting_task_cnt--; + } + } + + closedir(dir); + } + else + { + return -1; + } + + return 0; +} + +static int _is_main_thread() +{ + int pid = getpid(); + int tid = syscall(__NR_gettid); + + return (pid == tid); +} + +static int _waiting_for_done() +{ + int i; + + for (i=0; _s_exec_waiting_task_cnt && i < _EXEC_MAX_RETRY_CNT; i++) + { + usleep(100); // 0.1ms + } + + if (i == _EXEC_MAX_RETRY_CNT) + { + // time over + return -1; + } + + return 0; +} + +// external API +int EXECUTE_ON_WHOLE_THREAD(exec_func_t exec_func, int using_signum) +{ + int signum; + + assert(_s_exec_waiting_task_cnt == 0 && exec_func != NULL); + assert(using_signum == SIGUSR1 || using_signum == SIGUSR2); + + // check main thread + if (!_is_main_thread()) + { + return -1; + } + + signum = using_signum; + _s_exec_func = exec_func; + + // set signal handler + if (_set_exec_signal_handler(signum) != 0) + { + goto onerr_EXECUTE_ON_WHOLE_THREAD; + } + + // send signal + if (_send_signal_to_whole_thread(signum) != 0) + { + goto onerr_EXECUTE_ON_WHOLE_THREAD; + } + + // waiting + if (_waiting_for_done() != 0) + { + goto onerr_EXECUTE_ON_WHOLE_THREAD; + } + + // restore signal handler to previous + _restore_signal_handler(signum); + _s_exec_waiting_task_cnt = 0; + _s_exec_func = NULL; + _s_prev_handler = NULL; + + return 0; + + +onerr_EXECUTE_ON_WHOLE_THREAD: + _restore_signal_handler(signum); + _s_exec_waiting_task_cnt = 0; + _s_exec_func = NULL; + _s_prev_handler = NULL; + + return -1; +} + +#endif // __EXECUTE_ON_WHOLE_THREAD_UTIL_H__ diff --git a/src/wrt-launchpad-daemon/include/gl.h b/src/wrt-launchpad-daemon/include/gl.h new file mode 100644 index 0000000..0c26111 --- /dev/null +++ b/src/wrt-launchpad-daemon/include/gl.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __GL_H_ +#define __GL_H_ + +#ifdef GL_ACTIVATE +#define USE_ENGINE(engine) setenv("ELM_ENGINE", engine, 1); +#else +#define USE_ENGINE(engine) +#endif + +#endif //__GL_H_ \ No newline at end of file diff --git a/src/wrt-launchpad-daemon/include/launchpad_util.h b/src/wrt-launchpad-daemon/include/launchpad_util.h new file mode 100644 index 0000000..3e291bd --- /dev/null +++ b/src/wrt-launchpad-daemon/include/launchpad_util.h @@ -0,0 +1,325 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 launchpad_util.h + * @author Tae-Jeong Lee (taejeong.lee@samsung.com) + * @version 0.1 + * @brief Api library to support launchpad operation. + */ + +#ifndef __LAUNCHPAD_UTIL_H_ +#define __LAUNCHPAD_UTIL_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "gl.h" +#include "app_sock.h" +#include "menu_db_util.h" +#include "simple_util.h" +#include "access_control.h" + +#define _static_ static inline +#define WRT_AUL_PR_NAME 16 +#define PKG_ID_LENGTH 11 +#define SDK_CODE_COVERAGE "CODE_COVERAGE" +#define SDK_DYNAMIC_ANALYSIS "DYNAMIC_ANALYSIS" +#define PATH_DA_SO "/home/developer/sdk_tools/da/da_probe.so" +#define PATH_APP_ROOT "/opt/usr/apps" +#define PATH_DATA "/data" + +// Prototype +_static_ char** __create_argc_argv(bundle * kb, int *margc); +_static_ void __set_sdk_env(app_info_from_db* menu_info, char* str); +_static_ int __parser(const char *arg, char *out, int out_size); +_static_ void __modify_bundle(bundle * kb, int caller_pid, app_info_from_db * menu_info, int cmd); +_static_ void __set_env(app_info_from_db * menu_info, bundle * kb); +_static_ void __set_inherit_bit_for_CAP_MAC_ADMIN(); + +// Implementation +_static_ char** __create_argc_argv(bundle * kb, int *margc) +{ + char **argv; + int argc; + + argc = bundle_export_to_argv(kb, &argv); + + *margc = argc; + return argv; +} + +_static_ void __set_sdk_env(app_info_from_db* menu_info, char* str) +{ + char buf[MAX_LOCAL_BUFSZ]; + int ret; + + _D("key : %s / value : %s", AUL_K_SDK, str); + /* http://gcc.gnu.org/onlinedocs/gcc/Cross_002dprofiling.html*/ + /* GCOV_PREFIX contains the prefix to add to the absolute paths in the + *object file. */ + /* Prefix can be absolute, or relative. The default is no prefix. + * */ + /* GCOV_PREFIX_STRIP indicates the how many initial directory names */ + /* to stripoff the hardwired absolute paths. Default value is 0. */ + if (strncmp(str, SDK_CODE_COVERAGE, strlen(str)) == 0) { + snprintf(buf, + MAX_LOCAL_BUFSZ, + PATH_APP_ROOT "/%s"PATH_DATA, + _get_pkgname(menu_info)); + ret = setenv("GCOV_PREFIX", buf, 1); + _D("GCOV_PREFIX : %d", ret); + ret = setenv("GCOV_PREFIX_STRIP", "4096", 1); + _D("GCOV_PREFIX_STRIP : %d", ret); + } else if (strncmp(str, SDK_DYNAMIC_ANALYSIS, strlen(str)) == 0) { + ret = setenv("LD_PRELOAD", PATH_DA_SO, 1); + _D("LD_PRELOAD : %d", ret); + } +} + + +/* + * Parsing original app path to retrieve default bundle + * + * -1 : Invalid sequence + * -2 : Buffer overflow + * + */ +_static_ int __parser(const char *arg, char *out, int out_size) +{ + register int i; + int state = 1; + char *start_out = out; + + if (arg == NULL || out == NULL) { + /* Handles null buffer*/ + return 0; + } + + for (i = 0; out_size > 1; i++) { + switch (state) { + case 1: + switch (arg[i]) { + case ' ': + case '\t': + state = 5; + break; + case '\0': + state = 7; + break; + case '\"': + state = 2; + break; + case '\\': + state = 4; + break; + default: + *out = arg[i]; + out++; + out_size--; + break; + } + break; + case 2: /* escape start*/ + switch (arg[i]) { + case '\0': + state = 6; + break; + case '\"': + state = 1; + break; + default: + *out = arg[i]; + out++; + out_size--; + break; + } + break; + case 4: /* character escape*/ + if (arg[i] == '\0') { + state = 6; + } else { + *out = arg[i]; + out++; + out_size--; + state = 1; + } + break; + case 5: /* token*/ + if (out != start_out) { + *out = '\0'; + out_size--; + return i; + } + i--; + state = 1; + break; + case 6: + return -1; /* error*/ + case 7: /* terminate*/ + *out = '\0'; + out_size--; + return 0; + default: + state = 6; + break; /* error*/ + } + } + + if (out_size == 1) { + *out = '\0'; + } + /* Buffer overflow*/ + return -2; +} + + +_static_ void __modify_bundle(bundle * kb, int caller_pid, + app_info_from_db * menu_info, int cmd) +{ + // warning: unused parameter + (void) caller_pid; + + bundle_del(kb, AUL_K_PKG_NAME); + bundle_del(kb, AUL_K_EXEC); + bundle_del(kb, AUL_K_PACKAGETYPE); + bundle_del(kb, AUL_K_HWACC); + + /* Parse app_path to retrieve default bundle*/ + if (cmd == APP_START || cmd == APP_START_RES || cmd == APP_OPEN || cmd == + APP_RESUME) + { + char *ptr; + char exe[MAX_PATH_LEN]; + int flag; + + ptr = _get_original_app_path(menu_info); + + flag = __parser(ptr, exe, sizeof(exe)); + if (flag > 0) { + char key[256]; + char value[256]; + + ptr += flag; + _D("parsing app_path: EXEC - %s\n", exe); + + do { + flag = __parser(ptr, key, sizeof(key)); + if (flag <= 0) { + break; + } + ptr += flag; + + flag = __parser(ptr, value, sizeof(value)); + if (flag < 0) { + break; + } + ptr += flag; + + /*bundle_del(kb, key);*/ + bundle_add(kb, key, value); + } while (flag > 0); + } else if (flag == 0) { + _D("parsing app_path: No arguments\n"); + } else { + _D("parsing app_path: Invalid argument\n"); + } + } +} + +_static_ void __set_env(app_info_from_db * menu_info, bundle * kb) +{ + const char *str; + const char **str_array; + int len; + int i; + + char *pkgname = _get_pkgname(menu_info); + if (pkgname == NULL) { + _E("can't get pkgname"); + return; + } + setenv("PKG_NAME", pkgname, 1); + + USE_ENGINE("gl") + + str = bundle_get_val(kb, AUL_K_STARTTIME); + if (str != NULL) { + setenv("APP_START_TIME", str, 1); + } + + if (bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) { + str_array = bundle_get_str_array(kb, AUL_K_SDK, &len); + if (str_array != NULL) { + for (i = 0; i < len; i++) { + _D("index : [%d]", i); + __set_sdk_env(menu_info, (char *)str_array[i]); + } + } + } else { + str = bundle_get_val(kb, AUL_K_SDK); + if (str != NULL) { + __set_sdk_env(menu_info, (char *)str); + } + } + if (menu_info->hwacc != NULL) { + setenv("HWACC", menu_info->hwacc, 1); + } +} + +_static_ void __set_inherit_bit_for_CAP_MAC_ADMIN() +{ + cap_t caps = NULL; + cap_value_t target_caps[] = { CAP_MAC_ADMIN }; + + caps = cap_init(); + + if (caps == NULL) { + goto err_set_inherit_bit_for_CAP_MAC_ADMIN; + } + + if (cap_set_flag(caps, CAP_INHERITABLE, + sizeof(target_caps)/sizeof(cap_value_t), + target_caps, CAP_SET)) { + _E("cap_set_flag() failed!! : %s", strerror(errno)); + goto err_set_inherit_bit_for_CAP_MAC_ADMIN; + } + + if (cap_set_proc(caps)) { + _E("cap_set_proc() failed!! : %s", strerror(errno)); + goto err_set_inherit_bit_for_CAP_MAC_ADMIN; + } + + if (cap_free(caps)) { + _E("cap_free() failed!!"); + } + + return; + +err_set_inherit_bit_for_CAP_MAC_ADMIN: + if (caps != NULL) { + cap_free(caps); + } + + return; +} + +#endif // __LAUNCHPAD_UTIL_H_ diff --git a/src/wrt-launchpad-daemon/include/menu_db_util.h b/src/wrt-launchpad-daemon/include/menu_db_util.h new file mode 100644 index 0000000..6ed8065 --- /dev/null +++ b/src/wrt-launchpad-daemon/include/menu_db_util.h @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MENU_DB_UTIL_H_ +#define __MENU_DB_UTIL_H_ + +#include +#include +#include "simple_util.h" + +#define MAX_PATH_LEN 1024 + +#define AUL_APP_INFO_FLD_PKG_NAME "package" +#define AUL_APP_INFO_FLD_APP_PATH "exec" +#define AUL_APP_INFO_FLD_APP_TYPE "x_slp_packagetype" +#define AUL_APP_INFO_FLD_WIDTH "x_slp_baselayoutwidth" +#define AUL_APP_INFO_FLD_HEIGHT "x_slp_baselayoutheight" +#define AUL_APP_INFO_FLD_VERTICAL "x_slp_ishorizontalscale" +#define AUL_APP_INFO_FLD_MULTIPLE "x_slp_multiple" +#define AUL_APP_INFO_FLD_TASK_MANAGE "x_slp_taskmanage" +#define AUL_APP_INFO_FLD_MIMETYPE "mimetype" +#define AUL_APP_INFO_FLD_SERVICE "x_slp_service" + +#define AUL_RETRIEVE_PKG_NAME "package = '?'" +#define AUL_RETRIEVE_APP_PATH "exec = '?'" +#define AUL_RETRIEVE_MIMETYPE "mimetype like '?'" +#define AUL_RETRIEVE_SERVICE "x_slp_service like '?'" + +typedef struct { + char *pkg_name; /* package */ + char *app_path; /* exec */ + char *original_app_path; /* exec */ + char *pkg_type; /* x_slp_packagetype */ + char *hwacc; /* hwacceleration */ +} app_info_from_db; + +static inline char *_get_pkgname(app_info_from_db *menu_info) +{ + if (menu_info->pkg_name == NULL) { + return NULL; + } + return menu_info->pkg_name; +} + +static inline char *_get_app_path(app_info_from_db *menu_info) +{ + int i = 0; + int path_len = -1; + + if (menu_info->app_path == NULL) { + return NULL; + } + + while (menu_info->app_path[i] != 0) { + if (menu_info->app_path[i] == ' ' + || menu_info->app_path[i] == '\t') + { + path_len = i; + break; + } + i++; + } + + if (path_len == 0) { + free(menu_info->app_path); + menu_info->app_path = NULL; + } else if (path_len > 0) { + char *tmp_app_path = (char *)malloc(sizeof(char) * (path_len + 1)); + if (tmp_app_path == NULL) { + return NULL; + } + snprintf(tmp_app_path, path_len + 1, "%s", menu_info->app_path); + free(menu_info->app_path); + menu_info->app_path = tmp_app_path; + } + + return menu_info->app_path; +} + +static inline char *_get_original_app_path(app_info_from_db *menu_info) +{ + if (menu_info->original_app_path == NULL) { + return NULL; + } + return menu_info->original_app_path; +} + +static inline void _free_app_info_from_db(app_info_from_db *menu_info) +{ + if (menu_info != NULL) { + if (menu_info->pkg_name != NULL) { + free(menu_info->pkg_name); + } + if (menu_info->app_path != NULL) { + free(menu_info->app_path); + } + if (menu_info->original_app_path != NULL) { + free(menu_info->original_app_path); + } + if (menu_info->hwacc != NULL) { + free(menu_info->hwacc); + } + free(menu_info); + } +} + +static inline app_info_from_db *_get_app_info_from_db_by_pkgname( + const char *pkgname) +{ + app_info_from_db *menu_info; + pkgmgrinfo_appinfo_h appinfo_handle; + pkgmgrinfo_pkginfo_h pkginfo_handle; + int ret; + char *str = NULL; + + menu_info = (app_info_from_db *)calloc(1, sizeof(app_info_from_db)); + if (menu_info == NULL) { + return NULL; + } + + ret = pkgmgrinfo_appinfo_get_appinfo(pkgname, &appinfo_handle); + if (ret != PMINFO_R_OK ) { + _E("error pkgmgrinfo_appinfo_get_appinfo(%s) : %d", pkgname, ret); + _free_app_info_from_db(menu_info); + return NULL; + } + + ret = pkgmgrinfo_pkginfo_get_pkgid(appinfo_handle, &str); + if (ret != PMINFO_R_OK ) { + _E("pkgmgrinfo_pkginfo_get_pkgid failed"); + } else if (str) { + menu_info->pkg_name = strdup(str); + + ret = pkgmgrinfo_pkginfo_get_pkginfo(str, &pkginfo_handle); + if (ret != PMINFO_R_OK) { + _E("error pkgmgrinfo_pkginfo_get_pkginfo(%s) : %d", str, ret); + + _free_app_info_from_db(menu_info); + + if (appinfo_handle != NULL) { + ret = pkgmgrinfo_appinfo_destroy_appinfo(appinfo_handle); + if (ret != PMINFO_R_OK ) { + _E("pkgmgrinfo_appinfo_destroy_appinfo failed"); + } + } + return NULL; + } + + ret = pkgmgrinfo_pkginfo_get_type(pkginfo_handle, &str); + if (ret != PMINFO_R_OK ) { + _E("pkgmgrinfo_pkginfo_get_type failed"); + } else if (str) { + menu_info->pkg_type = strdup(str); + } + + if (pkginfo_handle != NULL) { + ret = pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_handle); + if (ret != PMINFO_R_OK ) { + _E("pkgmgrinfo_appinfo_destroy_pkginfo failed"); + } + } + + str = NULL; + } + + ret = pkgmgrinfo_appinfo_get_exec(appinfo_handle, &str); + if (ret != PMINFO_R_OK ) { + _E("pkgmgrinfo_appinfo_get_exec failed"); + } else if (str) { + menu_info->app_path = strdup(str); + str = NULL; + } + + if (menu_info->app_path != NULL) { + menu_info->original_app_path = strdup(menu_info->app_path); + } + + if (appinfo_handle != NULL) { + ret = pkgmgrinfo_appinfo_destroy_appinfo(appinfo_handle); + if (ret != PMINFO_R_OK ) { + _E("pkgmgrinfo_appinfo_destroy_appinfo failed"); + } + } + + if (!_get_app_path(menu_info)) { + _free_app_info_from_db(menu_info); + return NULL; + } + + return menu_info; +} + +static inline int __appinfo_func(const pkgmgrinfo_appinfo_h appinfo, + void *user_data) +{ + app_info_from_db *menu_info = (app_info_from_db *)user_data; + char *package; + + int ret = pkgmgrinfo_appinfo_get_pkgid(appinfo, &package); + if (ret != PMINFO_R_OK ) { + _E("pkgmgrinfo_appinfo_get_pkgid failed"); + return -1; + } + menu_info->pkg_name = strdup(package); + return 0; +} + +static inline app_info_from_db *_get_app_info_from_db_by_apppath( + const char *apppath) +{ + app_info_from_db *menu_info = NULL; + pkgmgrinfo_appinfo_filter_h filter; + int ret; + int count; + + if (apppath == NULL) { + return NULL; + } + + menu_info = (app_info_from_db *)calloc(1, sizeof(app_info_from_db)); + if (menu_info == NULL) { + return NULL; + } + + ret = pkgmgrinfo_appinfo_filter_create(&filter); + if (ret != PMINFO_R_OK ) { + _free_app_info_from_db(menu_info); + return NULL; + } + + ret = pkgmgrinfo_appinfo_filter_add_string(filter, PMINFO_APPINFO_PROP_APP_EXEC, apppath); + if (ret != PMINFO_R_OK ) { + ret = pkgmgrinfo_appinfo_filter_destroy(filter); + if (ret != PMINFO_R_OK ) { + _E("pkgmgrinfo_appinfo_filter_destroy failed"); + } + _free_app_info_from_db(menu_info); + return NULL; + } + + ret = pkgmgrinfo_appinfo_filter_count(filter, &count); + if (ret != PMINFO_R_OK ) { + ret = pkgmgrinfo_appinfo_filter_destroy(filter); + if (ret != PMINFO_R_OK ) { + _E("pkgmgrinfo_appinfo_filter_destroy failed"); + } + _free_app_info_from_db(menu_info); + return NULL; + } + if (count < 1) { + ret = pkgmgrinfo_appinfo_filter_destroy(filter); + if (ret != PMINFO_R_OK ) { + _E("pkgmgrinfo_appinfo_filter_destroy failed"); + } + _free_app_info_from_db(menu_info); + return NULL; + } + + ret = pkgmgrinfo_appinfo_filter_foreach_appinfo(filter, __appinfo_func, (void *)menu_info); + if (ret != PMINFO_R_OK ) { + _E("pkgmgrinfo_appinfo_filter_foreach_appinfo failed"); + } + + ret = pkgmgrinfo_appinfo_filter_destroy(filter); + if (ret != PMINFO_R_OK ) { + _E("pkgmgrinfo_appinfo_filter_destroy failed"); + } + + menu_info->app_path = strdup(apppath); + menu_info->original_app_path = strdup(apppath); + + return menu_info; +} + + +static inline app_info_from_db *_get_app_info_from_bundle_by_pkgname( + const char *pkgname, bundle *kb) +{ + app_info_from_db *menu_info; + + menu_info = (app_info_from_db*)calloc(1, sizeof(app_info_from_db)); + if (menu_info == NULL) { + return NULL; + } + + menu_info->pkg_name = strdup(pkgname); + menu_info->app_path = strdup(bundle_get_val(kb, AUL_K_EXEC)); + if (menu_info->app_path != NULL) { + menu_info->original_app_path = strdup(menu_info->app_path); + } + menu_info->pkg_type = strdup(bundle_get_val(kb, AUL_K_PACKAGETYPE)); + menu_info->hwacc = strdup(bundle_get_val(kb, AUL_K_HWACC)); + + if (!_get_app_path(menu_info)) { + _free_app_info_from_db(menu_info); + return NULL; + } + + return menu_info; +} +#endif //__MENU_DB_UTIL_H_ \ No newline at end of file diff --git a/src/wrt-launchpad-daemon/include/perf.h b/src/wrt-launchpad-daemon/include/perf.h new file mode 100644 index 0000000..831e086 --- /dev/null +++ b/src/wrt-launchpad-daemon/include/perf.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PERF_H__ +#define __PERF_H__ + +#ifdef PERF_ACTIVATE + +#include +static struct timeval __g_base_time = { + .tv_sec = 0, + .tv_usec = 0 +}; + +#define INIT_PERF(kb) \ + do { \ + const char *tmp; \ + struct timeval tv; \ + tmp = bundle_get_val(kb, AUL_K_STARTTIME); \ + if (tmp != NULL) { \ + sscanf(tmp, "%ld/%ld", &tv.tv_sec, &tv.tv_usec); } \ + else { \ + gettimeofday(&tv, NULL); } \ + __g_base_time.tv_sec = tv.tv_sec; \ + __g_base_time.tv_usec = tv.tv_usec; \ + } while (0); + +#define PERF(fmt, arg ...) \ + do { \ + struct timeval cur; \ + struct timeval res; \ + gettimeofday(&cur, NULL); \ + if (__g_base_time.tv_sec != 0) { \ + timersub(&cur, &__g_base_time, &res); \ + printf("%c[1;31m[%s,%d] %ld sec %ld msec "fmt " %c[0m\n", \ + 27, __FUNCTION__, __LINE__, \ + res.tv_sec, res.tv_usec / 1000,##arg, 27); \ + } \ + } while (0); + +#else + +#define INIT_PERF(kb) +#define PERF(fmt, arg ...) + +#endif + +#endif + diff --git a/src/wrt-launchpad-daemon/include/process_pool.h b/src/wrt-launchpad-daemon/include/process_pool.h new file mode 100644 index 0000000..eae5fbf --- /dev/null +++ b/src/wrt-launchpad-daemon/include/process_pool.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 process_pool.h + * @author Tae-Jeong Lee (taejeong.lee@samsung.com) + * @version 0.1 + * @brief process pool socket api prototypes + */ + +#ifndef __PROCESS_POOL_H_ +#define __PROCESS_POOL_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif //__cplusplus + +#include + +int __create_process_pool_server(); +int __connect_process_pool_server(); +int __accept_dummy_process(int server_fd, int* out_client_fd, int* out_client_pid); +void __refuse_dummy_process(int server_fd); +int __send_pkt_raw_data(int client_fd, app_pkt_t* pkt); +int __set_background_cgroup(int flag, int ui_pid, int web_pid); +int __accept_process_pool_client( + int server_fd, int* out_client_ui_fd, + int* out_client_ui_pid, int* out_client_web_pid); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__PROCESS_POOL_H_ + diff --git a/src/wrt-launchpad-daemon/include/process_pool_launchpad_util.h b/src/wrt-launchpad-daemon/include/process_pool_launchpad_util.h new file mode 100644 index 0000000..f41de11 --- /dev/null +++ b/src/wrt-launchpad-daemon/include/process_pool_launchpad_util.h @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 process_pool_launchpad_util.h + * @author Tae-Jeong Lee (taejeong.lee@samsung.com) + * @version 0.1 + * @brief Api library to support launchpad operation. + */ + +#ifndef __PROCESS_POOL_LAUNCHPAD_UTIL_H_ +#define __PROCESS_POOL_LAUNCHPAD_UTIL_H_ + +#include +#include +#include +#include + +#define DEBUG_NETWORK "system::debugging_network" + +// Prototype +_static_ int __process_pool_prepare_exec(const char *pkg_name, const char *app_path, app_info_from_db * menu_info, bundle * kb); +_static_ void process_pool_launchpad_main_loop(app_pkt_t* pkt, char* out_app_path, int* out_argc, char ***out_argv); +_static_ void __set_prcoess_name(const char *apppath); + +// Implementation +_static_ int __process_pool_prepare_exec(const char *pkg_name, + const char *app_path, app_info_from_db * menu_info, + bundle * kb) +{ + /* SET PRIVILEGES*/ + char pkg_id[PKG_ID_LENGTH]; + memset(pkg_id, '\0', PKG_ID_LENGTH); + snprintf(pkg_id, PKG_ID_LENGTH, "%s", pkg_name); + + const char* is_debug = bundle_get_val(kb, "debug"); + if (is_debug != NULL && !strcmp(is_debug, "true")) { + _D("Add system::debugging_network smack rule"); + __add_smack_rule(pkg_id, DEBUG_NETWORK, "rw"); + __add_smack_rule(DEBUG_NETWORK, pkg_id, "w"); + } + + if (set_app_smack_label(app_path) != 0) + { + _E("set_app_smack_label() failed"); + } + + if (__set_access(pkg_id, menu_info->pkg_type, app_path) < 0) { + _D("fail to set privileges - check your package's credential\n"); + return -1; + } + + /* SET INHERIT BIT FOR CAP_MAC_ADMIN TO WHOLE THREAD */ + EXECUTE_ON_WHOLE_THREAD(__set_inherit_bit_for_CAP_MAC_ADMIN, SIGUSR1); + + /* SET Process name */ + __set_prcoess_name(app_path); + + /* SET ENVIROMENT*/ + __set_env(menu_info, kb); + + return 0; +} + + +static bundle *_s_bundle = NULL; +static void __at_exit_to_release_bundle() +{ + if (_s_bundle) { + bundle_free(_s_bundle); + _s_bundle = NULL; + } +} + +_static_ void process_pool_launchpad_main_loop(app_pkt_t* pkt, char* out_app_path, int* out_argc, char ***out_argv) + +{ + bundle *kb = NULL; + app_info_from_db *menu_info = NULL; + + const char *pkg_name = NULL; + const char *app_path = NULL; + + kb = bundle_decode(pkt->data, pkt->len); + if (!kb) { + _E("bundle decode error"); + exit(-1); + } + + if (_s_bundle != NULL) { + bundle_free(_s_bundle); + } + _s_bundle = kb; + atexit(__at_exit_to_release_bundle); + + pkg_name = bundle_get_val(kb, AUL_K_PKG_NAME); + SECURE_LOGD("pkg name : %s", pkg_name); + + menu_info = _get_app_info_from_bundle_by_pkgname(pkg_name, kb); + if (menu_info == NULL) { + _D("such pkg no found"); + exit(-1); + } + + app_path = _get_app_path(menu_info); + + if (app_path == NULL) { + _E("app_path is NULL"); + exit(-1); + } + + if (app_path[0] != '/') { + _E("app_path is not absolute path"); + exit(-1); + } + + __modify_bundle(kb, /*cr.pid - unused parameter*/ 0, menu_info, pkt->cmd); + pkg_name = _get_pkgname(menu_info); + SECURE_LOGD("pkg name : %s", pkg_name); + + if (out_app_path != NULL && out_argc != NULL && out_argv != NULL) + { + int i; + + sprintf(out_app_path, "%s", app_path); + + *out_argv = __create_argc_argv(kb, out_argc); + (*out_argv)[0] = out_app_path; + + for (i = 0; i < *out_argc; i++) + { + _D("input argument %d : %s##", i, (*out_argv)[i]); + } + } + else + { + exit(-1); + } + + __process_pool_prepare_exec(pkg_name, app_path, menu_info, kb); + + + if (menu_info != NULL) { + _free_app_info_from_db(menu_info); + } +} + +_static_ void __set_prcoess_name(const char *apppath){ + char cmdline[WRT_AUL_PR_NAME+1] = {0,}; + const char *pos = strrchr(apppath, '/'); + if( pos++ == NULL ) + pos = apppath; + strncpy(cmdline, pos, WRT_AUL_PR_NAME); + _D("apppath = %s", apppath); + _D("cmdline = %s", cmdline); + prctl(PR_SET_NAME, cmdline); +} + + +#endif // __PROCESS_POOL_LAUNCHPAD_UTIL_H_ diff --git a/src/wrt-launchpad-daemon/include/simple_util.h b/src/wrt-launchpad-daemon/include/simple_util.h new file mode 100644 index 0000000..c96ae60 --- /dev/null +++ b/src/wrt-launchpad-daemon/include/simple_util.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SIMPLE_UTIL__ +#define __SIMPLE_UTIL__ + +#include +#include +#include + +#undef LOG_TAG +#define LOG_TAG "WRT_LAUNCHPAD" + + +#define MAX_LOCAL_BUFSZ 128 +#define MAX_PID_STR_BUFSZ 20 + +#undef _E +#define _E(fmt, arg ...) LOGE(fmt,##arg) +#undef _D +#define _D(fmt, arg ...) LOGD(fmt,##arg) + +#ifndef SECURE_LOGD +#define SECURE_LOGD(fmt, arg...) LOGD(fmt,##arg) +#endif + +#ifndef SECURE_LOGE +#define SECURE_LOGE(fmt, arg...) LOGE(fmt,##arg) +#endif + +#define retvm_if(expr, val, fmt, arg ...) do { \ + if (expr) { \ + _E(fmt,##arg); \ + _E("(%s) -> %s() return", #expr, __FUNCTION__); \ + return (val); \ + } \ +} while (0) + +#define retv_if(expr, val) do { \ + if (expr) { \ + _E("(%s) -> %s() return", #expr, __FUNCTION__); \ + return (val); \ + } \ +} while (0) + +int __proc_iter_cmdline(int (*iterfunc) + (const char *dname, const char *cmdline, void *priv), + void *priv); +int __proc_iter_pgid(int pgid, int (*iterfunc)(int pid, void *priv), + void *priv); +char *__proc_get_cmdline_bypid(int pid); + +static inline const char *FILENAME(const char *filename) +{ + const char *p; + const char *r; + + if (!filename) { + return NULL; + } + + r = p = filename; + while (*p) { + if (*p == '/') { + r = p + 1; + } + p++; + } + + return r; +} + +#endif diff --git a/src/wrt-launchpad-daemon/launchpad_src/launchpad.c b/src/wrt-launchpad-daemon/launchpad_src/launchpad.c new file mode 100644 index 0000000..f1adecb --- /dev/null +++ b/src/wrt-launchpad-daemon/launchpad_src/launchpad.c @@ -0,0 +1,1026 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * simple AUL daemon - launchpad + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "app_sock.h" +#include + +#include +#include + +#include "config.h" + +#include "menu_db_util.h" +#include "simple_util.h" +#include "access_control.h" +#include "preload.h" +#include "preexec.h" +#include "perf.h" +#include "sigchild.h" +#include "aul_util.h" + +#include "util_x.h" + +#include "gl.h" + +#include +#include + +#include "process_pool.h" +#include "launchpad_util.h" + +#define _static_ static inline +#define SQLITE_FLUSH_MAX (1048576) /* (1024*1024) */ +#define AUL_POLL_CNT 15 +#define AUL_PR_NAME 16 +#define PKG_ID_LENGTH 11 + +#define EXEC_DUMMY_EXPIRED 5 +#define DIFF(a,b) (((a)>(b))?(a)-(b):(b)-(a)) +#define WRT_CLIENT_PATH "/usr/bin/wrt-client" +#define LOWEST_PRIO 20 +#define DUMMY_NONE 0 +#define BOOST_TIME 3000 +#define CHECK_Xorg "/tmp/.wm_ready" +#define DEBUG_NETWORK "system::debugging_network" + +enum { + LAUNCH_PAD = 0, + POOL_SERVER, + POOL_CLIENT, + POLLFD_MAX +}; + +static char *launchpad_cmdline; +static int initialized = 0; +static int pool_client_used = 0; /* 0 = available, 1 = already used */ +static int pool_client_ui_pid = DUMMY_NONE; +static int pool_client_web_pid = DUMMY_NONE; +static int pool_client_ui_fd = -1; +static int pool_client_creating = 0; +static int process_pool_disable = 0; +static struct pollfd pfds[POLLFD_MAX]; + +_static_ int __prepare_exec(const char *pkg_name, + const char *app_path, app_info_from_db * menu_info, + bundle * kb); +_static_ int __fake_launch_app(int cmd, int pid, bundle * kb); +_static_ char **__create_argc_argv(bundle * kb, int *margc); +_static_ void __real_launch(const char *app_path, bundle * kb); +_static_ int __dummy_launch(int dummy_client_fd, app_pkt_t* pkt); +_static_ int __child_raise_win_by_x(int pid, void *priv); +_static_ int __raise_win_by_x(int pid); +_static_ int __send_to_sigkill(int pid); +_static_ int __term_app(int pid); +_static_ int __resume_app(int pid); +_static_ int __real_send(int clifd, int ret); +_static_ void __send_result_to_caller(int clifd, int ret); +_static_ void __launchpad_exec_dummy(int launchpad_fd, int pool_server_fd, int client_fd); +_static_ void __launchpad_clear_dummy(); +_static_ void __launchpad_main_loop(int launchpad_fd, int pool_server_fd); +_static_ int __launchpad_pre_init(int argc, char **argv); +_static_ int __launchpad_post_init(); +_static_ void __launchpad_use_boost(); + +static int append_variant(DBusMessageIter *iter, const char *sig, char *param[]); +int invoke_dbus_method_sync(const char *dest, const char *path, + const char *interface, const char *method, + const char *sig, char *param[]); + +int send_dbus_signal(const char *path, const char *iface, const char *name); + + +_static_ int __prepare_exec(const char *pkg_name, + const char *app_path, app_info_from_db * menu_info, + bundle * kb) +{ + char *file_name; + char process_name[AUL_PR_NAME]; + + /* Set new session ID & new process group ID*/ + /* In linux, child can set new session ID without check permission */ + /* TODO : should be add to check permission in the kernel*/ + setsid(); + + __preexec_run(menu_info->pkg_type, pkg_name, app_path); + + /* SET PRIVILEGES*/ + char pkg_id[PKG_ID_LENGTH]; + memset(pkg_id, '\0', PKG_ID_LENGTH); + snprintf(pkg_id, PKG_ID_LENGTH, "%s", pkg_name); + + /* SET PR_SET_KEEPCAPS */ + if (prctl(PR_SET_KEEPCAPS, 1) < 0) { + _E("prctl(PR_SET_KEEPCAPS) failed."); + } + + const char* is_debug = bundle_get_val(kb, "debug"); + if (is_debug != NULL && !strcmp(is_debug, "true")) { + _D("Add system::debugging_network smack rule"); + __add_smack_rule(pkg_id, DEBUG_NETWORK, "rw"); + __add_smack_rule(DEBUG_NETWORK, pkg_id, "w"); + } + + if (__set_access(pkg_id, menu_info->pkg_type, app_path) < 0) { + _D("fail to set privileges - check your package's credential\n"); + return -1; + } + + __set_inherit_bit_for_CAP_MAC_ADMIN(); + + /* SET DUMPABLE - for coredump*/ + prctl(PR_SET_DUMPABLE, 1); + + /* SET PROCESS NAME*/ + if (app_path == NULL) { + _D("app_path should not be NULL - check menu db"); + return -1; + } + file_name = strrchr(app_path, '/'); + if (file_name == NULL) { + _D("can't locate file name to execute"); + return -1; + } + memset(process_name, '\0', AUL_PR_NAME); + snprintf(process_name, AUL_PR_NAME, "%s", file_name + 1); + prctl(PR_SET_NAME, process_name); + + /* SET ENVIROMENT*/ + __set_env(menu_info, kb); + + return 0; +} + +_static_ int __fake_launch_app(int cmd, int pid, bundle * kb) +{ + int datalen; + int ret; + bundle_raw *kb_data; + + bundle_encode(kb, &kb_data, &datalen); + if ((ret = __app_send_raw(pid, cmd, kb_data, datalen)) < 0) { + _E("error request fake launch - error code = %d", ret); + } + free(kb_data); + return ret; +} + +_static_ void __real_launch(const char *app_path, bundle * kb) +{ + int app_argc; + char **app_argv; + int i; + + app_argv = __create_argc_argv(kb, &app_argc); + +#ifndef NATIVE_LAUNCHPAD + if (__change_cmdline((char *)app_path) < 0) { + _E("change cmdline fail"); + return; + } + + app_argv[0] = g_argv[0]; +#else + app_argv[0] = strdup(app_path); +#endif + + for (i = 0; i < app_argc; i++) { + _D("input argument %d : %s##", i, app_argv[i]); + } + + PERF("setup argument done"); + _E("lock up test log(no error) : setup argument done"); + + /* Temporary log: launch time checking */ + LOG(LOG_DEBUG, "LAUNCH", "[%s:Platform:launchpad:done]", app_path); + + __preload_exec(app_argc, app_argv); +} + +_static_ int __dummy_launch(int dummy_client_fd, app_pkt_t* pkt) +{ + return __send_pkt_raw_data(dummy_client_fd, pkt); +} + +_static_ int __child_raise_win_by_x(int pid, void *priv) +{ + // warning: unused parameter + priv = priv; + + return x_util_raise_win(pid); +} + +_static_ int __raise_win_by_x(int pid) +{ + int pgid; + if (x_util_raise_win(pid) == 0) { + return 0; + } + + /* support app launched by shell script*/ + pgid = getpgid(pid); + _D("X raise failed. try to find first child & raise it - c:%d p:%d\n", + pgid, pid); + + if (pgid <= 1) { + return -1; + } + if (__proc_iter_pgid(pgid, __child_raise_win_by_x, NULL) < 0) { + return -1; + } + + return 0; +} + +_static_ int __send_to_sigkill(int pid) +{ + int pgid; + + pgid = getpgid(pid); + if (pgid <= 1) { + return -1; + } + + if (killpg(pgid, SIGKILL) < 0) { + return -1; + } + + return 0; +} + +_static_ int __term_app(int pid) +{ + int dummy; + if (__app_send_raw + (pid, APP_TERM_BY_PID, (unsigned char *)&dummy, sizeof(int)) < 0) + { + _D("terminate packet send error - use SIGKILL"); + if (__send_to_sigkill(pid) < 0) { + _E("fail to killing - %d\n", pid); + return -1; + } + } + _D("term done\n"); + return 0; +} + +_static_ int __resume_app(int pid) +{ + int dummy; + int ret; + if ((ret = + __app_send_raw(pid, APP_RESUME_BY_PID, (unsigned char *)&dummy, + sizeof(int))) < 0) + { + if (ret == -EAGAIN) { + _E("resume packet timeout error"); + } else { + _D("resume packet send error - use raise win"); + if (__raise_win_by_x(pid) < 0) { + _E("raise failed - %d resume fail\n", pid); + _E("we will term the app - %d\n", pid); + __send_to_sigkill(pid); + ret = -1; + } else { + ret = 0; + } + } + } + _D("resume done\n"); + return ret; +} + +static int __get_caller_pid(bundle *kb) +{ + const char *pid_str; + int pid; + + pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID); + if (pid_str) { + goto end; + } + + pid_str = bundle_get_val(kb, AUL_K_CALLER_PID); + if (pid_str == NULL) { + return -1; + } + +end: + pid = atoi(pid_str); + if (pid <= 1) { + return -1; + } + + return pid; +} + +_static_ int __foward_cmd(int cmd, bundle *kb, int cr_pid) +{ + int pid; + char tmp_pid[MAX_PID_STR_BUFSZ]; + int datalen; + bundle_raw *kb_data; + int res; + + if ((pid = __get_caller_pid(kb)) < 0) { + return AUL_R_ERROR; + } + + snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", cr_pid); + + bundle_add(kb, AUL_K_CALLEE_PID, tmp_pid); + + bundle_encode(kb, &kb_data, &datalen); + if ((res = __app_send_raw(pid, cmd, kb_data, datalen)) < 0) { + res = AUL_R_ERROR; + } + + free(kb_data); + + return res; +} + +_static_ int __real_send(int clifd, int ret) +{ + if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) { + if (errno == EPIPE) { + _E("send failed due to EPIPE.\n"); + close(clifd); + return -1; + } + _E("send fail to client"); + } + + close(clifd); + return 0; +} + +_static_ void __send_result_to_caller(int clifd, int ret) +{ + char *cmdline; + int wait_count; + int cmdline_changed = 0; + int cmdline_exist = 0; + int r; + + if (clifd == -1) { + return; + } + + if (ret <= 1) { + __real_send(clifd, ret); + return; + } + /* check normally was launched?*/ + wait_count = 1; + do { + cmdline = __proc_get_cmdline_bypid(ret); + if (cmdline == NULL) { + _E("error founded when being launched with %d", ret); + } else if (strcmp(cmdline, launchpad_cmdline)) { + free(cmdline); + cmdline_changed = 1; + break; + } else { + cmdline_exist = 1; + free(cmdline); + } + + _D("-- now wait to change cmdline --"); + struct timespec duration = { 0, 50 * 1000 * 1000 }; + nanosleep(&duration, NULL); /* 50ms sleep*/ + wait_count++; + } while (wait_count <= 20); /* max 50*20ms will be sleep*/ + + if ((!cmdline_exist) && (!cmdline_changed)) { + __real_send(clifd, -1); /* abnormally launched*/ + return; + } + + if (!cmdline_changed) { + _E("process launched, but cmdline not changed"); + } + + if (__real_send(clifd, ret) < 0) { + r = kill(ret, SIGKILL); + if (r == -1) { + _E("send SIGKILL: %s", strerror(errno)); + } + } + + return; +} + +_static_ void __launchpad_exec_dummy(int launchpad_fd, int pool_server_fd, int client_fd) +{ + _D("%s - pool_client_creating = %d" ,__func__, pool_client_creating); + // dummy process was created but does not connected with daemon, so we should wait + if( pool_client_creating ) + return; + + pool_client_creating = 1; + + int pid; + pid = fork(); + + if (pid == 0) // child + { + setpriority(PRIO_PROCESS, 0, LOWEST_PRIO); + // add this dummy process to background cgroup + // later this would be changed after recieving launch request + // at this time, there is no web process + if (__set_background_cgroup(1, getpid(), 0) < 0) { + _D("failed to set dummy process into background cgroup"); + } else { + _D("success to set dummy process into background cgroup"); + } + + _D("Launch dummy process..."); + + /* Set new session ID & new process group ID*/ + /* In linux, child can set new session ID without check permission */ + /* TODO : should be add to check permission in the kernel*/ + setsid(); + + if (launchpad_fd != -1) + { + close(launchpad_fd); + } + + if (pool_server_fd != -1) + { + close(pool_server_fd); + } + + if (client_fd != -1) + { + close(client_fd); + } + + __signal_unset_sigchld(); + __signal_fini(); + + /* SET PR_SET_KEEPCAPS */ + if (prctl(PR_SET_KEEPCAPS, 1) < 0) { + _E("prctl(PR_SET_KEEPCAPS) failed."); + } + + /* SET DUMPABLE - for coredump*/ + prctl(PR_SET_DUMPABLE, 1); + + { + void *handle = NULL; + int (*dl_main) (int, char **); + + handle = dlopen(WRT_CLIENT_PATH, RTLD_NOW | RTLD_GLOBAL); + + if (handle == NULL) + { + _E("dlopen failed."); + exit(-1); + } + + dl_main = dlsym(handle, "main"); + + sprintf(g_argv[1], "%s", "-d"); + + if (dl_main != NULL) + { + dl_main(g_argc, g_argv); + } + else + { + _E("dlsym not founded. bad preloaded app - check fpie pie"); + } + + exit(0); + } + } + + // clear resource of dummy process + __launchpad_clear_dummy(); +} + +_static_ void __launchpad_clear_dummy() +{ + if (pfds[POOL_CLIENT].fd > 0) + { + close(pfds[POOL_CLIENT].fd); + } + + // in this case, resources for dummy process should be clear + pool_client_ui_pid = DUMMY_NONE; + pool_client_web_pid = DUMMY_NONE; + pool_client_ui_fd = -1; + + pfds[POOL_CLIENT].fd = -1; + pfds[POOL_CLIENT].events = 0; + pfds[POOL_CLIENT].revents = 0; +} + +_static_ void __launchpad_use_boost() +{ + char *arr[2]; + char val[32]; + snprintf(val, sizeof(val), "%d", BOOST_TIME); + arr[0] = val; + arr[1] = NULL; + /* TODO - Handle return value */ + invoke_dbus_method_sync(SYSTEM_BUS_NAME, SYSTEM_OBJECT_PATH, + SYSTEM_INTERFACE_NAME, SYSTEM_METHOD_NAME, "i", arr); +} + +_static_ void __launchpad_main_loop(int launchpad_fd, int pool_server_fd) +{ + bundle *kb = NULL; + app_pkt_t *pkt = NULL; + app_info_from_db *menu_info = NULL; + + const char *pkg_name = NULL; + const char *app_path = NULL; + int pid = -1; + int clifd = -1; + struct ucred cr; + char sock_path[UNIX_PATH_MAX] = { 0, }; + char *arr[4]; + + // add power lock to guarrenty app launching + arr[0] = "lcdoff"; + arr[1] = "staycurstate"; + arr[2] = "NULL"; + arr[3] = "10000"; + invoke_dbus_method_sync("org.tizen.system.deviced", + "/Org/Tizen/System/DeviceD/Display", + "org.tizen.system.deviced.display", + "lockstate", "sssi", arr); + + pkt = __app_recv_raw(launchpad_fd, &clifd, &cr); + if (!pkt) { + _D("packet is NULL"); + goto end; + } + + kb = bundle_decode(pkt->data, pkt->len); + if (!kb) { + _D("bundle decode error"); + goto end; + } + + INIT_PERF(kb); + PERF("packet processing start"); + + pkg_name = bundle_get_val(kb, AUL_K_PKG_NAME); + SECURE_LOGD("pkg name : %s\n", pkg_name); + + menu_info = _get_app_info_from_bundle_by_pkgname(pkg_name, kb); + if (menu_info == NULL) { + _D("such pkg no found"); + goto end; + } + + app_path = _get_app_path(menu_info); + if (app_path == NULL) { + _E("app_path is NULL"); + goto end; + } + if (app_path[0] != '/') { + _D("app_path is not absolute path"); + goto end; + } + + __modify_bundle(kb, cr.pid, menu_info, pkt->cmd); + pkg_name = _get_pkgname(menu_info); + + PERF("get package information & modify bundle done"); + + // use system boost temporarily + __launchpad_use_boost(); + + // check if this is first launching or not + if (!process_pool_disable && pool_client_ui_pid != DUMMY_NONE + && !pool_client_used) + { + snprintf(sock_path, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX, pool_client_ui_pid); + unlink(sock_path); + + // this should be changed for launching new web app + if (__set_background_cgroup(0, pool_client_ui_pid, pool_client_web_pid) < 0) { + _D("failed to set dummy process into foreground cgroup"); + } else { + _D("success to set dummy process into foreground cgroup"); + } + pool_client_used = 1; + __dummy_launch(pool_client_ui_fd, pkt); + pid = pool_client_ui_pid; + _D("==> app launch using dummy process(%d) : %s\n", pid, app_path); + } else { + pid = fork(); + if (pid == 0) + { + PERF("fork done"); + + // this process should not be set to background cgroup! + __set_background_cgroup(0, getpid(), 0); + + // clear resources of launchpad process like opened fd + close(clifd); + close(launchpad_fd); + close(pool_server_fd); + __signal_unset_sigchld(); + __signal_fini(); + + snprintf(sock_path, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX, getpid()); + unlink(sock_path); + + PERF("prepare exec - first done"); + + if (__prepare_exec(pkg_name, app_path, + menu_info, kb) < 0) + { + SECURE_LOGE("preparing work fail to launch - " + "can not launch %s\n", pkg_name); + exit(-1); + } + + PERF("prepare exec - second done"); + + __real_launch(app_path, kb); + exit(-1); + } + _D("==> app launch using process forked directly(%d) : %s\n", pid, app_path); + } + +end: + __send_result_to_caller(clifd, pid); + + /*TODO: retry*/ + __signal_block_sigchld(); + __send_app_launch_signal(pid); + __signal_unblock_sigchld(); + + if (menu_info != NULL) { + _free_app_info_from_db(menu_info); + } + + if (kb != NULL) { + bundle_free(kb); + } + if (pkt != NULL) { + free(pkt); + } + + /* Active Flusing for Daemon */ + if (initialized > AUL_POLL_CNT) { + sqlite3_release_memory(SQLITE_FLUSH_MAX); + malloc_trim(0); + initialized = 1; + } +} + +_static_ int __launchpad_pre_init(int argc, char **argv) +{ + /* signal init*/ + __signal_init(); + + /* get my(launchpad) command line*/ + launchpad_cmdline = __proc_get_cmdline_bypid(getpid()); + if (launchpad_cmdline == NULL) { + _E("launchpad cmdline fail to get"); + return -1; + } + _D("launchpad cmdline = %s", launchpad_cmdline); + + __preload_init(argc, argv); + + __preload_init_for_wrt(); + + __preexec_init(argc, argv); + + return 0; +} + +_static_ int __launchpad_post_init() +{ + /* Setting this as a global variable to keep track + * of launchpad poll cnt */ + /* static int initialized = 0;*/ + + if (initialized) { + initialized++; + return 0; + } + + if (__signal_set_sigchld() < 0) { + return -1; + } + + initialized++; + + return 0; +} + +int send_dbus_signal(const char *path, const char *iface, const char *name){ + DBusConnection *conn; + DBusMessage *msg; + + conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL); + dbus_connection_set_exit_on_disconnect(conn, FALSE); + + msg = dbus_message_new_signal(path, iface, name); + if (!msg) { + _E("dbus_message_new_signal(%s:%s-%s)", path, iface, name); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return -EBADMSG; + } + + dbus_connection_send (conn, msg, NULL); + dbus_message_unref(msg); + + dbus_connection_close(conn); + dbus_connection_unref(conn); + return 0; +} + + +int invoke_dbus_method_sync(const char *dest, const char *path, + const char *interface, const char *method, + const char *sig, char *param[]) +{ + DBusConnection *conn; + DBusMessage *msg; + DBusMessageIter iter; + DBusMessage *reply; + DBusError err; + int r, ret; + + conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL); + dbus_connection_set_exit_on_disconnect(conn, FALSE); + + msg = dbus_message_new_method_call(dest, path, interface, method); + if (!msg) { + _E("dbus_message_new_method_call(%s:%s-%s)", path, interface, method); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return -EBADMSG; + } + + dbus_message_iter_init_append(msg, &iter); + r = append_variant(&iter, sig, param); + if (r < 0) { + _E("append_variant error(%d)", r); + dbus_message_unref(msg); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return -EBADMSG; + } + + dbus_error_init(&err); + + reply = dbus_connection_send_with_reply_and_block(conn, msg, 500, &err); + dbus_message_unref(msg); + if (!reply) { + _E("dbus_connection_send error(%s:%s)", err.name, err.message); + dbus_error_free(&err); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return -EBADMSG; + } + + r = dbus_message_get_args(reply, &err, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID); + dbus_message_unref(reply); + if (!r) { + _E("no message : [%s:%s]", err.name, err.message); + dbus_error_free(&err); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return -EBADMSG; + } + + dbus_connection_close(conn); + dbus_connection_unref(conn); + return ret; +} + +static int append_variant(DBusMessageIter *iter, const char *sig, char *param[]) +{ + char *ch; + int i; + int int_type; + uint64_t int64_type; + + if (!sig || !param) + return 0; + + for (ch = (char*)sig, i = 0; *ch != '\0'; ++i, ++ch) { + switch (*ch) { + case 'i': + int_type = atoi(param[i]); + dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int_type); + break; + case 'u': + int_type = atoi(param[i]); + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &int_type); + break; + case 't': + int64_type = atoi(param[i]); + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &int64_type); + break; + case 's': + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, ¶m[i]); + break; + default: + return -EINVAL; + } + } + + return 0; +} + +int main(int argc, char **argv) +{ + int launchpad_fd = -1, pool_server_fd = -1; + int ret, count = 0; + memset(pfds, 0x00, sizeof(pfds)); + + // process pool feature disable + if (getenv("WRT_PROCESS_POOL_DISABLE")) + { + process_pool_disable = 1; + } + + /* preloading */ + if( __launchpad_pre_init(argc, argv) < 0){ + _E("launchpad pre init failed"); + goto exit_main; + } + + + /* create launchpad sock */ + launchpad_fd = __create_server_sock(WRT_LAUNCHPAD_PID); + if (launchpad_fd < 0) { + _E("server sock error"); + goto exit_main; + } + pfds[LAUNCH_PAD].fd = launchpad_fd; + pfds[LAUNCH_PAD].events = POLLIN; + pfds[LAUNCH_PAD].revents = 0; + + pool_server_fd = __create_process_pool_server(); + if (pool_server_fd == -1) + { + _E("Error creationg pool server!"); + goto exit_main; + } + + pfds[POOL_SERVER].fd = pool_server_fd; + pfds[POOL_SERVER].events = POLLIN; + pfds[POOL_SERVER].revents = 0; + + /* waiting initialzing Xorg process during 2 seconds */ + while (count != 5) { + ret = access(CHECK_Xorg, F_OK); + if (ret == 0) + break; + usleep(500*1000); + count++; + } + +#ifdef USE_POOL_FOR_FIRST_LAUNCH + // dummy process is created in advance for first launching + if(!process_pool_disable){ + __launchpad_exec_dummy(launchpad_fd, pool_server_fd, -1); + } +#endif + + send_dbus_signal(DBUS_WRT_OBJECT_PATH, DBUS_WRT_INTERFACE_NAME, DBUS_WRT_SIGNAL_READYDONE); + + while (1) + { + if (poll(pfds, POLLFD_MAX, -1) < 0) + { + continue; + } + + _D("pfds[LAUNCH_PAD].revents : 0x%x", pfds[LAUNCH_PAD].revents) ; + _D("pfds[POOL_SERVER].revents : 0x%x", pfds[POOL_SERVER].revents) ; + _D("pfds[POOL_CLIENT].revents : 0x%x", pfds[POOL_CLIENT].revents) ; + + /* init with concerning X & EFL (because of booting + * sequence problem)*/ + if (__launchpad_post_init() < 0) + { + _E("launcpad post init failed"); + goto exit_main; + } + + if ((pfds[LAUNCH_PAD].revents & POLLIN) != 0) + { + _D("pfds[LAUNCH_PAD].revents & POLLIN"); + __launchpad_main_loop(pfds[LAUNCH_PAD].fd, pfds[POOL_SERVER].fd); + } + + if (process_pool_disable) { + continue; + } + + // this is available in case of only process pool + if ((pfds[POOL_SERVER].revents & POLLIN) != 0) + { + _D("pfds[POOL_SERVER].revents & POLLIN"); + __accept_process_pool_client( + pfds[POOL_SERVER].fd, &pool_client_ui_fd, + &pool_client_ui_pid, &pool_client_web_pid); + + pfds[POOL_CLIENT].fd = pool_client_ui_fd; + pfds[POOL_CLIENT].events = POLLIN | POLLHUP | POLLNVAL; + pfds[POOL_CLIENT].revents = 0; + pool_client_creating = 0; + pool_client_used = 0; + } + + if ((pfds[POOL_CLIENT].revents & POLLIN) != 0) + { + _D("pfds[POOL_CLIENT].revents & POLLIN (pid:%d)", pool_client_ui_pid); + // 1. define status that app finishes to be launched normally + // 2. recieve status value from launched app + // 3. handle proper action according to status value + // + // status description + // 0 : success to launch app + // -1 : launching is delayed. that is, 5 seconds was gone. + // -2 : failed to launch app + int status = -2; + int ret = 0; + ret = recv(pool_client_ui_fd, &status, sizeof(status), 0); + if (ret < 0) { + _E("failed to receive launch status"); + } else { + _D("launch status: %d", status); + } + + if (pool_client_used) { + // create new dummy process unconditionally, + // regardless received status as now. + __launchpad_exec_dummy(launchpad_fd, pool_server_fd, -1); + } + } + + if ((pfds[POOL_CLIENT].revents & (POLLHUP|POLLNVAL)) != 0) + { + // this is executed when dummy process disconnects normally or abnormally + _D("pfds[POOL_CLIENT].revents & (POLLHUP|POLLNVAL) (pid:%d)", pool_client_ui_pid); + // clear resource of dummy process + __launchpad_clear_dummy(); + //re-create dummy process + __launchpad_exec_dummy(launchpad_fd, pool_server_fd, -1); + } + } + + return 0; + + exit_main: + if (launchpad_fd != -1) + { + close(launchpad_fd); + } + + if (pool_server_fd != -1) + { + close(pool_server_fd); + } + + return -1; +} diff --git a/src/wrt-launchpad-daemon/launchpad_src/sigchild.h b/src/wrt-launchpad-daemon/launchpad_src/sigchild.h new file mode 100644 index 0000000..5a35aa8 --- /dev/null +++ b/src/wrt-launchpad-daemon/launchpad_src/sigchild.h @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "app_signal.h" + +static struct sigaction old_sigchild; +static DBusConnection *bus = NULL; +sigset_t oldmask; + +static inline void __socket_garbage_collector() +{ + DIR *dp; + struct dirent dentry; + struct dirent *result; + char tmp[MAX_LOCAL_BUFSZ]; + + dp = opendir(AUL_SOCK_PREFIX); + if (dp == NULL) { + return; + } + + while (readdir_r(dp, &dentry, &result) == 0 && result != NULL) { + if (!isdigit(dentry.d_name[0])) { + continue; + } + + snprintf(tmp, MAX_LOCAL_BUFSZ, "/proc/%s", dentry.d_name); + if (access(tmp, F_OK) < 0) { /* Flawfinder: ignore */ + snprintf(tmp, MAX_LOCAL_BUFSZ, "%s/%s", AUL_SOCK_PREFIX, + dentry.d_name); + unlink(tmp); + continue; + } + } + closedir(dp); +} + +static inline int __send_app_dead_signal(int dead_pid) +{ + DBusMessage *message; + + if (bus == NULL) { + return -1; + } + + message = dbus_message_new_signal(AUL_DBUS_PATH, + AUL_DBUS_SIGNAL_INTERFACE, + AUL_DBUS_APPDEAD_SIGNAL); + + if (dbus_message_append_args(message, + DBUS_TYPE_UINT32, &dead_pid, + DBUS_TYPE_INVALID) == FALSE) + { + _E("Failed to load data error"); + return -1; + } + + if (dbus_connection_send(bus, message, NULL) == FALSE) { + _E("dbus send error"); + return -1; + } + + dbus_connection_flush(bus); + dbus_message_unref(message); + + _D("send dead signal done\n"); + + return 0; +} + +static inline int __send_app_launch_signal(int launch_pid) +{ + DBusMessage *message; + + if (bus == NULL) { + return -1; + } + + message = dbus_message_new_signal(AUL_DBUS_PATH, + AUL_DBUS_SIGNAL_INTERFACE, + AUL_DBUS_APPLAUNCH_SIGNAL); + + if (dbus_message_append_args(message, + DBUS_TYPE_UINT32, &launch_pid, + DBUS_TYPE_INVALID) == FALSE) + { + _E("Failed to load data error"); + return -1; + } + + if (dbus_connection_send(bus, message, NULL) == FALSE) { + _E("dbus send error"); + return -1; + } + + dbus_connection_flush(bus); + dbus_message_unref(message); + + _D("send launch signal done\n"); + + return 0; +} + +static int __sigchild_action(void *data) +{ + pid_t dead_pid; + char buf[MAX_LOCAL_BUFSZ]; + + dead_pid = (pid_t) data; + if (dead_pid <= 0) { + goto end; + } + + __send_app_dead_signal(dead_pid); + + snprintf(buf, MAX_LOCAL_BUFSZ, "%s/%d", AUL_SOCK_PREFIX, dead_pid); + unlink(buf); + + __socket_garbage_collector(); +end: + return 0; +} + +static void __launchpad_sig_child(int signo, siginfo_t *info, void *data) +{ + int status; + pid_t child_pid; + pid_t child_pgid; + + // warning: unused parameter + (void)signo; + (void)data; + + child_pgid = getpgid(info->si_pid); + _D("dead_pid = %d pgid = %d", info->si_pid, child_pgid); + + while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) { + if (child_pid == child_pgid) { + killpg(child_pgid, SIGKILL); + } + __sigchild_action((void *)child_pid); + } + + return; +} + +static inline int __signal_init(void) +{ + int i; + for (i = 0; i < _NSIG; i++) { + switch (i) { + /* controlled by sys-assert package*/ + case SIGQUIT: + case SIGILL: + case SIGABRT: + case SIGBUS: + case SIGFPE: + case SIGSEGV: + case SIGPIPE: + break; + default: + signal(i, SIG_DFL); + break; + } + } + + return 0; +} + +static inline int __signal_set_sigchld(void) +{ + struct sigaction act; + DBusError error; + + dbus_error_init(&error); + dbus_threads_init_default(); + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (!bus) { + _E("Failed to connect to the D-BUS daemon: %s", error.message); + dbus_error_free(&error); + return -1; + } + /* TODO: if process stop mechanism is included, + * should be modified (SA_NOCLDSTOP)*/ + act.sa_handler = NULL; + act.sa_sigaction = __launchpad_sig_child; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_NOCLDSTOP | SA_SIGINFO; + + if (sigaction(SIGCHLD, &act, &old_sigchild) < 0) { + return -1; + } + + return 0; +} + +static inline int __signal_unset_sigchld(void) +{ + struct sigaction dummy; + + if (bus == NULL) { + return 0; + } + + dbus_connection_close(bus); + dbus_connection_unref(bus); + if (sigaction(SIGCHLD, &old_sigchild, &dummy) < 0) { + return -1; + } + + return 0; +} + +static inline int __signal_block_sigchld(void) +{ + sigset_t newmask; + + sigemptyset(&newmask); + sigaddset(&newmask, SIGCHLD); + + if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) { + _E("SIG_BLOCK error"); + return -1; + } + + _D("SIGCHLD blocked"); + + return 0; +} + +static inline int __signal_unblock_sigchld(void) +{ + if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) { + _E("SIG_SETMASK error"); + return -1; + } + + _D("SIGCHLD unblocked"); + return 0; +} + +static inline int __signal_fini(void) +{ +#ifndef PRELOAD_ACTIVATE + int i; + for (i = 0; i < _NSIG; i++) { + signal(i, SIG_DFL); + } +#endif + return 0; +} + diff --git a/src/wrt-launchpad-daemon/launchpad_src/util_x.c b/src/wrt-launchpad-daemon/launchpad_src/util_x.c new file mode 100644 index 0000000..678434c --- /dev/null +++ b/src/wrt-launchpad-daemon/launchpad_src/util_x.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "simple_util.h" + +static Atom a_pid; +static int (*x_old_error)(Display *, XErrorEvent *); + +static pid_t __get_win_pid(Display *d, Window win); +static int __find_win(Display *d, Window *win, pid_t pid); +static int __raise_win(Display *d, Window win); +static int __cb_x_error(Display *disp, XErrorEvent *ev); + +static pid_t __get_win_pid(Display *d, Window win) +{ + int r; + pid_t pid; + + Atom a_type; + int format; + unsigned long nitems; + unsigned long bytes_after; + unsigned char *prop_ret; + + retv_if(d == NULL || !a_pid, -1); + + prop_ret = NULL; + r = XGetWindowProperty(d, win, a_pid, 0, 1, False, XA_CARDINAL, + &a_type, &format, &nitems, &bytes_after, &prop_ret); + if (r != Success || prop_ret == NULL) { + return -1; + } + + if (a_type == XA_CARDINAL && format == 32) { + pid = *(unsigned long *)prop_ret; + } else { + pid = -1; + } + + XFree(prop_ret); + + return pid; +} + +static int __find_win(Display *d, Window *win, pid_t pid) +{ + int r; + pid_t p; + unsigned int n; + Window root, parent, *child; + + p = __get_win_pid(d, *win); + if (p == pid) { + return 1; + } + + r = XQueryTree(d, *win, &root, &parent, &child, &n); + if (r) { + unsigned int i; + int found = 0; + + for (i = 0; i < n; i++) { + found = __find_win(d, &child[i], pid); + if (found) { + *win = child[i]; + break; + } + } + XFree(child); + + if (found) { + return 1; + } + } + + return 0; +} + +static int __raise_win(Display *d, Window win) +{ + XWindowAttributes attr; + attr.map_state = IsUnmapped; + + XMapRaised(d, win); + + XGetWindowAttributes(d, win, &attr); + + if (attr.map_state == IsUnmapped) { + _D("unmapped"); + } else if (attr.map_state == IsUnviewable) { + _D("unviewable"); + } else if (attr.map_state == IsViewable) { + _D("viewable"); + } + + retv_if(attr.map_state != IsViewable, -1); + + XSetInputFocus(d, win, RevertToPointerRoot, CurrentTime); + + return 0; +} + +int x_util_raise_win(pid_t pid) +{ + int r; + int found; + Display *d; + Window win; + + if (pid < 1) { + return -1; + } + + r = kill(pid, 0); + if (r == -1) { + return -1; + } + + d = XOpenDisplay(NULL); + retv_if(d == NULL, -1); + + win = XDefaultRootWindow(d); + + if (!a_pid) { + a_pid = XInternAtom(d, "X_CLIENT_PID", True); + } + + found = __find_win(d, &win, pid); + if (!found) { + XCloseDisplay(d); + _E("cannot found window with pid - %d", pid); + return -1; + } + + r = __raise_win(d, win); + if (r < 0) { + _E("fail to raise win"); + } + + XCloseDisplay(d); + + return r; +} + +int x_util_get_default_size(double *w, double *h) +{ + Display *d; + int screen_num; + + d = XOpenDisplay(NULL); + if (d == NULL) { + return -1; + } + + screen_num = DefaultScreen(d); + + *w = DisplayWidth(d, screen_num); + *h = DisplayHeight(d, screen_num); + + _D("Root Width = %lf, Height = %lf\n", *w, *h); + + XCloseDisplay(d); + + return 0; +} + +static int __cb_x_error(Display* disp, XErrorEvent *ev) +{ + //warning unused parameter + (void)disp; + + _E("X error received - Error Code = %d", ev->error_code); + return 0; +} + +int x_util_init() +{ + x_old_error = XSetErrorHandler(__cb_x_error); + return 0; +} + +int x_util_fini() +{ + XSetErrorHandler(x_old_error); + return 0; +} + diff --git a/src/wrt-launchpad-daemon/launchpad_src/util_x.h b/src/wrt-launchpad-daemon/launchpad_src/util_x.h new file mode 100644 index 0000000..7c13032 --- /dev/null +++ b/src/wrt-launchpad-daemon/launchpad_src/util_x.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTIL_X_H_ +#define __UTIL_X_H_ + +int x_util_init(); +int x_util_fini(); +int x_util_get_default_size(double *w, double *h); +int x_util_raise_win(pid_t pid); + +#endif + diff --git a/src/wrt-launchpad-daemon/legacy/preload.h b/src/wrt-launchpad-daemon/legacy/preload.h new file mode 100644 index 0000000..037ab67 --- /dev/null +++ b/src/wrt-launchpad-daemon/legacy/preload.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef PRELOAD_ACTIVATE + +#include + +#define PRELOAD_FILE SHARE_PREFIX "/preload_list.txt" +#define PRELOAD_FILE_WRT SHARE_PREFIX "/preload_list_wrt.txt" + +#define EFL_PREINIT_FUNC "elm_quicklaunch_init" +#define EFL_SHUTDOWN_FUNC "elm_quicklaunch_shutdown" + +static int preload_initialized = 0; +static int g_argc; +static char **g_argv; +static size_t max_cmdline_size = 0; + +typedef struct handle_list_t { + int (*dl_einit)(); + int (*dl_efini)(); + void *handle; +} handle_list_t; + +static inline void __preload_init(int argc, char **argv) +{ + int i; + + g_argc = argc; + g_argv = argv; + for (i = 0; i < argc; i++) { + max_cmdline_size += (strlen(argv[i]) + 1); + } + _D("max_cmdline_size = %d", max_cmdline_size); + + preload_initialized = 1; +} + +/* TODO : how to set cmdline gracefully ?? */ +static inline int __change_cmdline(char *cmdline) +{ + if (strlen(cmdline) > max_cmdline_size + 1) { + _E("cmdline exceed max size : %d", max_cmdline_size); + return -1; + } + + memset(g_argv[0], '\0', max_cmdline_size); + snprintf(g_argv[0], max_cmdline_size, "%s", cmdline); + + return 0; +} + +static inline void __preload_exec(int argc, char **argv) +{ + void *handle = NULL; + int (*dl_main)(int, char **); + + if (!preload_initialized) { + return; + } + + handle = dlopen(argv[0], RTLD_LAZY | RTLD_GLOBAL); + if (handle == NULL) { + _E("dlopen failed. bad preloaded app - check fpie pie"); + return; + } + + dl_main = dlsym(handle, "main"); + if (dl_main != NULL) { +#ifndef NATIVE_LAUNCHPAD + /* do nothing */ +#else + if (__change_cmdline(argv[0]) < 0) { + _E("change cmdline fail"); + return; + } +#endif + dl_main(argc, argv); + } else { + _E("dlsym not founded. bad preloaded app - check fpie pie"); + } + + exit(0); +} + +static int g_wrt_dlopen_size = 5; +static int g_wrt_dlopen_count = 0; +static void** g_wrt_dlopen_handle_list = NULL; + +static inline int __preload_save_dlopen_handle(void *handle) +{ + if (!handle) { + return 1; + } + if (g_wrt_dlopen_count == g_wrt_dlopen_size || !g_wrt_dlopen_handle_list) { + void** tmp = + realloc(g_wrt_dlopen_handle_list, 2 * g_wrt_dlopen_size * sizeof(void *)); + if (NULL == tmp) { + _E("out of memory\n"); + dlclose(handle); + return 1; + } + g_wrt_dlopen_size *= 2; + g_wrt_dlopen_handle_list = tmp; + } + g_wrt_dlopen_handle_list[g_wrt_dlopen_count++] = handle; + return 0; +} + +static inline void __preload_fini_for_wrt() +{ + int i = 0; + if (!g_wrt_dlopen_handle_list) { + return; + } + for (i = 0; i < g_wrt_dlopen_count; ++i) + { + void *handle = g_wrt_dlopen_handle_list[i]; + if (handle) { + if (0 != dlclose(handle)) { + _E("dlclose failed\n"); + } + } + } + free(g_wrt_dlopen_handle_list); + g_wrt_dlopen_handle_list = NULL; + g_wrt_dlopen_size = 5; + g_wrt_dlopen_count = 0; +} + +static inline void __preload_init_for_wrt() +{ + if (0 != atexit(__preload_fini_for_wrt)) { + _E("Cannot register atexit callback. Libraries will not be unloaded"); + } + void *handle = NULL; + FILE *preload_list; + char soname_untaint[MAX_LOCAL_BUFSZ] = {0}; + char *soname =(char*)malloc(sizeof(char)*MAX_LOCAL_BUFSZ); + + if (!soname) { + _E("Error allocating mem for soname\n"); + return; + } + preload_list = fopen(PRELOAD_FILE_WRT, "rt"); + if (preload_list == NULL) { + _E("no wrt preload\n"); + free(soname); + return; + } + + while (fgets(soname, MAX_LOCAL_BUFSZ, preload_list) != NULL) { + strcpy(soname_untaint,soname); + memset(soname,'\0',MAX_LOCAL_BUFSZ); + size_t len = strnlen(soname_untaint, MAX_LOCAL_BUFSZ); + if (len > 0) { + soname_untaint[len - 1] = '\0'; + } + handle = dlopen(soname_untaint, RTLD_NOW | RTLD_GLOBAL); + if (handle == NULL) { + _E("dlopen(\"%s\") was failed!", soname_untaint); + memset(soname_untaint,'\0',MAX_LOCAL_BUFSZ); + continue; + } + if (0 != __preload_save_dlopen_handle(handle)) { + _E("Cannot save handle, no more preloads"); + break; + } + _D("preload %s# - handle : %p\n", soname_untaint, handle); + memset(soname_untaint,'\0',MAX_LOCAL_BUFSZ); + } + + fclose(preload_list); + free(soname); +} + +#else + +static inline void __preload_init(int argc, char **argv); +static inline void __preload_exec(int argc, char **argv); +static inline void __preload_init_for_wrt(); + +#endif + diff --git a/src/wrt-launchpad-daemon/legacy/preload_list_wrt.txt b/src/wrt-launchpad-daemon/legacy/preload_list_wrt.txt new file mode 100644 index 0000000..1bf5837 --- /dev/null +++ b/src/wrt-launchpad-daemon/legacy/preload_list_wrt.txt @@ -0,0 +1,10 @@ +/usr/lib/libappcore-efl.so.1 +/usr/lib/libappcore-common.so.1 +/usr/lib/ecore/immodules/libisf-imf-module.so +/usr/bin/wrt-client +/usr/lib/libwrt-injected-bundle.so +/usr/lib/libewebkit2.so +/usr/lib/wrt-plugins/w3c-widget-interface/libwrt-plugins-w3c-widget-interface.so +/usr/lib/wrt-plugins/tizen-tizen/libwrt-plugins-tizen-tizen.so +/usr/lib/wrt-plugins/tizen-application/libwrt-plugins-tizen-application.so + diff --git a/src/wrt-launchpad-daemon/src/app_sock.c b/src/wrt-launchpad-daemon/src/app_sock.c new file mode 100644 index 0000000..19a74d4 --- /dev/null +++ b/src/wrt-launchpad-daemon/src/app_sock.c @@ -0,0 +1,445 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "app_sock.h" +#include "simple_util.h" + +static int __connect_client_sock(int sockfd, + const struct sockaddr *saptr, + socklen_t salen, + int nsec); + +static inline int __set_sock_option(int fd, int cli) +{ + int size; + struct timeval tv = { 3, 200 * 1000 }; /* 3.2 sec */ + + size = AUL_SOCK_MAXBUFF; + if (0 != setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) || + 0 != setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size))) + { + return 1; + } + if (cli && 0 != setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))) { + return 1; + } + return 0; +} + +int __create_server_sock(int pid) +{ + struct sockaddr_un saddr; + struct sockaddr_un p_saddr; + int fd; + mode_t orig_mask; + + memset(&saddr, 0, sizeof(saddr)); + saddr.sun_family = AF_UNIX; + snprintf(saddr.sun_path, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX, pid); + + /* Create basedir for our sockets */ + orig_mask = umask(0); + (void) mkdir(AUL_SOCK_PREFIX, S_IRWXU | S_IRWXG | S_IRWXO | S_ISVTX); + umask(orig_mask); + + fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + /* support above version 2.6.27*/ + if (fd < 0) { + if (errno == EINVAL) { + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + _E("second chance - socket create error"); + return -1; + } + } else { + _E("socket error"); + return -1; + } + } + + unlink(saddr.sun_path); + + /* labeling to socket for SMACK */ + if (getuid() == 0) { // this is meaningful iff current user is ROOT + if (smack_fsetlabel(fd, "@", SMACK_LABEL_IPOUT) != 0) { + /* in case of unsupported filesystem on 'socket' */ + /* or permission error by using 'emulator', bypass*/ + if ((errno != EOPNOTSUPP) && (errno != EPERM)) { + _E("labeling to socket(IPOUT) error"); + close(fd); + return -1; + } + } + if (smack_fsetlabel(fd, "*", SMACK_LABEL_IPIN) != 0) { + /* in case of unsupported filesystem on 'socket' */ + /* or permission error by using 'emulator', bypass*/ + if ((errno != EOPNOTSUPP) && (errno != EPERM)) { + _E("labeling to socket(IPIN) error"); + close(fd); + return -1; + } + } + } + + if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { + _E("bind error"); + close(fd); + return -1; + } + + if (chmod(saddr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + /* Flawfinder: ignore*/ + _E("failed to change the socket permission"); + close(fd); + return -1; + } + + if (0 != __set_sock_option(fd, 0)) { + close(fd); + return -1; + } + + if (listen(fd, 3) == -1) { + _E("listen error"); + close(fd); + return -1; + } + + /* support app launched by shell script */ + if (pid != WRT_LAUNCHPAD_PID) { + int pgid; + pgid = getpgid(pid); + if (pgid > 1) { + snprintf(p_saddr.sun_path, UNIX_PATH_MAX, "%s/%d", + AUL_SOCK_PREFIX, pgid); + if (link(saddr.sun_path, p_saddr.sun_path) < 0) { + if (errno == EEXIST) { + _D("pg path - already exists"); + } + else { + _E("pg path - unknown create error"); + } + } + } + } + _D("created socket: %s", saddr.sun_path); + + return fd; +} + +int __create_client_sock(int pid) +{ + int fd = -1; + struct sockaddr_un saddr; + int retry = 1; + int ret = -1; + + memset(&saddr, 0x00, sizeof(struct sockaddr_un)); + + fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + /* support above version 2.6.27*/ + if (fd < 0) { + if (errno == EINVAL) { + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + _E("second chance - socket create error"); + return -1; + } + } else { + _E("socket error"); + return -1; + } + } + + saddr.sun_family = AF_UNIX; + snprintf(saddr.sun_path, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX, pid); + + while ((ret = __connect_client_sock(fd, (struct sockaddr *)&saddr, sizeof(saddr), + 100 * 1000)) < -1) { + _E("maybe peer not launched or peer daed\n"); + if (retry > 0) { + struct timespec duration = { 0, 100 * 1000 * 1000 }; + nanosleep(&duration, NULL); /* 100ms sleep*/ + retry--; + } + else break; + } + + if (ret < 0) { + close(fd); + return -1; + } + + if (0 != __set_sock_option(fd, 1)) { + close(fd); + return -1; + } + + return fd; +} + +static int __connect_client_sock(int fd, + const struct sockaddr *saptr, + socklen_t salen, + int nsec) +{ + int flags; + int ret; + int error; + socklen_t len; + fd_set readfds; + fd_set writefds; + struct timeval timeout; + + flags = fcntl(fd, F_GETFL, 0); + if (0 != fcntl(fd, F_SETFL, flags | O_NONBLOCK)) { + return -1; + } + + error = 0; + if ((ret = connect(fd, (struct sockaddr *)saptr, salen)) < 0) { + if (errno != EAGAIN && errno != EINPROGRESS) { + (void) fcntl(fd, F_SETFL, flags); + return (-2); + } + } + + /* Do whatever we want while the connect is taking place. */ + if (ret == 0) { + goto done; /* connect completed immediately */ + } + FD_ZERO(&readfds); + FD_SET(fd, &readfds); + writefds = readfds; + timeout.tv_sec = 0; + timeout.tv_usec = nsec; + + if ((ret = select(fd + 1, &readfds, &writefds, NULL, + nsec ? &timeout : NULL)) == 0) { + close(fd); /* timeout */ + errno = ETIMEDOUT; + return (-1); + } + + if (FD_ISSET(fd, &readfds) || FD_ISSET(fd, &writefds)) { + len = sizeof(error); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { + return (-1); /* Solaris pending error */ + } + } + else { + return (-1); /* select error: sockfd not set*/ + } + +done: + (void) fcntl(fd, F_SETFL, flags); + if (error) { + close(fd); + errno = error; + return (-1); + } + return (0); +} + +/** + * @brief Send data (in raw) to the process with 'pid' via socket + */ +int __app_send_raw(int pid, int cmd, unsigned char *kb_data, int datalen) +{ + int fd; + int len; + int res = 0; + app_pkt_t *pkt = NULL; + + if (kb_data == NULL || datalen > AUL_SOCK_MAXBUFF - 8) { + _E("keybundle error\n"); + return -EINVAL; + } + + fd = __create_client_sock(pid); + if (fd < 0) { + return -ECOMM; + } + + pkt = (app_pkt_t *) malloc(sizeof(char) * AUL_SOCK_MAXBUFF); + if (NULL == pkt) { + _E("Malloc Failed!"); + return -ENOMEM; + } + memset(pkt, 0, AUL_SOCK_MAXBUFF); + + pkt->cmd = cmd; + pkt->len = datalen; + memcpy(pkt->data, kb_data, datalen); + + if ((len = send(fd, pkt, datalen + 8, 0)) != datalen + 8) { + _E("sendto() failed - %d %d (errno %d)", len, datalen + 8, errno); + if (errno == EPIPE) { + _E("pid:%d, fd:%d\n", pid, fd); + } + close(fd); + if (pkt) { + free(pkt); + pkt = NULL; + } + return -ECOMM; + } + if (pkt) { + free(pkt); + pkt = NULL; + } + + len = recv(fd, &res, sizeof(int), 0); + if (len == -1) { + if (errno == EAGAIN) { + _E("recv timeout \n"); + res = -EAGAIN; + } else { + _E("recv error\n"); + res = -ECOMM; + } + } + close(fd); + + return res; +} + +app_pkt_t *__app_recv_raw(int fd, int *clifd, struct ucred *cr) +{ + int len; + struct sockaddr_un aul_addr; + int sun_size; + app_pkt_t *pkt = NULL; + int cl = sizeof(struct ucred); + + memset(&aul_addr, 0x00, sizeof(struct sockaddr_un)); + sun_size = sizeof(struct sockaddr_un); + + if ((*clifd = accept(fd, (struct sockaddr *)&aul_addr, + (socklen_t *) &sun_size)) == -1) + { + if (errno != EINTR) { + _E("accept error"); + } + return NULL; + } + + if (getsockopt(*clifd, SOL_SOCKET, SO_PEERCRED, cr, + (socklen_t *) &cl) < 0) + { + _E("peer information error"); + close(*clifd); + return NULL; + } + + pkt = (app_pkt_t *) malloc(sizeof(char) * AUL_SOCK_MAXBUFF); + if(pkt == NULL) { + close(*clifd); + return NULL; + } + memset(pkt, 0, AUL_SOCK_MAXBUFF); + + if (0 != __set_sock_option(*clifd, 1)) { + free(pkt); + close(*clifd); + return NULL; + } + +retry_recv: + /* receive single packet from socket */ + len = recv(*clifd, pkt, AUL_SOCK_MAXBUFF, 0); + if (len < 0) { + if (errno == EINTR) { + goto retry_recv; + } + } + + if ((len < 8) || (len != (pkt->len + 8))) { + _E("recv error %d %d", len, pkt->len); + free(pkt); + close(*clifd); + return NULL; + } + + return pkt; +} + +app_pkt_t *__app_send_cmd_with_result(int pid, int cmd) +{ + int fd; + int len; + app_pkt_t *pkt = NULL; + + fd = __create_client_sock(pid); + if (fd < 0) { + return NULL; + } + + pkt = (app_pkt_t *) malloc(sizeof(char) * AUL_SOCK_MAXBUFF); + if (NULL == pkt) { + _E("Malloc Failed!"); + return NULL; + } + memset(pkt, 0, AUL_SOCK_MAXBUFF); + + pkt->cmd = cmd; + pkt->len = 0; + + if ((len = send(fd, pkt, 8, 0)) != 8) { + _E("sendto() failed - %d", len); + if (errno == EPIPE) { + _E("pid:%d, fd:%d\n", pid, fd); + } + close(fd); + + free(pkt); + return NULL; + } + +retry_recv: + /* receive single packet from socket */ + len = recv(fd, pkt, AUL_SOCK_MAXBUFF, 0); + if (len == -1) { + if (errno == EAGAIN) { + _E("recv timeout \n"); + free(pkt); + return NULL; + } else if (errno == EINTR) { + goto retry_recv; + } else { + _E("recv error %s\n", strerror(errno)); + free(pkt); + return NULL; + } + } else { + _D("recv result = %d", len); + } + close(fd); + + return pkt; +} + diff --git a/src/wrt-launchpad-daemon/src/process_pool.c b/src/wrt-launchpad-daemon/src/process_pool.c new file mode 100755 index 0000000..30b99ea --- /dev/null +++ b/src/wrt-launchpad-daemon/src/process_pool.c @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 process_pool.c + * @author Tae-Jeong Lee (taejeong.lee@samsung.com) + * @version 0.1 + * @brief process pool socket apis + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "process_pool.h" +#include "simple_util.h" + +#define TMP_PATH "/tmp" +#define PROCESS_POOL_SERVER "wrt_process_pool_server" +#define MAX_PENDING_CONNECTIONS 3 +#define CONNECT_RETRY_TIME 100 * 1000 +#define CONNECT_RETRY_COUNT 3 + +int __create_process_pool_server() +{ + struct sockaddr_un addr; + int fd = -1; + + memset(&addr, 0x00, sizeof(struct sockaddr_un)); + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%s", TMP_PATH, PROCESS_POOL_SERVER); + + fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (fd < 0) + { + _E("socket error"); + goto err_create_process_pool_server; + } + + unlink(addr.sun_path); + + _D("bind to %s", addr.sun_path); + if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + _E("bind error"); + goto err_create_process_pool_server; + } + + _D("chmod to %s", addr.sun_path); + if (chmod(addr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) + { + _E("chmod error"); + goto err_create_process_pool_server; + } + + _D("listen to %s", addr.sun_path); + if (listen(fd, MAX_PENDING_CONNECTIONS) == -1) + { + _E("listen error"); + goto err_create_process_pool_server; + } + + _D("__create_process_pool_server done : %d", fd); + return fd; + + +err_create_process_pool_server: + + if (fd != -1) + { + close(fd); + } + + return -1; +} + + +int __connect_process_pool_server() +{ + struct sockaddr_un addr; + int fd = -1; + int retry = CONNECT_RETRY_COUNT; + int send_ret = -1; + int ui_pid = getpid(); + + char pid_buff[8]; + size_t len = 8; + char command[256] = {0}; + char payload[16] = {0}; + + memset(&addr, 0x00, sizeof(struct sockaddr_un)); + + fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + + if (fd < 0) + { + _E("socket error"); + + goto err_connect_process_pool_server; + } + + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%s", TMP_PATH, PROCESS_POOL_SERVER); + + // find child process of ui process and set it to payload + sprintf(command, "/usr/bin/pgrep -P %d", ui_pid); + FILE *fp = (FILE*) popen(command, "r"); + + if( fp == NULL ){ + _E("popen error"); + goto err_connect_process_pool_server; + } + + if(fgets(pid_buff, len, fp)) { + if(!ferror(fp)) { + _D("child pid: %s", pid_buff); + sprintf(payload, "%7d %7s", ui_pid, pid_buff); + } else { + sprintf(payload, "%15d", ui_pid); + } + } + pclose(fp); + + _D("connect to %s", addr.sun_path); + while (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + if (errno != ETIMEDOUT || retry <= 0) + { + _E("connect error : %d", errno); + + goto err_connect_process_pool_server; + } + + usleep(CONNECT_RETRY_TIME); + retry--; + _D("re-connect to %s (%d)", addr.sun_path, retry); + } + + send_ret = send(fd, payload, strlen(payload) + 1, 0); + _D("send(payload: %s) : %d", payload, send_ret); + + if (send_ret == -1) + { + _E("send error"); + + goto err_connect_process_pool_server; + } + + _D("__connect_process_pool_server done : %d", fd); + return fd; + +err_connect_process_pool_server: + + if (fd != -1) + { + close(fd); + } + + return -1; +} + + +int __accept_process_pool_client( + int server_fd, int* out_client_ui_fd, + int* out_client_ui_pid, int* out_client_web_pid) +{ + int client_ui_fd = -1, recv_ret = 0; + + char* pid; + char payload[17] = {0}; + + if (server_fd == -1 || out_client_ui_fd == NULL || out_client_ui_pid == NULL) + { + _E("arguments error!"); + + goto err__accept_process_pool_client; + } + + client_ui_fd = accept(server_fd, NULL, NULL); + + if (client_ui_fd == -1) + { + _E("accept error!"); + + goto err__accept_process_pool_client; + } + + recv_ret = recv(client_ui_fd, payload, 16, MSG_WAITALL); + + if (recv_ret == -1) + { + _E("recv error!"); + + goto err__accept_process_pool_client; + } + + // parse payload and get pid of ui process and web process + pid = strtok(payload, " "); + if (!pid) { + // this case would have only pid of ui process + *out_client_ui_pid = atoi(payload); + *out_client_web_pid = 0; + } else { + *out_client_ui_pid = atoi(pid); + pid = strtok(NULL, "\0"); + if (pid == NULL) { + *out_client_web_pid = 0; + } else { + *out_client_web_pid = atoi(pid); + } + } + _D("pool client is connected! (ui pid: %d, web pid: %d)", + *out_client_ui_pid, *out_client_web_pid); + + *out_client_ui_fd = client_ui_fd; + return *out_client_ui_fd; + +err__accept_process_pool_client: + + if (client_ui_fd != -1) + { + close(client_ui_fd); + } + + return -1; +} + +void __refuse_process_pool_client(int server_fd) +{ + int client_fd = -1; + + if (server_fd == -1) + { + _E("arguments error!"); + + goto err__refuse_process_pool_client; + } + + client_fd = accept(server_fd, NULL, NULL); + + if (client_fd == -1) + { + _E("accept error!"); + + goto err__refuse_process_pool_client;; + } + + close(client_fd); + _D("refuse connection!"); + + err__refuse_process_pool_client: + + return; + +} + + +int __send_pkt_raw_data(int client_fd, app_pkt_t* pkt) +{ + int send_ret = 0; + int pkt_size = 0; + + if (client_fd == -1 || pkt == NULL) + { + _E("arguments error!"); + + goto err__send_pkt_raw_data; + } + + pkt_size = sizeof(pkt->cmd) + sizeof(pkt->len) + pkt->len; + + send_ret = send(client_fd, pkt, pkt_size, 0); + _D("send(%d) : %d / %d", client_fd, send_ret, pkt_size); + + if (send_ret == -1) + { + _E("send error!"); + + goto err__send_pkt_raw_data; + } + else if (send_ret != pkt_size) + { + _E("send byte fail!"); + + goto err__send_pkt_raw_data; + } + + return 0; + +err__send_pkt_raw_data: + + return -1; +} + +int __set_background_cgroup(int flag, int ui_pid, int web_pid) +{ + int i, fd; + char* filename; + char pid_buff[8]; + int pids[2]; + + if (ui_pid <= 0) { + return -1; + } + + pids[0] = ui_pid; + pids[1] = web_pid; + + if (flag) { + filename = "/sys/fs/cgroup/cpu/background/cgroup.procs"; + } else { + filename = "/sys/fs/cgroup/cpu/cgroup.procs"; + } + + fd = open(filename, O_WRONLY | O_CLOEXEC); + if (fd < 0) { + _D("failed to open sysfs"); + return -1; + } + + for (i = 0; i < 2; i++) { + if (!pids[i]) { + continue; + } + + sprintf(pid_buff, "%d", pids[i]); + if (write(fd, pid_buff, 8) < 0) { + _D("failed to write '%s' (%s); policy=%d", pid_buff, strerror(errno), flag); + continue; + } + } + + close(fd); + return 0; +} diff --git a/src/wrt-launchpad-daemon/src/simple_util.c b/src/wrt-launchpad-daemon/src/simple_util.c new file mode 100644 index 0000000..f45f945 --- /dev/null +++ b/src/wrt-launchpad-daemon/src/simple_util.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "simple_util.h" + +#define BINSH_NAME "/bin/sh" +#define BINSH_SIZE 7 + +#define PROC_STAT_GID_POS 5 + +static inline int __read_proc(const char *path, char *buf, int size); +static inline int __find_pid_by_cmdline(const char *dname, + const char *cmdline, void *priv); +static inline int __get_pgid_from_stat(int pid); + +static inline int __read_proc(const char *path, char *buf, int size) +{ + int fd; + int ret; + + if (buf == NULL || path == NULL) { + return -1; + } + + fd = open(path, O_RDONLY); + if (fd < 0) { + return -1; + } + + ret = read(fd, buf, size - 1); + if (ret <= 0) { + close(fd); + return -1; + } else { + buf[ret] = 0; + } + + close(fd); + + return ret; +} + +static inline int __find_pid_by_cmdline(const char *dname, + const char *cmdline, void *priv) +{ + char *apppath; + int pid = 0; + + apppath = (char *)priv; + if (strncmp(cmdline, apppath, MAX_LOCAL_BUFSZ - 1) == 0) { + pid = atoi(dname); + if (pid != getpgid(pid)) { + pid = 0; + } + } + + return pid; +} + +int __proc_iter_cmdline( + int (*iterfunc)(const char *dname, const char *cmdline, void *priv), + void *priv) +{ + DIR *dp; + struct dirent dentry; + struct dirent *result; + int pid; + int ret; + char buf[MAX_LOCAL_BUFSZ]; + + dp = opendir("/proc"); + if (dp == NULL) { + return -1; + } + + if (iterfunc == NULL) { + iterfunc = __find_pid_by_cmdline; + } + + while (readdir_r(dp, &dentry, &result) == 0 && result != NULL) { + if (!isdigit(dentry.d_name[0])) { + continue; + } + + snprintf(buf, sizeof(buf), "/proc/%s/cmdline", dentry.d_name); + ret = __read_proc(buf, buf, sizeof(buf)); + if (ret <= 0) { + continue; + } + + /* support app launched by shell script*/ + if (strncmp(buf, BINSH_NAME, BINSH_SIZE) == 0) { + pid = + iterfunc(dentry.d_name, &buf[BINSH_SIZE + 1], + priv); + } else { + pid = iterfunc(dentry.d_name, buf, priv); + } + + if (pid > 0) { + closedir(dp); + return pid; + } + } + + closedir(dp); + return -1; +} + +char *__proc_get_cmdline_bypid(int pid) +{ + char buf[MAX_LOCAL_BUFSZ]; + int ret; + + snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid); + ret = __read_proc(buf, buf, sizeof(buf)); + if (ret <= 0) { + return NULL; + } + + /* support app launched by shell script*/ + if (strncmp(buf, BINSH_NAME, BINSH_SIZE) == 0) { + return strdup(&buf[BINSH_SIZE + 1]); + } else { + return strdup(buf); + } +} + +static inline int __get_pgid_from_stat(int pid) +{ + char buf[MAX_LOCAL_BUFSZ]; + char *str = NULL; + int ret; + int i; + int count = 0; + + if (pid <= 1) { + return -1; + } + + snprintf(buf, sizeof(buf), "/proc/%d/stat", pid); + ret = __read_proc(buf, buf, sizeof(buf)); + if (ret < 0) { + return -1; + } + + for (i = 0; i < (ret - 1); i++) { + if (buf[i] == ' ') { + count++; + if (count == PROC_STAT_GID_POS - 1) { + str = &(buf[i + 1]); + } else if (count == PROC_STAT_GID_POS) { + buf[i] = 0; + break; + } + } + } + + if (count == PROC_STAT_GID_POS && str != NULL) { + pid = atoi(str); + } else { + pid = -1; + } + + return pid; +} + +int __proc_iter_pgid(int pgid, int (*iterfunc)(int pid, void *priv), + void *priv) +{ + DIR *dp; + struct dirent dentry; + struct dirent *result; + int _pgid; + int ret = -1; + + dp = opendir("/proc"); + if (dp == NULL) { + return -1; + } + + while (readdir_r(dp, &dentry, &result) == 0 && result != NULL) { + if (!isdigit(dentry.d_name[0])) { + continue; + } + + _pgid = __get_pgid_from_stat(atoi(dentry.d_name)); + if (pgid == _pgid) { + ret = iterfunc(atoi(dentry.d_name), priv); + if (ret >= 0) { + break; + } + } + } + + closedir(dp); + return ret; +} + diff --git a/src/wrt-launchpad-daemon/wrt_launchpad_daemon.map b/src/wrt-launchpad-daemon/wrt_launchpad_daemon.map new file mode 100644 index 0000000..253051a --- /dev/null +++ b/src/wrt-launchpad-daemon/wrt_launchpad_daemon.map @@ -0,0 +1,19 @@ +{ + global: + main; + _Jv_RegisterClasses; + __bss_end__; + __bss_start; + __bss_start__; + __cxa_finalize; + __end__; + __gmon_start__; + _bss_end__; + _edata; + _end; + _fini; + _init; + pthread_cancel; + local: *; +}; + diff --git a/systemd/wrt_launchpad_daemon.service b/systemd/wrt_launchpad_daemon.service new file mode 100644 index 0000000..f711870 --- /dev/null +++ b/systemd/wrt_launchpad_daemon.service @@ -0,0 +1,14 @@ +[Unit] +Description=Start the wrt_launchpad_daemon +After=launchpad-preload.service + +[Service] +EnvironmentFile=/run/tizen-mobile-env +ExecStart=/usr/bin/wrt_launchpad_daemon " " +KillSignal=SIGKILL +TimeoutStopSec=3s +Restart=always +RestartSec=0 + +[Install] +WantedBy=multi-user.target diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..da45ba9 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,19 @@ +# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Karol Pawlowski (k.pawlowski@samsung.com) +# + +ADD_SUBDIRECTORY(widgets) diff --git a/tests/widgets/CMakeLists.txt b/tests/widgets/CMakeLists.txt new file mode 100644 index 0000000..3037631 --- /dev/null +++ b/tests/widgets/CMakeLists.txt @@ -0,0 +1,83 @@ +# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Karol Pawlowski (k.pawlowski@samsung.com) +# + +# TODO cleanup dependencies +PKG_CHECK_MODULES(COMMON_LIB_PKGS + dbus-1 + libpcrecpp + dpl-efl + dpl-test-efl + dpl-utils-efl + dpl-wrt-dao-ro + dpl-event-efl + wrt-plugins-widgetdb + glib-2.0 + gthread-2.0 + ewebkit2 + edje + ecore + ecore-x + ecore-imf + ecore-ipc + ecore-evas + ecore-file + ecore-input + evas + eina + elementary + vconf + aul + libidn + libiri + REQUIRED + ) + +INCLUDE(CMakeUtils.txt) + +pkg_search_module(dpl REQUIRED dpl-efl) +pkg_search_module(dpl-test REQUIRED dpl-test-efl) + +SET(WRT_TEST_LIBRARY "wrt-tests-libs") + +include_directories( + ${dpl_INCLUDE_DIRS} + ${dpl-test_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/common + ${PROJECT_SOURCE_DIR}/src/view + ${WRT_API_NEW_INCLUDES} +) + +ADD_SUBDIRECTORY(files) +ADD_SUBDIRECTORY(common) + +SET(TESTS_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/TestInit.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TestCases.cpp +) + +SET(TESTS_TARGET "wrt-tests-general") + +WRT_TEST_BUILD(${TESTS_TARGET} ${TESTS_SOURCES}) +WRT_TEST_INSTALL(${TESTS_TARGET}) +target_link_libraries(${TESTS_TARGET} + ${dpl_LIBRARIES} + ${dpl-test_LIBRARIES} + ${WRT_TEST_LIBRARY} + ${TARGET_CORE_MODULE_LIB} + ${COMMON_LIB_PKGS_LIBRARIES} +) diff --git a/tests/widgets/CMakeUtils.txt b/tests/widgets/CMakeUtils.txt new file mode 100644 index 0000000..6af08ff --- /dev/null +++ b/tests/widgets/CMakeUtils.txt @@ -0,0 +1,184 @@ +# @file CMakeUtils.txt +# @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) +# @author Pawel Sikorski (p.sikorski@samsung.com) +# @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) +# @version 1.0 +# @brief +# + +# +# Discovers target's INCLUDE_DIRECTORIES and LINK_DIRECTORIES. +# This is done by retrieving the directory target was built in and +# fetching appropriate properties of that directory. +FUNCTION(WRT_INTROSPECT_TARGET PREFIX TARGET_NAME) + GET_TARGET_PROPERTY(LOCATION ${TARGET_NAME} LOCATION) + IF(${LOCATION} STREQUAL "LOCATION-NOTFOUND") + MESSAGE(FATAL_ERROR "Target '${TARGET_NAME}' introspection failed") + ELSE(${LOCATION} STREQUAL "LOCATION-NOTFOUND") + STRING(FIND ${LOCATION} "/" LAST_SLASH_POSITION REVERSE) + STRING(SUBSTRING ${LOCATION} 0 ${LAST_SLASH_POSITION} LOCATION) + + GET_DIRECTORY_PROPERTY(INCLUDE_DIRS DIRECTORY ${LOCATION} INCLUDE_DIRECTORIES) + SET("${PREFIX}_INCLUDE_DIRS" ${INCLUDE_DIRS} PARENT_SCOPE) + + GET_DIRECTORY_PROPERTY(LIBRARY_DIRS DIRECTORY ${LOCATION} LINK_DIRECTORIES) + SET("${PREFIX}_LIBRARY_DIRS" ${LIBRARY_DIRS} PARENT_SCOPE) + ENDIF(${LOCATION} STREQUAL "LOCATION-NOTFOUND") +ENDFUNCTION(WRT_INTROSPECT_TARGET) + +FUNCTION(WRT_TEST_LIBRARY) + SET_PROPERTY(GLOBAL APPEND PROPERTY COMMON_TESTS_LIBRARY ${ARGV}) +ENDFUNCTION(WRT_TEST_LIBRARY) + +# +# Replacement functions for standard (w/o "WRT_" prefix) CMake functions. +# They store supplied arguments in global properties to assign them to tests. +# Anything added with this functions is used by all targets that are built with +# WRT_TEST_BUILD function. + +# +# Appends directories to global property TESTS_INCLUDE_DIRS which is +# then read by WRT_TEST_BUILD and its content is forwarded to +# command INCLUDE_DIRECTORIES() (for all targets). +FUNCTION(WRT_INCLUDE_DIRECTORIES) + SET_PROPERTY(GLOBAL APPEND PROPERTY TESTS_INCLUDE_DIRS ${ARGV}) +ENDFUNCTION(WRT_INCLUDE_DIRECTORIES) + +# +# Appends directories to global property TESTS_LIBRARY_DIRS which is +# then read by WRT_TEST_BUILD and its content is forwarded to +# command LINK_DIRECTORIES() (for all targets). +FUNCTION(WRT_LINK_DIRECTORIES) + SET_PROPERTY(GLOBAL APPEND PROPERTY TESTS_LIBRARY_DIRS ${ARGV}) +ENDFUNCTION(WRT_LINK_DIRECTORIES) + +# +# Appends directories to global property TESTS_LIBRARIES which is +# then read by WRT_TEST_BUILD and its content is forwarded to +# command TARGET_LINK_LIBRARIES() (for all targets). +FUNCTION(WRT_TARGET_LINK_LIBRARIES) + SET_PROPERTY(GLOBAL APPEND PROPERTY TESTS_LIBRARIES ${ARGV}) +ENDFUNCTION(WRT_TARGET_LINK_LIBRARIES) + +# +# Convenience method that fills TESTS_INCLUDE_DIRS, TESTS_LIBRARY_DIRS +# and TESTS_LIBRARIES with values discovered from introspecting supplied +# targets. +# Function takes arbitrary number of targets. +FUNCTION(WRT_ADD_INTERNAL_DEPENDENCIES) + FOREACH(DEPENDENCY ${ARGV}) + WRT_INTROSPECT_TARGET(prefix ${DEPENDENCY}) + WRT_INCLUDE_DIRECTORIES(${prefix_INCLUDE_DIRS}) + WRT_LINK_DIRECTORIES(${prefix_LIBRARY_DIRS}) + WRT_TARGET_LINK_LIBRARIES(${DEPENDENCY}) + ENDFOREACH(DEPENDENCY) +ENDFUNCTION(WRT_ADD_INTERNAL_DEPENDENCIES) + + +# +# Replacement functions for standard (w/o "WRT_" prefix) CMake functions. +# They store supplied arguments in global properties to assign them to specific +# tests. Properties names are based on the test target name. +# Anything added with this functions is used only by the specified target that +# is built with WRT_TEST_BUILD function. + +# +# Appends directories to global property ${TARGET_NAME}_INCLUDE_DIRS +# which is then read by WRT_TEST_BUILD and its content is forwarded to +# command INCLUDE_DIRECTORIES() (for specified target). +FUNCTION(WRT_TEST_INCLUDE_DIRECTORIES TARGET_NAME) + SET_PROPERTY(GLOBAL APPEND PROPERTY ${TARGET_NAME}_INCLUDE_DIRS ${ARGN}) +ENDFUNCTION(WRT_TEST_INCLUDE_DIRECTORIES) + +# +# Appends directories to global property ${TARGET_NAME}_LIBRARY_DIRS +# which is then read by WRT_TEST_BUILD and its content is forwarded to +# command LINK_DIRECTORIES() (for specified target). +FUNCTION(WRT_TEST_LINK_DIRECTORIES TARGET_NAME) + SET_PROPERTY(GLOBAL APPEND PROPERTY ${TARGET_NAME}_LIBRARY_DIRS ${ARGN}) +ENDFUNCTION(WRT_TEST_LINK_DIRECTORIES) + +# +# Appends directories to global property ${TARGET_NAME}_LIBRARIES +# which is then read by WRT_TEST_BUILD and its content is forwarded to +# command TARGET_LINK_LIBRARIES() (for specified target). +FUNCTION(WRT_TEST_TARGET_LINK_LIBRARIES TARGET_NAME) + SET_PROPERTY(GLOBAL APPEND PROPERTY ${TARGET_NAME}_LIBRARIES ${ARGN}) +ENDFUNCTION(WRT_TEST_TARGET_LINK_LIBRARIES) + +# +# Convenience method that fills ${TARGET_NAME}_INCLUDE_DIRS, +# ${TARGET_NAME}_LIBRARY_DIRS and ${TARGET_NAME}_LIBRARIES with +# values discovered from introspecting supplied targets. +# Function takes arbitrary number of targets. +FUNCTION(WRT_TEST_ADD_INTERNAL_DEPENDENCIES TARGET_NAME) + FOREACH(DEPENDENCY ${ARGN}) + WRT_INTROSPECT_TARGET(prefix ${DEPENDENCY}) + WRT_TEST_INCLUDE_DIRECTORIES(${TARGET_NAME} ${prefix_INCLUDE_DIRS}) + WRT_TEST_LINK_DIRECTORIES(${TARGET_NAME} ${prefix_LIBRARY_DIRS}) + WRT_TEST_TARGET_LINK_LIBRARIES(${TARGET_NAME} ${DEPENDENCY}) + ENDFOREACH(DEPENDENCY) +ENDFUNCTION(WRT_TEST_ADD_INTERNAL_DEPENDENCIES) + +# Functions used to build test targets (proper sources, includes, libs are +# added automatically) +FUNCTION(WRT_TEST_BUILD TARGET_NAME) + SET(SOURCES "${ARGN}") + ADD_EXECUTABLE("${TARGET_NAME}" ${SOURCES}) + + # get include dirs global property + GET_PROPERTY(INCLUDE_DIRS GLOBAL PROPERTY TESTS_INCLUDE_DIRS) + GET_PROPERTY(TEST_INCLUDE_DIRS GLOBAL PROPERTY ${TARGET_NAME}_INCLUDE_DIRS) + INCLUDE_DIRECTORIES( + ${INCLUDE_DIRS} + ${TEST_INCLUDE_DIRS} + ) + + # get library dirs global property + GET_PROPERTY(LIBRARY_DIRS GLOBAL PROPERTY TESTS_LIBRARY_DIRS) + GET_PROPERTY(TEST_LIBRARY_DIRS GLOBAL PROPERTY ${TARGET_NAME}_LIBRARY_DIRS) + LINK_DIRECTORIES( + ${LIBRARY_DIRS} + ${TEST_LIBRARY_DIRS} + ) + + # get link libraries global property + GET_PROPERTY(LINK_LIBRARIES GLOBAL PROPERTY TESTS_LIBRARIES) + GET_PROPERTY(TEST_LIBRARIES GLOBAL PROPERTY ${TARGET_NAME}_LIBRARIES) + TARGET_LINK_LIBRARIES("${TARGET_NAME}" + ${LINK_LIBRARIES} + ${TEST_LIBRARIES} + ) + SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES + COMPILE_DEFINITIONS LOG_TAG="${LOG_TAG}") +ENDFUNCTION(WRT_TEST_BUILD) + +FUNCTION(WRT_TEST_INSTALL) + SET_TARGET_PROPERTIES(${ARGV} PROPERTIES + BUILD_WITH_INSTALL_RPATH ON + INSTALL_RPATH_USE_LINK_PATH ON + ) + INSTALL(TARGETS ${ARGV} + DESTINATION bin + PERMISSIONS OWNER_READ + OWNER_WRITE + OWNER_EXECUTE + GROUP_READ + GROUP_EXECUTE + WORLD_READ + WORLD_EXECUTE + ) +ENDFUNCTION(WRT_TEST_INSTALL) + +# Takes arbitrary number of arguments and concatenates them using ':' character. +# Rationale: +# CMake list when converted to a string is joined with ';' character. However, +# GCC takes strings with multiple elements separated with ':' (e.g. list of +# paths). Used typically when generating DB schemas with ORM mechanism. +FUNCTION(WRT_CONVERT_TO_GCC_LIST OUTPUT_VARIABLE) + FOREACH(ITEM ${ARGN}) + LIST(APPEND ITEMS ${ITEM}) + ENDFOREACH(ITEM) + STRING(REPLACE ";" ":" OUTPUT "${ITEMS}") + SET("${OUTPUT_VARIABLE}" "${OUTPUT}" PARENT_SCOPE) +ENDFUNCTION(WRT_CONVERT_TO_GCC_LIST) diff --git a/tests/widgets/TestCases.cpp b/tests/widgets/TestCases.cpp new file mode 100644 index 0000000..1cc92ba --- /dev/null +++ b/tests/widgets/TestCases.cpp @@ -0,0 +1,1321 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 TestCases.cpp + * @author Karol Pawłowski (k.pawlowski@samsung.com) + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @version 1.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace { + +struct Result { + bool m_exc; + bool m_exd; + bool m_exs; + std::string message; + Result(bool exc = false, bool exd = false, bool exs = false) + : m_exc(exc), m_exd(exd), m_exs(exs) {} +}; + +} + +RUNNER_TEST_GROUP_INIT(RunnableWidgetObjectState) + +//for call methods to get starting state or do clean up after test +#define CALL_TESTER( ARGUMENT ) \ + tester.perform##ARGUMENT(); \ + +//for performing test and catch excpeted and unexpected exceptions +#define RUNNABLE_TESTER( ARGUMENT ) \ + Result res; \ + Try \ + { \ + LogDebug("perform start"); \ + CALL_TESTER( ARGUMENT ) \ + LogDebug("perform stop"); \ + } \ + Catch(WRT::IRunnableWidgetObject::MethodInvocationForbidden) \ + { \ + res.m_exc = true; \ + res.message = _rethrown_exception.DumpToString(); \ + res.message += "(MethodInvocationForbidden)"; \ + } \ + Catch(DPL::Exception) \ + { \ + res.m_exd = true; \ + res.message = _rethrown_exception.DumpToString(); \ + res.message += "(DPL::Exception)"; \ + } \ + Catch(std::exception) \ + { \ + res.m_exs = true; \ + res.message = _rethrown_exception.what(); \ + res.message += "(std::exception)"; \ + } \ + + +//check of function success +#define SHOULD_BE_ALLOWED( ARGUMENT ) \ + { \ + RUNNABLE_TESTER( ARGUMENT ) \ + if(res.m_exc || res.m_exs || res.m_exd) \ + { \ + ok = false; \ + reason = "Exception throwed when not expected in "; \ + reason += __FUNCTION__; \ + reason += " calling "; \ + reason += #ARGUMENT; \ + reason += "message "; \ + reason += res.message; \ + } \ + } \ + + +//check of function failure +#define SHOULD_BE_FORBIDDEN( ARGUMENT ) \ + { \ + RUNNABLE_TESTER( ARGUMENT ) \ + if(!res.m_exc) \ + { \ + ok = false; \ + reason = "MethodInvocationForbidden should be throwed"; \ + reason += " when calling "; \ + reason += #ARGUMENT; \ + } \ + } \ + + +//marcos for hiding lamdba expression and and presenting it as if it is test body +#define RUNNABLE_TESTER_START \ + bool ok = true; \ + std::string reason; \ + auto func = [&ok,&reason](RunnableObjectStateTester & tester) \ + { \ + Try \ + { \ + + +#define RUNNABLE_TESTER_STOP \ + } \ + Catch(DPL::Exception) \ + { \ + ok = false; \ + reason = _rethrown_exception.DumpToString(); \ + reason += "(DPL::Exception)"; \ + } \ + Catch(std::exception) \ + { \ + reason = "Unknown exception"; \ + ok = false; \ + } \ + }; \ + RunnableObjectStateTester & instance = RunnableObjectStateTesterSingleton::Instance(); \ + instance.runTest(func); \ + RUNNER_ASSERT_MSG(ok, reason); \ + +//Initial +/* +Name: state_Initial_CheckBeforeLaunch +Description: Checks if RunnableWidgetObject + correctly reacts to calling method CheckBeforeLaunch in state Initial +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Initial_CheckBeforeLaunch) +{ + RUNNABLE_TESTER_START + SHOULD_BE_FORBIDDEN( CheckBeforeLaunch ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Initial_PrepareView +Description: Checks if RunnableWidgetObject + correctly reacts to calling method PrepareView in state Initial +Expected: Transistion should pass +*/ +RUNNER_TEST(state_Initial_PrepareView) +{ + RUNNABLE_TESTER_START + SHOULD_BE_ALLOWED( PrepareView ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Initial_Show +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Show in state Initial +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Initial_Show) +{ + RUNNABLE_TESTER_START + SHOULD_BE_FORBIDDEN( Show ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Initial_Hide +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Hide in state Initial +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Initial_Hide) +{ + RUNNABLE_TESTER_START + SHOULD_BE_FORBIDDEN( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Initial_Suspend +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Suspend in state Initial +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Initial_Suspend) +{ + RUNNABLE_TESTER_START + SHOULD_BE_FORBIDDEN( Suspend ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Initial_Resume +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Resume in state Initial +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Initial_Resume) +{ + RUNNABLE_TESTER_START + SHOULD_BE_FORBIDDEN( Resume ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Initial_Reset +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Reset in state Initial +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Initial_Reset) +{ + RUNNABLE_TESTER_START + SHOULD_BE_FORBIDDEN( Reset ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Initial_GetCurrentWebview +Description: Checks if RunnableWidgetObject + correctly reacts to calling method GetCurrentWebview in state Initial +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Initial_GetCurrentWebview) +{ + RUNNABLE_TESTER_START + SHOULD_BE_FORBIDDEN( GetCurrentWebview ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Initial_SetUserDelegates +Description: Checks if RunnableWidgetObject + correctly reacts to calling method SetUserDelegates in state Initial +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Initial_SetUserDelegates) +{ + RUNNABLE_TESTER_START + SHOULD_BE_FORBIDDEN( SetUserDelegates ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Initial_Backward +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Backward in state Initial +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Initial_Backward) +{ + RUNNABLE_TESTER_START + SHOULD_BE_FORBIDDEN( Backward ); + RUNNABLE_TESTER_STOP +} + + +//Prepared +/* +Name: state_Prepared_CheckBeforeLaunch +Description: Checks if RunnableWidgetObject + correctly reacts to calling method CheckBeforeLaunch in state Prepared +Expected: Transistion should pass +*/ +RUNNER_TEST(state_Prepared_CheckBeforeLaunch) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + SHOULD_BE_ALLOWED( CheckBeforeLaunch ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Prepared_PrepareView +Description: Checks if RunnableWidgetObject + correctly reacts to calling method PrepareView in state Prepared +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Prepared_PrepareView) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + SHOULD_BE_FORBIDDEN( PrepareView ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Prepared_Show +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Show in state Prepared +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Prepared_Show) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + SHOULD_BE_FORBIDDEN( Show ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Prepared_Hide +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Hide in state Prepared +Expected: Transistion should pass +*/ +RUNNER_TEST(state_Prepared_Hide) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + SHOULD_BE_ALLOWED( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Prepared_Suspend +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Suspend in state Prepared +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Prepared_Suspend) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + SHOULD_BE_FORBIDDEN( Suspend ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Prepared_Resume +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Resume in state Prepared +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Prepared_Resume) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + SHOULD_BE_FORBIDDEN( Resume ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Prepared_Reset +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Reset in state Prepared +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Prepared_Reset) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + SHOULD_BE_FORBIDDEN( Reset ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Prepared_GetCurrentWebview +Description: Checks if RunnableWidgetObject + correctly reacts to calling method GetCurrentWebview in state Prepared +Expected: Transistion should pass +*/ +RUNNER_TEST(state_Prepared_GetCurrentWebview) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + SHOULD_BE_ALLOWED( GetCurrentWebview ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Prepared_SetUserDelegates +Description: Checks if RunnableWidgetObject + correctly reacts to calling method SetUserDelegates in state Prepared +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Prepared_SetUserDelegates) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + SHOULD_BE_FORBIDDEN( SetUserDelegates ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Prepared_Backward +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Backward in state Prepared +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Prepared_Backward) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + SHOULD_BE_FORBIDDEN( Backward ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +//SecChecked +/* +Name: state_SecChecked_CheckBeforeLaunch +Description: Checks if RunnableWidgetObject + correctly reacts to calling method CheckBeforeLaunch in state SecChecked +Expected: Transistion should fail +*/ +RUNNER_TEST(state_SecChecked_CheckBeforeLaunch) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + SHOULD_BE_FORBIDDEN( CheckBeforeLaunch ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_SecChecked_PrepareView +Description: Checks if RunnableWidgetObject + correctly reacts to calling method PrepareView in state SecChecked +Expected: Transistion should fail +*/ +RUNNER_TEST(state_SecChecked_PrepareView) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + SHOULD_BE_FORBIDDEN( PrepareView ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_SecChecked_Show +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Show in state SecChecked +Expected: Transistion should pass +*/ +RUNNER_TEST(state_SecChecked_Show) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( SetUserDelegates ); + SHOULD_BE_ALLOWED( Show ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_SecChecked_Hide +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Hide in state SecChecked +Expected: Transistion should pass +*/ +RUNNER_TEST(state_SecChecked_Hide) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + SHOULD_BE_ALLOWED( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_SecChecked_Suspend +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Suspend in state SecChecked +Expected: Transistion should fail +*/ +RUNNER_TEST(state_SecChecked_Suspend) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + SHOULD_BE_FORBIDDEN( Suspend ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_SecChecked_Resume +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Resume in state SecChecked +Expected: Transistion should fail +*/ +RUNNER_TEST(state_SecChecked_Resume) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + SHOULD_BE_FORBIDDEN( Resume ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_SecChecked_Reset +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Reset in state SecChecked +Expected: Transistion should fail +*/ +RUNNER_TEST(state_SecChecked_Reset) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + SHOULD_BE_FORBIDDEN( Reset ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_SecChecked_GetCurrentWebview +Description: Checks if RunnableWidgetObject + correctly reacts to calling method GetCurrentWebview in state SecChecked +Expected: Transistion should pass +*/ +RUNNER_TEST(state_SecChecked_GetCurrentWebview) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + SHOULD_BE_ALLOWED( GetCurrentWebview ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_SecChecked_SetUserDelegates +Description: Checks if RunnableWidgetObject + correctly reacts to calling method SetUserDelegates in state SecChecked +Expected: Transistion should pass +*/ +RUNNER_TEST(state_SecChecked_SetUserDelegates) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + SHOULD_BE_ALLOWED( SetUserDelegates ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_SecChecked_Backward +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Backward in state SecChecked +Expected: Transistion should fail +*/ +RUNNER_TEST(state_SecChecked_Backward) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + SHOULD_BE_FORBIDDEN( Backward ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +//Showed +/* +Name: state_Showed_CheckBeforeLaunch +Description: Checks if RunnableWidgetObject + correctly reacts to calling method CheckBeforeLaunch in state Showed +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Showed_CheckBeforeLaunch) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + SHOULD_BE_FORBIDDEN( CheckBeforeLaunch ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Showed_PrepareView +Description: Checks if RunnableWidgetObject + correctly reacts to calling method PrepareView in state Showed +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Showed_PrepareView) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + SHOULD_BE_FORBIDDEN( PrepareView ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Showed_Show +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Show in state Showed +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Showed_Show) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + SHOULD_BE_FORBIDDEN( Show ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Showed_Hide +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Hide in state Showed +Expected: Transistion should pass +*/ +RUNNER_TEST(state_Showed_Hide) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + SHOULD_BE_ALLOWED( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Showed_Suspend +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Suspend in state Showed +Expected: Transistion should pass +*/ +RUNNER_TEST(state_Showed_Suspend) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + SHOULD_BE_ALLOWED( Suspend ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Showed_Resume +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Resume in state Showed +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Showed_Resume) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + SHOULD_BE_FORBIDDEN( Resume ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Showed_Reset +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Reset in state Showed +Expected: Transistion should pass +*/ +RUNNER_TEST(state_Showed_Reset) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + SHOULD_BE_ALLOWED( Reset ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Showed_GetCurrentWebview +Description: Checks if RunnableWidgetObject + correctly reacts to calling method GetCurrentWebview in state Showed +Expected: Transistion should pass +*/ +RUNNER_TEST(state_Showed_GetCurrentWebview) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + SHOULD_BE_ALLOWED( GetCurrentWebview ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Showed_SetUserDelegates +Description: Checks if RunnableWidgetObject + correctly reacts to calling method SetUserDelegates in state Showed +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Showed_SetUserDelegates) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + SHOULD_BE_FORBIDDEN( SetUserDelegates ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Showed_Backward +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Backward in state Showed +Expected: Transistion should pass +*/ +RUNNER_TEST(state_Showed_Backward) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + SHOULD_BE_ALLOWED( Backward ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +//Suspended +/* +Name: state_Suspended_CheckBeforeLaunch +Description: Checks if RunnableWidgetObject + correctly reacts to calling method CheckBeforeLaunch in state Suspended +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Suspended_CheckBeforeLaunch) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + SHOULD_BE_FORBIDDEN( CheckBeforeLaunch ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Suspended_PrepareView +Description: Checks if RunnableWidgetObject + correctly reacts to calling method PrepareView in state Suspended +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Suspended_PrepareView) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + SHOULD_BE_FORBIDDEN( PrepareView ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Suspended_Show +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Show in state Suspended +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Suspended_Show) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + SHOULD_BE_FORBIDDEN( Show ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Suspended_Hide +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Hide in state Suspended +Expected: Transistion should pass +*/ +RUNNER_TEST(state_Suspended_Hide) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + SHOULD_BE_ALLOWED( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Suspended_Suspend +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Suspend in state Suspended +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Suspended_Suspend) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + SHOULD_BE_FORBIDDEN( Suspend ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Suspended_Resume +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Resume in state Suspended +Expected: Transistion should pass +*/ +RUNNER_TEST(state_Suspended_Resume) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + SHOULD_BE_ALLOWED( Resume ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Suspended_Reset +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Reset in state Suspended +Expected: Transistion should pass +*/ +RUNNER_TEST(state_Suspended_Reset) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + SHOULD_BE_ALLOWED( Reset ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Suspended_GetCurrentWebview +Description: Checks if RunnableWidgetObject + correctly reacts to calling method GetCurrentWebview in state Suspended +Expected: Transistion should pass +*/ +RUNNER_TEST(state_Suspended_GetCurrentWebview) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + SHOULD_BE_ALLOWED( GetCurrentWebview ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Suspended_SetUserDelegates +Description: Checks if RunnableWidgetObject + correctly reacts to calling method SetUserDelegates in state Suspended +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Suspended_SetUserDelegates) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + SHOULD_BE_FORBIDDEN( SetUserDelegates ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Suspended_Backward +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Backward in state Suspended +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Suspended_Backward) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + SHOULD_BE_FORBIDDEN( Backward ); + CALL_TESTER( Hide ); + RUNNABLE_TESTER_STOP +} + +//Hidden +/* +Name: state_Hidden_CheckBeforeLaunch +Description: Checks if RunnableWidgetObject + correctly reacts to calling method CheckBeforeLaunch in state Hidden +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Hidden_CheckBeforeLaunch) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + CALL_TESTER( Hide ); + SHOULD_BE_FORBIDDEN( CheckBeforeLaunch ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Hidden_PrepareView +Description: Checks if RunnableWidgetObject + correctly reacts to calling method PrepareView in state Hidden +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Hidden_PrepareView) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + CALL_TESTER( Hide ); + SHOULD_BE_FORBIDDEN( PrepareView ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Hidden_Show +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Show in state Hidden +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Hidden_Show) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + CALL_TESTER( Hide ); + SHOULD_BE_FORBIDDEN( Show ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Hidden_Hide +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Hide in state Hidden +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Hidden_Hide) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + CALL_TESTER( Hide ); + SHOULD_BE_FORBIDDEN( Hide ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Hidden_Suspend +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Suspend in state Hidden +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Hidden_Suspend) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + CALL_TESTER( Hide ); + SHOULD_BE_FORBIDDEN( Suspend ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Hidden_Resume +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Resume in state Hidden +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Hidden_Resume) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + CALL_TESTER( Hide ); + SHOULD_BE_FORBIDDEN( Resume ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Hidden_Reset +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Reset in state Hidden +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Hidden_Reset) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + CALL_TESTER( Hide ); + SHOULD_BE_FORBIDDEN( Reset ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Hidden_GetCurrentWebview +Description: Checks if RunnableWidgetObject + correctly reacts to calling method GetCurrentWebview in state Hidden +Expected: Transistion should pass +*/ +RUNNER_TEST(state_Hidden_GetCurrentWebview) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + CALL_TESTER( Hide ); + SHOULD_BE_ALLOWED( GetCurrentWebview ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Hidden_SetUserDelegates +Description: Checks if RunnableWidgetObject + correctly reacts to calling method SetUserDelegates in state Hidden +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Hidden_SetUserDelegates) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + CALL_TESTER( Hide ); + SHOULD_BE_FORBIDDEN( SetUserDelegates ); + RUNNABLE_TESTER_STOP +} + +/* +Name: state_Hidden_Backward +Description: Checks if RunnableWidgetObject + correctly reacts to calling method Backward in state Hidden +Expected: Transistion should fail +*/ +RUNNER_TEST(state_Hidden_Backward) +{ + RUNNABLE_TESTER_START + CALL_TESTER( PrepareView ); + CALL_TESTER( CheckBeforeLaunch ); + CALL_TESTER( Show ); + CALL_TESTER( Suspend ); + CALL_TESTER( Hide ); + SHOULD_BE_FORBIDDEN( Backward ); + RUNNABLE_TESTER_STOP +} + + +RUNNER_TEST_GROUP_INIT(CommandLineParameters) + + +struct PassAllParserPolicy +{ + static bool SkipLine(const std::vector & ) { return false; } + static bool Validate(std::shared_ptr > > &) { return true; } +}; + +struct ListTokenizerPolicy +{ + static std::string GetSeperators() { return " "; } + static bool SkipEmpty() { return true; } + static void PrepareValue(std::string & value) { DPL::Trim(value, " "); } + static bool TryAgainAtEnd(int) { return false; } +}; + +typedef DPL::VSReader LListReader; + +RUNNER_TEST(CommandLineParameters_ListWidgets) +{ + int status = system("wrt_reset_all.sh"); + RUNNER_ASSERT_MSG(WIFEXITED(status) == TRUE, "wrt_reset_all.sh not exited properly"); + RUNNER_ASSERT_MSG(WEXITSTATUS(status) == 0, "wrt_reset_all.sh failed"); + + //reset database connection + WrtDB::WrtDatabase::detachFromThread(); + WrtDB::WrtDatabase::attachToThreadRW(); + + std::string tizenId; + RUNNER_ASSERT(InstallerWrapper::install("/opt/share/widget/tests/general/minimal.wgt", tizenId) == InstallerWrapper::Success); + + try + { + DPL::ProcessPipe pipe(DPL::ProcessPipe::PipeErrorPolicy::OFF); + pipe.Open("DPL_USE_OLD_STYLE_LOGS=0 wrt-launcher -l"); + LListReader launcher(std::make_shared(&pipe)); + DPL::VSResultPtr result = launcher.ReadInput(); + pipe.Close(); + + RUNNER_ASSERT_MSG((*result)[2][0] == "1", " Wrong position number"); + RUNNER_ASSERT_MSG((*result)[2][1] == "Minimal", "Wrong name"); + RUNNER_ASSERT_MSG((*result)[2][2] == "1.0", "Wrong version"); + RUNNER_ASSERT_MSG((*result)[2][3] == "http://test.samsung.com/widget/minimalTest", "Wrong GUID"); + RUNNER_ASSERT_MSG((*result)[2][4] == "aHFQwMDkmC", "Wrong pkgID"); + RUNNER_ASSERT_MSG((*result)[2][5] == "aHFQwMDkmC.minimal", "Wrong appID"); + } + catch(...) + { + RUNNER_ASSERT(InstallerWrapper::uninstall(tizenId)); + throw; + } + RUNNER_ASSERT(InstallerWrapper::uninstall(tizenId)); +} + + +struct ResultTokenizerPolicy +{ + static std::string GetSeperators() { return ":"; } + static bool SkipEmpty() { return true; } + static void PrepareValue(std::string & value) { DPL::Trim(value, " "); } + static bool TryAgainAtEnd(int) { return false; } +}; + +typedef DPL::VSReader LResultReader; + +RUNNER_TEST(CommandLineParameters_SimpleLaunch) +{ + bool launched = false; + bool running = false; + bool stopped = false; + std::string tizenId; + RUNNER_ASSERT(InstallerWrapper::install("/opt/share/widget/tests/general/minimal.wgt", tizenId) == InstallerWrapper::Success); + + //start + { + DPL::ProcessPipe pipe(DPL::ProcessPipe::PipeErrorPolicy::OFF); + pipe.Open(std::string("DPL_USE_OLD_STYLE_LOGS=0 wrt-launcher -s ") + tizenId); + LResultReader launcher(std::make_shared(&pipe)); + DPL::VSResultPtr result = launcher.ReadInput(); + pipe.Close(); + + FOREACH(row, *result) + { + if(row->at(0) == "result") + { + if(row->at(1) == "launched") + { + launched = true; + break; + } + else + { + RUNNER_ASSERT(InstallerWrapper::uninstall(tizenId)); + RUNNER_ASSERT_MSG(false, "Launch failed"); + } + } + } + } + if(!launched) + { + RUNNER_ASSERT(InstallerWrapper::uninstall(tizenId)); + RUNNER_ASSERT_MSG(false, "Result not returned"); + } + + //is-running + { + DPL::ProcessPipe pipe(DPL::ProcessPipe::PipeErrorPolicy::OFF); + pipe.Open(std::string("DPL_USE_OLD_STYLE_LOGS=0 wrt-launcher -r ") + tizenId); + LResultReader launcher(std::make_shared(&pipe)); + DPL::VSResultPtr result = launcher.ReadInput(); + pipe.Close(); + + FOREACH(row, *result) + { + if(row->at(0) == "result") + { + if(row->at(1) == "running") + { + running = true; + break; + } + else + { + RUNNER_ASSERT(InstallerWrapper::uninstall(tizenId)); + RUNNER_ASSERT_MSG(false, "App launched but not running"); + } + } + } + } + if(!running) + { + RUNNER_ASSERT(InstallerWrapper::uninstall(tizenId)); + RUNNER_ASSERT_MSG(false, "Result not returned"); + } + + //stop + { + DPL::ProcessPipe pipe(DPL::ProcessPipe::PipeErrorPolicy::OFF); + pipe.Open(std::string("DPL_USE_OLD_STYLE_LOGS=0 wrt-launcher -k ") + tizenId); + LResultReader launcher(std::make_shared(&pipe)); + DPL::VSResultPtr result = launcher.ReadInput(); + pipe.Close(); + + FOREACH(row, *result) + { + if(row->at(0) == "result") + { + if(row->at(1) == "killed") + { + stopped = true; + break; + } + else + { + RUNNER_ASSERT(InstallerWrapper::uninstall(tizenId)); + RUNNER_ASSERT_MSG(false, "Stop failed"); + } + } + } + } + RUNNER_ASSERT(InstallerWrapper::uninstall(tizenId)); + if(stopped) + { + return; + } + RUNNER_ASSERT_MSG(false, "Result not returned"); +} + +RUNNER_TEST(CommandLineParameters_WebDebuggerPort) +{ + std::string tizenId; + RUNNER_ASSERT(InstallerWrapper::install("/opt/share/widget/tests/general/minimal.wgt", tizenId) == InstallerWrapper::Success); + + DPL::ProcessPipe pipe(DPL::ProcessPipe::PipeErrorPolicy::OFF); + pipe.Open(std::string("DPL_USE_OLD_STYLE_LOGS=0 wrt-launcher -d -t 5 -s ") + tizenId); + LResultReader launcher(std::make_shared(&pipe)); + DPL::VSResultPtr result = launcher.ReadInput(); + pipe.Close(); + + FOREACH(row, *result) + { + if(row->at(0) == "port") + { + int value = DPL::lexical_cast(row->at(1)); + if(value >= 1024 && value <= 65535) + { + RUNNER_ASSERT(InstallerWrapper::uninstall(tizenId)); + return; + } + else + { + RUNNER_ASSERT(InstallerWrapper::uninstall(tizenId)); + RUNNER_ASSERT_MSG(false, "Wrong port number"); + } + } + } + RUNNER_ASSERT(InstallerWrapper::uninstall(tizenId)); + RUNNER_ASSERT_MSG(false, "Port number not returned"); +} + diff --git a/tests/widgets/TestInit.cpp b/tests/widgets/TestInit.cpp new file mode 100644 index 0000000..b728f69 --- /dev/null +++ b/tests/widgets/TestInit.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 TestInit.cpp + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @version 1.0 + * @brief main for misc tests + */ + +#include +#include +#include + +int main (int argc, char *argv[]) +{ + LogDebug("Starting tests"); + + WrtDB::WrtDatabase::attachToThreadRW(); + int status = + DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); + WrtDB::WrtDatabase::detachFromThread(); + + return status; +} diff --git a/tests/widgets/common/CMakeLists.txt b/tests/widgets/common/CMakeLists.txt new file mode 100644 index 0000000..a41b284 --- /dev/null +++ b/tests/widgets/common/CMakeLists.txt @@ -0,0 +1,45 @@ +# Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Tomasz Iwanek (t.iwanek@samsung.com) +# @version 1.0 +# @brief +# + +SET(COMMON_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/include") + +WRT_TEST_LIBRARY(${WRT_TEST_LIBRARY}) + +WRT_INCLUDE_DIRECTORIES( + ${COMMON_LIB_PKGS_INCLUDE_DIRS} + ${COMMON_INCLUDES} + ${WRT_API_NEW_INCLUDES} + ) + +WRT_LINK_DIRECTORIES(${COMMON_LIB_PKGS_LIBRARY_DIRS}) +WRT_TARGET_LINK_LIBRARIES(${COMMON_LIB_PKGS_LIBRARIES}) + +SET(WRT_DETAIL_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/src/InstallerWrapper.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/RunnableObjectStateTester.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/mock/MockViewModule.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/mock/MockContextManager.cpp +) + +INCLUDE_DIRECTORIES(${COMMON_INCLUDES}) +INCLUDE_DIRECTORIES(${COMMON_LIB_PKGS_INCLUDE_DIRS}) +ADD_LIBRARY(${WRT_TEST_LIBRARY} STATIC ${WRT_DETAIL_SOURCES}) +SET_TARGET_PROPERTIES(${WRT_TEST_LIBRARY} PROPERTIES + COMPILE_DEFINITIONS LOG_TAG="${LOG_TAG}") diff --git a/tests/widgets/common/include/InstallerWrapper.h b/tests/widgets/common/include/InstallerWrapper.h new file mode 100644 index 0000000..7bce1cd --- /dev/null +++ b/tests/widgets/common/include/InstallerWrapper.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WRT_TESTS_W3C_TESTS_INSTALLER_WRAPPER_H +#define WRT_TESTS_W3C_TESTS_INSTALLER_WRAPPER_H + +#include + +namespace InstallerWrapper +{ + +typedef int InstallResult; +const InstallResult WrongWidgetPackage = -2; +const InstallResult OtherError = -1; +const InstallResult Success = 0; + +InstallResult install( + const std::string& path, + std::string& tizenId, + const std::string& user = ""); +bool uninstall(const std::string& tizenId); +bool uninstallByGuid(const std::string& guid); +/** + * @brief killWrtClients kills processes that matches 'wrt-client' + * @return True if any client was killed + */ +bool sigintWrtClients(); + +} + +#endif//WRT_TESTS_W3C_TESTS_INSTALLER_WRAPPER_H diff --git a/tests/widgets/common/include/RunnableObjectStateTester.h b/tests/widgets/common/include/RunnableObjectStateTester.h new file mode 100644 index 0000000..e76ab48 --- /dev/null +++ b/tests/widgets/common/include/RunnableObjectStateTester.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 RunnableObjectStateTester.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief Tester for RunnableWidgetObject's states + */ + +#ifndef WRT_EXTRA_AUTO_TESTS_COMMON_INCLUDE_RUNNABLE_OBJECT_STATE_TESTER_H +#define WRT_EXTRA_AUTO_TESTS_COMMON_INCLUDE_RUNNABLE_OBJECT_STATE_TESTER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +DECLARE_GENERIC_EVENT_0(NextStepEvent) + +class RunnableObjectStateTester : public DPL::ApplicationExt, + private DPL::Event::Controller::Type>, + public DPL::TaskDecl +{ +public: + typedef std::function Test; + + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CoreModuleFailure) + DECLARE_EXCEPTION_TYPE(Base, CallbackFailure) + + RunnableObjectStateTester(); + ~RunnableObjectStateTester(); + + void performCheckBeforeLaunch(); + void performPrepareView(); + + void performShow(); + void performHide(); + void performSuspend(); + void performResume(); + void performReset(); + + void performGetCurrentWebview(); + void performSetUserDelegates(); + void performBackward(); + + void performTest(); + + void runTest(Test func); + + void OnEventReceived(const NextStepEvent& /*event*/); + + void loadFinishCallback(Evas_Object* obj, void* eventInfo); + +private: + std::string m_handle; + WRT::RunnableWidgetObjectPtr m_widget; + Test m_func; + const std::string m_widgetPath; +}; + +typedef DPL::Singleton RunnableObjectStateTesterSingleton; + +#endif // WRT_EXTRA_AUTO_TESTS_COMMON_INCLUDE_RUNNABLE_OBJECT_STATE_TESTER_H diff --git a/tests/widgets/common/include/mock/MockContextManager.h b/tests/widgets/common/include/mock/MockContextManager.h new file mode 100644 index 0000000..c1734df --- /dev/null +++ b/tests/widgets/common/include/mock/MockContextManager.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 MockContextManager.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief Mock for view module + */ +#ifndef MOCKCONTEXTMANAGER_H +#define MOCKCONTEXTMANAGER_H + +#include + +class MockContextManager : public ViewModule::IContextManager +{ +public: + MockContextManager(const std::string& tizenAppId, + Ewk_Context* ewkContext, + ViewModule::IViewModulePtr viewModule); + virtual ~MockContextManager(); + Ewk_Context* getEwkContext() const; + void handleLowMemory(); +}; + +#endif // MOCKCONTEXTMANAGER_H diff --git a/tests/widgets/common/include/mock/MockViewModule.h b/tests/widgets/common/include/mock/MockViewModule.h new file mode 100644 index 0000000..ab437d4 --- /dev/null +++ b/tests/widgets/common/include/mock/MockViewModule.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 MockViewModule.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief Mock for view module + */ + +#ifndef MOCKVIEWMODULE_H +#define MOCKVIEWMODULE_H + +#include + +class MockViewModule : public ViewModule::IViewModule +{ +public: + MockViewModule(); + bool createView(Ewk_Context* context, Evas_Object* window); + void prepareView(WidgetModel *, const std::string &); + void showWidget(); + void hideWidget(); + void suspendWidget(); + void resumeWidget(); + void resetWidgetFromSuspend(); + void resetWidgetFromResume(); + void backward(); + void reloadStartPage(bool isbackground); + Evas_Object* getCurrentWebview(); + void fireJavascriptEvent(int event, void* data); + void setUserCallbacks(const WRT::UserDelegatesPtr& cbs); + void checkSyncMessageFromBundle( + const char* name, + const char* body, + char** returnData); + void checkAsyncMessageFromBundle( + const char* name, + const char* body); + void downloadData(const char* url); + void activateVibration(bool on, uint64_t time); +}; + +#endif // MOCKVIEWMODULE_H diff --git a/tests/widgets/common/src/InstallerWrapper.cpp b/tests/widgets/common/src/InstallerWrapper.cpp new file mode 100644 index 0000000..7f51931 --- /dev/null +++ b/tests/widgets/common/src/InstallerWrapper.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "InstallerWrapper.h" + +#include + +#include + +namespace +{ + +const std::string params = "DPL_USE_OLD_STYLE_LOGS=0 " + "DPL_USE_OLD_STYLE_PEDANTIC_LOGS=0 WRT_TEST_MODE=1 "; +const std::string installCmd = params + "wrt-installer -i "; +const std::string uninstallCmd = params + "wrt-installer -un "; +const std::string uninstallByGuidCmd = params + "wrt-installer -ug \""; +const std::string redirection = " 2>&1"; +const std::string INSTALLER_MESSAGE_ID_LINE = + "## wrt-installer : %s installation was successful.\n"; +const std::string INSTALLER_MESSSGE_START = "## wrt-installer : "; + +std::string getAndCutInstallerLogLine(std::string &src) +{ + size_t startIndex = src.find(INSTALLER_MESSSGE_START); + if (startIndex == std::string::npos) + { + LogWarning("Installer message can not be found"); + return std::string(); + } + size_t newLineIndex = src.find("\n", startIndex); + std::string line = src.substr(startIndex, newLineIndex - startIndex + 1); + src.erase(0, newLineIndex + 1); + return line; +} + +} + +namespace InstallerWrapper +{ + +InstallResult install( + const std::string& path, + std::string& tizenId, + const std::string& user) +{ + std::string msg; + + auto cmd = installCmd + path + redirection; + if(user.length()) //if other user should be used + { + cmd = "su " + user + " -c '" + cmd + "'"; + } + LogDebug("executing: " << cmd); + auto filehandle = popen(cmd.c_str(), "r"); + if (!filehandle) { + return OtherError; + } + + char buffer[1024] = ""; + while (fread_unlocked(buffer, sizeof(char), sizeof(buffer)/sizeof(char), + filehandle) > 0) + { + msg += buffer; + } + LogDebug(msg); + auto err = pclose(filehandle); + if (!WIFEXITED(err)) { + return OtherError; + } + if (0 != WEXITSTATUS(err)) { + if (1 == WEXITSTATUS(err)) { + return WrongWidgetPackage; + } + return OtherError; + } + + char* id = NULL; + std::string line; + + while ((line = getAndCutInstallerLogLine(msg)) != "") + { + if (line.find("successful") != std::string::npos) + { + id = new char[line.length()]; + int nr = sscanf(line.c_str(), INSTALLER_MESSAGE_ID_LINE.c_str(), id); + + if (1 != nr) + { + LogWarning("Can not read widget ID from message: " << line); + delete[] id; + return OtherError; + } + tizenId = id; + delete[] id; + if (tizenId != "plugin") + { + return Success; + } + } + } + + return OtherError; +} + +bool uninstall(const std::string& tizenId) +{ + std::string cmd = uninstallCmd + tizenId + " > /dev/null 2>/dev/null"; + LogDebug("executing: " << cmd); + return (system(cmd.c_str()) == EXIT_SUCCESS); +} + +bool uninstallByGuid(const std::string& guid) +{ + std::string cmd = uninstallByGuidCmd + guid + "\" > /dev/null 2>/dev/null"; + LogDebug("executing: " << cmd); + return (system(cmd.c_str()) == EXIT_SUCCESS); +} + +bool sigintWrtClients() +{ + return (system("pkill -2 wrt-client") == 0); +} + +} + diff --git a/tests/widgets/common/src/RunnableObjectStateTester.cpp b/tests/widgets/common/src/RunnableObjectStateTester.cpp new file mode 100644 index 0000000..704a2c3 --- /dev/null +++ b/tests/widgets/common/src/RunnableObjectStateTester.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 RunnableObjectStateTester.cpp + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief Tester for RunnableWidgetObject's states + */ + +#include "RunnableObjectStateTester.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +IMPLEMENT_SINGLETON(RunnableObjectStateTester) + +namespace { +const std::string widgetPathMnimal = "/opt/share/widget/tests/general/any.wgt"; +const int widgetInitializationTimeBounding = 3; +} + +RunnableObjectStateTester::RunnableObjectStateTester() + : DPL::ApplicationExt(1, NULL, "test-app"), + DPL::TaskDecl(this), + m_widgetPath(widgetPathMnimal) +{ + LogDebug("enter"); + + int argc = 0; + const char * argv[] = { "wrt-tests-wrt" }; + if (!getenv("ELM_ENGINE")) { + if (setenv("ELM_ENGINE", "gl", 1)) { + LogDebug("Enable backend"); + } + } + setenv("COREGL_FASTPATH", "1", 1); + DPL::Log::LogSystemSingleton::Instance().SetTag("WRT-CLIENT"); + + Touch(); + + //initialize + elm_init(argc, const_cast(argv)); + if(!WRT::CoreModuleSingleton::Instance().Init()) + { + ThrowMsg(CoreModuleFailure, "Init() fails"); + } + + InstallerWrapper::install(m_widgetPath, m_handle); + LogDebug("Widget Installed: " << m_handle); + + AddStep(&RunnableObjectStateTester::performTest); +} + +RunnableObjectStateTester::~RunnableObjectStateTester() +{ + LogDebug("enter"); + WRT::CoreModuleSingleton::Instance().Terminate(); + InstallerWrapper::uninstall(m_handle); + elm_shutdown(); +} + +void RunnableObjectStateTester::performCheckBeforeLaunch() +{ + m_widget->CheckBeforeLaunch(); +} + +void RunnableObjectStateTester::performPrepareView() +{ + //this address is invalid but we use mock (may be problematic when implementation'll change) + Evas_Object * fakeWindowAddress = reinterpret_cast(0x01); + m_widget->PrepareView(DPL::ToUTF8String(DPL::String()), + fakeWindowAddress); +} + +void RunnableObjectStateTester::performShow() +{ + m_widget->Show(); +} + +void RunnableObjectStateTester::performHide() +{ + m_widget->Hide(); +} + +void RunnableObjectStateTester::performSuspend() +{ + m_widget->Suspend(); +} + +void RunnableObjectStateTester::performResume() +{ + m_widget->Resume(); +} + +void RunnableObjectStateTester::performReset() +{ + m_widget->Reset(); +} + +void RunnableObjectStateTester::performGetCurrentWebview() +{ + m_widget->GetCurrentWebview(); +} + +void RunnableObjectStateTester::performSetUserDelegates() +{ + WRT::UserDelegatesPtr dlgs(new WRT::UserDelegates); + dlgs->loadFinishedCallback = + std::bind(&RunnableObjectStateTester::loadFinishCallback, + this, + std::placeholders::_1, + std::placeholders::_2); + m_widget->SetUserDelegates(dlgs); +} + +void RunnableObjectStateTester::performBackward() +{ + m_widget->Backward(); +} + +void RunnableObjectStateTester::OnEventReceived(const NextStepEvent& /*event*/) +{ + NextStep(); +} + +void RunnableObjectStateTester::loadFinishCallback(Evas_Object* obj, void* eventInfo) +{ + DPL_UNUSED_PARAM(obj); + DPL_UNUSED_PARAM(eventInfo); + + LogDebug("enter"); +} + +void RunnableObjectStateTester::runTest(RunnableObjectStateTester::Test func) +{ + m_widget = WRT::CoreModuleSingleton::Instance().getRunnableWidgetObject(m_handle); + //as we know we uses specific implementation + WRT::RunnableWidgetObject * m_widget_impl = dynamic_cast(m_widget.get()); + Assert(m_widget_impl); + m_widget_impl->setViewModule(ViewModule::IViewModulePtr(new MockViewModule())); + m_widget_impl->setContextManagerFactoryMethod(ViewModule::makeContextManagerFactoryMethod()); + if(!m_widget) + { + ThrowMsg(CoreModuleFailure, "getRunnableWidgetObject() fails"); + } + + m_func = func; + SwitchToStep(&RunnableObjectStateTester::performTest); + DPL::Event::ControllerEventHandler::PostTimedEvent(NextStepEvent(), 1.0); //TODO: time hazard + + elm_run(); //elm_run should be called instead of ecore_main_loop +} + +void RunnableObjectStateTester::performTest() +{ + LogDebug("enter"); + + Try { + m_func(*this); + } Catch(DPL::Exception) { + LogDebug("Test broken not at condition to be checked. Check other tests"); + LogDebug(_rethrown_exception.DumpToString()); + } + + Quit(); + m_widget.reset(); + + LogDebug("leave"); +} diff --git a/tests/widgets/common/src/mock/MockContextManager.cpp b/tests/widgets/common/src/mock/MockContextManager.cpp new file mode 100644 index 0000000..1e94d57 --- /dev/null +++ b/tests/widgets/common/src/mock/MockContextManager.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 MockContextManager.cpp + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief Mock for view module + */ +#include "mock/MockContextManager.h" + +MockContextManager::MockContextManager( + const std::string& tizenAppId, + Ewk_Context* ewkContext, + ViewModule::IViewModulePtr viewModule) : + ViewModule::IContextManager(tizenAppId, ewkContext, viewModule) +{ +} + +MockContextManager::~MockContextManager() +{ +} + +Ewk_Context* MockContextManager::getEwkContext() const +{ + return NULL; +} + +void MockContextManager::handleLowMemory() +{ +} + +namespace ViewModule { + +ContextManagerPtr contextManagerFactoryMethod( + const std::string& id, + Ewk_Context* c, + IViewModulePtr view) +{ + ContextManagerPtr ptr (new MockContextManager(id, c, view)); + return ptr; +} + +ContextManagerFactoryMethod makeContextManagerFactoryMethod() +{ + return contextManagerFactoryMethod; +} + +} // namespace ViewModule \ No newline at end of file diff --git a/tests/widgets/common/src/mock/MockViewModule.cpp b/tests/widgets/common/src/mock/MockViewModule.cpp new file mode 100644 index 0000000..c1b0545 --- /dev/null +++ b/tests/widgets/common/src/mock/MockViewModule.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 MockViewModule.cpp + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief Mock for view module + */ + +#include "mock/MockViewModule.h" + +MockViewModule::MockViewModule() +{ +} + +bool MockViewModule::createView( + Ewk_Context* /*context*/, + Evas_Object* /*window*/) +{ + return true; +} + +void MockViewModule::prepareView(WidgetModel *, const std::string &) +{ +} + +void MockViewModule::showWidget() +{ +} + +void MockViewModule::hideWidget() +{ +} + +void MockViewModule::suspendWidget() +{ +} + +void MockViewModule::resumeWidget() +{ +} + +void MockViewModule::resetWidgetFromSuspend() +{ +} + +void MockViewModule::resetWidgetFromResume() +{ +} + +void MockViewModule::backward() +{ +} + +void MockViewModule::reloadStartPage(bool isbackground) +{ +} + +Evas_Object* MockViewModule::getCurrentWebview() +{ + return NULL; +} + +void MockViewModule::fireJavascriptEvent(int /*event*/, void* /*data*/) +{ +} + +void MockViewModule::setUserCallbacks(const WRT::UserDelegatesPtr& /*cbs*/) +{ +} + +void MockViewModule::checkSyncMessageFromBundle( + const char* /*name*/, + const char* /*body*/, + char** /*returnData*/) +{ +} + +void MockViewModule::checkAsyncMessageFromBundle( + const char* /*name*/, + const char* /*body*/) +{ +} + +void MockViewModule::downloadData(const char* /*url*/) +{ +} + +void MockViewModule::activateVibration(bool /*on*/, uint64_t /*time*/) +{ +} diff --git a/tests/widgets/files/CMakeLists.txt b/tests/widgets/files/CMakeLists.txt new file mode 100644 index 0000000..5f87442 --- /dev/null +++ b/tests/widgets/files/CMakeLists.txt @@ -0,0 +1,22 @@ +# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Tomasz Iwanek (t.iwanek@samsung.com) +# + +SET(WRT_TESTS_GENERAL_WIDGETS_PATH "/opt/share/widget/tests/general/") + +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/any.wgt DESTINATION ${WRT_TESTS_GENERAL_WIDGETS_PATH}) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/minimal.wgt DESTINATION ${WRT_TESTS_GENERAL_WIDGETS_PATH}) diff --git a/tests/widgets/files/any.wgt b/tests/widgets/files/any.wgt new file mode 100644 index 0000000..8157660 Binary files /dev/null and b/tests/widgets/files/any.wgt differ diff --git a/tests/widgets/files/minimal.wgt b/tests/widgets/files/minimal.wgt new file mode 100644 index 0000000..86466af Binary files /dev/null and b/tests/widgets/files/minimal.wgt differ 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..f1edae0 --- /dev/null +++ b/uncrustify.sh @@ -0,0 +1 @@ +uncrustify -c uncrustify.cfg --no-backup `find . -regex "\(.*\.cpp\|.*\.h\|.*\.c\|.*\.cc\)" | grep -v "orm.h\|orm_generator.h"` diff --git a/wrt-engine-test.map b/wrt-engine-test.map new file mode 100644 index 0000000..02ed1dd --- /dev/null +++ b/wrt-engine-test.map @@ -0,0 +1,7 @@ +{ + global: *; + extern "C++" { + *; + }; +}; + diff --git a/wrt-engine.map b/wrt-engine.map new file mode 100644 index 0000000..15414cc --- /dev/null +++ b/wrt-engine.map @@ -0,0 +1,21 @@ +{ + global: wrt_*; + plugin_api_*; + extern "C++" { + Popup::PopupRenderer::*PopupRenderer*; + Popup::PopupRenderer::Initialize*; + Popup::PopupRenderer::Deinitialize*; + + Popup::PopupManager::*PopupManager*; + Popup::PopupManager::Initialize*; + Popup::PopupManager::Deinitialize*; + Popup::PopupManager::CreatePopup*; + Popup::PopupRenderer::PopupRenderer*; + Popup::PopupRenderer::*PopupRenderer*; + Popup::PopupRenderer::Initialize*; + Popup::PopupRenderer::Deinitialize*; + }; + main; + local: *; +}; + diff --git a/wrt-launcher.efl b/wrt-launcher.efl new file mode 100644 index 0000000..246d174 --- /dev/null +++ b/wrt-launcher.efl @@ -0,0 +1 @@ +wrt::wrt-launcher aul::terminate --x--- ------ \ No newline at end of file diff --git a/wrt.manifest b/wrt.manifest new file mode 100644 index 0000000..4011d8e --- /dev/null +++ b/wrt.manifest @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + diff --git a/wrt_env.sh b/wrt_env.sh new file mode 100644 index 0000000..7c2001f --- /dev/null +++ b/wrt_env.sh @@ -0,0 +1,8 @@ +export WRT_PROCESS_POOL_DISABLE=ON +#export WRT_WILL_SEND_REQUEST_LOG_ENABLE=ON +#export WRT_LOAD_PLUGINS_LOG_ENABLE=ON +#export WRT_FRAME_RENDERED_LOG_ENABLE=ON +#export WRT_CONSOLE_LOG_ENABLE=ON +#export WRT_WIDGET_DATA_TYPES_LOG_ENABLE=ON +export WRT_ECORE_EVAS_EXTN_SOCKET_ENGINE=gl_pixmap + diff --git a/wrt_launchpad_daemon.efl b/wrt_launchpad_daemon.efl new file mode 100644 index 0000000..c9961d2 --- /dev/null +++ b/wrt_launchpad_daemon.efl @@ -0,0 +1,9 @@ +wrt_launchpad_daemon system::share rwx--- ------ +wrt_launchpad_daemon system::homedir rwx--- ------ +wrt_launchpad_daemon device::app_logging -w---- ------ +wrt_launchpad_daemon xorg rw---- ------ +wrt_launchpad_daemon webkit2-efl rwxa-- ------ +wrt_launchpad_daemon sys-assert::core rwxat- ------ +wrt_launchpad_daemon aul::launch --x--- ------ +wrt_launchpad_daemon deviced::power rwx--- ------ +wrt_launchpad_daemon deviced::display rwx--- ------ \ No newline at end of file diff --git a/wrt_reset_all.sh b/wrt_reset_all.sh new file mode 100755 index 0000000..cda1c3e --- /dev/null +++ b/wrt_reset_all.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# resets all databases and security daemon +wrt_reset_db.sh "$@" +pkill -9 wrt-security +pkill -9 security-serv +security-server /dev/null 2>/dev/null & +wrt-security-daemon /dev/null 2>/dev/null & + diff --git a/wrt_reset_db.sh b/wrt_reset_db.sh new file mode 100755 index 0000000..e54b69d --- /dev/null +++ b/wrt_reset_db.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# resets all databases +# wrt_commons_reset_db.sh is trying to uninstall all widgets first +# so should be called first +wrt_commons_reset_db.sh "$@" +wrt_security_create_clean_db.sh