tizen 2.3 release tizen_2.3 submit/tizen_2.3/20150202.082759 tizen_2.3_release
authorjk7744.park <jk7744.park@samsung.com>
Sun, 1 Feb 2015 05:45:29 +0000 (14:45 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Sun, 1 Feb 2015 05:45:29 +0000 (14:45 +0900)
24 files changed:
CMakeLists.txt [new file with mode: 0644]
LICENSE [new file with mode: 0644]
packaging/wrt-service.spec [new file with mode: 0644]
src/CMakeLists.txt [new file with mode: 0644]
src/common/CMakeLists.txt [new file with mode: 0644]
src/common/access-control.cpp [new file with mode: 0644]
src/common/access-control.h [new file with mode: 0644]
src/common/native-context.cpp [new file with mode: 0755]
src/common/native-context.h [new file with mode: 0644]
src/common/native-plugin.h [new file with mode: 0644]
src/common/wrt-common-native.pc.in [new file with mode: 0644]
src/js/wrt-service.js [new file with mode: 0755]
src/node/CMakeLists.txt [new file with mode: 0644]
src/node/dlog.cpp [new file with mode: 0644]
src/node/gcontext.cpp [new file with mode: 0644]
src/node/gcontext.h [new file with mode: 0644]
src/node/native-node.cpp [new file with mode: 0644]
src/node/native-node.h [new file with mode: 0644]
src/node/native-plugin-loader.cpp [new file with mode: 0755]
src/node/native-plugin-loader.h [new file with mode: 0644]
src/node/service-util.cpp [new file with mode: 0644]
src/node/tizen-appfw.cpp [new file with mode: 0644]
src/node/tizen-appfw.h [new file with mode: 0644]
wrt-service.manifest [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f161070
--- /dev/null
@@ -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.
+#
+
+############################# Check minimum CMake version #####################
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT("wrt-service")
+
+############################# cmake packages ##################################
+
+INCLUDE(FindPkgConfig)
+
+############################# build type ######################################
+
+IF(NOT CMAKE_BUILD_TYPE)
+    SET(CMAKE_BUILD_TYPE "Release")
+ENDIF(NOT CMAKE_BUILD_TYPE)
+
+############################# compilation defines #############################
+
+
+############################# 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      "-O2 -g")
+SET(CMAKE_CXX_FLAGS_RELEASE    "-O2 -std=c++0x -g -fvisibility-inlines-hidden")
+SET(CMAKE_CXX_FLAGS_CCOV       "-O0 -std=c++0x -g --coverage")
+
+ADD_DEFINITIONS("-fPIC")
+
+# 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("-Wno-deprecated")      # No warnings about deprecated features
+ADD_DEFINITIONS("-std=c++0x")           # accept C++11x standard
+
+############################# target names ####################################
+
+SET(TARGET_SERVICE "wrt-service")
+SET(TARGET_COMMON_NATIVE "wrt-common-native")
+SET(TARGET_NODE_NATIVE "native")
+SET(TARGET_NODE_GCONTEXT "gcontext")
+SET(TARGET_NODE_APPFW "appfw")
+SET(TARGET_NODE_SERVICEUTIL "serviceutil")
+SET(TARGET_NODE_DLOG "nodedlog")
+
+############################# subdirectories ##################################
+ADD_SUBDIRECTORY(src)
+
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..247c97d
--- /dev/null
+++ b/LICENSE
@@ -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/packaging/wrt-service.spec b/packaging/wrt-service.spec
new file mode 100644 (file)
index 0000000..2ddd5d2
--- /dev/null
@@ -0,0 +1,86 @@
+Name:       wrt-service
+Summary:    Service Model for Web Runtime
+Version:    0.1.2
+Release:    1
+Group:      Development/Libraries
+License:    Apache License, Version 2.0
+URL:        N/A
+Source0:    %{name}-%{version}.tar.gz
+BuildRequires: cmake
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(gobject-2.0)
+BuildRequires: pkgconfig(aul)
+BuildRequires: pkgconfig(nodejs)
+BuildRequires: pkgconfig(sqlite3)
+BuildRequires: pkgconfig(security-client)
+BuildRequires: pkgconfig(libprivilege-control)
+Requires: nodejs
+
+%description
+Providing service model for tizen web runtime.
+
+%package -n wrt-common-native
+Summary:    Common libraries for bridge between JS and native
+Group:      Development/Libraries
+
+%description -n wrt-common-native
+Common libraries for bridge between JS and native
+
+%package -n wrt-common-native-devel
+Summary:    Common libraries for bridge between JS and native (Development)
+Group:      Development/Libraries
+Requires:   wrt-common-native
+
+%description -n wrt-common-native-devel
+Development package for wrt-common-native
+
+%prep
+%setup -q
+
+%build
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+
+export LDFLAGS="$LDFLAGS -Wl,--rpath=/usr/lib -Wl,--hash-style=both -Wl,--as-needed"
+
+mkdir -p cmake_build_tmp
+cd cmake_build_tmp
+
+cmake .. \
+        -DCMAKE_INSTALL_PREFIX=/usr \
+        -DCMAKE_BUILD_TYPE=%{?build_type:%build_type} \
+        -DFULLVER=%{version} -DMAJORVER=${MAJORVER}
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}/usr/share/license
+cp LICENSE %{buildroot}/usr/share/license/%{name}
+
+cd cmake_build_tmp
+%make_install
+
+%clean
+rm -rf %{buildroot}
+
+%post
+/sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest wrt-service.manifest
+%{_datadir}/license/%{name}
+%attr(755,root,root) %{_bindir}/wrt-service
+%{_libdir}/wrt-service/*.node
+
+
+%files -n wrt-common-native
+%manifest wrt-service.manifest
+%{_libdir}/lib*.so.*
+
+%files -n wrt-common-native-devel
+%{_libdir}/lib*.so
+%{_libdir}/pkgconfig/*.pc
+%{_includedir}/wrt-common/*.h
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f3bd526
--- /dev/null
@@ -0,0 +1,5 @@
+
+ADD_SUBDIRECTORY(common)
+ADD_SUBDIRECTORY(node)
+
+INSTALL(FILES js/wrt-service.js DESTINATION bin RENAME wrt-service)
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6911875
--- /dev/null
@@ -0,0 +1,40 @@
+SET(dependencies "dlog nodejs sqlite3 security-client")
+PKG_CHECK_MODULES(pkgs REQUIRED ${dependencies})
+
+INCLUDE_DIRECTORIES (
+    ${pkgs_INCLUDE_DIRS}
+)
+
+SET(SRCS
+    native-context.cpp
+    access-control.cpp
+)
+
+ADD_DEFINITIONS("-fPIC")
+#ADD_DEFINITIONS("-DUSE_SECURITY_CLIENT")
+
+# Shared Library
+ADD_LIBRARY(${TARGET_COMMON_NATIVE} SHARED ${SRCS})
+SET_TARGET_PROPERTIES(${TARGET_COMMON_NATIVE} PROPERTIES SOVERSION ${FULLVER} VERSION ${MAJORVER})
+TARGET_LINK_LIBRARIES(${TARGET_COMMON_NATIVE} ${pkgs_LIBRARIES})
+INSTALL(TARGETS ${TARGET_COMMON_NATIVE} DESTINATION lib)
+
+# Header Files for Development
+SET(INC_DIR include/wrt-common)
+INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION ${INC_DIR}
+        FILES_MATCHING PATTERN "*.h" PATTERN "CMakeFiles" EXCLUDE)
+
+# pkg-config For Development
+SET(PC_NAME ${TARGET_COMMON_NATIVE})
+SET(PACKAGE_DESCRIPTION "WRT Common Library for Native Module")
+SET(VERSION ${FULLVER})
+SET(PC_REQUIRED ${dependencies})
+SET(PC_LDFLAGS -l${TARGET_COMMON_NATIVE})
+SET(PC_CFLAGS -I${CMAKE_INSTALL_PREFIX}/${INC_DIR})
+
+CONFIGURE_FILE(
+    ${TARGET_COMMON_NATIVE}.pc.in
+    ${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_COMMON_NATIVE}.pc
+    @ONLY
+)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_COMMON_NATIVE}.pc DESTINATION lib/pkgconfig)
diff --git a/src/common/access-control.cpp b/src/common/access-control.cpp
new file mode 100644 (file)
index 0000000..b17f43f
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * 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.
+ */
+
+#include <string.h>
+#include <sqlite3.h>
+#include <string>
+#include <vector>
+
+#ifdef USE_SECURITY_CLIENT
+#include <unistd.h>
+#include <sys/types.h>
+#include <sstream>
+#include <ace_api_client.h>
+#endif
+
+#include "access-control.h"
+
+using namespace std;
+
+namespace {
+    const char *kWrtDBPath = "/opt/dbspace/.wrt.db";
+}
+
+namespace wrt {
+namespace common {
+
+#ifndef USE_SECURITY_CLIENT
+///////////////////////////////////////////////////////////////////
+// use wrt db
+class AccessControlImpl {
+public:
+    AccessControlImpl():initialized_(false){
+    }
+    virtual ~AccessControlImpl();
+    void InitAppPrivileges(const std::string& appid);
+    bool CheckAccessibility(const std::vector<std::string>& privileges);
+    bool CheckAccessibility(const char** privileges);
+
+private:
+    bool initialized_;
+    std::vector<std::string> granted_privileges_;
+};
+
+AccessControlImpl::~AccessControlImpl(){
+}
+void AccessControlImpl::InitAppPrivileges(const string & appid){
+    if(initialized_)
+        return;
+    initialized_ = true;
+    granted_privileges_.clear();
+
+    int ret = 0;
+    sqlite3 *db = NULL;
+    sqlite3_stmt *stmt = NULL;
+
+    ret = sqlite3_open(kWrtDBPath, &db);
+    if( ret ){
+        initialized_ = false;
+        return;
+    }
+
+    const char * query = "select name from WidgetFeature where app_id = "
+                 "(select app_id from WidgetInfo where tizen_appid = ?)"
+                 " and rejected = 0";
+
+
+    ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
+    ret |= sqlite3_bind_text(stmt, 1, appid.c_str(), -1, SQLITE_TRANSIENT);
+
+    if( ret ){
+        initialized_ = false;
+        goto error;
+    }
+
+    while( sqlite3_step(stmt) == SQLITE_ROW ){
+        char privilege[1024] = {0,};
+        strncpy(privilege, (const char*)sqlite3_column_text(stmt, 0), 1023);
+        granted_privileges_.push_back(privilege);
+    }
+
+error:
+    sqlite3_finalize(stmt);
+    sqlite3_close(db);
+
+}
+
+bool AccessControlImpl::CheckAccessibility(const std::vector<std::string>& privileges){
+    if(!initialized_)
+        return false;
+    bool found = false;
+    std::vector<std::string>::iterator itr = granted_privileges_.begin();
+    while( !found && itr != granted_privileges_.end() ){
+        for( int i = 0; i< privileges.size(); i++){
+            if( privileges[i] == *itr ){
+                found = true;
+                break;
+            }
+        }
+        ++itr;
+    }
+    return found;
+}
+
+bool AccessControlImpl::CheckAccessibility(const char** privileges){
+    if(!initialized_)
+        return false;
+    bool found = false;
+
+
+    std::vector<std::string>::iterator itr = granted_privileges_.begin();
+    while( !found && itr != granted_privileges_.end() ){
+        for( int i = 0; privileges[i] != NULL ; i++ ){
+            if( privileges[i] == *itr ){
+                found = true;
+                break;
+            }
+        }
+        ++itr;
+    }
+    return found;
+}
+
+
+#else
+////////////////////////////////////////////////////////////////////////
+// Use security client
+
+static ace_return_t allwaysDeny(
+        ace_popup_t popup_type,
+        const ace_resource_t resource_name,
+        const ace_session_id_t session_id,
+        const ace_param_list_t* param_list,
+        ace_widget_handle_t handle,
+        ace_bool_t* validation_result){
+    if( validation_result)
+        *validation_result = ACE_TRUE;
+    return ACE_OK;
+}
+
+class AccessControlImpl {
+public:
+    AccessControlImpl():initialized_(false),widget_id_(-1){
+    }
+    virtual ~AccessControlImpl();
+    void InitAppPrivileges(const std::string& appid);
+    bool CheckAccessibility(const std::vector<std::string>& privileges);
+    bool CheckAccessibility(const char** privileges);
+
+private:
+    bool initialized_;
+    int widget_id_;
+    std::string session_id_;
+};
+
+AccessControlImpl::~AccessControlImpl(){
+    if( initialized_ )
+        ace_client_shutdown();
+}
+void AccessControlImpl::InitAppPrivileges(const string & appid){
+    if(initialized_)
+        return;
+    initialized_ = true;
+    ace_client_initialize(allwaysDeny);
+    stringstream ss;
+    ss << appid << getpid();
+    session_id_ = ss.str();
+
+    int ret = 0;
+    sqlite3 *db = NULL;
+    sqlite3_stmt *stmt = NULL;
+
+    ret = sqlite3_open(WRT_DB_PATH, &db);
+    if( ret ){
+        initialized_ = false;
+        return;
+    }
+
+    const char * query = "select app_id from WidgetInfo where tizen_appid = ?";
+
+
+    ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
+    ret |= sqlite3_bind_text(stmt, 1, appid.c_str(), -1, SQLITE_TRANSIENT);
+
+    if( ret ){
+        initialized_ = false;
+        goto error;
+    }
+
+    if( sqlite3_step(stmt) == SQLITE_ROW ){
+        widget_id_ = sqlite3_column_int(stmt, 0);
+    }else
+        initialized_ = false;
+
+error:
+    sqlite3_finalize(stmt);
+    sqlite3_close(db);
+
+}
+
+bool AccessControlImpl::CheckAccessibility( const std::vector<std::string>& privileges){
+    if(!initialized_)
+        return false;
+    const char** privilegeTable;
+    int count = privileges.size();
+    privilegeTable = new const char*[count];
+    for( int i = 0 ; i < count; i++ ){
+        privilegeTable[i] = privileges[i].c_str();
+    }
+
+    bool result = CheckAccessibility(privilegeTable, count);
+    delete privilegeTable;
+    return result;
+}
+
+bool AccessControlImpl::CheckAccessibility(const char** privileges){
+    if(!initialized_)
+        return false;
+    ace_request_t request;
+    ace_check_result_t result;
+    request.session_id = (char*)session_id_.c_str();
+    request.widget_handle = widget_id_;
+    request.feature_list = {0,0};
+    request.dev_cap_list = {0,0};
+    int count = 0;
+    const char** check = privileges;
+    while( check++ )
+        count++;
+
+    request.feature_list.count = count;
+    request.feature_list.items = const_cast<char**>(privileges);
+
+    ace_check_access_ex(&request, &result);
+    return result == ACE_ACCESS_GRANTED;
+}
+#endif
+
+
+AccessControl* AccessControl::GetInstance(){
+    static AccessControl instance;
+    return &instance;
+}
+
+AccessControl::AccessControl():impl_(new AccessControlImpl()){
+}
+AccessControl::~AccessControl(){
+}
+
+void AccessControl::InitAppPrivileges(const string & appid){
+    impl_->InitAppPrivileges(appid);
+}
+bool AccessControl::CheckAccessibility(const std::vector<std::string>& privileges){
+    return impl_->CheckAccessibility(privileges);
+}
+
+bool AccessControl::CheckAccessibility(const char** privileges){
+    return impl_->CheckAccessibility(privileges);
+}
+
+} // namespace common
+} // namespace wrt
+
diff --git a/src/common/access-control.h b/src/common/access-control.h
new file mode 100644 (file)
index 0000000..f2425ba
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+#ifndef WRT_COMMON_ACCESS_CONTROL_H_
+#define WRT_COMMON_ACCESS_CONTROL_H_
+
+#include <vector>
+#include <string>
+#include <memory>
+
+namespace wrt {
+namespace common {
+
+class AccessControlImpl;
+class AccessControl{
+public:
+    static AccessControl* GetInstance();
+
+    /**
+     * Initialize Access Control module with a application id
+     *
+     * @remarks
+     * Before All others APIs used, This API should be called.
+     * Application id was set, You can not change it. 
+     *
+     * @param appid The application id to check
+     */
+    void InitAppPrivileges(const std::string& appid);
+
+    /**
+     * Check API Accessibility
+     *
+     * @param privileges Wanted privileges, should have a privilege at least one in these privileges
+     */
+    bool CheckAccessibility(const std::vector<std::string>& privileges);
+    /**
+     * Check API Accessibility
+     *
+     * @remarks
+     * privileges should be end with NULL
+     *
+     * @param privileges Wanted privileges, should have a privilege at least one in these privileges
+     */
+    bool CheckAccessibility(const char** privileges);
+
+
+private:
+    AccessControl();
+    virtual ~AccessControl();
+    std::shared_ptr<AccessControlImpl> impl_;
+};
+
+} // namespace common
+} // namespace wrt
+
+#endif // WRT_COMMON_ACCESS_CONTROL_H_
+
diff --git a/src/common/native-context.cpp b/src/common/native-context.cpp
new file mode 100755 (executable)
index 0000000..32c6acb
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * 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.
+ */
+
+#include <string>
+#include <map>
+#include <list>
+
+#include <v8.h>
+
+#include <dlog.h>
+
+#include "native-context.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "WRT"
+
+using namespace v8;
+
+namespace wrt {
+namespace common {
+
+NativeContext::NativeContext()
+{
+}
+
+NativeContext::~NativeContext()
+{
+    ClearCallbackMap();
+    ClearEventMap();
+}
+
+NativeContext* NativeContext::GetInstance()
+{
+    static NativeContext instance;
+    return &instance;
+}
+
+int NativeContext::newHandle()
+{
+    static unsigned int handle = 0;
+    return (int)++handle;
+}
+
+int NativeContext::AddCallbackToMap(void* callback)
+{
+    int handle = newHandle();
+    async_callback_map_.insert(std::make_pair(handle, callback));
+    return handle;
+}
+
+void NativeContext::InvokeCallback(int handle, const std::string& data)
+{
+    HandleScope scope;
+
+    CallbackMap::iterator it;
+    it = async_callback_map_.find(handle);
+    if (it != async_callback_map_.end()) {
+        // Invoke a callback
+        Persistent<Function> func = static_cast<Function*>(it->second);
+        Local<Value> args[] = { Local<Value>::New(String::New(data.c_str())) };
+        func->Call(func, 1, args);
+
+        // Remove callback from the list.
+        func.Dispose();
+        async_callback_map_.erase(it);
+    }
+}
+
+void NativeContext::AddEventToMap(const std::string& event, void* callback)
+{
+    HandleScope scope;
+
+    bool exist = false;
+    std::pair<EventMultiMap::iterator, EventMultiMap::iterator> iter_pair;
+
+    Local<Function> func_to_add = static_cast<Function*>(callback);
+
+    iter_pair = event_map_.equal_range(event);
+    for(EventMultiMap::iterator it = iter_pair.first; it != iter_pair.second; ++it) {
+        Persistent<Function> func = static_cast<Function*>(it->second);
+        if (func_to_add->Equals(func)) {
+            exist = true;
+            break;
+        }
+    }
+
+    if (!exist) {
+        event_map_.insert(std::make_pair(event, callback));
+    }
+}
+
+void NativeContext::RemoveEventFromMap(const std::string& event, void* callback)
+{
+    HandleScope scope;
+
+    std::pair<EventMultiMap::iterator, EventMultiMap::iterator> iter_pair;
+
+    Local<Function> func_to_remove = static_cast<Function*>(callback);
+
+    iter_pair = event_map_.equal_range(event);
+    for(EventMultiMap::iterator it = iter_pair.first; it != iter_pair.second;) {
+        Persistent<Function> func = static_cast<Function*>(it->second);
+        if (func_to_remove->Equals(func)) {
+            func.Dispose();
+            event_map_.erase(it++);
+        } else {
+            ++it;
+        }
+    }
+}
+
+void NativeContext::FireEvent(const std::string& event, const std::string& data)
+{
+    HandleScope scope;
+
+    std::pair<EventMultiMap::iterator, EventMultiMap::iterator> iter_pair;
+    //Temporarily function list
+    std::list<Local<Function>> function_snapshot;
+
+    iter_pair = event_map_.equal_range(event);
+    for(EventMultiMap::iterator it = iter_pair.first; it != iter_pair.second;++it) {
+        Local<Function> func = static_cast<Function*>(it->second);
+        // save listener function temporarily
+        function_snapshot.push_back(func);
+    }
+    Local<Value> args[] = { Local<Value>::New(String::New(data.c_str())) };
+    for( auto &func : function_snapshot ){
+        // perform the call
+        func->Call(func, 1, args);
+    }
+}
+
+void NativeContext::ClearCallbackMap()
+{
+    CallbackMap::iterator it;
+    for (it = async_callback_map_.begin(); it != async_callback_map_.end(); ++it) {
+        Persistent<Function> func = static_cast<Function*>(it->second);
+        func.Dispose();
+    }
+    async_callback_map_.clear();
+}
+
+void NativeContext::ClearEventMap()
+{
+    EventMultiMap::iterator it;
+    for (it = event_map_.begin(); it != event_map_.end(); ++it) {
+        Persistent<Function> func = static_cast<Function*>(it->second);
+        func.Dispose();
+    }
+    event_map_.clear();
+}
+
+void NativeContext::dump()
+{
+    LOGD("Dump [AsyncCallbackMap] Size: %d", async_callback_map_.size());
+    LOGD("------------------------------------------------------------");
+    CallbackMap::iterator cit;
+    for (cit = async_callback_map_.begin(); cit != async_callback_map_.end(); ++cit) {
+        LOGD("Key: %d  -->  El: %p", cit->first, cit->second);
+    }
+
+    LOGD("Dump [EventMap] Size: %d", event_map_.size());
+    LOGD("------------------------------------------------------------");
+    EventMultiMap::iterator eit;
+    for (eit = event_map_.begin(); eit != event_map_.end(); ++eit) {
+        LOGD("Key: %s  -->  El: %p", eit->first.c_str(), eit->second);
+    }
+    LOGD("------------------------------------------------------------");
+}
+
+} // namespace common
+} // namespace wrt
+
diff --git a/src/common/native-context.h b/src/common/native-context.h
new file mode 100644 (file)
index 0000000..1d099a1
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#ifndef WRT_COMMON_NATIVE_CONTEXT_H_
+#define WRT_COMMON_NATIVE_CONTEXT_H_
+
+#include <string>
+#include <map>
+
+namespace wrt {
+namespace common {
+
+class NativeContext {
+public:
+    static NativeContext* GetInstance();
+
+    int AddCallbackToMap(void* callback);
+    void InvokeCallback(int callback_handle, const std::string& data);
+
+    void AddEventToMap(const std::string& event, void* callback);
+    void RemoveEventFromMap(const std::string& event, void* callback);
+    void FireEvent(const std::string& event, const std::string& data);
+private:
+    NativeContext();
+    virtual ~NativeContext();
+
+    void ClearCallbackMap();
+    void ClearEventMap();
+
+    int newHandle();
+
+    void dump();
+
+    typedef std::map<int, void*> CallbackMap;
+    CallbackMap async_callback_map_;
+
+    typedef std::multimap<std::string, void*> EventMultiMap;
+    EventMultiMap event_map_;
+};
+
+} // namespace common
+} // namespace wrt
+
+#endif // WRT_COMMON_NATIVE_CONTEXT_H_
diff --git a/src/common/native-plugin.h b/src/common/native-plugin.h
new file mode 100644 (file)
index 0000000..edee19f
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#ifndef WRT_COMMON_NATIVE_PLUGIN_H_
+#define WRT_COMMON_NATIVE_PLUGIN_H_
+
+#include <string>
+
+namespace wrt {
+namespace common {
+
+class NativePlugin {
+public:
+    virtual void OnLoad() = 0;
+    virtual std::string OnCallSync(std::string& data) = 0;
+    virtual std::string OnCall(std::string& data, int callback_handle) = 0;
+};
+
+typedef NativePlugin* create_native_plugin_t();
+
+} // namespace common
+} // namespace wrt
+
+#define EXPORT_NATIVE_PLUGIN(pluginClass) \
+    extern "C" wrt::common::NativePlugin* create_native_plugin() { \
+        return (wrt::common::NativePlugin *)(new pluginClass()); \
+    }
+
+#endif // WRT_COMMON_NATIVE_PLUGIN_H_
diff --git a/src/common/wrt-common-native.pc.in b/src/common/wrt-common-native.pc.in
new file mode 100644 (file)
index 0000000..f03994c
--- /dev/null
@@ -0,0 +1,13 @@
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=/usr
+libdir=/usr/lib
+includedir=/usr/include
+
+Name: @PC_NAME@
+Description: @PACKAGE_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_REQUIRED@
+Libs: -L${libdir} @PC_LDFLAGS@
+Cflags: -I${includedir} @PC_CFLAGS@
\ No newline at end of file
diff --git a/src/js/wrt-service.js b/src/js/wrt-service.js
new file mode 100755 (executable)
index 0000000..f9cc3aa
--- /dev/null
@@ -0,0 +1,176 @@
+#!/usr/bin/env node
+
+
+(function(){
+    var path = require('path');
+
+    function loadModules(){
+        var PLUGINS_PATH = '/usr/lib/webapi-plugins';
+        var fs = require('fs');
+        var moduleList = [];
+        if (fs.existsSync(PLUGINS_PATH)) {
+            moduleList = fs.readdirSync(PLUGINS_PATH);
+        }
+
+        var globalModules = [];
+        var subModules = {};
+        for( var i in moduleList ){
+            if( path.extname(moduleList[i]) == '.plugin' ){
+                var module = moduleList[i].split('.');
+                var modulepath = moduleList[i];
+                if(module.length == 2){
+                    globalModules.push(modulepath);
+                }else if( module.length == 3 ){ // only support 2 depth submodule xx.yy.plugin (0) , xx.yy.zz.plugin(x)
+                    if( !subModules.hasOwnProperty(module[0]) )
+                        subModules[module[0]] = [];
+                    subModules[module[0]].push(modulepath);
+                }
+            }
+        }
+        function redefineProperty(name,prop){
+            if(prop.hasOwnProperty('value')){
+                var v = prop.value;
+                var isloaded = false;
+                delete prop.value;
+                prop.get = function(){
+                    if( !isloaded ){
+                        isloaded = true;
+                        for( var i in subModules[name] ){
+                            var submodule = subModules[name][i];
+                            var submoduleobj = require( path.join(PLUGINS_PATH, submodule) );
+                            Object.defineProperties(v, submoduleobj);
+                        }
+                    }
+                    return v;
+                }
+                if( prop.hasOwnProperty('writable') ){
+                    delete prop.writable;
+                }
+            }
+            return prop;
+        }
+
+        //load global module
+        for( var i in globalModules ){
+            var globalmodule = globalModules[i];
+            var modulename = globalmodule.split('.')[0];
+
+            var loadedSymbols = require(path.join(PLUGINS_PATH, globalmodule));
+            for( var symbol in loadedSymbols ){
+                var prop = loadedSymbols[symbol];
+                //redefine property description
+                prop = redefineProperty(symbol, prop);
+                Object.defineProperty(GLOBAL, symbol, prop);
+                //Dirty patch for unknown situation.
+                //TODO: Remove Dirty Patch
+                try {
+                    if (symbol == 'tizen')
+                        tizen;
+                } catch(e) {
+                }
+            }
+        }
+    }
+
+    //change cmdline
+    process.title = process.argv[1];
+    var cmdpath =  process.argv[1].split('/');
+
+    //getting appid from cmdpath
+    var appid = cmdpath.pop();
+    cmdpath.pop();
+
+    //getting package path
+    var packagePath = cmdpath.join('/');
+
+    //Change App privilege
+    var serviceUtil = require('/usr/lib/wrt-service/serviceutil.node');
+    serviceUtil.setPrivilege(appid.split('.')[0], process.argv[1]);
+
+
+    // change cwd
+    process.chdir(packagePath);
+    process.chdir('res/wgt');
+
+
+    //initialize internal modules
+
+    //dlog enable
+    var util = require('util');
+    var dlog = require('/usr/lib/wrt-service/nodedlog.node');
+    console.log = function(){
+        dlog.logd(appid, util.format.apply(this, arguments));
+    };
+    console.info = function(){
+        dlog.logv(appid, util.format.apply(this, arguments));
+    };
+    console.error = function(){
+        dlog.loge(appid, util.format.apply(this, arguments));
+    };
+    console.warn = console.info;
+    console.logd = function(){
+        if( arguments.length > 1 ){
+            dlog.logd(arguments[0], util.format.apply(this,  Array.prototype.slice.call(arguments,1)) );
+        }else{
+            dlog.logd(util.format.apply(this, arguments) );
+        }
+    };
+    console.logv = function(){
+        if( arguments.length > 1 ){
+            dlog.logv(arguments[0], util.format.apply(this,  Array.prototype.slice.call(arguments,1)) );
+        }else{
+            dlog.logv(util.format.apply(this, arguments) );
+        }
+    };
+    console.loge = function(){
+        if( arguments.length > 1 ){
+            dlog.loge(arguments[0], util.format.apply(this,  Array.prototype.slice.call(arguments,1)) );
+        }else{
+            dlog.loge(util.format.apply(this, arguments) );
+        }
+    };
+
+    //init g main loop
+    require('/usr/lib/wrt-service/gcontext.node').init();
+
+    //appfw load
+    var appfw = require('/usr/lib/wrt-service/appfw.node');
+    //native load
+    GLOBAL.native = require('/usr/lib/wrt-service/native.node');
+    //ACE module load
+    serviceUtil.initAce(appid);
+    loadModules();
+
+    //module path update for custom modules
+    var modulepaths = [ process.cwd(), process.cwd() + '/node_modules' ];
+    module.paths = modulepaths.concat(module.paths);
+
+    //getting start page
+    var startScript = serviceUtil.getStartScript(appid);
+    if (!startScript) {
+        startScript = "index.js";
+    }
+
+    //load user script
+    var app = require( path.join(packagePath, '/res/wgt/' + startScript));
+
+    appfw.init(process.argv.slice(1));
+    appfw.onService = function(bundle) {
+        appfw.bundle = bundle;
+        if (app.onRequest) {
+            app.onRequest();
+        }
+    };
+    appfw.onTerminate = function() { process.exit(); };
+
+    if (app.onExit) {
+        process.on('exit',app.onExit);
+    }
+
+    if (app.onStart) {
+        app.onStart();
+    }
+
+    //running main loop
+
+})();
diff --git a/src/node/CMakeLists.txt b/src/node/CMakeLists.txt
new file mode 100644 (file)
index 0000000..417f37e
--- /dev/null
@@ -0,0 +1,96 @@
+
+ADD_DEFINITIONS("-fPIC")
+
+SET(NODE_PLUGIN_PATH lib/wrt-service)
+
+#################################### native #####################################
+
+PKG_CHECK_MODULES(native_pkgs REQUIRED dlog nodejs)
+
+INCLUDE_DIRECTORIES (
+    ../common
+    ${native_pkgs_INCLUDE_DIRS}
+)
+
+SET(SRCS
+    native-node.cpp
+    native-plugin-loader.cpp
+)
+
+ADD_LIBRARY(${TARGET_NODE_NATIVE} MODULE ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NODE_NATIVE} PROPERTIES PREFIX "" SUFFIX ".node")
+TARGET_LINK_LIBRARIES(${TARGET_NODE_NATIVE} ${native_pkgs_LIBRARIES} ${TARGET_COMMON_NATIVE})
+INSTALL(TARGETS ${TARGET_NODE_NATIVE} DESTINATION ${NODE_PLUGIN_PATH})
+
+#################################### gcontext #####################################
+
+PKG_CHECK_MODULES(gcontext_pkgs REQUIRED nodejs glib-2.0 gobject-2.0)
+
+INCLUDE_DIRECTORIES (
+    ${gcontext_pkgs_INCLUDE_DIRS}
+)
+
+SET(SRCS
+    gcontext.cpp
+)
+
+ADD_LIBRARY(${TARGET_NODE_GCONTEXT} MODULE ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NODE_GCONTEXT} PROPERTIES PREFIX "" SUFFIX ".node")
+TARGET_LINK_LIBRARIES(${TARGET_NODE_GCONTEXT} ${gcontext_pkgs_LIBRARIES})
+INSTALL(TARGETS ${TARGET_NODE_GCONTEXT} DESTINATION ${NODE_PLUGIN_PATH})
+
+#################################### appfw #########################################
+
+PKG_CHECK_MODULES(appfw_pkgs REQUIRED dlog nodejs glib-2.0 aul)
+
+INCLUDE_DIRECTORIES (
+    ${appfw_pkgs_INCLUDE_DIRS}
+)
+
+SET(SRCS
+    tizen-appfw.cpp
+)
+
+ADD_LIBRARY(${TARGET_NODE_APPFW} MODULE ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NODE_APPFW} PROPERTIES PREFIX "" SUFFIX ".node")
+TARGET_LINK_LIBRARIES(${TARGET_NODE_APPFW} ${appfw_pkgs_LIBRARIES})
+INSTALL(TARGETS ${TARGET_NODE_APPFW} DESTINATION ${NODE_PLUGIN_PATH})
+
+
+#################################### serviceutil #########################################
+PKG_CHECK_MODULES(serviceutil_pkgs REQUIRED dlog nodejs sqlite3)
+PKG_CHECK_MODULES(privilege_pkgs REQUIRED libprivilege-control)
+INCLUDE_DIRECTORIES (
+    ${serviceutil_pkgs_INCLUDE_DIRS}
+    ${privilege_pkgs_INCLUDE_DIRS}
+)
+
+SET(SRCS
+    service-util.cpp
+)
+
+ADD_LIBRARY(${TARGET_NODE_SERVICEUTIL} MODULE ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NODE_SERVICEUTIL} PROPERTIES PREFIX "" SUFFIX ".node")
+TARGET_LINK_LIBRARIES(${TARGET_NODE_SERVICEUTIL} ${privilege_pkgs_LIBRARIES} ${serviceutil_pkgs_LIBRARIES} ${TARGET_COMMON_NATIVE})
+INSTALL(TARGETS ${TARGET_NODE_SERVICEUTIL} DESTINATION ${NODE_PLUGIN_PATH})
+
+#################################### dlog #########################################
+PKG_CHECK_MODULES(nodedlog_pkgs REQUIRED dlog nodejs)
+INCLUDE_DIRECTORIES (
+    ${nodedlog_pkgs_INCLUDE_DIRS}
+)
+
+SET(SRCS
+    dlog.cpp
+)
+
+ADD_LIBRARY(${TARGET_NODE_DLOG} MODULE ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NODE_DLOG} PROPERTIES PREFIX "" SUFFIX ".node")
+TARGET_LINK_LIBRARIES(${TARGET_NODE_DLOG} ${nodedlog_pkgs_LIBRARIES} ${TARGET_COMMON_NATIVE})
+INSTALL(TARGETS ${TARGET_NODE_DLOG} DESTINATION ${NODE_PLUGIN_PATH})
+
diff --git a/src/node/dlog.cpp b/src/node/dlog.cpp
new file mode 100644 (file)
index 0000000..39b4779
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+#include <dlog.h>
+#include <node.h>
+#include <v8.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "WRT_SERVICE"
+
+using namespace node;
+using namespace v8;
+
+namespace wrt {
+namespace service {
+
+static void logd(const char* tag, const char* format, ...){
+    va_list args;
+    va_start(args, format);
+    LOG_VA(LOG_DEBUG, tag, format, args);
+    va_end(args);
+}
+
+static void logv(const char* tag, const char* format, ...){
+    va_list args;
+    va_start(args, format);
+    LOG_VA(LOG_VERBOSE, tag, format, args);
+    va_end(args);
+}
+
+static void loge(const char* tag, const char* format, ...){
+    va_list args;
+    va_start(args, format);
+    LOG_VA(LOG_ERROR, tag, format, args);
+    va_end(args);
+}
+
+static Handle<Value> logD(const Arguments& args){
+    HandleScope scope;
+    if( args.Length() == 1 ){
+        logd(LOG_TAG, *String::Utf8Value(args[0]->ToString()));
+    }else if( args.Length() > 1 ){
+        logd(*String::Utf8Value(args[0]->ToString()), *String::Utf8Value(args[1]->ToString()));
+    }
+    return Undefined();
+}
+
+static Handle<Value> logV(const Arguments& args){
+    HandleScope scope;
+    if( args.Length() == 1 ){
+        logv(LOG_TAG, *String::Utf8Value(args[0]->ToString()));
+    }else if( args.Length() > 1 ){
+        logv(*String::Utf8Value(args[0]->ToString()), *String::Utf8Value(args[1]->ToString()));
+    }
+    return Undefined();
+}
+
+static Handle<Value> logE(const Arguments& args){
+    HandleScope scope;
+    if( args.Length() == 1 ){
+        loge(LOG_TAG, *String::Utf8Value(args[0]->ToString()));
+    }else if( args.Length() > 1 ){
+        loge(*String::Utf8Value(args[0]->ToString()), *String::Utf8Value(args[1]->ToString()));
+    }
+    return Undefined();
+}
+static void init(Handle<Object> target) {
+    HandleScope scope;
+    target->Set(String::NewSymbol("log"), v8::FunctionTemplate::New(logD)->GetFunction());
+    target->Set(String::NewSymbol("logd"), v8::FunctionTemplate::New(logD)->GetFunction());
+    target->Set(String::NewSymbol("logv"), v8::FunctionTemplate::New(logV)->GetFunction());
+    target->Set(String::NewSymbol("loge"), v8::FunctionTemplate::New(logE)->GetFunction());
+}
+
+NODE_MODULE(nodedlog, init);
+
+} // namespace service
+} // namespace wrt
+
diff --git a/src/node/gcontext.cpp b/src/node/gcontext.cpp
new file mode 100644 (file)
index 0000000..ccf4b81
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <glib-object.h>
+
+#include <v8.h>
+#include <node.h>
+
+#include "gcontext.h"
+
+using namespace node;
+using namespace v8;
+
+namespace wrt {
+namespace service {
+
+struct poll_handler {
+       int fd;
+       uv_poll_t *uv_poll;
+    int eventmask;
+       int ref;
+    std::list<GPollFD*> fd_list;
+};
+
+GContext::GContext():initialized_(false){
+}
+
+GContext::~GContext(){
+};
+
+void GContext::Init(){
+    if(initialized_)
+        return;
+    initialized_ = true;
+
+       GMainContext *gc = g_main_context_default();
+
+       if (!g_thread_supported())
+               g_thread_init(NULL);
+
+#if !GLIB_CHECK_VERSION(2, 35, 0)
+       g_type_init();
+#endif
+
+       g_main_context_acquire(gc);
+    context_ = g_main_context_ref(gc);
+    fd_list_ = NULL;
+    fd_list_size_ = 0;
+    fd_count_ = 0;
+
+
+    // allocate memory to memory
+    prepare_handle_ = (uv_prepare_t*)malloc(sizeof(uv_prepare_t));
+    check_handle_ = (uv_check_t*)malloc(sizeof(uv_check_t));
+    timeout_handle_ = (uv_timer_t*)malloc(sizeof(uv_timer_t));
+
+    memset(prepare_handle_, 0, sizeof(uv_prepare_t));
+    memset(check_handle_, 0, sizeof(uv_check_t));
+    memset(timeout_handle_, 0, sizeof(uv_timer_t));
+
+       uv_prepare_init(uv_default_loop(), prepare_handle_);
+       uv_check_init(uv_default_loop(), check_handle_);
+       uv_timer_init(uv_default_loop(), timeout_handle_);
+
+    prepare_handle_->data = this;
+    check_handle_->data = this;
+    timeout_handle_->data = this;
+
+       uv_prepare_start(prepare_handle_, GContext::OnPrepare);
+       uv_check_start(check_handle_, GContext::OnCheck);
+
+}
+
+void GContext::Uninit(){
+    if(!initialized_)
+        return;
+
+    initialized_ = false;
+
+       /* Remove all handlers */
+       std::list<poll_handler*>::iterator itr = poll_handle_list_.begin();
+       while(itr != poll_handle_list_.end()) {
+               /* Stop polling handler */
+               uv_unref((uv_handle_t *)(*itr)->uv_poll);
+               uv_poll_stop((*itr)->uv_poll);
+               uv_close((uv_handle_t *)(*itr)->uv_poll, (uv_close_cb)free);
+        delete *itr;
+               itr = poll_handle_list_.erase(itr);
+       }
+
+       uv_unref((uv_handle_t *)check_handle_);
+       uv_unref((uv_handle_t *)prepare_handle_);
+       uv_unref((uv_handle_t *)timeout_handle_);
+
+       uv_check_stop(check_handle_);
+       uv_prepare_stop(prepare_handle_);
+       uv_timer_stop(timeout_handle_);
+
+       uv_close((uv_handle_t *)check_handle_, (uv_close_cb)free);
+       uv_close((uv_handle_t *)prepare_handle_, (uv_close_cb)free);
+    uv_close((uv_handle_t *)timeout_handle_, (uv_close_cb)free);
+
+    check_handle_ = NULL;
+    prepare_handle_ = NULL;
+    timeout_handle_ = NULL;
+
+       g_free(fd_list_);
+    fd_list_ = NULL;
+
+       /* Release GMainContext loop */
+       g_main_context_unref(context_);
+}
+
+static void poll_cb(uv_poll_t *uv_handle, int status, int events){
+       poll_handler *handle = static_cast<poll_handler*>(uv_handle->data);
+    if( status == 0 ){
+        //printf("poll cb!!!! fd = %d, read = %d , write  = %d \n",handle->fd, events & UV_READABLE , events & UV_WRITABLE );
+        std::list<GPollFD*>::iterator itr = handle->fd_list.begin();
+        while( itr != handle->fd_list.end()){
+            GPollFD* pfd = *itr;
+            pfd->revents |= pfd->events & ((events & UV_READABLE ? G_IO_IN : 0) | (events & UV_WRITABLE ? G_IO_OUT : 0));
+            ++itr;
+        }
+    }else{
+        uv_poll_stop(uv_handle);
+    }
+}
+
+void GContext::onPrepare(int status){
+       int i;
+       int timeout;
+
+       g_main_context_prepare(context_, &max_priority_);
+
+       /* Getting all sources from GLib main context */
+       while(fd_list_size_ < (fd_count_ = g_main_context_query(context_,
+                       max_priority_,
+                       &timeout,
+                       fd_list_,
+                       fd_list_size_))){
+               g_free(fd_list_);
+               fd_list_size_ = fd_count_;
+               fd_list_ = g_new(GPollFD, fd_list_size_);
+       }
+
+    //printf("context query : fdCount=%d , timeout = %d\n", fd_count_, timeout);
+
+       /* Poll */
+       if (fd_count_ > 0) {
+               char flagsTable[fd_count_];
+        memset(flagsTable, 0, fd_count_);
+        std::list<poll_handler*>::iterator itr = poll_handle_list_.begin();
+
+        //for each poll handler
+               while ( itr != poll_handle_list_.end() ) {
+            poll_handler *handle = *itr;
+            int origin_mask = handle->eventmask;
+                       handle->ref = 0;
+            handle->eventmask = 0;
+            handle->fd_list.clear();
+
+            //check already initialized poll handles
+                       for (i = 0; i < fd_count_; ++i) {
+                               GPollFD *pfd = fd_list_ + i;
+                               if (handle->fd == pfd->fd){
+                                       flagsTable[i] = 1;
+                                       handle->ref++;
+                                       pfd->revents = 0;
+                    handle->eventmask |= (pfd->events & G_IO_IN ? UV_READABLE: 0) | (pfd->events & G_IO_OUT ? UV_WRITABLE: 0);
+                    handle->fd_list.push_back(pfd);
+                               }
+                       }
+
+            // remasking events
+            if( handle->ref > 0){
+               if( handle->eventmask != origin_mask ){
+                    //printf("polling restart fd = %d\n", handle->fd);
+                    uv_poll_stop(handle->uv_poll);
+                    uv_poll_start(handle->uv_poll, handle->eventmask, poll_cb);
+                }
+            }
+
+            // remove unused poll handles
+            if( handle->ref == 0 ){
+                               uv_unref((uv_handle_t *)handle->uv_poll);
+                               uv_poll_stop(handle->uv_poll);
+                               uv_close((uv_handle_t *)handle->uv_poll, (uv_close_cb)free);
+                               itr = poll_handle_list_.erase(itr);
+                delete handle;
+            }else{
+                ++itr;
+            }
+               }
+
+        std::list<poll_handler*> new_poll_fds;
+               /* Process current file descriptors from GContext */
+               for (i = 0; i < fd_count_; ++i) {
+                       GPollFD *pfd = &fd_list_[i];
+                       int exists = flagsTable[i];
+                       if (exists)
+                               continue;
+
+                       pfd->revents = 0;
+            for( itr = new_poll_fds.begin(); itr != new_poll_fds.end(); ++itr){
+                poll_handler *handle = *itr;
+                if(handle->fd == pfd->fd){
+                    int oldmask = handle->eventmask;
+                    handle->eventmask |= (pfd->events & G_IO_IN ? UV_READABLE: 0) | (pfd->events & G_IO_OUT ? UV_WRITABLE: 0);
+                    if( oldmask != handle->eventmask ){
+                        uv_poll_stop(handle->uv_poll);
+                        uv_poll_start(handle->uv_poll, handle->eventmask, poll_cb);
+                    }
+                    exists = 1;
+                    break;
+                };
+            }
+
+            if(exists)
+                continue;
+
+                       /* Preparing poll handler */
+                       struct poll_handler* handle = new poll_handler();
+                       handle->fd = pfd->fd;
+                       handle->ref = 1;
+
+                       /* Create uv poll handler, then append own poll handler on it */
+                       uv_poll_t *pt = (uv_poll_t *)malloc(sizeof(uv_poll_t));
+            memset(pt,0, sizeof(uv_poll_t));
+                       pt->data = handle;
+                       handle->uv_poll= pt;
+
+                       uv_poll_init(uv_default_loop(), pt, pfd->fd);
+            //printf("uv poll start fd = %d\n", pfd->fd);
+            int uv_events = (pfd->events & G_IO_IN ? UV_READABLE: 0) | (pfd->events & G_IO_OUT ? UV_WRITABLE: 0);
+            handle->eventmask = uv_events;
+                       uv_poll_start(pt, uv_events, poll_cb);
+            new_poll_fds.push_back(handle);
+               }
+        if( !new_poll_fds.empty() )
+            poll_handle_list_.merge(new_poll_fds);
+       }
+
+    if( timeout >= 0 ){
+        uv_timer_start(timeout_handle_, OnTimeout, timeout, 0);
+    }
+
+
+}
+
+
+void GContext::OnPrepare(uv_prepare_t *handle, int status){
+    GContext *This = static_cast<GContext*>(handle->data);
+    This->onPrepare(status);
+}
+
+void GContext::OnCheck(uv_check_t *handle, int status){
+    GContext* This = static_cast<GContext*>(handle->data);
+    This->onCheck(status);
+}
+
+void GContext::onCheck(int status){
+       int ready = g_main_context_check(context_, max_priority_, fd_list_, fd_count_);
+       if (ready){
+               g_main_context_dispatch(context_);
+    }
+}
+
+void GContext::OnTimeout(uv_timer_t *handle, int status){
+    GContext* This = static_cast<GContext*>(handle->data);
+    This->onTimeout(status);
+}
+
+void GContext::onTimeout(int status){
+}
+
+
+static GContext *g_context = NULL;
+
+static Handle<Value> GContextInit(const Arguments& args){
+       HandleScope scope;
+
+       if (g_context == NULL) {
+               g_context = new GContext();
+       }
+    g_context->Init();
+       return Undefined();
+}
+
+static Handle<Value> GContextUninit(const Arguments& args){
+       HandleScope scope;
+       if (g_context != NULL) {
+               g_context->Uninit();
+        delete g_context;
+        g_context = NULL;
+       }
+       return Undefined();
+}
+
+static void init(Handle<Object> target) {
+       HandleScope scope;
+
+       NODE_SET_METHOD(target, "init", GContextInit);
+       NODE_SET_METHOD(target, "uninit", GContextUninit);
+}
+
+NODE_MODULE(gcontext, init);
+
+} // namespace service
+} // namespace wrt
diff --git a/src/node/gcontext.h b/src/node/gcontext.h
new file mode 100644 (file)
index 0000000..94a5bfe
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+#ifndef WRT_SERVICE_NODE_GCONTEXT_H_
+#define WRT_SERVICE_NODE_GCONTEXT_H_
+
+#include <glib.h>
+#include <list>
+#include <uv.h>
+
+namespace wrt {
+namespace service {
+
+class poll_handler;
+
+class GContext {
+public:
+    GContext();
+    virtual ~GContext();
+    void Init();
+    void Uninit();
+
+private:
+    void onPrepare(int status);
+    void onCheck(int status);
+    void onTimeout(int status);
+
+    static void OnPrepare(uv_prepare_t *handle, int status);
+    static void OnCheck(uv_check_t *handle, int status);
+    static void OnTimeout(uv_timer_t *handle, int status);
+
+    bool initialized_;
+    GMainContext *context_;
+    int max_priority_;
+
+    GPollFD *fd_list_;
+    int fd_list_size_;
+    int fd_count_;
+    std::list<poll_handler*> poll_handle_list_;
+
+    uv_prepare_t *prepare_handle_;
+    uv_check_t *check_handle_;
+    uv_timer_t *timeout_handle_;
+
+};
+
+} // namespace service
+} // namespace wrt
+
+#endif // WRT_SERVICE_NODE_GCONTEXT_H_
diff --git a/src/node/native-node.cpp b/src/node/native-node.cpp
new file mode 100644 (file)
index 0000000..d2b3e67
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * 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.
+ */
+
+#include <v8.h>
+#include <node.h>
+
+#include <native-plugin.h>
+#include <native-context.h>
+
+#include "native-node.h"
+#include "native-plugin-loader.h"
+
+using namespace v8;
+using namespace node;
+using namespace wrt::common;
+
+namespace wrt {
+namespace service {
+
+static Handle<String> ToJSON(const Handle<Value> object)
+{
+    HandleScope scope;
+
+    Local<Object> global = Context::GetCurrent()->Global();
+    Local<Object> JSON = global->Get(String::New("JSON"))->ToObject();
+    Local<Function> JSON_stringify
+            = Local<Function>::Cast(JSON->Get(String::New("stringify")));
+
+    Local<Value> args[] = { Local<Value>::New(object) };
+    Local<String> result = Local<String>::Cast(JSON_stringify->Call(JSON, 1, args));
+    return scope.Close(result);
+}
+
+void NativeNode::Init(Handle<Object> target)
+{
+    HandleScope scope;
+
+    target->Set(String::NewSymbol("call"),
+        FunctionTemplate::New(Call)->GetFunction());
+
+    target->Set(String::NewSymbol("callSync"),
+        FunctionTemplate::New(CallSync)->GetFunction());
+
+    target->Set(String::NewSymbol("addListener"),
+        FunctionTemplate::New(AddListener)->GetFunction());
+
+    target->Set(String::NewSymbol("removeListener"),
+        FunctionTemplate::New(RemoveListener)->GetFunction());
+}
+
+Handle<Value> NativeNode::Call(const Arguments& args)
+{
+    HandleScope scope;
+
+    if (args.Length() < 1 || !args[0]->IsObject()) {
+        return ThrowException(Exception::TypeError(String::New("First argument must be an object")));
+    }
+
+    if (args.Length() < 2 || !args[1]->IsFunction()) {
+        return ThrowException(Exception::TypeError(String::New("Second argument must be an function")));
+    }
+
+    Handle<Object> obj = Handle<Object>::Cast(args[0]);
+    Persistent<Function> func = Persistent<Function>::New(Handle<Function>::Cast(args[1]));
+
+    if (obj->Has(String::New("module"))) {
+        // Load module
+        std::string module(*String::Utf8Value(obj->Get(String::New("module"))->ToString()));
+        NativePlugin* plugin = NativePluginLoader::GetInstance()->Load(module);
+        if (!plugin) {
+            return ThrowException(Exception::TypeError(String::New("Plugin cannot be loaded")));
+        }
+
+        if (plugin && obj->Has(String::New("data"))) {
+            std::string data_str;
+            Handle<Value> data = obj->Get(String::New("data"));
+            if (data->IsObject()) {
+                data_str = *(String::Utf8Value(ToJSON(data)));
+            } else {
+                data_str = *(String::Utf8Value(data->ToString()));
+            }
+
+            // Register callback
+            int handle = NativeContext::GetInstance()->AddCallbackToMap(static_cast<void*>(*func));
+
+            // Invoke method
+            std::string ret_str = plugin->OnCall(data_str, handle);
+
+            // Return
+            return scope.Close(String::New(ret_str.c_str()));
+        }
+    }
+
+    return Undefined();
+}
+
+Handle<Value> NativeNode::CallSync(const Arguments& args)
+{
+    HandleScope scope;
+
+    if (args.Length() < 1 || !args[0]->IsObject()) {
+        return ThrowException(Exception::TypeError(String::New("Argument must be an object")));
+    }
+
+    Handle<Object> obj = Handle<Object>::Cast(args[0]);
+
+    if (obj->Has(String::New("module"))) {
+        // Load module
+        std::string module(*String::Utf8Value(obj->Get(String::New("module"))->ToString()));
+        NativePlugin* plugin = NativePluginLoader::GetInstance()->Load(module);
+        if (!plugin) {
+            return ThrowException(Exception::TypeError(String::New("Plugin cannot be loaded")));
+        }
+
+        if (plugin && obj->Has(String::New("data"))) {
+            std::string data_str;
+            Handle<Value> data = obj->Get(String::New("data"));
+            if (data->IsObject()) {
+                data_str = *(String::Utf8Value(ToJSON(data)));
+            } else {
+                data_str = *(String::Utf8Value(data->ToString()));
+            }
+
+            // Invoke method
+            std::string ret_str = plugin->OnCallSync(data_str);
+
+            // Return
+            return scope.Close(String::New(ret_str.c_str()));
+        }
+    }
+
+    return Undefined();
+}
+
+Handle<Value> NativeNode::AddListener(const Arguments& args)
+{
+    HandleScope scope;
+
+    if (args.Length() < 1 || !args[0]->IsString()) {
+        return ThrowException(Exception::TypeError(String::New("First argument must be an string")));
+    }
+
+    if (args.Length() < 2 || !args[1]->IsFunction()) {
+        return ThrowException(Exception::TypeError(String::New("Second argument must be an function")));
+    }
+
+    std::string event(*String::Utf8Value(Handle<String>::Cast(args[0])));
+    Persistent<Function> func = Persistent<Function>::New(Handle<Function>::Cast(args[1]));
+
+    NativeContext::GetInstance()->AddEventToMap(event, static_cast<void*>(*func));
+
+    return Undefined();
+}
+
+Handle<Value> NativeNode::RemoveListener(const Arguments& args)
+{
+    HandleScope scope;
+
+    if (args.Length() < 1 || !args[0]->IsString()) {
+        return ThrowException(Exception::TypeError(String::New("First argument must be an string")));
+    }
+
+    if (args.Length() < 2 || !args[1]->IsFunction()) {
+        return ThrowException(Exception::TypeError(String::New("Second argument must be an function")));
+    }
+
+    std::string event(*String::Utf8Value(Handle<String>::Cast(args[0])));
+    Local<Function> func = Local<Function>::New(Handle<Function>::Cast(args[1]));
+
+    NativeContext::GetInstance()->RemoveEventFromMap(event, static_cast<void*>(*func));
+
+    return Undefined();
+}
+
+} // namespace service
+} // namespace wrt
+
+extern "C" {
+    void static NodeInit(Handle<Object> target) {
+        wrt::service::NativeNode::Init(target);
+    }
+
+    NODE_MODULE(native, NodeInit);
+}
diff --git a/src/node/native-node.h b/src/node/native-node.h
new file mode 100644 (file)
index 0000000..05c14ce
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#ifndef WRT_SERIVCE_NODE_NATIVE_NODE_H_
+#define WRT_SERIVCE_NODE_NATIVE_NODE_H_
+
+#include <v8.h>
+
+using namespace v8;
+
+namespace wrt {
+namespace service {
+
+class NativeNode {
+public:
+    static void Init(Handle<Object> target);
+
+    static Handle<Value> Call(const Arguments& args);
+    static Handle<Value> CallSync(const Arguments& args);
+    static Handle<Value> AddListener(const Arguments& args);
+    static Handle<Value> RemoveListener(const Arguments& args);
+
+};
+
+} // namespace service
+} // namespace wrt
+
+#endif // WRT_SERIVCE_NODE_NATIVE_NODE_H_
diff --git a/src/node/native-plugin-loader.cpp b/src/node/native-plugin-loader.cpp
new file mode 100755 (executable)
index 0000000..356509f
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+#include <dlfcn.h>
+
+#include <dlog.h>
+
+#include "native-plugin-loader.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "WRT_SERVICE"
+
+namespace wrt {
+namespace service {
+
+namespace {
+    const char* kPluginPath = "/usr/lib/wrt-plugins";
+    const char* kPluginPrefix = "lib";
+    const char* kPluginSuffix = ".so";
+}
+
+NativePluginLoader* NativePluginLoader::GetInstance()
+{
+    static NativePluginLoader instance;
+    return &instance;
+}
+
+NativePlugin* NativePluginLoader::Load(std::string& name)
+{
+    std::string pluginPath(kPluginPath);
+    pluginPath.append("/");
+    pluginPath.append(kPluginPrefix);
+    pluginPath.append(name);
+    pluginPath.append(kPluginSuffix);
+
+    PluginMap::iterator it;
+
+    NativePlugin* plugin = NULL;
+    void* handle;
+
+    it = plugin_map_.find(name);
+    if (it == plugin_map_.end()) {
+        // Open a plugin object
+        handle = dlopen(pluginPath.c_str(), RTLD_NOW | RTLD_GLOBAL);
+        if (!handle) {
+            LOGE("Plugin Loading is failed. %s", dlerror());
+            return NULL;
+        }
+        // Clear errors
+        dlerror();
+
+        // Get a factory Function
+        create_native_plugin_t* createFunc
+                = (create_native_plugin_t *)dlsym(handle, "create_native_plugin");
+        if (!createFunc) {
+            LOGE("Plugin Loading is failed. %s", dlerror());
+            dlclose(handle);
+            return NULL;
+        }
+
+        // Create a new plugin instance
+        plugin = createFunc();
+        if (!plugin) {
+            LOGE("Plugin initialization is failed.");
+            fprintf(stderr, "Plugin initialization is failed.");
+            dlclose(handle);
+            return NULL;
+        }
+
+        // Call "OnLoad" callback
+        plugin->OnLoad();
+
+        plugin_map_[name] = plugin;
+
+    } else {
+        plugin = it->second;
+    }
+
+    return plugin;
+}
+
+} // namespace service
+} // namespace wrt
+
diff --git a/src/node/native-plugin-loader.h b/src/node/native-plugin-loader.h
new file mode 100644 (file)
index 0000000..27b51c0
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#ifndef WRT_SERVICE_NODE_NATIVE_PLUGIN_LOADER_H_
+#define WRT_SERVICE_NODE_NATIVE_PLUGIN_LOADER_H_
+
+#include <map>
+#include <string>
+
+#include <native-plugin.h>
+
+using namespace wrt::common;
+
+namespace wrt {
+namespace service {
+
+class NativePluginLoader {
+public:
+    static NativePluginLoader* GetInstance();
+
+    NativePlugin* Load(std::string& name);
+
+private:
+    typedef std::map<std::string, NativePlugin*> PluginMap;
+    PluginMap plugin_map_;
+
+};
+
+} // namespace service
+} // namespace wrt
+
+#endif // WRT_SERVICE_NODE_NATIVE_PLUGIN_LOADER_H_
diff --git a/src/node/service-util.cpp b/src/node/service-util.cpp
new file mode 100644 (file)
index 0000000..13dcc49
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+#include <string.h>
+
+#include <glib.h>
+#include <sqlite3.h>
+#include <dlog.h>
+#include <node.h>
+#include <v8.h>
+
+#include <privilege-control.h>
+#include <access-control.h>
+
+
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "WRT_SERVICE"
+
+using namespace node;
+using namespace v8;
+
+namespace {
+    const char *kWrtDBPath = "/opt/dbspace/.wrt.db";
+}
+
+namespace wrt {
+namespace service {
+
+static std::string GetStartScript(const std::string &appid){
+    std::string value;
+    sqlite3 *db = NULL;
+    sqlite3_stmt *stmt = NULL;
+
+    int ret = 0;
+    ret = sqlite3_open(kWrtDBPath, &db);
+    if( ret ){
+        return value;
+    }
+
+    const char * query = "select src from WidgetStartFile where app_id = "
+                 "(select app_id from WidgetInfo where tizen_appid = ?)"
+                 " order by start_file_id asc limit 1";
+
+    ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
+    ret |= sqlite3_bind_text(stmt, 1, appid.c_str(), -1, SQLITE_TRANSIENT);
+
+    if( ret )
+        goto error;
+
+    if( sqlite3_step(stmt) == SQLITE_ROW ){
+       char startfile[1024] = {0,};
+       strncpy(startfile, (char*)sqlite3_column_text(stmt, 0), 1023);
+       value = startfile;
+    }
+
+error:
+    sqlite3_finalize(stmt);
+    sqlite3_close(db);
+
+    return value;
+}
+
+static void InitAce(const std::string & appid){
+    wrt::common::AccessControl::GetInstance()->InitAppPrivileges(appid);
+}
+
+static void SetPrivilege(const std::string& pkgid, const std::string& path){
+    SECURE_LOGD("Set privilege : %s(%s)", pkgid.c_str(), path.c_str());
+    int ret = perm_app_set_privilege(pkgid.c_str(), "wgt", path.c_str());
+    if (ret != PC_OPERATION_SUCCESS) {
+        LOGE("error perm_app_set_privilege : (%d)", ret);
+    }
+}
+
+static Handle<Value> initAce(const Arguments& args){
+    HandleScope scope;
+    if( args.Length() < 1 )
+        return Undefined();
+
+    std::string appid(*String::Utf8Value(args[0]->ToString()));
+    InitAce(appid);
+
+    return Undefined();
+}
+
+static Handle<Value> getStartScript(const Arguments& args){
+    HandleScope scope;
+    if( args.Length() < 1 )
+        return Undefined();
+
+    std::string appid(*String::Utf8Value(args[0]->ToString()));
+    std::string start_script = GetStartScript(appid);
+
+    return String::New(start_script.c_str());
+}
+
+static Handle<Value> setPrivilege(const Arguments& args){
+    HandleScope scope;
+    if( args.Length() < 2 ){
+        LOGE("No enough arguments");
+        return Undefined();
+    }
+    std::string pkgid(*String::Utf8Value(args[0]->ToString()));
+    std::string path(*String::Utf8Value(args[1]->ToString()));
+    SetPrivilege(pkgid, path);
+
+    return Undefined();
+}
+
+static void init(Handle<Object> target) {
+    HandleScope scope;
+    target->Set(String::NewSymbol("getStartScript"), v8::FunctionTemplate::New(getStartScript)->GetFunction());
+    target->Set(String::NewSymbol("initAce"), v8::FunctionTemplate::New(initAce)->GetFunction());
+    target->Set(String::NewSymbol("setPrivilege"), v8::FunctionTemplate::New(setPrivilege)->GetFunction());
+}
+
+NODE_MODULE(serviceutil, init);
+
+} // namespace service
+} // namespace wrt
+
diff --git a/src/node/tizen-appfw.cpp b/src/node/tizen-appfw.cpp
new file mode 100644 (file)
index 0000000..cc403bc
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * 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.
+ */
+
+#include <string.h>
+#include <glib.h>
+#include <dlog.h>
+#include <v8.h>
+#include <node.h>
+
+#include "tizen-appfw.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "WRT_SERVICE"
+
+using namespace node;
+using namespace v8;
+
+namespace wrt {
+namespace service {
+
+static int aulHandler(aul_type type, bundle *bd, void *data){
+    TizenAppFW *appfw = static_cast<TizenAppFW*>(data);
+    if(appfw == NULL)
+        return 0;
+
+    switch(type){
+        case AUL_START:
+        {
+            int len;
+            char *encoded_bundle;
+            bundle_encode(bd, (bundle_raw**)&encoded_bundle, &len);
+            appfw->OnService(encoded_bundle);
+            free(encoded_bundle);
+            break;
+        }
+        case AUL_TERMINATE:
+            appfw->OnTerminate();
+            break;
+        default:
+            LOGW("Unhandled aul event. type=%d", type);
+            break;
+    }
+    return 0;
+}
+
+TizenAppFW& TizenAppFW::GetInstance(){
+    static TizenAppFW instance;
+    return instance;
+}
+
+TizenAppFW::TizenAppFW():initialized_(false){
+}
+TizenAppFW::~TizenAppFW(){
+}
+
+void TizenAppFW::Init(int argc, char **argv){
+    if( initialized_ )
+        return;
+    initialized_ = true;
+    aul_launch_init(aulHandler, this);
+    aul_launch_argv_handler(argc, argv);
+}
+
+void TizenAppFW::OnService( const char * bundle ){
+    if( service_handler_->IsFunction()){
+        Handle<String> v = String::New(bundle);
+        Handle<Value> args[1] = {v};
+        service_handler_->Call(service_handler_, 1, args);
+    }
+}
+
+void TizenAppFW::OnTerminate(){
+    if( terminate_handler_->IsFunction())
+        terminate_handler_->Call(terminate_handler_, 0, NULL);
+}
+
+void TizenAppFW::set_service_handler(Handle<Function> handler){
+    service_handler_.Dispose();
+    service_handler_ = Persistent<Function>::New(handler);
+}
+
+v8::Handle<v8::Function> TizenAppFW::service_handler(){
+    return service_handler_;
+}
+
+void TizenAppFW::set_terminate_handler(Handle<Function> handler){
+    terminate_handler_.Dispose();
+    terminate_handler_ = Persistent<Function>::New(handler);
+}
+
+v8::Handle<v8::Function> TizenAppFW::terminate_handler(){
+    return terminate_handler_;
+}
+
+
+static Handle<Value> onServiceGetter(Local<String> property, const AccessorInfo &info){
+    HandleScope scope;
+    Handle<Value> handler = TizenAppFW::GetInstance().service_handler();
+    return scope.Close(handler);
+}
+
+static void onServiceSetter(Local<String> property, Local<Value> value, const AccessorInfo &info){
+    HandleScope scope;
+    if( value->IsFunction() )
+        TizenAppFW::GetInstance().set_service_handler(Handle<Function>::Cast(value));
+}
+
+static Handle<Value> onTerminateGetter(Local<String> property, const AccessorInfo &info){
+    HandleScope scope;
+    Handle<Value> handler = TizenAppFW::GetInstance().terminate_handler();
+    return scope.Close(handler);
+}
+
+static void onTerminateSetter(Local<String> property, Local<Value> value, const AccessorInfo &info){
+    HandleScope scope;
+    if( value->IsFunction() )
+        TizenAppFW::GetInstance().set_terminate_handler(Handle<Function>::Cast(value));
+}
+
+static Handle<Value> appfwInit(const Arguments& args){
+    HandleScope scope;
+    if( args.Length() < 1 )
+        return Undefined();
+
+    if( !args[0]->IsArray() ){
+        return Undefined();
+    }
+    Local<Array> array_args = Local<Array>::Cast(args[0]);
+    int argc = array_args->Length();
+    {
+        char *argv[argc];
+        for(int i=0; i< argc; i++){
+            Local<String> arg = array_args->Get(i)->ToString();
+            int nsize = arg->Utf8Length()+1;
+            argv[i] = static_cast<char*>(malloc(nsize));
+            memset(argv[i], 0, nsize);
+            arg->WriteUtf8(argv[i]);
+        }
+        TizenAppFW::GetInstance().Init(argc, argv);
+        for(int i=0; i<argc;i++){
+            free(argv[i]);
+        }
+    }
+       return Undefined();
+}
+
+static void init(Handle<Object> target) {
+    HandleScope scope;
+    TizenAppFW::GetInstance();
+    target->Set(String::NewSymbol("init"), v8::FunctionTemplate::New(appfwInit)->GetFunction());
+    target->SetAccessor(String::NewSymbol("onService"), onServiceGetter, onServiceSetter);
+    target->SetAccessor(String::NewSymbol("onTerminate"), onTerminateGetter, onTerminateSetter);
+
+}
+
+NODE_MODULE(appfw, init);
+
+} // namespace service
+} // namespace wrt
diff --git a/src/node/tizen-appfw.h b/src/node/tizen-appfw.h
new file mode 100644 (file)
index 0000000..259363f
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#ifndef WRT_SERIVCE_NODE_TIZEN_APPFW_H_
+#define WRT_SERIVCE_NODE_TIZEN_APPFW_H_
+
+#include <string>
+#include <aul.h>
+#include <v8.h>
+
+namespace wrt {
+namespace service {
+
+class TizenAppFW{
+public:
+    static TizenAppFW& GetInstance();
+
+    void set_service_handler(v8::Handle<v8::Function> handler);
+    v8::Handle<v8::Function> service_handler();
+    void set_terminate_handler(v8::Handle<v8::Function> handler);
+    v8::Handle<v8::Function> terminate_handler();
+
+    void Init(int argc , char **argv);
+    void OnService(const char * bundle);
+    void OnTerminate();
+
+private:
+    TizenAppFW();
+    virtual ~TizenAppFW();
+
+    bool initialized_;
+    v8::Persistent<v8::Function> service_handler_;
+    v8::Persistent<v8::Function> terminate_handler_;
+
+};
+
+} // namespace service
+} // namespace wrt
+
+#endif // WRT_SERIVCE_NODE_TIZEN_APPFW_H_
diff --git a/wrt-service.manifest b/wrt-service.manifest
new file mode 100644 (file)
index 0000000..75b0fa5
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+    <request>
+        <domain name="_"/>
+    </request>
+</manifest>