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 f399892ac544cc88dc8f359dc5b60cc0d2cffd5a..ac3327cc77a25127fce40bbebd4cb4a02527f5f3 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 69ef48fc905882ec27839cc8d4e01ff6e53d2c4f..cfc9fa4838b1cc9d1ff7be15d2e2712778344aa9 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 6d0eb5daa2f7a7d7582997629b21c1221d41d88f..588f09b63d7050aa46a3c156a30393ee3f004d8f 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 87817d21be3b9c77a38bfe57807cf083f4a028aa..1d3e50d60feeec3db2e05894462823c47d46f137 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 8a0cd783dc95c469e72b5651a27f9f103ceb22b4..71c657509db1ef58f387505663c12e030abe6291 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 0f9574849df7c6452f733218a7fca77a6d7f2e7e..c7eb0c6015659c3079b1b175690e6a0c1a9dbbb5 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 aaae62767afe07c897513de424e242069d8e3492..d612ae0ab37801e3c9197bd014f573a886e19b74 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 b5da10440099ed01730d774727287b0e5f2da9db..21e1d39b62b6e7cf7c6e3d618a6b38a7f9e9fd8c 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 8423d038e4b452a0b54028611375d16f8e9633ec..d38ec045eda7ca8dd42a6100cef8278402004f73 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 9d464440fde42c0c0b9310364c414ed125040dc9..275be52914250956abb9a7c528a097d3467fefc6 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 232fb7d44442b8f980751bba0afa12e86040e15a..4294ec6b107308a58d98134ec63a898bc9016934 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 eea3d0156f8e3a3bfb0510ff3ae7e68d1dec4d20..1076f0fa7b0a0a0d1f1a46766c15a5b84b81329f 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 6e570aaa9da1e1b11a7db6b92c757a5b23c33593..384abbbf3e4a76e1b1a317aba15da3c1bb81414c 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 ac7d295ac346768cba82b83b49c72e7d72b256d7..b5507213685535ffef786438c67ed56691e07598 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 a7091e6092dd019cae3aa8f8ceba7d61cf838f42..5324e3e2d0af5750428ce71b2433ecff8547baa0 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 5b650b83ec5b32ba4c5d5b7800ce74747ae0c7fe..936377384d40fbcff178b6dcb89e78fa3dced608 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 2eefcf2dae500523e36393ba205eb098fa026c0a..c4995332570f9773a92322678315bc9c76185626 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 c38336612131323d55137c5035bd52c4d8f319b8..1996e9295f596614e68dafddb470bbc082f98ef6 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 e3f5730e36de75b2cae3adb08f27b3f3bdaeb422..fa9c972785ff3f7699f03a8c3c3654ab502a7c07 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 2c962cdd542aad3e824f4c16b04bd24575057629..e93e9e721c7840a4eccff6dfa6a2e1fd4387c2bc 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',