Apply DBus IPC to Runtime and Extension
authorWonYoung Choi <wy80.choi@samsung.com>
Fri, 17 Apr 2015 06:18:58 +0000 (15:18 +0900)
committerWonYoung Choi <wy80.choi@samsung.com>
Wed, 22 Apr 2015 09:11:47 +0000 (18:11 +0900)
- Added DBusServer for Runtime
- Added DBusServer for Extension
- Added ExtensionProcess

Change-Id: I0733701ca6d9cc59ec08e13974cc5e6c773dced0

21 files changed:
CMakeLists.txt
packaging/wrt.spec
src/bundle/CMakeLists.txt
src/bundle/injected_bundle.cc
src/common/CMakeLists.txt
src/common/constants.cc [new file with mode: 0644]
src/common/constants.h [new file with mode: 0644]
src/common/dbus_client.cc
src/common/dbus_client.h
src/common/dbus_server.cc
src/common/message_types.cc [deleted file]
src/common/message_types.h [deleted file]
src/common/picojson.h [deleted file]
src/extension/CMakeLists.txt
src/extension/extension_main.cc [new file with mode: 0644]
src/extension/extension_server.cc
src/extension/extension_server.h
src/runtime/CMakeLists.txt
src/runtime/runtime.cc
src/runtime/runtime.h
src/runtime/web_application.cc

index 2429ad6..f98c49e 100644 (file)
@@ -41,7 +41,7 @@ ENDIF(WAYLAND_SUPPORT)
 # Targets names
 SET(TARGET_RUNTIME  "wrt")
 SET(TARGET_COMMON_STATIC "wrt-common-static")
-SET(TARGET_EXTENSION_STATIC "wrt-extension-static")
+SET(TARGET_EXTENSION "wrt-extension")
 SET(TARGET_INJECTED_BUNDLE "wrt-injected-bundle")
 
 # Sub Directories
index 0639cb7..eb048d1 100755 (executable)
@@ -25,6 +25,7 @@ BuildRequires: pkgconfig(deviced)
 BuildRequires: pkgconfig(capi-system-runtime-info)
 BuildRequires: pkgconfig(cert-svc)
 BuildRequires: pkgconfig(uuid)
+BuildRequires: pkgconfig(gio-2.0)
 BuildRequires: boost-devel
 %if %{with x}
 BuildRequires: pkgconfig(ecore-x)
@@ -81,5 +82,6 @@ rm -fr %{buildroot}
 
 %files
 %attr(755,root,root) %{_bindir}/wrt
+%attr(755,root,root) %{_bindir}/wrt-extension
 %attr(644,root,root) %{_datadir}/edje/wrt/wrt.edj
 %attr(644,root,root) %{_libdir}/libwrt-injected-bundle.so
index b3afd1e..5545362 100644 (file)
@@ -4,6 +4,7 @@
 
 # Dependencies
 PKG_CHECK_MODULES(TARGET_INJECTED_BUNDLE_DEPS REQUIRED
+  dlog
   elementary
   chromium-efl
 )
index 73b49b2..1aa6305 100644 (file)
@@ -6,7 +6,10 @@
 #include <ewk_ipc_message.h>
 #include <string>
 
