Change to single process model
authorWonYoung Choi <wy80.choi@samsung.com>
Wed, 11 May 2016 01:50:49 +0000 (10:50 +0900)
committerWonYoung Choi <wy80.choi@samsung.com>
Wed, 18 May 2016 14:12:25 +0000 (23:12 +0900)
Chromium-efl supports single process model to reduce memory consumption
and improve loading performance. The extension server is running in the
browser thread in this model. The extension server and client use the
ewk IPC methods to exchange messages each other, but the IPC just exchanges
the messages between threads.

26 files changed:
common/common.gyp
common/dbus_client.cc [deleted file]
common/dbus_client.h [deleted file]
common/dbus_server.cc [deleted file]
common/dbus_server.h [deleted file]
extensions/common/constants.cc
extensions/common/constants.h
extensions/common/xwalk_extension_manager.cc
extensions/common/xwalk_extension_manager.h
extensions/common/xwalk_extension_server.cc [new file with mode: 0644]
extensions/common/xwalk_extension_server.h [new file with mode: 0644]
extensions/extensions.gyp
extensions/renderer/runtime_ipc_client.cc
extensions/renderer/runtime_ipc_client.h
extensions/renderer/xwalk_extension_client.cc
extensions/renderer/xwalk_extension_client.h
extensions/renderer/xwalk_extension_module.cc
extensions/renderer/xwalk_extension_module.h
extensions/renderer/xwalk_extension_renderer_controller.cc
extensions/renderer/xwalk_extension_renderer_controller.h
packaging/crosswalk-tizen.spec
runtime/browser/preload_manager.cc
runtime/browser/runtime_process.cc
runtime/browser/web_application.cc
runtime/renderer/injected_bundle.cc
runtime/runtime.gyp

index f399892..ac3327c 100644 (file)
@@ -9,10 +9,6 @@
       'sources': [
         'command_line.h',
         'command_line.cc',
-        'dbus_client.h',
-        'dbus_client.cc',
-        'dbus_server.h',
-        'dbus_server.cc',
         'file_utils.h',
         'file_utils.cc',
         'string_utils.h',
@@ -46,7 +42,6 @@
           'capi-appfw-package-manager',
           'capi-system-system-settings',
           'dlog',
-          'gio-2.0',
           'uuid',
           'libwebappenc',
           'manifest-parser',
@@ -63,7 +58,6 @@
         'variables': {
           'packages': [
             'dlog',
-            'gio-2.0',
           ],
         },
       },
