Upstream version 8.36.169.0
[platform/framework/web/crosswalk.git] / src / xwalk / extensions / common / xwalk_extension_server.cc
index bbf4ad5..5f9db7a 100644 (file)
@@ -7,10 +7,12 @@
 #include "base/file_util.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
+#include "base/memory/shared_memory.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/stl_util.h"
 #include "content/public/browser/render_process_host.h"
+#include "ipc/ipc_message.h"
 #include "ipc/ipc_sender.h"
 #include "xwalk/extensions/common/xwalk_extension_messages.h"
 #include "xwalk/extensions/common/xwalk_external_extension.h"
 namespace xwalk {
 namespace extensions {
 
+// Threshold to determine using shared memory or message
+const size_t kInlineMessageMaxSize = 256 * 1024;
+
 XWalkExtensionServer::XWalkExtensionServer()
     : sender_(NULL),
+      renderer_process_handle_(base::kNullProcessHandle),
       permissions_delegate_(NULL) {}
 
 XWalkExtensionServer::~XWalkExtensionServer() {
@@ -47,6 +53,10 @@ bool XWalkExtensionServer::OnMessageReceived(const IPC::Message& message) {
   return handled;
 }
 
+void XWalkExtensionServer::OnChannelConnected(int32 peer_pid) {
+  CHECK(base::OpenProcessHandle(peer_pid, &renderer_process_handle_));
+}
+
 void XWalkExtensionServer::OnCreateInstance(int64_t instance_id,
     std::string name) {
   ExtensionMap::const_iterator it = extensions_.find(name);
@@ -185,7 +195,31 @@ void XWalkExtensionServer::PostMessageToJSCallback(
     int64_t instance_id, scoped_ptr<base::Value> msg) {
   base::ListValue wrapped_msg;
   wrapped_msg.Append(msg.release());
-  Send(new XWalkExtensionClientMsg_PostMessageToJS(instance_id, wrapped_msg));
+
+  scoped_ptr<IPC::Message> message(
+      new XWalkExtensionClientMsg_PostMessageToJS(instance_id, wrapped_msg));
+  if (message->size() <= kInlineMessageMaxSize) {
+    Send(message.release());
+    return;
+  }
+
+  base::SharedMemoryCreateOptions options;
+  options.size = message->size();
+  options.share_read_only = true;
+
+  base::SharedMemory shared_memory;
+  if (!shared_memory.Create(options) || !shared_memory.Map(message->size())) {
+    LOG(WARNING) << "Can't create shared memory to send out of line message";
+    return;
+  }
+
+  memcpy(shared_memory.memory(), message->data(), message->size());
+
+  base::SharedMemoryHandle handle;
+  shared_memory.GiveReadOnlyToProcess(renderer_process_handle_, &handle);
+
+  Send(new XWalkExtensionClientMsg_PostOutOfLineMessageToJS(handle,
+                                                            message->size()));
 }
 
 void XWalkExtensionServer::SendSyncReplyToJSCallback(
@@ -348,7 +382,7 @@ base::FilePath::StringType GetNativeLibraryPattern() {
 
 std::vector<std::string> RegisterExternalExtensionsInDirectory(
     XWalkExtensionServer* server, const base::FilePath& dir,
-    const base::ValueMap& runtime_variables) {
+    scoped_ptr<base::ValueMap> runtime_variables) {
   CHECK(server);
 
   std::vector<std::string> registered_extensions;
@@ -366,7 +400,14 @@ std::vector<std::string> RegisterExternalExtensionsInDirectory(
         !extension_path.empty(); extension_path = libraries.Next()) {
     scoped_ptr<XWalkExternalExtension> extension(
         new XWalkExternalExtension(extension_path));
-    extension->set_runtime_variables(runtime_variables);
+
+    // Let the extension know about its own path, so it can be used
+    // as an identifier in case you have symlinks to extensions to force it
+    // load multiple times.
+    (*runtime_variables)["extension_path"] =
+        base::Value::CreateStringValue(extension_path.AsUTF8Unsafe());
+
+    extension->set_runtime_variables(*runtime_variables);
     if (server->permissions_delegate())
       extension->set_permissions_delegate(server->permissions_delegate());
     if (extension->Initialize()) {