+#include "common/logger.h"
+
 extern "C" void DynamicSetWidgetInfo(int widget_id) {
+  LoggerD("InjectedBundle::DynamicSetWidgetInfo !!");
 }
 
 extern "C" void DynamicPluginStartSession(int widget_id,
@@ -16,21 +19,27 @@ extern "C" void DynamicPluginStartSession(int widget_id,
                                           const char* encoded_bundle,
                                           const char* theme,
                                           const char* base_url) {
+  LoggerD("InjectedBundle::DynamicPluginStartSession !!");
 }
 
 extern "C" void DynamicPluginStopSession(
     int widget_id, v8::Handle<v8::Context> context) {
+  LoggerD("InjectedBundle::DynamicPluginStopSession !!");
 }
 
 extern "C" void DynamicUrlParsing(
     std::string* old_url, std::string* new_url, int widget_id) {
+  LoggerD("InjectedBundle::DynamicUrlParsing !!");
 }
 
 extern "C" void DynamicDatabaseAttach(int attach) {
+  LoggerD("InjectedBundle::DynamicDatabaseAttach !!");
 }
 
 extern "C" void DynamicOnIPCMessage(const Ewk_IPC_Wrt_Message_Data& data) {
+  LoggerD("InjectedBundle::DynamicOnIPCMessage !!");
 }
 
 extern "C" void DynamicPreloading() {
+  LoggerD("InjectedBundle::DynamicPreloading !!");
 }
index 633db26..0c5faa1 100644 (file)
@@ -4,6 +4,7 @@
 
 PKG_CHECK_MODULES(TARGET_COMMON_STATIC_DEPS
   uuid
+  gio-2.0
   dlog
   REQUIRED
 )
@@ -14,10 +15,12 @@ SET(TARGET_COMMON_STATIC_INCS
 )
 
 SET(TARGET_COMMON_STATIC_SRCS
+  ${BASE_SRCDIR}/common/constants.cc
   ${BASE_SRCDIR}/common/file_utils.cc
-  ${BASE_SRCDIR}/common/message_types.cc
   ${BASE_SRCDIR}/common/string_utils.cc
   ${BASE_SRCDIR}/common/command_line.cc
+  ${BASE_SRCDIR}/common/dbus_server.cc
+  ${BASE_SRCDIR}/common/dbus_client.cc
 )
 
 INCLUDE_DIRECTORIES(${TARGET_COMMON_STATIC_INCS})
diff --git a/src/common/constants.cc b/src/common/constants.cc
new file mode 100644 (file)
index 0000000..fe49580
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "common/constants.h"
+
+namespace wrt {
+
+const char kSystemExtensionPath[] = "/usr/lib/tizen-extensions-crosswalk";
+const char kExtensionPrefix[] = "lib";
+const char kExtensionSuffix[] = ".so";
+
+const char kDBusNameForRuntime[] = "Runtime";
+const char kDBusInterfaceNameForRuntime[] = "org.tizen.wrt.Runtime";
+const char kMethodNotifyEPCreated[] = "NotifyEPCreated";
+const char kMethodGetRuntimeVariable[] = "GetRuntimeVariable";
+
+const char kDBusNameForExtension[] = "Extension";
+const char kDBusInterfaceNameForExtension[] = "org.tizen.wrt.Extension";
+
+}  // namespace wrt
diff --git a/src/common/constants.h b/src/common/constants.h
new file mode 100644 (file)
index 0000000..7895c73
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WRT_COMMON_CONSTANTS_H_
+#define WRT_COMMON_CONSTANTS_H_
+
+namespace wrt {
+
+extern const char kSystemExtensionPath[];
+extern const char kExtensionPrefix[];
+extern const char kExtensionSuffix[];
+
+extern const char kDBusNameForRuntime[];
+extern const char kDBusInterfaceNameForRuntime[];
+extern const char kMethodNotifyEPCreated[];
+extern const char kMethodGetRuntimeVariable[];
+
+extern const char kDBusNameForExtension[];
+extern const char kDBusInterfaceNameForExtension[];
+
+}  // namespace wrt
+
+#endif  // WRT_COMMON_CONSTANTS_H_
index 1262739..de5ff18 100644 (file)
@@ -41,22 +41,31 @@ bool DBusClient::Connect(const std::string& address) {
   return true;
 }
 
-GVariant* DBusClient::CallSync(const std::string& iface,
-                               const std::string& method,
-                               GVariant* parameters,
-                               const GVariantType* reply_type) {
+GVariant* DBusClient::Call(const std::string& iface,
+                           const std::string& method,
+                           GVariant* parameters,
+                           const GVariantType* reply_type) {
   if (!connection_) {
     return NULL;
   }
 
   GError *err = NULL;
-  GVariant* reply = g_dbus_connection_call_sync(
-      connection_, NULL, "/", iface.c_str(), method.c_str(), parameters,
-      reply_type, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
-  if (!reply) {
-    LoggerE("Failed to CallSync : %s", err->message);
-    g_error_free(err);
+  GVariant* reply = NULL;
+
+  if (reply_type) {
+    reply = g_dbus_connection_call_sync(
+        connection_, NULL, "/", iface.c_str(), method.c_str(), parameters,
+        reply_type, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
+    if (!reply) {
+      LoggerE("Failed to CallSync : %s", err->message);
+      g_error_free(err);
+    }
+  } else {
+    g_dbus_connection_call(
+        connection_, NULL, "/", iface.c_str(), method.c_str(), parameters,
+        NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
   }
+
   return reply;
 }
 
index fbea099..c171ca7 100644 (file)
@@ -20,8 +20,8 @@ class DBusClient {
   bool Connect(const std::string& address);
   bool ConnectByName(const std::string& name);
 
-  GVariant* CallSync(const std::string& iface, const std::string& method,
-                     GVariant* parameters, const GVariantType* reply_type);
+  GVariant* Call(const std::string& iface, const std::string& method,
+                 GVariant* parameters, const GVariantType* reply_type);
  private:
   GDBusConnection* connection_;
 };
index c204862..c2569eb 100644 (file)
@@ -34,7 +34,7 @@ static GVariant* OnGetProperty(GDBusConnection* /*connection*/,
                                const gchar* /*object_path*/,
                                const gchar* interface_name,
                                const gchar* property_name,
-                               GError** error,
+                               GError** /*error*/,
                                gpointer user_data) {
   DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
   if (!self) {
@@ -59,7 +59,7 @@ static gboolean OnSetProperty(GDBusConnection* /*connection*/,
                               const gchar* interface_name,
                               const gchar* property_name,
                               GVariant* value,
-                              GError** error,
+                              GError** /*error*/,
                               gpointer user_data) {
   DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
   if (!self) {
@@ -167,7 +167,9 @@ void DBusServer::Start(const std::string& name) {
   unlink(address.c_str());
   address = "unix:path=" + address;
 
-  // create new bus
+  // create new bus socket
+  // TODO(wy80.choi): bus socket (Address) should be removed gracefully
+  // when application is terminated.
   gchar* guid = g_dbus_generate_guid();
   server_ = g_dbus_server_new_sync(
                   address.c_str(), G_DBUS_SERVER_FLAGS_NONE,
@@ -184,6 +186,8 @@ void DBusServer::Start(const std::string& name) {
                    G_CALLBACK(OnClientRequest), this);
 
   g_dbus_server_start(server_);
+
+  LoggerD("DBusServer(%s) has been started.", address.c_str());
 }
 
 std::string DBusServer::GetClientAddress() const {
diff --git a/src/common/message_types.cc b/src/common/message_types.cc
deleted file mode 100644 (file)
index 80185ac..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/message_types.h"
-
-namespace wrt {
-
-namespace message_types {
-
-const char* kExtensionTypePrefix = "tizen://extension/";
-const char* kExtensionEPCreated = "tizen://extension/ep_created";
-const char* kExtensionGetExtensions = "tizen://extension/get_extensions";
-const char* kExtensionCreateInstance = "tizen://extension/create_instance";
-const char* kExtensionDestroyInstance = "tizen://extension/destroy_instance";
-const char* kExtensionCallSync = "tizen://extension/call_sync";
-const char* kExtensionCallAsync = "tizen://extension/call_async";
-const char* kExtensionPostMessageToJS = "tizen://extension/post_message_to_js";
-
-}  // namespace message_types
-
-}  // namespace wrt
diff --git a/src/common/message_types.h b/src/common/message_types.h
deleted file mode 100644 (file)
index 827890d..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef WRT_COMMON_MESSAGE_TYPES_H_
-#define WRT_COMMON_MESSAGE_TYPES_H_
-
-namespace wrt {
-
-namespace message_types {
-
-extern const char* kExtensionTypePrefix;
-extern const char* kExtensionEPCreated;
-extern const char* kExtensionGetExtensions;
-extern const char* kExtensionCreateInstance;
-extern const char* kExtensionDestroyInstance;
-extern const char* kExtensionCallSync;
-extern const char* kExtensionCallAsync;
-extern const char* kExtensionPostMessageToJS;
-
-}  // namespace message_types
-
-}  // namespace wrt
-
-#endif  // WRT_COMMON_MESSAGE_TYPES_H_
diff --git a/src/common/picojson.h b/src/common/picojson.h
deleted file mode 100644 (file)
index 48bb64e..0000000
+++ /dev/null
@@ -1,1010 +0,0 @@
-/*
- * Copyright 2009-2010 Cybozu Labs, Inc.
- * Copyright 2011-2014 Kazuho Oku
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef picojson_h
-#define picojson_h
-
-#include <algorithm>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <iostream>
-#include <iterator>
-#include <limits>
-#include <map>
-#include <stdexcept>
-#include <string>
-#include <vector>
-
-// for isnan/isinf
-#if __cplusplus>=201103L
-# include <cmath>
-#else
-extern "C" {
-# ifdef _MSC_VER
-#  include <float.h>
-# elif defined(__INTEL_COMPILER)
-#  include <mathimf.h>
-# else
-#  include <math.h>
-# endif
-}
-#endif
-
-// experimental support for int64_t (see README.mkdn for detail)
-#ifdef PICOJSON_USE_INT64
-# define __STDC_FORMAT_MACROS
-# include <errno.h>
-# include <inttypes.h>
-#endif
-
-// to disable the use of localeconv(3), set PICOJSON_USE_LOCALE to 0
-#ifndef PICOJSON_USE_LOCALE
-# define PICOJSON_USE_LOCALE 1
-#endif
-#if PICOJSON_USE_LOCALE
-extern "C" {
-# include <locale.h>
-}
-#endif
-
-#ifndef PICOJSON_ASSERT
-# define PICOJSON_ASSERT(e) do { if (! (e)) throw std::runtime_error(#e); } while (0)
-#endif
-
-#ifdef _MSC_VER
-    #define SNPRINTF _snprintf_s
-    #pragma warning(push)
-    #pragma warning(disable : 4244) // conversion from int to char
-    #pragma warning(disable : 4127) // conditional expression is constant
-    #pragma warning(disable : 4702) // unreachable code
-#else
-    #define SNPRINTF snprintf
-#endif
-
-namespace picojson {
-  
-  enum {
-    null_type,
-    boolean_type,
-    number_type,
-    string_type,
-    array_type,
-    object_type
-#ifdef PICOJSON_USE_INT64
-    , int64_type
-#endif
-  };
-  
-  enum {
-    INDENT_WIDTH = 2
-  };
-
-  struct null {};
-  
-  class value {
-  public:
-    typedef std::vector<value> array;
-    typedef std::map<std::string, value> object;
-    union _storage {
-      bool boolean_;
-      double number_;
-#ifdef PICOJSON_USE_INT64
-      int64_t int64_;
-#endif
-      std::string* string_;
-      array* array_;
-      object* object_;
-    };
-  protected:
-    int type_;
-    _storage u_;
-  public:
-    value();
-    value(int type, bool);
-    explicit value(bool b);
-#ifdef PICOJSON_USE_INT64
-    explicit value(int64_t i);
-#endif
-    explicit value(double n);
-    explicit value(const std::string& s);
-    explicit value(const array& a);
-    explicit value(const object& o);
-    explicit value(const char* s);
-    value(const char* s, size_t len);
-    ~value();
-    value(const value& x);
-    value& operator=(const value& x);
-    void swap(value& x);
-    template <typename T> bool is() const;
-    template <typename T> const T& get() const;
-    template <typename T> T& get();
-    bool evaluate_as_boolean() const;
-    const value& get(size_t idx) const;
-    const value& get(const std::string& key) const;
-    value& get(size_t idx);
-    value& get(const std::string& key);
-
-    bool contains(size_t idx) const;
-    bool contains(const std::string& key) const;
-    std::string to_str() const;
-    template <typename Iter> void serialize(Iter os, bool prettify = false) const;
-    std::string serialize(bool prettify = false) const;
-  private:
-    template <typename T> value(const T*); // intentionally defined to block implicit conversion of pointer to bool
-    template <typename Iter> static void _indent(Iter os, int indent);
-    template <typename Iter> void _serialize(Iter os, int indent) const;
-    std::string _serialize(int indent) const;
-  };
-  
-  typedef value::array array;
-  typedef value::object object;
-  
-  inline value::value() : type_(null_type) {}
-  
-  inline value::value(int type, bool) : type_(type) {
-    switch (type) {
-#define INIT(p, v) case p##type: u_.p = v; break
-      INIT(boolean_, false);
-      INIT(number_, 0.0);
-#ifdef PICOJSON_USE_INT64
-      INIT(int64_, 0);
-#endif
-      INIT(string_, new std::string());
-      INIT(array_, new array());
-      INIT(object_, new object());
-#undef INIT
-    default: break;
-    }
-  }
-  
-  inline value::value(bool b) : type_(boolean_type) {
-    u_.boolean_ = b;
-  }
-
-#ifdef PICOJSON_USE_INT64
-  inline value::value(int64_t i) : type_(int64_type) {
-    u_.int64_ = i;
-  }
-#endif
-
-  inline value::value(double n) : type_(number_type) {
-    if (
-#ifdef _MSC_VER
-        ! _finite(n)
-#elif __cplusplus>=201103L || !(defined(isnan) && defined(isinf))
-               std::isnan(n) || std::isinf(n)
-#else
-        isnan(n) || isinf(n)
-#endif
-        ) {
-      throw std::overflow_error("");
-    }
-    u_.number_ = n;
-  }
-  
-  inline value::value(const std::string& s) : type_(string_type) {
-    u_.string_ = new std::string(s);
-  }
-  
-  inline value::value(const array& a) : type_(array_type) {
-    u_.array_ = new array(a);
-  }
-  
-  inline value::value(const object& o) : type_(object_type) {
-    u_.object_ = new object(o);
-  }
-  
-  inline value::value(const char* s) : type_(string_type) {
-    u_.string_ = new std::string(s);
-  }
-  
-  inline value::value(const char* s, size_t len) : type_(string_type) {
-    u_.string_ = new std::string(s, len);
-  }
-  
-  inline value::~value() {
-    switch (type_) {
-#define DEINIT(p) case p##type: delete u_.p; break
-      DEINIT(string_);
-      DEINIT(array_);
-      DEINIT(object_);
-#undef DEINIT
-    default: break;
-    }
-  }
-  
-  inline value::value(const value& x) : type_(x.type_) {
-    switch (type_) {
-#define INIT(p, v) case p##type: u_.p = v; break
-      INIT(string_, new std::string(*x.u_.string_));
-      INIT(array_, new array(*x.u_.array_));
-      INIT(object_, new object(*x.u_.object_));
-#undef INIT
-    default:
-      u_ = x.u_;
-      break;
-    }
-  }
-  
-  inline value& value::operator=(const value& x) {
-    if (this != &x) {
-      value t(x);
-      swap(t);
-    }
-    return *this;
-  }
-  
-  inline void value::swap(value& x) {
-    std::swap(type_, x.type_);
-    std::swap(u_, x.u_);
-  }
-  
-#define IS(ctype, jtype)                            \
-  template <> inline bool value::is<ctype>() const { \
-    return type_ == jtype##_type;                   \
-  }
-  IS(null, null)
-  IS(bool, boolean)
-#ifdef PICOJSON_USE_INT64
-  IS(int64_t, int64)
-#endif
-  IS(std::string, string)
-  IS(array, array)
-  IS(object, object)
-#undef IS
-  template <> inline bool value::is<double>() const {
-    return type_ == number_type
-#ifdef PICOJSON_USE_INT64
-      || type_ == int64_type
-#endif
-      ;
-  }
-  
-#define GET(ctype, var)                                                \
-  template <> inline const ctype& value::get<ctype>() const {  \
-    PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" \
-          && is<ctype>());                                     \
-    return var;                                                        \
-  }                                                            \
-  template <> inline ctype& value::get<ctype>() {              \
-    PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()"        \
-          && is<ctype>());                                     \
-    return var;                                                        \
-  }
-  GET(bool, u_.boolean_)
-  GET(std::string, *u_.string_)
-  GET(array, *u_.array_)
-  GET(object, *u_.object_)
-#ifdef PICOJSON_USE_INT64
-  GET(double, (type_ == int64_type && (const_cast<value*>(this)->type_ = number_type, const_cast<value*>(this)->u_.number_ = u_.int64_), u_.number_))
-  GET(int64_t, u_.int64_)
-#else
-  GET(double, u_.number_)
-#endif
-#undef GET
-  
-  inline bool value::evaluate_as_boolean() const {
-    switch (type_) {
-    case null_type:
-      return false;
-    case boolean_type:
-      return u_.boolean_;
-    case number_type:
-      return u_.number_ != 0;
-    case string_type:
-      return ! u_.string_->empty();
-    default:
-      return true;
-    }
-  }
-  
-  inline const value& value::get(size_t idx) const {
-    static value s_null;
-    PICOJSON_ASSERT(is<array>());
-    return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
-  }
-
-  inline value& value::get(size_t idx) {
-    static value s_null;
-    PICOJSON_ASSERT(is<array>());
-    return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
-  }
-
-  inline const value& value::get(const std::string& key) const {
-    static value s_null;
-    PICOJSON_ASSERT(is<object>());
-    object::const_iterator i = u_.object_->find(key);
-    return i != u_.object_->end() ? i->second : s_null;
-  }
-
-  inline value& value::get(const std::string& key) {
-    static value s_null;
-    PICOJSON_ASSERT(is<object>());
-    object::iterator i = u_.object_->find(key);
-    return i != u_.object_->end() ? i->second : s_null;
-  }
-
-  inline bool value::contains(size_t idx) const {
-    PICOJSON_ASSERT(is<array>());
-    return idx < u_.array_->size();
-  }
-
-  inline bool value::contains(const std::string& key) const {
-    PICOJSON_ASSERT(is<object>());
-    object::const_iterator i = u_.object_->find(key);
-    return i != u_.object_->end();
-  }
-  
-  inline std::string value::to_str() const {
-    switch (type_) {
-    case null_type:      return "null";
-    case boolean_type:   return u_.boolean_ ? "true" : "false";
-#ifdef PICOJSON_USE_INT64
-    case int64_type: {
-      char buf[sizeof("-9223372036854775808")];
-      SNPRINTF(buf, sizeof(buf), "%" PRId64, u_.int64_);
-      return buf;
-    }
-#endif
-    case number_type:    {
-      char buf[256];
-      double tmp;
-      SNPRINTF(buf, sizeof(buf), fabs(u_.number_) < (1ULL << 53) && modf(u_.number_, &tmp) == 0 ? "%.f" : "%.17g", u_.number_);
-#if PICOJSON_USE_LOCALE
-      char *decimal_point = localeconv()->decimal_point;
-      if (strcmp(decimal_point, ".") != 0) {
-        size_t decimal_point_len = strlen(decimal_point);
-        for (char *p = buf; *p != '\0'; ++p) {
-          if (strncmp(p, decimal_point, decimal_point_len) == 0) {
-            return std::string(buf, p) + "." + (p + decimal_point_len);
-          }
-        }
-      }
-#endif
-      return buf;
-    }
-    case string_type:    return *u_.string_;
-    case array_type:     return "array";
-    case object_type:    return "object";
-    default:             PICOJSON_ASSERT(0);
-#ifdef _MSC_VER
-      __assume(0);
-#endif
-    }
-    return std::string();
-  }
-  
-  template <typename Iter> void copy(const std::string& s, Iter oi) {
-    std::copy(s.begin(), s.end(), oi);
-  }
-  
-  template <typename Iter> void serialize_str(const std::string& s, Iter oi) {
-    *oi++ = '"';
-    for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) {
-      switch (*i) {
-#define MAP(val, sym) case val: copy(sym, oi); break
-       MAP('"', "\\\"");
-       MAP('\\', "\\\\");
-       MAP('/', "\\/");
-       MAP('\b', "\\b");
-       MAP('\f', "\\f");
-       MAP('\n', "\\n");
-       MAP('\r', "\\r");
-       MAP('\t', "\\t");
-#undef MAP
-      default:
-       if (static_cast<unsigned char>(*i) < 0x20 || *i == 0x7f) {
-         char buf[7];
-         SNPRINTF(buf, sizeof(buf), "\\u%04x", *i & 0xff);
-         copy(buf, buf + 6, oi);
-         } else {
-         *oi++ = *i;
-       }
-       break;
-      }
-    }
-    *oi++ = '"';
-  }
-
-  template <typename Iter> void value::serialize(Iter oi, bool prettify) const {
-    return _serialize(oi, prettify ? 0 : -1);
-  }
-  
-  inline std::string value::serialize(bool prettify) const {
-    return _serialize(prettify ? 0 : -1);
-  }
-
-  template <typename Iter> void value::_indent(Iter oi, int indent) {
-    *oi++ = '\n';
-    for (int i = 0; i < indent * INDENT_WIDTH; ++i) {
-      *oi++ = ' ';
-    }
-  }
-
-  template <typename Iter> void value::_serialize(Iter oi, int indent) const {
-    switch (type_) {
-    case string_type:
-      serialize_str(*u_.string_, oi);
-      break;
-    case array_type: {
-      *oi++ = '[';
-      if (indent != -1) {
-        ++indent;
-      }
-      for (array::const_iterator i = u_.array_->begin();
-           i != u_.array_->end();
-           ++i) {
-       if (i != u_.array_->begin()) {
-         *oi++ = ',';
-       }
-        if (indent != -1) {
-          _indent(oi, indent);
-        }
-       i->_serialize(oi, indent);
-      }
-      if (indent != -1) {
-        --indent;
-        if (! u_.array_->empty()) {
-          _indent(oi, indent);
-        }
-      }
-      *oi++ = ']';
-      break;
-    }
-    case object_type: {
-      *oi++ = '{';
-      if (indent != -1) {
-        ++indent;
-      }
-      for (object::const_iterator i = u_.object_->begin();
-          i != u_.object_->end();
-          ++i) {
-       if (i != u_.object_->begin()) {
-         *oi++ = ',';
-       }
-        if (indent != -1) {
-          _indent(oi, indent);
-        }
-       serialize_str(i->first, oi);
-       *oi++ = ':';
-        if (indent != -1) {
-          *oi++ = ' ';
-        }
-        i->second._serialize(oi, indent);
-      }
-      if (indent != -1) {
-        --indent;
-        if (! u_.object_->empty()) {
-          _indent(oi, indent);
-        }
-      }
-      *oi++ = '}';
-      break;
-    }
-    default:
-      copy(to_str(), oi);
-      break;
-    }
-    if (indent == 0) {
-      *oi++ = '\n';
-    }
-  }
-  
-  inline std::string value::_serialize(int indent) const {
-    std::string s;
-    _serialize(std::back_inserter(s), indent);
-    return s;
-  }
-  
-  template <typename Iter> class input {
-  protected:
-    Iter cur_, end_;
-    int last_ch_;
-    bool ungot_;
-    int line_;
-  public:
-    input(const Iter& first, const Iter& last) : cur_(first), end_(last), last_ch_(-1), ungot_(false), line_(1) {}
-    int getc() {
-      if (ungot_) {
-       ungot_ = false;
-       return last_ch_;
-      }
-      if (cur_ == end_) {
-       last_ch_ = -1;
-       return -1;
-      }
-      if (last_ch_ == '\n') {
-       line_++;
-      }
-      last_ch_ = *cur_ & 0xff;
-      ++cur_;
-      return last_ch_;
-    }
-    void ungetc() {
-      if (last_ch_ != -1) {
-       PICOJSON_ASSERT(! ungot_);
-       ungot_ = true;
-      }
-    }
-    Iter cur() const { return cur_; }
-    int line() const { return line_; }
-    void skip_ws() {
-      while (1) {
-       int ch = getc();
-       if (! (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')) {
-         ungetc();
-         break;
-       }
-      }
-    }
-    bool expect(int expect) {
-      skip_ws();
-      if (getc() != expect) {
-       ungetc();
-       return false;
-      }
-      return true;
-    }
-    bool match(const std::string& pattern) {
-      for (std::string::const_iterator pi(pattern.begin());
-          pi != pattern.end();
-          ++pi) {
-       if (getc() != *pi) {
-         ungetc();
-         return false;
-       }
-      }
-      return true;
-    }
-  };
-  
-  template<typename Iter> inline int _parse_quadhex(input<Iter> &in) {
-    int uni_ch = 0, hex;
-    for (int i = 0; i < 4; i++) {
-      if ((hex = in.getc()) == -1) {
-       return -1;
-      }
-      if ('0' <= hex && hex <= '9') {
-       hex -= '0';
-      } else if ('A' <= hex && hex <= 'F') {
-       hex -= 'A' - 0xa;
-      } else if ('a' <= hex && hex <= 'f') {
-       hex -= 'a' - 0xa;
-      } else {
-       in.ungetc();
-       return -1;
-      }
-      uni_ch = uni_ch * 16 + hex;
-    }
-    return uni_ch;
-  }
-  
-  template<typename String, typename Iter> inline bool _parse_codepoint(String& out, input<Iter>& in) {
-    int uni_ch;
-    if ((uni_ch = _parse_quadhex(in)) == -1) {
-      return false;
-    }
-    if (0xd800 <= uni_ch && uni_ch <= 0xdfff) {
-      if (0xdc00 <= uni_ch) {
-       // a second 16-bit of a surrogate pair appeared
-       return false;
-      }
-      // first 16-bit of surrogate pair, get the next one
-      if (in.getc() != '\\' || in.getc() != 'u') {
-       in.ungetc();
-       return false;
-      }
-      int second = _parse_quadhex(in);
-      if (! (0xdc00 <= second && second <= 0xdfff)) {
-       return false;
-      }
-      uni_ch = ((uni_ch - 0xd800) << 10) | ((second - 0xdc00) & 0x3ff);
-      uni_ch += 0x10000;
-    }
-    if (uni_ch < 0x80) {
-      out.push_back(uni_ch);
-    } else {
-      if (uni_ch < 0x800) {
-       out.push_back(0xc0 | (uni_ch >> 6));
-      } else {
-       if (uni_ch < 0x10000) {
-         out.push_back(0xe0 | (uni_ch >> 12));
-       } else {
-         out.push_back(0xf0 | (uni_ch >> 18));
-         out.push_back(0x80 | ((uni_ch >> 12) & 0x3f));
-       }
-       out.push_back(0x80 | ((uni_ch >> 6) & 0x3f));
-      }
-      out.push_back(0x80 | (uni_ch & 0x3f));
-    }
-    return true;
-  }
-  
-  template<typename String, typename Iter> inline bool _parse_string(String& out, input<Iter>& in) {
-    while (1) {
-      int ch = in.getc();
-      if (ch < ' ') {
-       in.ungetc();
-       return false;
-      } else if (ch == '"') {
-       return true;
-      } else if (ch == '\\') {
-       if ((ch = in.getc()) == -1) {
-         return false;
-       }
-       switch (ch) {
-#define MAP(sym, val) case sym: out.push_back(val); break
-         MAP('"', '\"');
-         MAP('\\', '\\');
-         MAP('/', '/');
-         MAP('b', '\b');
-         MAP('f', '\f');
-         MAP('n', '\n');
-         MAP('r', '\r');
-         MAP('t', '\t');
-#undef MAP
-       case 'u':
-         if (! _parse_codepoint(out, in)) {
-           return false;
-         }
-         break;
-       default:
-         return false;
-       }
-      } else {
-       out.push_back(ch);
-      }
-    }
-    return false;
-  }
-  
-  template <typename Context, typename Iter> inline bool _parse_array(Context& ctx, input<Iter>& in) {
-    if (! ctx.parse_array_start()) {
-      return false;
-    }
-    size_t idx = 0;
-    if (in.expect(']')) {
-      return ctx.parse_array_stop(idx);
-    }
-    do {
-      if (! ctx.parse_array_item(in, idx)) {
-       return false;
-      }
-      idx++;
-    } while (in.expect(','));
-    return in.expect(']') && ctx.parse_array_stop(idx);
-  }
-  
-  template <typename Context, typename Iter> inline bool _parse_object(Context& ctx, input<Iter>& in) {
-    if (! ctx.parse_object_start()) {
-      return false;
-    }
-    if (in.expect('}')) {
-      return true;
-    }
-    do {
-      std::string key;
-      if (! in.expect('"')
-         || ! _parse_string(key, in)
-         || ! in.expect(':')) {
-       return false;
-      }
-      if (! ctx.parse_object_item(in, key)) {
-       return false;
-      }
-    } while (in.expect(','));
-    return in.expect('}');
-  }
-  
-  template <typename Iter> inline std::string _parse_number(input<Iter>& in) {
-    std::string num_str;
-    while (1) {
-      int ch = in.getc();
-      if (('0' <= ch && ch <= '9') || ch == '+' || ch == '-'
-          || ch == 'e' || ch == 'E') {
-        num_str.push_back(ch);
-      } else if (ch == '.') {
-#if PICOJSON_USE_LOCALE
-        num_str += localeconv()->decimal_point;
-#else
-        num_str.push_back('.');
-#endif
-      } else {
-       in.ungetc();
-       break;
-      }
-    }
-    return num_str;
-  }
-  
-  template <typename Context, typename Iter> inline bool _parse(Context& ctx, input<Iter>& in) {
-    in.skip_ws();
-    int ch = in.getc();
-    switch (ch) {
-#define IS(ch, text, op) case ch: \
-      if (in.match(text) && op) { \
-       return true; \
-      } else { \
-       return false; \
-      }
-      IS('n', "ull", ctx.set_null());
-      IS('f', "alse", ctx.set_bool(false));
-      IS('t', "rue", ctx.set_bool(true));
-#undef IS
-    case '"':
-      return ctx.parse_string(in);
-    case '[':
-      return _parse_array(ctx, in);
-    case '{':
-      return _parse_object(ctx, in);
-    default:
-      if (('0' <= ch && ch <= '9') || ch == '-') {
-        double f;
-        char *endp;
-       in.ungetc();
-        std::string num_str = _parse_number(in);
-        if (num_str.empty()) {
-          return false;
-        }
-#ifdef PICOJSON_USE_INT64
-        {
-          errno = 0;
-          intmax_t ival = strtoimax(num_str.c_str(), &endp, 10);
-          if (errno == 0
-              && std::numeric_limits<int64_t>::min() <= ival
-              && ival <= std::numeric_limits<int64_t>::max()
-              && endp == num_str.c_str() + num_str.size()) {
-            ctx.set_int64(ival);
-            return true;
-          }
-        }
-#endif
-        f = strtod(num_str.c_str(), &endp);
-        if (endp == num_str.c_str() + num_str.size()) {
-          ctx.set_number(f);
-          return true;
-        }
-        return false;
-      }
-      break;
-    }
-    in.ungetc();
-    return false;
-  }
-  
-  class deny_parse_context {
-  public:
-    bool set_null() { return false; }
-    bool set_bool(bool) { return false; }
-#ifdef PICOJSON_USE_INT64
-    bool set_int64(int64_t) { return false; }
-#endif
-    bool set_number(double) { return false; }
-    template <typename Iter> bool parse_string(input<Iter>&) { return false; }
-    bool parse_array_start() { return false; }
-    template <typename Iter> bool parse_array_item(input<Iter>&, size_t) {
-      return false;
-    }
-    bool parse_array_stop(size_t) { return false; }
-    bool parse_object_start() { return false; }
-    template <typename Iter> bool parse_object_item(input<Iter>&, const std::string&) {
-      return false;
-    }
-  };
-  
-  class default_parse_context {
-  protected:
-    value* out_;
-  public:
-    default_parse_context(value* out) : out_(out) {}
-    bool set_null() {
-      *out_ = value();
-      return true;
-    }
-    bool set_bool(bool b) {
-      *out_ = value(b);
-      return true;
-    }
-#ifdef PICOJSON_USE_INT64
-    bool set_int64(int64_t i) {
-      *out_ = value(i);
-      return true;
-    }
-#endif
-    bool set_number(double f) {
-      *out_ = value(f);
-      return true;
-    }
-    template<typename Iter> bool parse_string(input<Iter>& in) {
-      *out_ = value(string_type, false);
-      return _parse_string(out_->get<std::string>(), in);
-    }
-    bool parse_array_start() {
-      *out_ = value(array_type, false);
-      return true;
-    }
-    template <typename Iter> bool parse_array_item(input<Iter>& in, size_t) {
-      array& a = out_->get<array>();
-      a.push_back(value());
-      default_parse_context ctx(&a.back());
-      return _parse(ctx, in);
-    }
-    bool parse_array_stop(size_t) { return true; }
-    bool parse_object_start() {
-      *out_ = value(object_type, false);
-      return true;
-    }
-    template <typename Iter> bool parse_object_item(input<Iter>& in, const std::string& key) {
-      object& o = out_->get<object>();
-      default_parse_context ctx(&o[key]);
-      return _parse(ctx, in);
-    }
-  private:
-    default_parse_context(const default_parse_context&);
-    default_parse_context& operator=(const default_parse_context&);
-  };
-
-  class null_parse_context {
-  public:
-    struct dummy_str {
-      void push_back(int) {}
-    };
-  public:
-    null_parse_context() {}
-    bool set_null() { return true; }
-    bool set_bool(bool) { return true; }
-#ifdef PICOJSON_USE_INT64
-    bool set_int64(int64_t) { return true; }
-#endif
-    bool set_number(double) { return true; }
-    template <typename Iter> bool parse_string(input<Iter>& in) {
-      dummy_str s;
-      return _parse_string(s, in);
-    }
-    bool parse_array_start() { return true; }
-    template <typename Iter> bool parse_array_item(input<Iter>& in, size_t) {
-      return _parse(*this, in);
-    }
-    bool parse_array_stop(size_t) { return true; }
-    bool parse_object_start() { return true; }
-    template <typename Iter> bool parse_object_item(input<Iter>& in, const std::string&) {
-      return _parse(*this, in);
-    }
-  private:
-    null_parse_context(const null_parse_context&);
-    null_parse_context& operator=(const null_parse_context&);
-  };
-  
-  // obsolete, use the version below
-  template <typename Iter> inline std::string parse(value& out, Iter& pos, const Iter& last) {
-    std::string err;
-    pos = parse(out, pos, last, &err);
-    return err;
-  }
-  
-  template <typename Context, typename Iter> inline Iter _parse(Context& ctx, const Iter& first, const Iter& last, std::string* err) {
-    input<Iter> in(first, last);
-    if (! _parse(ctx, in) && err != NULL) {
-      char buf[64];
-      SNPRINTF(buf, sizeof(buf), "syntax error at line %d near: ", in.line());
-      *err = buf;
-      while (1) {
-       int ch = in.getc();
-       if (ch == -1 || ch == '\n') {
-         break;
-       } else if (ch >= ' ') {
-         err->push_back(ch);
-       }
-      }
-    }
-    return in.cur();
-  }
-  
-  template <typename Iter> inline Iter parse(value& out, const Iter& first, const Iter& last, std::string* err) {
-    default_parse_context ctx(&out);
-    return _parse(ctx, first, last, err);
-  }
-  
-  inline std::string parse(value& out, const std::string& s) {
-    std::string err;
-    parse(out, s.begin(), s.end(), &err);
-    return err;
-  }
-
-  inline std::string parse(value& out, std::istream& is) {
-    std::string err;
-    parse(out, std::istreambuf_iterator<char>(is.rdbuf()),
-         std::istreambuf_iterator<char>(), &err);
-    return err;
-  }
-  
-  template <typename T> struct last_error_t {
-    static std::string s;
-  };
-  template <typename T> std::string last_error_t<T>::s;
-  
-  inline void set_last_error(const std::string& s) {
-    last_error_t<bool>::s = s;
-  }
-  
-  inline const std::string& get_last_error() {
-    return last_error_t<bool>::s;
-  }
-
-  inline bool operator==(const value& x, const value& y) {
-    if (x.is<null>())
-      return y.is<null>();
-#define PICOJSON_CMP(type)                                     \
-    if (x.is<type>())                                          \
-      return y.is<type>() && x.get<type>() == y.get<type>()
-    PICOJSON_CMP(bool);
-    PICOJSON_CMP(double);
-    PICOJSON_CMP(std::string);
-    PICOJSON_CMP(array);
-    PICOJSON_CMP(object);
-#undef PICOJSON_CMP
-    PICOJSON_ASSERT(0);
-#ifdef _MSC_VER
-    __assume(0);
-#endif
-    return false;
-  }
-  
-  inline bool operator!=(const value& x, const value& y) {
-    return ! (x == y);
-  }
-}
-
-namespace std {
-  template<> inline void swap(picojson::value& x, picojson::value& y)
-    {
-      x.swap(y);
-    }
-}
-
-inline std::istream& operator>>(std::istream& is, picojson::value& x)
-{
-  picojson::set_last_error(std::string());
-  std::string err = picojson::parse(x, is);
-  if (! err.empty()) {
-    picojson::set_last_error(err);
-    is.setstate(std::ios::failbit);
-  }
-  return is;
-}
-
-inline std::ostream& operator<<(std::ostream& os, const picojson::value& x)
-{
-  x.serialize(std::ostream_iterator<char>(os));
-  return os;
-}
-#ifdef _MSC_VER
-    #pragma warning(pop)
-#endif
-
-#endif
index 754a4e8..ab4ff78 100644 (file)
@@ -2,26 +2,53 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-PKG_CHECK_MODULES(TARGET_EXTENSION_STATIC_DEPS
+# Dependencies
+PKG_CHECK_MODULES(TARGET_EXTENSION_DEPS
   dlog
-  elementary
-  chromium-efl
+  glib-2.0
+  gio-2.0
   REQUIRED
 )
 
-SET(TARGET_EXTENSION_STATIC_INCS
+# Includes
+SET(TARGET_EXTENSION_INCS
   ${BASE_SRCDIR}
-  ${TARGET_EXTENSION_STATIC_DEPS_INCLUDE_DIRS}
+  ${TARGET_EXTENSION_DEPS_INCLUDE_DIRS}
 )
 
-SET(TARGET_EXTENSION_STATIC_SRCS
+# Libraries
+SET(TARGET_EXTENSION_LIBS
+  ${TARGET_EXTENSION_DEPS_LIBRARIES}
+)
+
+# Source Files
+SET(TARGET_EXTENSION_SRCS
+  ${BASE_SRCDIR}/extension/extension_main.cc
   ${BASE_SRCDIR}/extension/extension.cc
   ${BASE_SRCDIR}/extension/extension_instance.cc
   ${BASE_SRCDIR}/extension/extension_adapter.cc
   ${BASE_SRCDIR}/extension/extension_server.cc
 )
 
-INCLUDE_DIRECTORIES(${TARGET_EXTENSION_STATIC_INCS})
-ADD_LIBRARY(${TARGET_EXTENSION_STATIC} STATIC
-  ${TARGET_EXTENSION_STATIC_SRCS}
+# Compiler Flags
+SET(TARGET_EXTENSION_CFLAGS
+  "-fPIE"
+)
+
+# Linker Flags
+SET(TARGET_EXTENSION_LDFLAGS
+  "-pie -ldl"
 )
+
+# Build Executable
+INCLUDE_DIRECTORIES(${TARGET_EXTENSION_INCS})
+ADD_DEFINITIONS(${TARGET_EXTENSION_CFLAGS})
+ADD_EXECUTABLE(${TARGET_EXTENSION} ${TARGET_EXTENSION_SRCS})
+TARGET_LINK_LIBRARIES(${TARGET_EXTENSION}
+  ${TARGET_COMMON_STATIC}
+  ${TARGET_EXTENSION_LIBS}
+  ${TARGET_EXTENSION_LDFLAGS}
+)
+
+# Install
+INSTALL(TARGETS ${TARGET_EXTENSION} DESTINATION bin)
diff --git a/src/extension/extension_main.cc b/src/extension/extension_main.cc
new file mode 100644 (file)
index 0000000..9758925
--- /dev/null
@@ -0,0 +1,59 @@
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <glib.h>
+#include <glib-unix.h>
+
+#include "common/logger.h"
+#include "common/command_line.h"
+#include "extension/extension_server.h"
+
+namespace {
+
+gboolean HandleQuitSignal(gpointer data) {
+  GMainLoop* loop = reinterpret_cast<GMainLoop*>(data);
+  g_main_loop_quit(loop);
+  return false;
+}
+
+}  // namespace
+
+// TODO(wy80.choi): This main function should be merged to wrt runtime
+// to reduce static code size of memory.
+int main(int argc, char* argv[]) {
+  GMainLoop* loop;
+
+  loop = g_main_loop_new(NULL, FALSE);
+  g_unix_signal_add(SIGINT, HandleQuitSignal, loop);
+  g_unix_signal_add(SIGTERM, HandleQuitSignal, loop);
+
+  wrt::CommandLine::Init(argc, argv);
+  wrt::CommandLine* cmd = wrt::CommandLine::ForCurrentProcess();
+
+  // TODO(wy80.choi): Receive extension paths for user defined extensions.
+
+  // Receive AppID from arguments.
+  if (cmd->arguments().size() < 1) {
+    LoggerE("uuid is required.");
+    exit(1);
+  }
+  std::string uuid = cmd->arguments()[0];
+
+  // Start ExtensionServer
+  wrt::ExtensionServer server(uuid);
+  if (!server.Start()) {
+    LoggerE("Failed to start extension server.");
+    exit(1);
+  }
+
+  LoggerI("extension process has been started.");
+
+  g_main_loop_run(loop);
+
+  LoggerI("extension process is exiting.");
+
+  g_main_loop_unref(loop);
+
+  return 0;
+}
index f50f16b..fb7bab2 100644 (file)
@@ -4,32 +4,95 @@
 
 #include "extension/extension_server.h"
 
-#include <Elementary.h>
 #include <glob.h>
 #include <string>
 #include <vector>
 
 #include "common/logger.h"
+#include "common/constants.h"
 #include "common/file_utils.h"
-#include "common/message_types.h"
-#include "common/picojson.h"
 #include "extension/extension.h"
 
 namespace wrt {
 
 namespace {
-const char kExtensionDir[] = "/usr/lib/tizen-extensions-crosswalk";
-const char kExtensionPrefix[] = "lib";
-const char kExtensionSuffix[] = ".so";
+
+const char kDBusIntrospectionXML[] =
+  "<node>"
+  "  <interface name='org.tizen.wrt.Extension'>"
+  "    <method name='GetExtensions'>"
+  "      <arg name='extensions' type='a(ssas)' direction='out' />"
+  "    </method>"
+  "    <method name='CreateInstance'>"
+  "      <arg name='extension_name' type='s' direction='in' />"
+  "      <arg name='instance_id' type='s' direction='in' />"
+  "    </method>"
+  "    <method name='DestroyInstance'>"
+  "      <arg name='instance_id' type='s' direction='in' />"
+  "    </method>"
+  "    <method name='CallASync'>"
+  "      <arg name='instance_id' type='s' direction='in' />"
+  "      <arg name='body' type='s' direction='in' />"
+  "    </method>"
+  "    <method name='CallSync'>"
+  "      <arg name='instance_id' type='s' direction='in' />"
+  "      <arg name='body' type='s' direction='in' />"
+  "      <arg name='reply' type='s' direction='out' />"
+  "    </method>"
+  "    <signal name='OnMessageToJS'>"
+  "      <arg name='instance_id' type='s' />"
+  "      <arg name='body' type='s' />"
+  "    </signal>"
+  "  </interface>"
+  "</node>";
+
 }  // namespace
 
-ExtensionServer::ExtensionServer(Ewk_Context* ewk_context)
-    : ewk_context_(ewk_context) {
+ExtensionServer::ExtensionServer(const std::string& uuid)
+    : app_uuid_(uuid) {
 }
 
 ExtensionServer::~ExtensionServer() {
 }
 
+bool ExtensionServer::Start() {
+  return Start(StringVector());
+}
+
+bool ExtensionServer::Start(const StringVector& paths) {
+  // Register system extensions to support Tizen Device APIs
+  RegisterSystemExtensions();
+
+  // Register user extensions
+  for (auto it = paths.begin(); it != paths.end(); ++it) {
+    if (utils::Exists(*it)) {
+      RegisterExtension(*it);
+    }
+  }
+
+  // Connect to DBusServer for Runtime
+  if (!dbus_runtime_client_.ConnectByName(
+          app_uuid_ + "." + std::string(kDBusNameForRuntime))) {
+    LoggerE("Failed to connect to the dbus server for Runtime.");
+    return false;
+  }
+
+  // Start DBusServer
+  using std::placeholders::_1;
+  using std::placeholders::_2;
+  using std::placeholders::_3;
+  dbus_server_.SetIntrospectionXML(kDBusIntrospectionXML);
+  dbus_server_.SetMethodCallback(
+      kDBusInterfaceNameForExtension,
+      std::bind(&ExtensionServer::HandleDBusMethod, this, _1, _2, _3));
+  dbus_server_.Start(app_uuid_ + "." + std::string(kDBusNameForExtension));
+
+  // Send 'ready' signal to Injected Bundle.
+  NotifyEPCreatedToRuntime();
+
+  return true;
+}
+
 void ExtensionServer::RegisterExtension(const std::string& path) {
   Extension* ext = new Extension(path, this);
   if (!ext->Initialize() || !RegisterSymbols(ext)) {
@@ -39,7 +102,7 @@ void ExtensionServer::RegisterExtension(const std::string& path) {
 }
 
 void ExtensionServer::RegisterSystemExtensions() {
-  std::string extension_path(kExtensionDir);
+  std::string extension_path(kSystemExtensionPath);
   extension_path.append("/");
   extension_path.append(kExtensionPrefix);
   extension_path.append("*");
@@ -96,185 +159,18 @@ void ExtensionServer::GetRuntimeVariable(const char* key, char* value,
   }
 }
 
-void ExtensionServer::Start() {
-  Start(StringVector());
+void ExtensionServer::NotifyEPCreatedToRuntime() {
+  dbus_runtime_client_.Call(
+      kDBusInterfaceNameForRuntime, kMethodNotifyEPCreated,
+      g_variant_new("(s)", dbus_server_.GetClientAddress().c_str()),
+      NULL);
 }
 
-void ExtensionServer::Start(const StringVector& paths) {
-  // Register system extensions to support Tizen Device APIs
-  RegisterSystemExtensions();
-
-  // Register user extensions
-  for (auto it = paths.begin(); it != paths.end(); ++it) {
-    if (utils::Exists(*it)) {
-      RegisterExtension(*it);
-    }
-  }
-
-  // Send 'ready' signal to Injected Bundle.
-  SendWrtMessage(message_types::kExtensionEPCreated);
+void ExtensionServer::HandleDBusMethod(const std::string& method_name,
+                                       GVariant* parameters,
+                                       GDBusMethodInvocation* invocation) {
+  // TODO(wy80.choi): Handle DBus Method Calls from InjectedBundle
 }
 
-void ExtensionServer::HandleWrtMessage(Ewk_IPC_Wrt_Message_Data* message) {
-  if (!message) {
-    LoggerW("Message object is NULL.");
-    return;
-  }
-
-  if (!ewk_context_) {
-    LoggerW("Ewk_Context is NULL.");
-    return;
-  }
-
-  Eina_Stringshare* msg_id = ewk_ipc_wrt_message_data_id_get(message);
-  Eina_Stringshare* msg_reference_id
-                        = ewk_ipc_wrt_message_data_reference_id_get(message);
-  Eina_Stringshare* msg_type = ewk_ipc_wrt_message_data_type_get(message);
-  Eina_Stringshare* msg_value = ewk_ipc_wrt_message_data_value_get(message);
-
-  Ewk_IPC_Wrt_Message_Data* reply = ewk_ipc_wrt_message_data_new();
-
-  #define START_WITHS(x, s) (strncmp(x, s, strlen(s)) == 0)
-  if (START_WITHS(msg_type, message_types::kExtensionGetExtensions)) {
-    OnGetExtensions(msg_id);
-  } else if (START_WITHS(msg_type, message_types::kExtensionCreateInstance)) {
-    OnCreateInstance(msg_reference_id, msg_value);
-  } else if (START_WITHS(msg_type, message_types::kExtensionDestroyInstance)) {
-    OnDestroyInstance(msg_reference_id);
-  } else if (START_WITHS(msg_type, message_types::kExtensionCallSync)) {
-    OnSendSyncMessageToNative(msg_id, msg_reference_id, msg_value);
-  } else if (START_WITHS(msg_type, message_types::kExtensionCallAsync)) {
-    OnPostMessageToNative(msg_reference_id, msg_value);
-  }
-
-  eina_stringshare_del(msg_id);
-  eina_stringshare_del(msg_reference_id);
-  eina_stringshare_del(msg_type);
-  eina_stringshare_del(msg_value);
-  ewk_ipc_wrt_message_data_del(reply);
-
-  #undef START_WITHS
-}
-
-void ExtensionServer::SendWrtMessage(const std::string& type) {
-  SendWrtMessage(type, std::string(), std::string(), std::string());
-}
-
-void ExtensionServer::SendWrtMessage(
-    const std::string& type, const std::string& id,
-    const std::string& ref_id, const std::string& value) {
-  if (!ewk_context_) {
-    LoggerW("Ewk_Context is NULL.");
-    return;
-  }
-  Ewk_IPC_Wrt_Message_Data* msg = ewk_ipc_wrt_message_data_new();
-  ewk_ipc_wrt_message_data_type_set(msg, type.c_str());
-  ewk_ipc_wrt_message_data_id_set(msg, id.c_str());
-  ewk_ipc_wrt_message_data_reference_id_set(msg, ref_id.c_str());
-  ewk_ipc_wrt_message_data_value_set(msg, value.c_str());
-  if (!ewk_ipc_wrt_message_send(ewk_context_, msg)) {
-    LoggerE("Failed to send message to injected bundle.");
-  }
-  ewk_ipc_wrt_message_data_del(msg);
-}
-
-void ExtensionServer::OnGetExtensions(const std::string& id) {
-  picojson::array ext_array = picojson::array(0);
-  for (auto it = extensions_.begin(); it != extensions_.end(); ++it) {
-    picojson::object ext_obj = picojson::object();
-    ext_obj["name"] = picojson::value(it->second->name());
-    ext_obj["javascript_api"] = picojson::value(it->second->javascript_api());
-    ext_obj["entry_points"] = picojson::value(picojson::array(0));
-    picojson::array ext_ep_array
-        = ext_obj["entry_points"].get<picojson::array>();
-    Extension::StringVector entry_points = it->second->entry_points();
-    for (auto it_ep = entry_points.begin();
-         it_ep != entry_points.end(); ++it_ep) {
-      ext_ep_array.push_back(picojson::value(*it_ep));
-    }
-    ext_array.push_back(picojson::value(ext_obj));
-  }
-
-  picojson::value reply(ext_array);
-  SendWrtMessage(message_types::kExtensionGetExtensions,
-                 std::string(), id, reply.serialize());
-}
-
-void ExtensionServer::OnCreateInstance(
-    const std::string& instance_id, const std::string& extension_name) {
-  // find extension with given name
-  auto it = extensions_.find(extension_name);
-  if (it == extensions_.end()) {
-    LoggerE("Can't find extension [%s].", extension_name.c_str());
-    return;
-  }
-
-  // create instance
-  ExtensionInstance* instance = it->second->CreateInstance();
-  if (!instance) {
-    LoggerE("Can't create instance of extension [%s].", extension_name.c_str());
-    return;
-  }
-
-  // Set PostMessageCallback / SendSyncReplyCallback
-  using std::placeholders::_1;
-  instance->SetPostMessageCallback(
-    std::bind(&ExtensionServer::OnPostMessageToJS, this, instance_id, _1));
-  instance->SetSendSyncReplyCallback(
-    std::bind(&ExtensionServer::OnSendSyncReplyToJS, this, instance_id, _1));
-
-  instances_[instance_id] = instance;
-}
-
-void ExtensionServer::OnDestroyInstance(const std::string& instance_id) {
-  auto it = instances_.find(instance_id);
-  if (it == instances_.end()) {
-    LoggerE("Can't find instance [%s].", instance_id.c_str());
-    return;
-  }
-
-  ExtensionInstance* instance = it->second;
-  delete instance;
-
-  instances_.erase(it);
-}
-
-void ExtensionServer::OnSendSyncMessageToNative(
-    const std::string& msg_id, const std::string& instance_id,
-    const std::string& msg_body) {
-  auto it = instances_.find(instance_id);
-  if (it == instances_.end()) {
-    LoggerE("Can't find instance [%s].", instance_id.c_str());
-    SendWrtMessage(message_types::kExtensionCallSync, "", msg_id, "ERROR");
-    return;
-  }
-
-  ExtensionInstance* instance = it->second;
-  instance->HandleSyncMessage(msg_body);
-}
-
-void ExtensionServer::OnPostMessageToNative(
-    const std::string& instance_id, const std::string& msg_body) {
-  auto it = instances_.find(instance_id);
-  if (it == instances_.end()) {
-    LoggerE("Can't find instance [%s].", instance_id.c_str());
-    return;
-  }
-
-  ExtensionInstance* instance = it->second;
-  instance->HandleMessage(msg_body);
-}
-
-void ExtensionServer::OnPostMessageToJS(
-    const std::string& instance_id, const std::string& msg) {
-  SendWrtMessage(message_types::kExtensionPostMessageToJS,
-                 "", instance_id, msg);
-}
-
-void ExtensionServer::OnSendSyncReplyToJS(
-    const std::string& instance_id, const std::string& msg) {
-  SendWrtMessage(message_types::kExtensionCallSync,
-                 "", instance_id, msg);
-}
 
 }  // namespace wrt
index b6e85d7..23cf20a 100644 (file)
@@ -5,13 +5,13 @@
 #ifndef WRT_EXTENSION_EXTENSION_SERVER_H_
 #define WRT_EXTENSION_EXTENSION_SERVER_H_
 
-#include <ewk_ipc_message.h>
-
 #include <string>
 #include <set>
 #include <map>
 #include <vector>
 
+#include "common/dbus_server.h"
+#include "common/dbus_client.h"
 #include "extension/extension.h"
 
 class Ewk_Context;
@@ -22,13 +22,11 @@ class ExtensionServer : public Extension::ExtensionDelegate {
  public:
   typedef std::vector<std::string> StringVector;
 
-  explicit ExtensionServer(Ewk_Context* ewk_context);
+  explicit ExtensionServer(const std::string& appid);
   virtual ~ExtensionServer();
 
-  void Start();
-  void Start(const StringVector& paths);
-
-  void HandleWrtMessage(Ewk_IPC_Wrt_Message_Data* message);
+  bool Start();
+  bool Start(const StringVector& paths);
 
  private:
   void RegisterExtension(const std::string& path);
@@ -39,26 +37,14 @@ class ExtensionServer : public Extension::ExtensionDelegate {
   void GetRuntimeVariable(const char* key, char* value, size_t value_len);
   void ClearRuntimeVariables();
 
-  void SendWrtMessage(const std::string& type);
-  void SendWrtMessage(const std::string& type, const std::string& id,
-                      const std::string& ref_id, const std::string& value);
-
-  void OnGetExtensions(const std::string& id);
-  void OnCreateInstance(const std::string& instance_id,
-                        const std::string& extension_name);
-  void OnDestroyInstance(const std::string& instance_id);
-  void OnSendSyncMessageToNative(const std::string& msg_id,
-                                 const std::string& instance_id,
-                                 const std::string& msg_body);
-  void OnPostMessageToNative(const std::string& instance_id,
-                             const std::string& msg_body);
-
-  void OnPostMessageToJS(const std::string& instance_id,
-                         const std::string& msg);
-  void OnSendSyncReplyToJS(const std::string& instance_id,
-                           const std::string& msg);
-
-  Ewk_Context* ewk_context_;
+  void NotifyEPCreatedToRuntime();
+  void HandleDBusMethod(const std::string& method_name,
+                        GVariant* parameters,
+                        GDBusMethodInvocation* invocation);
+
+  std::string app_uuid_;
+  DBusServer dbus_server_;
+  DBusClient dbus_runtime_client_;
 
   typedef std::set<std::string> StringSet;
   StringSet extension_symbols_;
index e8f75ba..b59ecf3 100755 (executable)
@@ -11,6 +11,8 @@ IF(WAYLAND_SUPPORT)
 ENDIF(WAYLAND_SUPPORT)
 
 PKG_CHECK_MODULES(TARGET_RUNTIME_DEPS
+  glib-2.0
+  gio-2.0
   uuid
   appsvc
   bundle
@@ -71,7 +73,6 @@ ADD_DEFINITIONS(${TARGET_RUNTIME_CFLAGS})
 ADD_EXECUTABLE(${TARGET_RUNTIME} ${TARGET_RUNTIME_SRCS})
 TARGET_LINK_LIBRARIES(${TARGET_RUNTIME}
   ${TARGET_COMMON_STATIC}
-  ${TARGET_EXTENSION_STATIC}
   ${TARGET_RUNTIME_LIBS}
   ${TARGET_RUNTIME_LDFLAGS}
 )
index 0df625c..d7cac25 100755 (executable)
@@ -9,6 +9,7 @@
 #include <memory>
 
 #include "common/logger.h"
+#include "common/constants.h"
 #include "common/command_line.h"
 #include "runtime/native_app_window.h"
 #include "runtime/app_control.h"
@@ -17,12 +18,39 @@ namespace wrt {
 
 namespace {
 
+static const char* kDBusIntrospectionXML =
+  "<node>"
+  "  <interface name='org.tizen.wrt.Runtime'>"
+  "    <method name='NotifyEPCreated'>"
+  "      <arg name='status' type='s' direction='in'/>"
+  "    </method>"
+  "    <method name='GetRuntimeVariable'>"
+  "      <arg name='key' type='s' direction='in' />"
+  "      <arg name='value' type='s' direction='out' />"
+  "    </method>"
+  "  </interface>"
+  "</node>";
+
 static NativeWindow* CreateNativeWindow() {
   // TODO(wy80.choi) : consider other type of native window.
   NativeWindow* window = new NativeAppWindow();
   return window;
 }
 
+static void ExecExtensionProcess(const std::string& uuid) {
+  pid_t pid = -1;
+  if ((pid = fork()) < 0) {
+    LoggerE("Failed to fork child process for extension process.");
+  }
+
+  if (pid == 0) {
+    // TODO(wy80.choi): wrt-extension should be merged to this runtime exec.
+    // It should be changed to "/usr/bin/wrt --extension-process"
+    execl("/usr/bin/wrt-extension",
+          "/usr/bin/wrt-extension", uuid.c_str(), NULL);
+  }
+}
+
 }  // namespace
 
 Runtime::Runtime()
@@ -46,6 +74,21 @@ bool Runtime::OnCreate() {
   native_window_ = CreateNativeWindow();
   application_ = new WebApplication(native_window_, appid);
   application_->set_terminator([](){ ui_app_exit(); });
+
+  // Start DBus Server for Runtime
+  // TODO(wy80.choi): Should I add PeerCredentials checker?
+  using std::placeholders::_1;
+  using std::placeholders::_2;
+  using std::placeholders::_3;
+  dbus_server_.SetIntrospectionXML(kDBusIntrospectionXML);
+  dbus_server_.SetMethodCallback(kDBusInterfaceNameForRuntime,
+    std::bind(&Runtime::HandleDBusMethod, this, _1, _2, _3));
+  dbus_server_.Start(application_->uuid() +
+                     "." + std::string(kDBusNameForRuntime));
+
+  // Launch Extension Process
+  ExecExtensionProcess(application_->uuid());
+
   return true;
 }
 
@@ -87,6 +130,18 @@ void Runtime::OnLowMemory() {
   }
 }
 
+void Runtime::HandleDBusMethod(const std::string& method_name,
+                               GVariant* parameters,
+                               GDBusMethodInvocation* invocation) {
+  if (method_name == kMethodNotifyEPCreated) {
+    // TODO(wy80.choi): send signal to injected bundle to make connection
+    // between injected bundle and extension process
+    LoggerD("Call!!!! NotifyEPCreated!");
+  } else if (method_name == kMethodGetRuntimeVariable) {
+    // TODO(wy80.choi): return runtime variable
+  }
+}
+
 int Runtime::Exec(int argc, char* argv[]) {
   ui_app_lifecycle_callback_s ops = {0, };
 
index 7f12d15..2d5a7c5 100755 (executable)
@@ -8,6 +8,7 @@
 #include <app.h>
 #include <string>
 
+#include "common/dbus_server.h"
 #include "runtime/native_window.h"
 #include "runtime/web_application.h"
 
@@ -30,8 +31,13 @@ class Runtime {
   virtual void OnLowMemory();
 
  private:
+  void HandleDBusMethod(const std::string& method_name,
+                        GVariant* parameters,
+                        GDBusMethodInvocation* invocation);
+
   WebApplication* application_;
   NativeWindow* native_window_;
+  DBusServer dbus_server_;
 };
 
 }  // namespace wrt
index 7ef8207..394e0db 100755 (executable)
@@ -131,6 +131,13 @@ bool WebApplication::Initialize(
                                              vibration_stop_callback,
                                              NULL);
 
+  // send widget info to injected bundle
+  // TODO(wy80.choi): ewk_send_widget_info should be fixed to receive uuid of
+  // application instead of widget_id.
+  // Currently, uuid is passed as theme argument temporarily.
+
+  ewk_send_widget_info(ewk_context_, 1, 0.0, uuid_.c_str(), "");
+
   // TODO(sngn.lee): Find the path of certificate file
   // ewk_context_certificate_file_set(ewk_context_, .... );