diff --git a/common/dbus_client.cc b/common/dbus_client.cc
deleted file mode 100644 (file)
index 52caa82..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2015 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 "common/dbus_client.h"
-
-#include "common/file_utils.h"
-#include "common/logger.h"
-
-namespace common {
-
-namespace {
-
-void OnSignalReceived(GDBusConnection* /*connection*/,
-                      const gchar* /*sender_name*/,
-                      const gchar* /*object_path*/,
-                      const gchar* interface_name,
-                      const gchar* signal_name,
-                      GVariant* parameters,
-                      gpointer user_data) {
-  DBusClient* self = reinterpret_cast<DBusClient*>(user_data);
-  auto callback = self->GetSignalCallback(interface_name);
-  if (callback) {
-    callback(signal_name, parameters);
-  }
-}
-
-}  // namespace
-
-DBusClient::DBusClient()
-    : connection_(NULL),
-      signal_subscription_id_(0) {
-}
-
-DBusClient::~DBusClient() {
-  if (connection_) {
-    g_dbus_connection_signal_unsubscribe(connection_, signal_subscription_id_);
-    g_dbus_connection_close_sync(connection_, NULL, NULL);
-  }
-}
-
-bool DBusClient::ConnectByName(const std::string& name) {
-  std::string address("unix:path=");
-  address.append(utils::GetUserRuntimeDir());
-  address.append("/.");
-  address.append(name);
-  return Connect(address);
-}
-
-bool DBusClient::Connect(const std::string& address) {
-  GError *err = NULL;
-  connection_ = g_dbus_connection_new_for_address_sync(
-      address.c_str(),
-      G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
-      NULL, NULL, &err);
-  if (!connection_) {
-    LOGGER(ERROR) << "Failed to connect to bus address " << address
-                  << " : " << err->message;
-    g_error_free(err);
-    return false;
-  }
-
-  signal_subscription_id_ = g_dbus_connection_signal_subscribe(
-      connection_, NULL, NULL, NULL, NULL, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
-      OnSignalReceived, this, NULL);
-
-  return true;
-}
-
-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 = 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) {
-      LOGGER(ERROR) << "Failed to CallSync : " << 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;
-}
-
-void DBusClient::SetSignalCallback(const std::string& iface,
-                                   SignalCallback func) {
-  signal_callbacks_[iface] = func;
-}
-
-DBusClient::SignalCallback
-DBusClient::GetSignalCallback(const std::string& iface) {
-  return signal_callbacks_[iface];
-}
-
-}  // namespace common
diff --git a/common/dbus_client.h b/common/dbus_client.h
deleted file mode 100644 (file)
index 0863a5c..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2015 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 XWALK_COMMON_DBUS_CLIENT_H_
-#define XWALK_COMMON_DBUS_CLIENT_H_
-
-#include <gio/gio.h>
-#include <glib.h>
-
-#include <functional>
-#include <map>
-#include <string>
-
-namespace common {
-
-class DBusClient {
- public:
-  typedef std::function<void(const std::string& signal,
-                             GVariant* parameters)> SignalCallback;
-
-  DBusClient();
-  virtual ~DBusClient();
-
-  bool Connect(const std::string& address);
-  bool ConnectByName(const std::string& name);
-
-  GVariant* Call(const std::string& iface, const std::string& method,
-                 GVariant* parameters, const GVariantType* reply_type);
-
-  void SetSignalCallback(const std::string& iface, SignalCallback func);
-  SignalCallback GetSignalCallback(const std::string& iface);
-
- private:
-  GDBusConnection* connection_;
-  guint signal_subscription_id_;
-  std::map<std::string, SignalCallback> signal_callbacks_;
-};
-
-}  // namespace common
-
-#endif  // XWALK_COMMON_DBUS_CLIENT_H_
diff --git a/common/dbus_server.cc b/common/dbus_server.cc
deleted file mode 100644 (file)
index 7e3a711..0000000
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (c) 2015 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 "common/dbus_server.h"
-
-#include "common/logger.h"
-#include "common/file_utils.h"
-
-namespace common {
-
-namespace {
-
-static void OnMethodCall(GDBusConnection* connection,
-                         const gchar* /*sender*/,
-                         const gchar* /*object_path*/,
-                         const gchar* interface_name,
-                         const gchar* method_name,
-                         GVariant* parameters,
-                         GDBusMethodInvocation* invocation,
-                         gpointer user_data) {
-  DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
-  if (!self) {
-    LOGGER(ERROR) << "DBusServer is NULL.";
-    return;
-  }
-  auto callback = self->GetMethodCallback(interface_name);
-  if (callback) {
-    callback(connection, method_name, parameters, invocation);
-  }
-}
-
-static GVariant* OnGetProperty(GDBusConnection* connection,
-                               const gchar* /*sender*/,
-                               const gchar* /*object_path*/,
-                               const gchar* interface_name,
-                               const gchar* property_name,
-                               GError** /*error*/,
-                               gpointer user_data) {
-  DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
-  if (!self) {
-    LOGGER(ERROR) << "DBusServer is NULL.";
-    return NULL;
-  }
-
-  auto callback =
-      self->GetPropertyGetter(interface_name);
-
-  GVariant* ret = NULL;
-  if (callback) {
-    ret = callback(connection, property_name);
-  }
-
-  return ret;
-}
-
-static gboolean OnSetProperty(GDBusConnection* connection,
-                              const gchar* /*sender*/,
-                              const gchar* /*object_path*/,
-                              const gchar* interface_name,
-                              const gchar* property_name,
-                              GVariant* value,
-                              GError** /*error*/,
-                              gpointer user_data) {
-  DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
-  if (!self) {
-    LOGGER(ERROR) << "DBusServer is NULL.";
-    return FALSE;
-  }
-
-  auto callback =
-      self->GetPropertySetter(interface_name);
-
-  gboolean ret = FALSE;
-  if (callback) {
-    if (callback(connection, property_name, value)) {
-      ret = TRUE;
-    }
-  }
-
-  return ret;
-}
-
-static const GDBusInterfaceVTable kInterfaceVTable = {
-  OnMethodCall,
-  OnGetProperty,
-  OnSetProperty
-};
-
-static void OnClosedConnection(GDBusConnection* connection,
-                               gboolean /*remote_peer_vanished*/,
-                               GError* /*error*/,
-                               gpointer user_data) {
-  DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
-  if (self) {
-    auto callback = self->GetDisconnectedCallback();
-    if (callback) {
-      callback(connection);
-    }
-  }
-
-  g_signal_handlers_disconnect_by_func(connection,
-                                       (gpointer)OnClosedConnection,
-                                       user_data);
-  g_object_unref(connection);
-}
-
-static gboolean OnClientRequest(GDBusServer* /*dbus_server*/,
-                                GDBusConnection* connection,
-                                gpointer user_data) {
-  GError* err = NULL;
-  DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
-
-  g_signal_connect(connection, "closed",
-                   G_CALLBACK(OnClosedConnection), self);
-
-  if (self) {
-    // Check Peer Credentials
-    DBusServer::PeerCredentialsCallback callback =
-        self->GetPeerCredentialsCallback();
-    if (callback && !callback(
-        g_dbus_connection_get_peer_credentials(connection))) {
-      LOGGER(WARN) << "Invalid peer credentials.";
-      g_dbus_connection_close_sync(connection, NULL, NULL);
-    }
-
-    GDBusNodeInfo* node_info = self->GetIntrospectionNodeInfo();
-    if (!node_info) {
-      LOGGER(ERROR) << "Introspection is not set.";
-      return TRUE;
-    }
-
-    // TODO(wy80.choi): register multiple interfaces
-    g_object_ref(connection);
-    guint reg_id = g_dbus_connection_register_object(
-                          connection,
-                          "/",
-                          node_info->interfaces[0],
-                          &kInterfaceVTable,
-                          self,
-                          NULL,
-                          &err);
-    if (reg_id == 0) {
-      LOGGER(ERROR) << "Failed to register object : " << err->message;
-      g_error_free(err);
-    }
-  }
-  return TRUE;
-}
-
-}  // namespace
-
-DBusServer::DBusServer()
-    : server_(NULL),
-      node_info_(NULL) {
-}
-
-DBusServer::~DBusServer() {
-  if (node_info_) {
-    g_dbus_node_info_unref(node_info_);
-  }
-
-  if (server_) {
-    g_object_unref(server_);
-  }
-
-  if (!address_path_.empty()) {
-    unlink(address_path_.c_str());
-  }
-}
-
-void DBusServer::Start(const std::string& name) {
-  GError* err = NULL;
-
-  address_path_.clear();
-  address_path_.append(utils::GetUserRuntimeDir());
-  address_path_.append("/.");
-  address_path_.append(name);
-  // unlink existing bus address
-  unlink(address_path_.c_str());
-
-  std::string address("unix:path=");
-  address.append(address_path_);
-
-  // 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,
-                  guid, NULL, NULL, &err);
-  g_free(guid);
-  if (!server_) {
-    LOGGER(ERROR) << "Failed to create dbus server : " << err->message;
-    g_error_free(err);
-    return;
-  }
-
-  // start server
-  g_signal_connect(server_, "new-connection",
-                   G_CALLBACK(OnClientRequest), this);
-
-  g_dbus_server_start(server_);
-}
-
-std::string DBusServer::GetClientAddress() const {
-  return std::string(g_dbus_server_get_client_address(server_));
-}
-
-void DBusServer::SetIntrospectionXML(const std::string& xml) {
-  GError* err = NULL;
-  node_info_ = g_dbus_node_info_new_for_xml(xml.c_str(), &err);
-  if (!node_info_) {
-    LOGGER(ERROR) << "Failed to create node info from introspection xml : "
-                  << err->message;
-    g_error_free(err);
-  }
-}
-
-void DBusServer::SendSignal(GDBusConnection* connection,
-                            const std::string& iface,
-                            const std::string& signal_name,
-                            GVariant* parameters) {
-  GError* err = NULL;
-  gboolean ret = g_dbus_connection_emit_signal(
-      connection, NULL, "/",
-      iface.c_str(), signal_name.c_str(),
-      parameters, &err);
-  if (!ret) {
-    LOGGER(ERROR) << "Failed to emit signal : '"
-                  << iface << '.' << signal_name << "'";
-    g_error_free(err);
-  }
-}
-
-void DBusServer::SetDisconnectedCallback(DisconnectedCallback func) {
-  disconnected_callback_ = func;
-}
-
-void DBusServer::SetPeerCredentialsCallback(PeerCredentialsCallback func) {
-  peer_credentials_callback_ = func;
-}
-
-void DBusServer::SetMethodCallback(
-    const std::string& iface, MethodCallback func) {
-  method_callbacks_[iface] = func;
-}
-
-void DBusServer::SetPropertyGetter(
-    const std::string& iface, PropertyGetter func) {
-  property_getters_[iface] = func;
-}
-
-void DBusServer::SetPropertySetter(
-    const std::string& iface, PropertySetter func) {
-  property_setters_[iface] = func;
-}
-
-DBusServer::DisconnectedCallback
-DBusServer::GetDisconnectedCallback() const {
-  return disconnected_callback_;
-}
-
-DBusServer::PeerCredentialsCallback
-DBusServer::GetPeerCredentialsCallback() const {
-  return peer_credentials_callback_;
-}
-
-DBusServer::MethodCallback
-DBusServer::GetMethodCallback(const std::string& iface) {
-  return method_callbacks_[iface];
-}
-
-DBusServer::PropertySetter
-DBusServer::GetPropertySetter(const std::string& iface) {
-  return property_setters_[iface];
-}
-
-DBusServer::PropertyGetter
-DBusServer::GetPropertyGetter(const std::string& iface) {
-  return property_getters_[iface];
-}
-
-}  // namespace common
diff --git a/common/dbus_server.h b/common/dbus_server.h
deleted file mode 100644 (file)
index 112f891..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2015 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 XWALK_COMMON_DBUS_SERVER_H_
-#define XWALK_COMMON_DBUS_SERVER_H_
-
-#include <gio/gio.h>
-#include <glib.h>
-#include <functional>
-#include <map>
-#include <string>
-
-namespace common {
-
-class DBusServer {
- public:
-  typedef std::function<bool(GCredentials* creds)> PeerCredentialsCallback;
-  typedef std::function<void(GDBusConnection* connection,
-                             const std::string& method_name,
-                             GVariant* parameters,
-                             GDBusMethodInvocation* invocation)> MethodCallback;
-  typedef std::function<GVariant*(GDBusConnection* connection,
-                                  const gchar* property)> PropertyGetter;
-  typedef std::function<bool(GDBusConnection* connection,
-                             const gchar* property,
-                             GVariant* value)> PropertySetter;
-  typedef std::function<void(GDBusConnection* connection)> DisconnectedCallback;
-
-  DBusServer();
-  virtual ~DBusServer();
-
-  void Start(const std::string& name);
-
-  std::string GetClientAddress() const;
-
-  void SetIntrospectionXML(const std::string& xml);
-  GDBusNodeInfo* GetIntrospectionNodeInfo() const { return node_info_; }
-
-  void SendSignal(GDBusConnection* connection,
-                  const std::string& iface, const std::string& signal_name,
-                  GVariant* parameters);
-
-  void SetDisconnectedCallback(DisconnectedCallback func);
-  void SetPeerCredentialsCallback(PeerCredentialsCallback func);
-  void SetMethodCallback(const std::string& iface, MethodCallback func);
-  void SetPropertyGetter(const std::string& iface, PropertyGetter func);
-  void SetPropertySetter(const std::string& iface, PropertySetter func);
-  DisconnectedCallback GetDisconnectedCallback() const;
-  PeerCredentialsCallback GetPeerCredentialsCallback() const;
-  MethodCallback GetMethodCallback(const std::string& iface);
-  PropertySetter GetPropertySetter(const std::string& iface);
-  PropertyGetter GetPropertyGetter(const std::string& iface);
-
- private:
-  std::string address_path_;
-  GDBusServer* server_;
-  GDBusNodeInfo* node_info_;
-
-  DisconnectedCallback disconnected_callback_;
-  PeerCredentialsCallback peer_credentials_callback_;
-  std::map<std::string, MethodCallback> method_callbacks_;
-  std::map<std::string, PropertyGetter> property_getters_;
-  std::map<std::string, PropertySetter> property_setters_;
-};
-
-}  // namespace common
-
-#endif  // XWALK_COMMON_DBUS_SERVER_H_
index 69ef48f..cfc9fa4 100644 (file)
 
 namespace extensions {
 
-const char kDBusNameForExtension[] = "Extension";
-const char kDBusInterfaceNameForExtension[] = "org.tizen.xwalk.Extension";
-const char kMethodGetExtensions[] = "GetExtensions";
-const char kMethodCreateInstance[] = "CreateInstance";
-const char kMethodDestroyInstance[] = "DestroyInstance";
-const char kMethodSendSyncMessage[] = "SendSyncMessage";
-const char kMethodPostMessage[] = "PostMessage";
-const char kSignalOnMessageToJS[] = "OnMessageToJS";
-const char kMethodGetJavascriptCode[] = "GetJavascriptCode";
+const char kMethodGetExtensions[] = "xwalk://GetExtensions";
+const char kMethodCreateInstance[] = "xwalk://CreateInstance";
+const char kMethodDestroyInstance[] = "xwalk://DestroyInstance";
+const char kMethodSendSyncMessage[] = "xwalk://SendSyncMessage";
+const char kMethodPostMessage[] = "xwalk://PostMessage";
+const char kMethodGetAPIScript[] = "xwalk://GetAPIScript";
+const char kMethodPostMessageToJS[] = "xwalk://PostMessageToJS";
+
 
 }  // namespace extensions
index 6d0eb5d..588f09b 100644 (file)
 
 namespace extensions {
 
-extern const char kDBusNameForExtension[];
-extern const char kDBusInterfaceNameForExtension[];
 extern const char kMethodGetExtensions[];
 extern const char kMethodCreateInstance[];
 extern const char kMethodDestroyInstance[];
 extern const char kMethodSendSyncMessage[];
 extern const char kMethodPostMessage[];
-extern const char kSignalOnMessageToJS[];
-extern const char kMethodGetJavascriptCode[];
+extern const char kMethodGetAPIScript[];
+extern const char kMethodPostMessageToJS[];
 
 }  // namespace extensions
 
index 87817d2..1d3e50d 100644 (file)
@@ -5,6 +5,7 @@
 #include "extensions/common/xwalk_extension_manager.h"
 
 #include <glob.h>
+#include <dlfcn.h>
 
 #include <fstream>
 #include <set>
 #include "extensions/common/constants.h"
 #include "extensions/common/xwalk_extension.h"
 
+#ifndef EXTENSION_PATH
+  #error EXTENSION_PATH is not set.
+#endif
+
 namespace extensions {
 
 namespace {
@@ -30,6 +35,14 @@ const char kExtensionPrefix[] = "lib";
 const char kExtensionSuffix[] = ".so";
 const char kExtensionMetadataSuffix[] = ".json";
 
+static const char* kPreloadLibs[] = {
+  EXTENSION_PATH"/libtizen.so",
+  EXTENSION_PATH"/libtizen_common.so",
+  EXTENSION_PATH"/libtizen_application.so",
+  EXTENSION_PATH"/libtizen_utils.so",
+  NULL
+};
+
 }  // namespace
 
 XWalkExtensionManager::XWalkExtensionManager() {
@@ -38,16 +51,23 @@ XWalkExtensionManager::XWalkExtensionManager() {
 XWalkExtensionManager::~XWalkExtensionManager() {
 }
 
+void XWalkExtensionManager::PreloadExtensions() {
+  for (int i = 0; kPreloadLibs[i]; i++) {
+    LOGGER(DEBUG) << "Preload libs : " << kPreloadLibs[i];
+    void* handle = dlopen(kPreloadLibs[i], RTLD_NOW|RTLD_GLOBAL);
+    if (handle == nullptr) {
+      LOGGER(WARN) << "Fail to load libs : " << dlerror();
+    }
+  }
+}
+
 void XWalkExtensionManager::LoadExtensions(bool meta_only) {
   if (!extensions_.empty()) {
     return;
   }
 
-#ifdef EXTENSION_PATH
   std::string extension_path(EXTENSION_PATH);
-#else
-  #error EXTENSION_PATH is not set.
-#endif
+
   // Gets all extension files in the EXTENSION_PATH
   std::string ext_pattern(extension_path);
   ext_pattern.append("/");
@@ -131,11 +151,7 @@ void XWalkExtensionManager::RegisterExtension(XWalkExtension* extension) {
 
 void XWalkExtensionManager::RegisterExtensionsByMeta(
     const std::string& meta_path, StringSet* files) {
-#ifdef EXTENSION_PATH
   std::string extension_path(EXTENSION_PATH);
-#else
-  #error EXTENSION_PATH is not set.
-#endif
 
   std::ifstream metafile(meta_path.c_str());
   if (!metafile.is_open()) {
index 8a0cd78..71c6575 100644 (file)
@@ -19,11 +19,13 @@ class XWalkExtensionManager : public XWalkExtension::XWalkExtensionDelegate {
   typedef std::map<std::string, XWalkExtension*> ExtensionMap;
 
   XWalkExtensionManager();
-  ~XWalkExtensionManager();
+  virtual ~XWalkExtensionManager();
 
   ExtensionMap extensions() const { return extensions_; }
 
   void LoadExtensions(bool meta_only = true);
+  void PreloadExtensions();
+
  private:
   // override
   void GetRuntimeVariable(const char* key, char* value, size_t value_len);
diff --git a/extensions/common/xwalk_extension_server.cc b/extensions/common/xwalk_extension_server.cc
new file mode 100644 (file)
index 0000000..5009af1
--- /dev/null
@@ -0,0 +1,217 @@
+// Copyright (c) 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 "extensions/common/xwalk_extension_server.h"
+
+#include <Ecore.h>
+
+#include <string>
+
+#include "common/logger.h"
+#include "common/profiler.h"
+#include "common/string_utils.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/xwalk_extension_manager.h"
+
+namespace extensions {
+
+// static
+XWalkExtensionServer* XWalkExtensionServer::GetInstance() {
+  static XWalkExtensionServer self;
+  return &self;
+}
+
+XWalkExtensionServer::XWalkExtensionServer() {
+  manager_.LoadExtensions();
+}
+
+XWalkExtensionServer::~XWalkExtensionServer() {
+}
+
+void XWalkExtensionServer::SetupIPC(Ewk_Context* ewk_context) {
+  ewk_context_ = ewk_context;
+}
+
+void XWalkExtensionServer::Preload() {
+  manager_.PreloadExtensions();
+}
+
+Json::Value XWalkExtensionServer::GetExtensions() {
+  Json::Value out;
+  auto extensions = manager_.extensions();
+  for (auto it = extensions.begin(); it != extensions.end(); ++it) {
+    Json::Value ext;
+    ext["name"] = it->second->name();
+    // ext["api"] = it->second->GetJavascriptCode();
+    auto entry_points = it->second->entry_points();
+    for (auto ite = entry_points.begin(); ite != entry_points.end(); ++ite) {
+      ext["entry_points"].append(*ite);
+    }
+    out.append(ext);
+  }
+  return out;
+}
+
+std::string XWalkExtensionServer::GetAPIScript(
+    const std::string& extension_name) {
+  auto extensions = manager_.extensions();
+  auto it = extensions.find(extension_name);
+  if (it == extensions.end()) {
+    LOGGER(ERROR) << "No such extension '" << extension_name << "'";
+    return std::string();
+  }
+
+  return it->second->GetJavascriptCode();
+}
+
+std::string XWalkExtensionServer::CreateInstance(
+    const std::string& extension_name) {
+  std::string instance_id;
+
+  auto extensions = manager_.extensions();
+  auto it = extensions.find(extension_name);
+  if (it != extensions.end()) {
+    XWalkExtensionInstance* instance = it->second->CreateInstance();
+    if (instance) {
+      instance_id = common::utils::GenerateUUID();
+      instance->SetPostMessageCallback(
+          [this, instance_id](const std::string& msg) {
+        Ewk_IPC_Wrt_Message_Data* ans = ewk_ipc_wrt_message_data_new();
+        ewk_ipc_wrt_message_data_type_set(ans, kMethodPostMessageToJS);
+        ewk_ipc_wrt_message_data_id_set(ans, instance_id.c_str());
+        ewk_ipc_wrt_message_data_value_set(ans, msg.c_str());
+        if (!ewk_ipc_wrt_message_send(ewk_context_, ans)) {
+          LOGGER(ERROR) << "Failed to send response";
+        }
+        ewk_ipc_wrt_message_data_del(ans);
+      });
+
+      instances_[instance_id] = instance;
+    } else {
+      LOGGER(ERROR) << "Failed to create instance of the extension '"
+                    << extension_name << "'";
+    }
+  } else {
+    LOGGER(ERROR) << "No such extension '" << extension_name << "'";
+  }
+  return instance_id;
+}
+
+void XWalkExtensionServer::HandleIPCMessage(Ewk_IPC_Wrt_Message_Data* data) {
+  if (!data) {
+    LOGGER(ERROR) << "Invalid parameter. data is NULL.";
+    return;
+  }
+
+  if (!ewk_context_) {
+    LOGGER(WARN) << "IPC is not ready yet.";
+    return;
+  }
+
+  Eina_Stringshare* msg_type = ewk_ipc_wrt_message_data_type_get(data);
+  #define TYPE_IS(x) (!strcmp(msg_type, x))
+
+  if (TYPE_IS(kMethodGetExtensions)) {
+    HandleGetExtensions(data);
+  } else if (TYPE_IS(kMethodCreateInstance)) {
+    HandleCreateInstance(data);
+  } else if (TYPE_IS(kMethodDestroyInstance)) {
+    HandleDestroyInstance(data);
+  } else if (TYPE_IS(kMethodPostMessage)) {
+    HandlePostMessageToNative(data);
+  } else if (TYPE_IS(kMethodSendSyncMessage)) {
+    HandleSendSyncMessageToNative(data);
+  } else if (TYPE_IS(kMethodGetAPIScript)) {
+    HandleGetAPIScript(data);
+  }
+
+  eina_stringshare_del(msg_type);
+  #undef TYPE_IS
+}
+
+void XWalkExtensionServer::HandleGetExtensions(Ewk_IPC_Wrt_Message_Data* data) {
+  Json::Value reply = GetExtensions();
+  Json::FastWriter writer;
+  std::string reply_str = writer.write(reply);
+  ewk_ipc_wrt_message_data_value_set(data, reply_str.c_str());
+}
+
+void XWalkExtensionServer::HandleCreateInstance(
+    Ewk_IPC_Wrt_Message_Data* data) {
+  Eina_Stringshare* extension_name = ewk_ipc_wrt_message_data_value_get(data);
+
+  std::string instance_id = CreateInstance(extension_name);
+
+  ewk_ipc_wrt_message_data_value_set(data, instance_id.c_str());
+
+  eina_stringshare_del(extension_name);
+}
+
+void XWalkExtensionServer::HandleDestroyInstance(
+    Ewk_IPC_Wrt_Message_Data* data) {
+  Eina_Stringshare* instance_id = ewk_ipc_wrt_message_data_id_get(data);
+
+  auto it = instances_.find(instance_id);
+  if (it != instances_.end()) {
+    XWalkExtensionInstance* instance = it->second;
+    delete instance;
+    instances_.erase(it);
+  } else {
+    LOGGER(ERROR) << "No such instance '" << instance_id << "'";
+  }
+
+  eina_stringshare_del(instance_id);
+}
+
+void XWalkExtensionServer::HandlePostMessageToNative(
+    Ewk_IPC_Wrt_Message_Data* data) {
+  Eina_Stringshare* instance_id = ewk_ipc_wrt_message_data_id_get(data);
+
+  auto it = instances_.find(instance_id);
+  if (it != instances_.end()) {
+    Eina_Stringshare* msg = ewk_ipc_wrt_message_data_value_get(data);
+    XWalkExtensionInstance* instance = it->second;
+    instance->HandleMessage(msg);
+    eina_stringshare_del(msg);
+  } else {
+    LOGGER(ERROR) << "No such instance '" << instance_id << "'";
+  }
+
+  eina_stringshare_del(instance_id);
+}
+
+void XWalkExtensionServer::HandleSendSyncMessageToNative(
+    Ewk_IPC_Wrt_Message_Data* data) {
+  Eina_Stringshare* instance_id = ewk_ipc_wrt_message_data_id_get(data);
+
+  auto it = instances_.find(instance_id);
+  if (it != instances_.end()) {
+    Eina_Stringshare* msg = ewk_ipc_wrt_message_data_value_get(data);
+    XWalkExtensionInstance* instance = it->second;
+    std::string reply;
+    instance->SetSendSyncReplyCallback([&reply](const std::string& msg) {
+      reply = msg;
+    });
+    instance->HandleSyncMessage(msg);
+    ewk_ipc_wrt_message_data_value_set(data, reply.c_str());
+    eina_stringshare_del(msg);
+  } else {
+    LOGGER(ERROR) << "No such instance '" << instance_id << "'";
+  }
+
+  eina_stringshare_del(instance_id);
+}
+
+void XWalkExtensionServer::HandleGetAPIScript(
+    Ewk_IPC_Wrt_Message_Data* data) {
+  Eina_Stringshare* extension_name = ewk_ipc_wrt_message_data_value_get(data);
+
+  std::string api = GetAPIScript(extension_name);
+
+  ewk_ipc_wrt_message_data_value_set(data, api.c_str());
+
+  eina_stringshare_del(extension_name);
+}
+
+}  // namespace extensions
diff --git a/extensions/common/xwalk_extension_server.h b/extensions/common/xwalk_extension_server.h
new file mode 100644 (file)
index 0000000..fd6cce1
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright (c) 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 XWALK_EXTENSIONS_XWALK_EXTENSION_SERVER_H_
+#define XWALK_EXTENSIONS_XWALK_EXTENSION_SERVER_H_
+
+#include <ewk_chromium.h>
+#include <json/json.h>
+
+#include <string>
+#include <map>
+
+#include "extensions/common/xwalk_extension_manager.h"
+#include "extensions/common/xwalk_extension_instance.h"
+
+namespace extensions {
+
+class XWalkExtensionServer {
+ public:
+  static XWalkExtensionServer* GetInstance();
+
+  void SetupIPC(Ewk_Context* ewk_context);
+  void Preload();
+  Json::Value GetExtensions();
+  std::string GetAPIScript(const std::string& extension_name);
+  std::string CreateInstance(const std::string& extension_name);
+
+  void HandleIPCMessage(Ewk_IPC_Wrt_Message_Data* data);
+
+ private:
+  XWalkExtensionServer();
+  virtual ~XWalkExtensionServer();
+
+  void HandleGetExtensions(Ewk_IPC_Wrt_Message_Data* data);
+  void HandleCreateInstance(Ewk_IPC_Wrt_Message_Data* data);
+  void HandleDestroyInstance(Ewk_IPC_Wrt_Message_Data* data);
+  void HandlePostMessageToNative(Ewk_IPC_Wrt_Message_Data* data);
+  void HandleSendSyncMessageToNative(Ewk_IPC_Wrt_Message_Data* data);
+  void HandleGetAPIScript(Ewk_IPC_Wrt_Message_Data* data);
+
+  typedef std::map<std::string, XWalkExtensionInstance*> InstanceMap;
+
+  Ewk_Context* ewk_context_;
+
+  XWalkExtensionManager manager_;
+
+  InstanceMap instances_;
+};
+
+}  // namespace extensions
+
+#endif  // XWALK_EXTENSIONS_XWALK_EXTENSION_SERVER_H_
index 0f95748..c7eb0c6 100644 (file)
@@ -4,8 +4,8 @@
   ],
   'targets': [
     {
-      'target_name': 'xwalk_extension_renderer',
-      'type': 'static_library',
+      'target_name': 'xwalk_extension_shared',
+      'type': 'shared_library',
       'dependencies': [
         '../common/common.gyp:xwalk_tizen_common',
       ],
@@ -20,6 +20,8 @@
         'common/xwalk_extension_adapter.cc',
         'common/xwalk_extension_manager.h',
         'common/xwalk_extension_manager.cc',
+        'common/xwalk_extension_server.h',
+        'common/xwalk_extension_server.cc',
         'renderer/xwalk_extension_client.h',
         'renderer/xwalk_extension_client.cc',
         'renderer/xwalk_extension_module.h',
         'renderer/runtime_ipc_client.h',
         'renderer/runtime_ipc_client.cc',
       ],
+      'cflags': [
+        '-fvisibility=default',
+      ],
       'variables': {
         'packages': [
           'chromium-efl',
           'elementary',
         ],
       },
-    }, # end of target 'xwalk_extension_renderer'
+      'direct_dependent_settings': {
+        'libraries': [
+          '-lxwalk_extension_shared',
+        ],
+        'variables': {
+          'packages': [
+            'jsoncpp',
+          ],
+        },
+      },
+    }, # end of target 'xwalk_extension_static'
     {
       'target_name': 'widget_plugin',
       'type': 'shared_library',
index aaae627..d612ae0 100644 (file)
@@ -17,6 +17,7 @@
 #include "extensions/renderer/runtime_ipc_client.h"
 
 #include "common/logger.h"
+#include "common/profiler.h"
 #include "common/string_utils.h"
 
 namespace extensions {
@@ -77,16 +78,35 @@ void RuntimeIPCClient::SetRoutingId(v8::Handle<v8::Context> context,
 void RuntimeIPCClient::SendMessage(v8::Handle<v8::Context> context,
                                    const std::string& type,
                                    const std::string& value) {
+  SendMessage(context, type, "", "", value);
+}
+
+void RuntimeIPCClient::SendMessage(v8::Handle<v8::Context> context,
+                                   const std::string& type,
+                                   const std::string& id,
+                                   const std::string& value) {
+  SendMessage(context, type, id, "", value);
+}
+
+void RuntimeIPCClient::SendMessage(v8::Handle<v8::Context> context,
+                                   const std::string& type,
+                                   const std::string& id,
+                                   const std::string& ref_id,
+                                   const std::string& value) {
+  int routing_id = GetRoutingId(context);
+  if (routing_id < 1) {
+    LOGGER(ERROR) << "Invalid routing handle for IPC.";
+    return;
+  }
+
   Ewk_IPC_Wrt_Message_Data* msg = ewk_ipc_wrt_message_data_new();
-  ewk_ipc_wrt_message_data_id_set(msg, "");
   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());
 
-  int routing_id = GetRoutingId(context);
-  if (routing_id > 0) {
-    if (!ewk_ipc_plugins_message_send(routing_id, msg)) {
-      LOGGER(ERROR) << "Failed to send message to runtime using ewk_ipc.";
-    }
+  if (!ewk_ipc_plugins_message_send(routing_id, msg)) {
+    LOGGER(ERROR) << "Failed to send message to runtime using ewk_ipc.";
   }
 
   ewk_ipc_wrt_message_data_del(msg);
@@ -95,23 +115,43 @@ void RuntimeIPCClient::SendMessage(v8::Handle<v8::Context> context,
 std::string RuntimeIPCClient::SendSyncMessage(v8::Handle<v8::Context> context,
                                               const std::string& type,
                                               const std::string& value) {
+  return SendSyncMessage(context, type, "", "", value);
+}
+
+std::string RuntimeIPCClient::SendSyncMessage(v8::Handle<v8::Context> context,
+                                              const std::string& type,
+                                              const std::string& id,
+                                              const std::string& value) {
+  return SendSyncMessage(context, type, id, "", value);
+}
+
+std::string RuntimeIPCClient::SendSyncMessage(v8::Handle<v8::Context> context,
+                                              const std::string& type,
+                                              const std::string& id,
+                                              const std::string& ref_id,
+                                              const std::string& value) {
+  int routing_id = GetRoutingId(context);
+  if (routing_id < 1) {
+    LOGGER(ERROR) << "Invalid routing handle for IPC.";
+    return std::string();
+  }
+
   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());
 
-  int routing_id = GetRoutingId(context);
-  if (routing_id > 0) {
-    if (!ewk_ipc_plugins_sync_message_send(routing_id, msg)) {
-      LOGGER(ERROR) << "Failed to send message to runtime using ewk_ipc.";
-      ewk_ipc_wrt_message_data_del(msg);
-      return std::string();
-    }
+  if (!ewk_ipc_plugins_sync_message_send(routing_id, msg)) {
+    LOGGER(ERROR) << "Failed to send message to runtime using ewk_ipc.";
+    ewk_ipc_wrt_message_data_del(msg);
+    return std::string();
   }
 
   Eina_Stringshare* msg_value = ewk_ipc_wrt_message_data_value_get(msg);
-
   std::string result(msg_value);
   eina_stringshare_del(msg_value);
+
   ewk_ipc_wrt_message_data_del(msg);
 
   return result;
@@ -121,6 +161,12 @@ void RuntimeIPCClient::SendAsyncMessage(v8::Handle<v8::Context> context,
                                         const std::string& type,
                                         const std::string& value,
                                         ReplyCallback callback) {
+  int routing_id = GetRoutingId(context);
+  if (routing_id < 1) {
+    LOGGER(ERROR) << "Invalid routing handle for IPC.";
+    return;
+  }
+
   std::string msg_id = common::utils::GenerateUUID();
 
   Ewk_IPC_Wrt_Message_Data* msg = ewk_ipc_wrt_message_data_new();
@@ -128,13 +174,10 @@ void RuntimeIPCClient::SendAsyncMessage(v8::Handle<v8::Context> context,
   ewk_ipc_wrt_message_data_type_set(msg, type.c_str());
   ewk_ipc_wrt_message_data_value_set(msg, value.c_str());
 
-  int routing_id = GetRoutingId(context);
-  if (routing_id > 0) {
-    if (!ewk_ipc_plugins_message_send(routing_id, msg)) {
-      LOGGER(ERROR) << "Failed to send message to runtime using ewk_ipc.";
-      ewk_ipc_wrt_message_data_del(msg);
-      return;
-    }
+  if (!ewk_ipc_plugins_message_send(routing_id, msg)) {
+    LOGGER(ERROR) << "Failed to send message to runtime using ewk_ipc.";
+    ewk_ipc_wrt_message_data_del(msg);
+    return;
   }
 
   callbacks_[msg_id] = callback;
index b5da104..21e1d39 100755 (executable)
@@ -46,13 +46,36 @@ class RuntimeIPCClient {
 
   // Send message to BrowserProcess without reply
   void SendMessage(v8::Handle<v8::Context> context,
-                   const std::string& type, const std::string& value);
+                   const std::string& type,
+                   const std::string& value);
+
+  void SendMessage(v8::Handle<v8::Context> context,
+                   const std::string& type,
+                   const std::string& id,
+                   const std::string& value);
+
+  void SendMessage(v8::Handle<v8::Context> context,
+                   const std::string& type,
+                   const std::string& id,
+                   const std::string& ref_id,
+                   const std::string& value);
 
   // Send message to BrowserProcess synchronous with reply
   std::string SendSyncMessage(v8::Handle<v8::Context> context,
                               const std::string& type,
                               const std::string& value);
 
+  std::string SendSyncMessage(v8::Handle<v8::Context> context,
+                              const std::string& type,
+                              const std::string& id,
+                              const std::string& value);
+
+  std::string SendSyncMessage(v8::Handle<v8::Context> context,
+                              const std::string& type,
+                              const std::string& id,
+                              const std::string& ref_id,
+                              const std::string& value);
+
   // Send message to BrowserProcess asynchronous,
   // reply message will be passed to callback function.
   void SendAsyncMessage(v8::Handle<v8::Context> context,
index 8423d03..d38ec04 100644 (file)
@@ -5,9 +5,10 @@
 
 #include "extensions/renderer/xwalk_extension_client.h"
 
-#include <gio/gio.h>
-#include <glib.h>
+#include <Ecore.h>
 #include <unistd.h>
+#include <v8/v8.h>
+#include <json/json.h>
 
 #include <string>
 
 #include "common/profiler.h"
 #include "common/string_utils.h"
 #include "extensions/common/constants.h"
+#include "extensions/common/xwalk_extension_server.h"
+#include "extensions/renderer/runtime_ipc_client.h"
 
 namespace extensions {
 
+namespace {
+  void* CreateInstanceInMainloop(void* data) {
+    const char* extension_name = static_cast<const char*>(data);
+    XWalkExtensionServer* server = XWalkExtensionServer::GetInstance();
+    std::string instance_id = server->CreateInstance(extension_name);
+    return static_cast<void*>(new std::string(instance_id));
+  }
+}  // namespace
+
 XWalkExtensionClient::XWalkExtensionClient() {
 }
 
 XWalkExtensionClient::~XWalkExtensionClient() {
+  for (auto it = extension_apis_.begin(); it != extension_apis_.end(); ++it) {
+    delete it->second;
+  }
+  extension_apis_.clear();
 }
 
 void XWalkExtensionClient::Initialize() {
-  manager_.LoadExtensions();
-}
-
-XWalkExtension* XWalkExtensionClient::GetExtension(
-    const std::string& extension_name) {
-  // find extension with given the extension name
-  ExtensionMap extensions = manager_.extensions();
-  auto it = extensions.find(extension_name);
-  if (it == extensions.end()) {
-    LOGGER(ERROR) << "No such extension '" << extension_name << "'";
-    return nullptr;
+  if (!extension_apis_.empty()) {
+    return;
   }
 
-  return it->second;
-}
-
-XWalkExtensionClient::ExtensionMap XWalkExtensionClient::GetExtensions() {
-  return manager_.extensions();
+  XWalkExtensionServer* server = XWalkExtensionServer::GetInstance();
+  Json::Value reply = server->GetExtensions();
+  for (auto it = reply.begin(); it != reply.end(); ++it) {
+    ExtensionCodePoints* codepoint = new ExtensionCodePoints;
+    Json::Value entry_points = (*it)["entry_points"];
+    for (auto ep = entry_points.begin(); ep != entry_points.end(); ++ep) {
+      codepoint->entry_points.push_back((*ep).asString());
+    }
+    std::string name = (*it)["name"].asString();
+    extension_apis_[name] = codepoint;
+  }
 }
 
 std::string XWalkExtensionClient::CreateInstance(
+    v8::Handle<v8::Context> context,
     const std::string& extension_name, InstanceHandler* handler) {
-  std::string instance_id = common::utils::GenerateUUID();
-
-  // find extension with given the extension name
-  ExtensionMap extensions = manager_.extensions();
-  auto it = extensions.find(extension_name);
-  if (it == extensions.end()) {
-    LOGGER(ERROR) << "No such extension '" << extension_name << "'";
-    return std::string();
-  }
-
-  // create instance
-  XWalkExtensionInstance* instance = it->second->CreateInstance();
-  if (!instance) {
-    LOGGER(ERROR) << "Failed to create instance of extension '"
-                  << extension_name << "'";
-    return std::string();
-  }
-
-  // set callbacks
-  using std::placeholders::_1;
-  instance->SetPostMessageCallback([handler](const std::string& msg) {
-    if (handler) {
-      handler->HandleMessageFromNative(msg);
-    }
-  });
-
-  instances_[instance_id] = instance;
+  void* ret = ecore_main_loop_thread_safe_call_sync(
+      CreateInstanceInMainloop,
+      static_cast<void*>(const_cast<char*>(extension_name.data())));
+  std::string* sp = static_cast<std::string*>(ret);
+  std::string instance_id = *sp;
+  delete sp;
+
+  handlers_[instance_id] = handler;
   return instance_id;
 }
 
-void XWalkExtensionClient::DestroyInstance(const std::string& instance_id) {
-  // find instance with the given instance id
-  auto it = instances_.find(instance_id);
-  if (it == instances_.end()) {
-    LOGGER(ERROR) << "No such instance '" << instance_id << "'";
+void XWalkExtensionClient::DestroyInstance(
+    v8::Handle<v8::Context> context, const std::string& instance_id) {
+  auto it = handlers_.find(instance_id);
+  if (it == handlers_.end()) {
+    LOGGER(WARN) << "Failed to destory invalid instance id: " << instance_id;
     return;
   }
+  RuntimeIPCClient* ipc = RuntimeIPCClient::GetInstance();
+  ipc->SendMessage(context, kMethodDestroyInstance, instance_id, "");
 
-  // destroy the instance
-  XWalkExtensionInstance* instance = it->second;
-  delete instance;
-
-  instances_.erase(it);
+  handlers_.erase(it);
 }
 
 void XWalkExtensionClient::PostMessageToNative(
+    v8::Handle<v8::Context> context,
     const std::string& instance_id, const std::string& msg) {
-  // find instance with the given instance id
-  auto it = instances_.find(instance_id);
-  if (it == instances_.end()) {
-    LOGGER(ERROR) << "No such instance '" << instance_id << "'";
-    return;
-  }
-
-  // Post a message
-  XWalkExtensionInstance* instance = it->second;
-  instance->HandleMessage(msg);
+  RuntimeIPCClient* ipc = RuntimeIPCClient::GetInstance();
+  ipc->SendMessage(context, kMethodPostMessage, instance_id, msg);
 }
 
 std::string XWalkExtensionClient::SendSyncMessageToNative(
+    v8::Handle<v8::Context> context,
+    const std::string& instance_id, const std::string& msg) {
+  RuntimeIPCClient* ipc = RuntimeIPCClient::GetInstance();
+  std::string reply =
+      ipc->SendSyncMessage(context, kMethodSendSyncMessage, instance_id, msg);
+  return reply;
+}
+
+std::string XWalkExtensionClient::GetAPIScript(
+    v8::Handle<v8::Context> context,
+    const std::string& extension_name) {
+  XWalkExtensionServer* server = XWalkExtensionServer::GetInstance();
+  return server->GetAPIScript(extension_name);
+}
+
+void XWalkExtensionClient::OnReceivedIPCMessage(
     const std::string& instance_id, const std::string& msg) {
-  // find instance with the given instance id
-  auto it = instances_.find(instance_id);
-  if (it == instances_.end()) {
-    LOGGER(ERROR) << "No such instance '" << instance_id << "'";
-    return std::string();
+  auto it = handlers_.find(instance_id);
+  if (it == handlers_.end()) {
+    LOGGER(WARN) << "Failed to post the message. Invalid instance id.";
+    return;
   }
 
-  // Post a message and receive a reply message
-  std::string reply;
-  XWalkExtensionInstance* instance = it->second;
-  instance->SetSendSyncReplyCallback([&reply](const std::string& msg) {
-    reply = msg;
-  });
-  instance->HandleSyncMessage(msg);
-  return reply;
+  if (!it->second)
+    return;
+
+  it->second->HandleMessageFromNative(msg);
 }
 
 }  // namespace extensions
index 9d46444..275be52 100644 (file)
@@ -6,22 +6,19 @@
 #ifndef XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_CLIENT_H_
 #define XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_CLIENT_H_
 
+#include <v8/v8.h>
+
 #include <map>
 #include <memory>
 #include <string>
 #include <vector>
 
-#include "extensions/common/xwalk_extension.h"
-#include "extensions/common/xwalk_extension_instance.h"
-#include "extensions/common/xwalk_extension_manager.h"
+#include "extensions/renderer/xwalk_module_system.h"
 
 namespace extensions {
 
 class XWalkExtensionClient {
  public:
-  typedef std::map<std::string, XWalkExtension*> ExtensionMap;
-  typedef std::map<std::string, XWalkExtensionInstance*> InstanceMap;
-
   struct InstanceHandler {
     virtual void HandleMessageFromNative(const std::string& msg) = 0;
    protected:
@@ -33,21 +30,39 @@ class XWalkExtensionClient {
 
   void Initialize();
 
-  XWalkExtension* GetExtension(const std::string& extension_name);
-  ExtensionMap GetExtensions();
-
-  std::string CreateInstance(const std::string& extension_name,
+  std::string CreateInstance(v8::Handle<v8::Context> context,
+                             const std::string& extension_name,
                              InstanceHandler* handler);
-  void DestroyInstance(const std::string& instance_id);
+  void DestroyInstance(v8::Handle<v8::Context> context,
+                       const std::string& instance_id);
 
-  void PostMessageToNative(const std::string& instance_id,
+  void PostMessageToNative(v8::Handle<v8::Context> context,
+                           const std::string& instance_id,
                            const std::string& msg);
-  std::string SendSyncMessageToNative(const std::string& instance_id,
+  std::string SendSyncMessageToNative(v8::Handle<v8::Context> context,
+                                      const std::string& instance_id,
                                       const std::string& msg);
 
+  std::string GetAPIScript(v8::Handle<v8::Context> context,
+                           const std::string& extension_name);
+
+  void OnReceivedIPCMessage(const std::string& instance_id,
+                            const std::string& msg);
+
+  struct ExtensionCodePoints {
+    std::string api;
+    std::vector<std::string> entry_points;
+  };
+
+  typedef std::map<std::string, ExtensionCodePoints*> ExtensionAPIMap;
+
+  const ExtensionAPIMap& extension_apis() const { return extension_apis_; }
+
  private:
-  XWalkExtensionManager manager_;
-  InstanceMap instances_;
+  ExtensionAPIMap extension_apis_;
+
+  typedef std::map<std::string, InstanceHandler*> HandlerMap;
+  HandlerMap handlers_;
 };
 
 }  // namespace extensions
index 232fb7d..4294ec6 100644 (file)
@@ -13,6 +13,7 @@
 #include <vector>
 
 #include "common/logger.h"
+#include "common/profiler.h"
 #include "extensions/renderer/runtime_ipc_client.h"
 #include "extensions/renderer/xwalk_extension_client.h"
 #include "extensions/renderer/xwalk_module_system.h"
@@ -48,10 +49,12 @@ const char* kXWalkExtensionModule = "kXWalkExtensionModule";
 
 XWalkExtensionModule::XWalkExtensionModule(XWalkExtensionClient* client,
                                            XWalkModuleSystem* module_system,
-                                           const std::string& extension_name) :
-    extension_name_(extension_name),
-    client_(client),
-    module_system_(module_system) {
+                                           const std::string& extension_name,
+                                           const std::string& extension_code)
+    : extension_name_(extension_name),
+      extension_code_(extension_code),
+      client_(client),
+      module_system_(module_system) {
   v8::Isolate* isolate = v8::Isolate::GetCurrent();
   v8::HandleScope handle_scope(isolate);
   v8::Handle<v8::Object> function_data = v8::Object::New(isolate);
@@ -108,7 +111,7 @@ XWalkExtensionModule::~XWalkExtensionModule() {
   message_listener_.Reset();
 
   if (!instance_id_.empty())
-    client_->DestroyInstance(instance_id_);
+    client_->DestroyInstance(module_system_->GetV8Context(), instance_id_);
 }
 
 namespace {
@@ -267,21 +270,21 @@ v8::Handle<v8::Value> RunString(const std::string& code,
 
 void XWalkExtensionModule::LoadExtensionCode(
     v8::Handle<v8::Context> context, v8::Handle<v8::Function> require_native) {
-  instance_id_ = client_->CreateInstance(extension_name_, this);
+  instance_id_ = client_->CreateInstance(context, extension_name_, this);
   if (instance_id_.empty()) {
     LOGGER(ERROR) << "Failed to create an instance of " << extension_name_;
     return;
   }
 
-
-
-  XWalkExtension* ext = client_->GetExtension(extension_name_);
-  if (ext == nullptr) {
-    LOGGER(ERROR) << "Failed to get an extension " << extension_name_;
-    return;
+  if (extension_code_.empty()) {
+    extension_code_ = client_->GetAPIScript(context, extension_name_);
+    if (extension_code_.empty()) {
+      LOGGER(ERROR) << "Failed to get API script of " << extension_name_;
+      return;
+    }
   }
-  std::string wrapped_api_code =
-      WrapAPICode(ext->GetJavascriptCode(), extension_name_);
+
+  std::string wrapped_api_code = WrapAPICode(extension_code_, extension_name_);
 
   std::string exception;
   v8::Handle<v8::Value> result = RunString(wrapped_api_code, &exception);
@@ -347,7 +350,8 @@ void XWalkExtensionModule::PostMessageCallback(
   v8::String::Utf8Value value(info[0]->ToString());
 
   // CHECK(module->instance_id_);
-  module->client_->PostMessageToNative(module->instance_id_,
+  module->client_->PostMessageToNative(module->module_system_->GetV8Context(),
+                                       module->instance_id_,
                                        std::string(*value));
   result.Set(true);
 }
@@ -366,8 +370,10 @@ void XWalkExtensionModule::SendSyncMessageCallback(
 
   // CHECK(module->instance_id_);
   std::string reply =
-      module->client_->SendSyncMessageToNative(module->instance_id_,
-                                               std::string(*value));
+      module->client_->SendSyncMessageToNative(
+          module->module_system_->GetV8Context(),
+          module->instance_id_,
+          std::string(*value));
 
   // If we tried to send a message to an instance that became invalid,
   // then reply will be NULL.
index eea3d01..1076f0f 100644 (file)
@@ -28,7 +28,8 @@ class XWalkExtensionModule : public XWalkExtensionClient::InstanceHandler {
  public:
   XWalkExtensionModule(XWalkExtensionClient* client,
                   XWalkModuleSystem* module_system,
-                  const std::string& extension_name);
+                  const std::string& extension_name,
+                  const std::string& extension_code);
   virtual ~XWalkExtensionModule();
 
   // TODO(cmarcelo): Make this return a v8::Handle<v8::Object>, and
@@ -71,6 +72,7 @@ class XWalkExtensionModule : public XWalkExtensionClient::InstanceHandler {
   v8::Persistent<v8::Function> message_listener_;
 
   std::string extension_name_;
+  std::string extension_code_;
 
   XWalkExtensionClient* client_;
   XWalkModuleSystem* module_system_;
index 6e570aa..384abbb 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "extensions/renderer/xwalk_extension_renderer_controller.h"
 
+#include <Ecore.h>
 #include <v8/v8.h>
 #include <string>
 #include <utility>
@@ -17,6 +18,7 @@
 #include "extensions/renderer/xwalk_extension_module.h"
 #include "extensions/renderer/xwalk_module_system.h"
 #include "extensions/renderer/xwalk_v8tools_module.h"
+#include "extensions/renderer/runtime_ipc_client.h"
 
 namespace extensions {
 
@@ -24,14 +26,16 @@ namespace {
 
 void CreateExtensionModules(XWalkExtensionClient* client,
                             XWalkModuleSystem* module_system) {
-  SCOPE_PROFILE();
+  const XWalkExtensionClient::ExtensionAPIMap& extensions =
+      client->extension_apis();
 
-  auto extensions = client->GetExtensions();
   for (auto it = extensions.begin(); it != extensions.end(); ++it) {
+    XWalkExtensionClient::ExtensionCodePoints* codepoint = it->second;
     std::unique_ptr<XWalkExtensionModule> module(
-        new XWalkExtensionModule(client, module_system, it->first));
-    module_system->RegisterExtensionModule(
-        std::move(module), it->second->entry_points());
+        new XWalkExtensionModule(client, module_system,
+                                 it->first, codepoint->api));
+    module_system->RegisterExtensionModule(std::move(module),
+                                           codepoint->entry_points);
   }
 }
 
@@ -44,8 +48,7 @@ XWalkExtensionRendererController::GetInstance() {
 }
 
 XWalkExtensionRendererController::XWalkExtensionRendererController()
-    : initialized_(false),
-      extensions_client_(new XWalkExtensionClient()) {
+    : extensions_client_(new XWalkExtensionClient()) {
 }
 
 XWalkExtensionRendererController::~XWalkExtensionRendererController() {
@@ -53,11 +56,9 @@ XWalkExtensionRendererController::~XWalkExtensionRendererController() {
 
 void XWalkExtensionRendererController::DidCreateScriptContext(
     v8::Handle<v8::Context> context) {
-  SCOPE_PROFILE();
   XWalkModuleSystem* module_system = new XWalkModuleSystem(context);
   XWalkModuleSystem::SetModuleSystemInContext(
       std::unique_ptr<XWalkModuleSystem>(module_system), context);
-
   module_system->RegisterNativeModule(
         "v8tools",
         std::unique_ptr<XWalkNativeModule>(new XWalkV8ToolsModule));
@@ -68,7 +69,9 @@ void XWalkExtensionRendererController::DidCreateScriptContext(
         "objecttools",
         std::unique_ptr<XWalkNativeModule>(new ObjectToolsModule));
 
+  extensions_client_->Initialize();
   CreateExtensionModules(extensions_client_.get(), module_system);
+
   module_system->Initialize();
 }
 
@@ -78,13 +81,29 @@ void XWalkExtensionRendererController::WillReleaseScriptContext(
   XWalkModuleSystem::ResetModuleSystemFromContext(context);
 }
 
-void XWalkExtensionRendererController::InitializeExtensions() {
-  if (initialized_) {
-    LOGGER(DEBUG) << "already initialized";
-    return;
+void XWalkExtensionRendererController::OnReceivedIPCMessage(
+    const Ewk_IPC_Wrt_Message_Data* data) {
+
+  Eina_Stringshare* type = ewk_ipc_wrt_message_data_type_get(data);
+
+#define TYPE_BEGIN(x) (!strncmp(type, x, strlen(x)))
+  if (TYPE_BEGIN("xwalk://"))  {
+    Eina_Stringshare* id = ewk_ipc_wrt_message_data_id_get(data);
+    Eina_Stringshare* msg = ewk_ipc_wrt_message_data_value_get(data);
+    extensions_client_->OnReceivedIPCMessage(id, msg);
+    eina_stringshare_del(id);
+    eina_stringshare_del(msg);
+  } else {
+    RuntimeIPCClient* ipc = RuntimeIPCClient::GetInstance();
+    ipc->HandleMessageFromRuntime(data);
   }
+#undef TYPE_BEGIN
+
+  eina_stringshare_del(type);
+}
+
+void XWalkExtensionRendererController::InitializeExtensionClient() {
   extensions_client_->Initialize();
-  initialized_ = true;
 }
 
 }  // namespace extensions
index ac7d295..b550721 100644 (file)
@@ -6,7 +6,9 @@
 #ifndef XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_RENDERER_CONTROLLER_H_
 #define XWALK_EXTENSIONS_RENDERER_XWALK_EXTENSION_RENDERER_CONTROLLER_H_
 
+#include <ewk_chromium.h>
 #include <v8/v8.h>
+
 #include <memory>
 #include <string>
 
@@ -21,14 +23,15 @@ class XWalkExtensionRendererController {
   void DidCreateScriptContext(v8::Handle<v8::Context> context);
   void WillReleaseScriptContext(v8::Handle<v8::Context> context);
 
-  void InitializeExtensions();
+  void OnReceivedIPCMessage(const Ewk_IPC_Wrt_Message_Data* data);
+
+  void InitializeExtensionClient();
 
  private:
   XWalkExtensionRendererController();
   virtual ~XWalkExtensionRendererController();
 
  private:
-  bool initialized_;
   std::unique_ptr<XWalkExtensionClient> extensions_client_;
 };
 
index a7091e6..5324e3e 100755 (executable)
@@ -32,7 +32,6 @@ BuildRequires: pkgconfig(ecore)
 BuildRequires: pkgconfig(ecore-wayland)
 BuildRequires: pkgconfig(efl-extension)
 BuildRequires: pkgconfig(elementary)
-BuildRequires: pkgconfig(gio-2.0)
 BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(libwebappenc)
 BuildRequires: pkgconfig(wgt-manifest-handlers)
@@ -43,6 +42,7 @@ BuildRequires: pkgconfig(sqlite3)
 BuildRequires: pkgconfig(uuid)
 BuildRequires: pkgconfig(launchpad)
 BuildRequires: pkgconfig(ttrace)
+BuildRequires: pkgconfig(jsoncpp)
 
 %if "%{?profile}" == "mobile"
 %define tizen_feature_rotary_event_support     0
@@ -122,6 +122,9 @@ install -p -m 755 out/Default/xwalk_runtime %{buildroot}%{_bindir}
 ln -s %{_bindir}/xwalk_runtime %{buildroot}%{_bindir}/wrt
 ln -s %{_bindir}/xwalk_runtime %{buildroot}%{_bindir}/wrt-loader
 
+# xwalk extension shared
+install -p -m 644 out/Default/lib/libxwalk_extension_shared.so %{buildroot}%{_libdir}
+
 # xwalk_runtime_resources
 for file in $(find out/Default/gen/locales -type f -name *.mo); do
   install -m 644 -D $file %{buildroot}%{_datadir}/locale/${file#out/Default/gen/locales/}
@@ -141,6 +144,7 @@ rm -fr %{buildroot}
 %attr(644,root,root) %{_datadir}/edje/xwalk/*.edj
 %attr(644,root,root) %{_libdir}/libxwalk_tizen_common.so
 %attr(644,root,root) %{_libdir}/libxwalk_injected_bundle.so
+%attr(644,root,root) %{_libdir}/libxwalk_extension_shared.so
 %attr(644,root,root) %{extension_path}/libwidget_plugin.so
 %attr(644,root,root) %{extension_path}/widget.json
 %attr(644,root,root) %{extension_path}/libsplash_screen_plugin.so
index 5b650b8..9363773 100755 (executable)
 #include <ewk_chromium.h>
 #include <stdio.h>
 
-#include "runtime/browser/native_app_window.h"
 #include "common/logger.h"
+#include "runtime/browser/native_app_window.h"
+#include "extensions/common/xwalk_extension_server.h"
 
 #ifndef INJECTED_BUNDLE_PATH
 #error INJECTED_BUNDLE_PATH is not set.
 #endif
 
-
 namespace runtime {
 
-
 PreloadManager* PreloadManager::GetInstance() {
   static PreloadManager instance;
   return &instance;
@@ -40,6 +39,10 @@ PreloadManager::PreloadManager() {
 }
 
 void PreloadManager::CreateCacheComponet() {
+  // Load extensions in the preload step
+  auto extension_server = extensions::XWalkExtensionServer::GetInstance();
+  extension_server->Preload();
+
   // It was not used. just to fork zygote process
   auto context =
       ewk_context_new_with_injected_bundle_path(INJECTED_BUNDLE_PATH);
index 2eefcf2..c499533 100755 (executable)
@@ -42,7 +42,8 @@ int real_main(int argc, char* argv[]) {
       const_cast<char*>("--no-sandbox"),
       const_cast<char*>("--enable-file-cookies"),
       const_cast<char*>("--allow-file-access-from-files"),
-      const_cast<char*>("--allow-universal-access-from-files")
+      const_cast<char*>("--allow-universal-access-from-files"),
+      const_cast<char*>("--single-process")
     };
     const int chromium_arg_cnt =
         sizeof(chromium_arg_options) / sizeof(chromium_arg_options[0]);
@@ -72,7 +73,8 @@ int main(int argc, char* argv[]) {
         const_cast<char*>("--no-sandbox"),
         const_cast<char*>("--enable-file-cookies"),
         const_cast<char*>("--allow-file-access-from-files"),
-        const_cast<char*>("--allow-universal-access-from-files")
+        const_cast<char*>("--allow-universal-access-from-files"),
+        const_cast<char*>("--single-process")
       };
       const int chromium_arg_cnt =
           sizeof(chromium_arg_options) / sizeof(chromium_arg_options[0]);
index c383366..1996e92 100644 (file)
@@ -43,6 +43,7 @@
 #include "runtime/browser/vibration_manager.h"
 #include "runtime/browser/web_view.h"
 #include "runtime/browser/splash_screen.h"
+#include "extensions/common/xwalk_extension_server.h"
 
 #ifndef INJECTED_BUNDLE_PATH
 #error INJECTED_BUNDLE_PATH is not set.
@@ -241,6 +242,10 @@ WebApplication::~WebApplication() {
 
 bool WebApplication::Initialize() {
   SCOPE_PROFILE();
+
+  auto extension_server = extensions::XWalkExtensionServer::GetInstance();
+  extension_server->SetupIPC(ewk_context_);
+
   // ewk setting
   ewk_context_cache_model_set(ewk_context_, EWK_CACHE_MODEL_DOCUMENT_BROWSER);
 
@@ -529,65 +534,71 @@ void WebApplication::OnClosedWebView(WebView* view) {
 
 void WebApplication::OnReceivedWrtMessage(WebView* /*view*/,
                                           Ewk_IPC_Wrt_Message_Data* msg) {
-  Eina_Stringshare* msg_id = ewk_ipc_wrt_message_data_id_get(msg);
-  Eina_Stringshare* msg_ref_id = ewk_ipc_wrt_message_data_reference_id_get(msg);
+  SCOPE_PROFILE();
   Eina_Stringshare* msg_type = ewk_ipc_wrt_message_data_type_get(msg);
-  Eina_Stringshare* msg_value = ewk_ipc_wrt_message_data_value_get(msg);
-
-  LOGGER(DEBUG) << "RecvMsg: id = " << msg_id;
-  LOGGER(DEBUG) << "RecvMsg: refid = " << msg_ref_id;
-  LOGGER(DEBUG) << "RecvMsg: type = " << msg_type;
-  LOGGER(DEBUG) << "RecvMsg: value = " << msg_value;
 
+#define TYPE_BEGIN(x) (!strncmp(msg_type, x, strlen(x)))
 #define TYPE_IS(x) (!strcmp(msg_type, x))
-  if (TYPE_IS("tizen://hide")) {
-    // One Way Message
-    window_->InActive();
-  } else if (TYPE_IS("tizen://exit")) {
-    // One Way Message
-    ecore_idler_add(ExitAppIdlerCallback, this);
-  } else if (TYPE_IS("tizen://changeUA")) {
-    // Async Message
-    // Change UserAgent of current WebView
-    bool ret = false;
-    if (view_stack_.size() > 0 && view_stack_.front() != NULL) {
-      ret = view_stack_.front()->SetUserAgent(std::string(msg_value));
-    }
-    // Send response
-    Ewk_IPC_Wrt_Message_Data* ans = ewk_ipc_wrt_message_data_new();
-    ewk_ipc_wrt_message_data_type_set(ans, msg_type);
-    ewk_ipc_wrt_message_data_reference_id_set(ans, msg_id);
-    if (ret)
-      ewk_ipc_wrt_message_data_value_set(ans, "success");
-    else
-      ewk_ipc_wrt_message_data_value_set(ans, "failed");
-    if (!ewk_ipc_wrt_message_send(ewk_context_, ans)) {
-      LOGGER(ERROR) << "Failed to send response";
-    }
-    ewk_ipc_wrt_message_data_del(ans);
-  } else if (TYPE_IS("tizen://deleteAllCookies")) {
-    Ewk_IPC_Wrt_Message_Data* ans = ewk_ipc_wrt_message_data_new();
-    ewk_ipc_wrt_message_data_type_set(ans, msg_type);
-    ewk_ipc_wrt_message_data_reference_id_set(ans, msg_id);
-    if (ClearCookie(ewk_context_))
-      ewk_ipc_wrt_message_data_value_set(ans, "success");
-    else
-      ewk_ipc_wrt_message_data_value_set(ans, "failed");
-    if (!ewk_ipc_wrt_message_send(ewk_context_, ans)) {
-      LOGGER(ERROR) << "Failed to send response";
+
+  if (TYPE_BEGIN("xwalk://")) {
+    auto extension_server = extensions::XWalkExtensionServer::GetInstance();
+    extension_server->HandleIPCMessage(msg);
+  } else {
+    Eina_Stringshare* msg_id = ewk_ipc_wrt_message_data_id_get(msg);
+    Eina_Stringshare* msg_ref_id =
+        ewk_ipc_wrt_message_data_reference_id_get(msg);
+    Eina_Stringshare* msg_value = ewk_ipc_wrt_message_data_value_get(msg);
+
+    if (TYPE_IS("tizen://hide")) {
+      // One Way Message
+      window_->InActive();
+    } else if (TYPE_IS("tizen://exit")) {
+      // One Way Message
+      ecore_idler_add(ExitAppIdlerCallback, this);
+    } else if (TYPE_IS("tizen://changeUA")) {
+      // Async Message
+      // Change UserAgent of current WebView
+      bool ret = false;
+      if (view_stack_.size() > 0 && view_stack_.front() != NULL) {
+        ret = view_stack_.front()->SetUserAgent(std::string(msg_value));
+      }
+      // Send response
+      Ewk_IPC_Wrt_Message_Data* ans = ewk_ipc_wrt_message_data_new();
+      ewk_ipc_wrt_message_data_type_set(ans, msg_type);
+      ewk_ipc_wrt_message_data_reference_id_set(ans, msg_id);
+      if (ret)
+        ewk_ipc_wrt_message_data_value_set(ans, "success");
+      else
+        ewk_ipc_wrt_message_data_value_set(ans, "failed");
+      if (!ewk_ipc_wrt_message_send(ewk_context_, ans)) {
+        LOGGER(ERROR) << "Failed to send response";
+      }
+      ewk_ipc_wrt_message_data_del(ans);
+    } else if (TYPE_IS("tizen://deleteAllCookies")) {
+      Ewk_IPC_Wrt_Message_Data* ans = ewk_ipc_wrt_message_data_new();
+      ewk_ipc_wrt_message_data_type_set(ans, msg_type);
+      ewk_ipc_wrt_message_data_reference_id_set(ans, msg_id);
+      if (ClearCookie(ewk_context_))
+        ewk_ipc_wrt_message_data_value_set(ans, "success");
+      else
+        ewk_ipc_wrt_message_data_value_set(ans, "failed");
+      if (!ewk_ipc_wrt_message_send(ewk_context_, ans)) {
+        LOGGER(ERROR) << "Failed to send response";
+      }
+      ewk_ipc_wrt_message_data_del(ans);
+    } else if (TYPE_IS("tizen://hide_splash_screen")) {
+      splash_screen_->HideSplashScreen(SplashScreen::HideReason::CUSTOM);
     }
-    ewk_ipc_wrt_message_data_del(ans);
-  } else if (TYPE_IS("tizen://hide_splash_screen")) {
-    splash_screen_->HideSplashScreen(SplashScreen::HideReason::CUSTOM);
-  }
 
+    eina_stringshare_del(msg_ref_id);
+    eina_stringshare_del(msg_id);
+    eina_stringshare_del(msg_value);
+  }
 
 #undef TYPE_IS
+#undef TYPE_BEGIN
 
-  eina_stringshare_del(msg_value);
   eina_stringshare_del(msg_type);
-  eina_stringshare_del(msg_ref_id);
-  eina_stringshare_del(msg_id);
 }
 
 void WebApplication::OnOrientationLock(
index e3f5730..fa9c972 100755 (executable)
 
 namespace runtime {
 
-static const char* kPreloadLibs[] = {
-  "/usr/lib/tizen-extensions-crosswalk/libtizen.so",
-  "/usr/lib/tizen-extensions-crosswalk/libtizen_common.so",
-  "/usr/lib/tizen-extensions-crosswalk/libtizen_application.so",
-  "/usr/lib/tizen-extensions-crosswalk/libtizen_utils.so",
-  NULL
-};
-
-static void PreloadLibrary() {
-  for (int i = 0; kPreloadLibs[i]; i++) {
-    LOGGER(DEBUG) << "Preload libs : " << kPreloadLibs[i];
-    void* handle = dlopen(kPreloadLibs[i], RTLD_NOW|RTLD_GLOBAL);
-    if (handle == nullptr) {
-      LOGGER(DEBUG) << "Fail to load libs : " << dlerror();
-    }
-  }
-}
-
 class BundleGlobalData {
  public:
   static BundleGlobalData* GetInstance() {
@@ -107,11 +89,6 @@ extern "C" void DynamicSetWidgetInfo(const char* tizen_id) {
   LOGGER(DEBUG) << "InjectedBundle::DynamicSetWidgetInfo !!" << tizen_id;
   ecore_init();
 
-  STEP_PROFILE_START("Initialize XWalkExtensionRendererController");
-  auto& controller = extensions::XWalkExtensionRendererController::GetInstance();
-  controller.InitializeExtensions();
-  STEP_PROFILE_END("Initialize XWalkExtensionRendererController");
-
   runtime::BundleGlobalData::GetInstance()->Initialize(tizen_id);
 }
 
@@ -189,18 +166,15 @@ extern "C" void DynamicDatabaseAttach(int /*attach*/) {
 
 extern "C" void DynamicOnIPCMessage(const Ewk_IPC_Wrt_Message_Data& data) {
   LOGGER(DEBUG) << "InjectedBundle::DynamicOnIPCMessage !!";
-  extensions::RuntimeIPCClient* rc =
-      extensions::RuntimeIPCClient::GetInstance();
-  rc->HandleMessageFromRuntime(&data);
+  extensions::XWalkExtensionRendererController& controller =
+    extensions::XWalkExtensionRendererController::GetInstance();
+  controller.OnReceivedIPCMessage(&data);
 }
 
 extern "C" void DynamicPreloading() {
   LOGGER(DEBUG) << "InjectedBundle::DynamicPreloading !!";
-  runtime::PreloadLibrary();
   runtime::BundleGlobalData::GetInstance()->PreInitialize();
-
-  STEP_PROFILE_START("Initialize XWalkExtensionRendererController");
-  auto& controller = extensions::XWalkExtensionRendererController::GetInstance();
-  controller.InitializeExtensions();
-  STEP_PROFILE_END("Initialize XWalkExtensionRendererController");
+  extensions::XWalkExtensionRendererController& controller =
+    extensions::XWalkExtensionRendererController::GetInstance();
+  controller.InitializeExtensionClient();
 }
index 2c962cd..e93e9e7 100755 (executable)
@@ -8,6 +8,7 @@
       'type': 'executable',
       'dependencies': [
         '../common/common.gyp:xwalk_tizen_common',
+        '../extensions/extensions.gyp:xwalk_extension_shared',
         'resources/resources.gyp:xwalk_runtime_resources',
       ],
       'sources': [
@@ -70,7 +71,7 @@
       'type': 'shared_library',
       'dependencies': [
         '../common/common.gyp:xwalk_tizen_common',
-        '../extensions/extensions.gyp:xwalk_extension_renderer',
+        '../extensions/extensions.gyp:xwalk_extension_shared',
       ],
       'sources': [
         'renderer/injected_bundle.cc',