summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--android_webview/android_webview.gyp7
-rw-r--r--android_webview/browser/aw_browser_context.cc8
-rw-r--r--android_webview/browser/aw_browser_context.h4
-rw-r--r--android_webview/browser/aw_message_port_message_filter.cc60
-rw-r--r--android_webview/browser/aw_message_port_message_filter.h45
-rw-r--r--android_webview/browser/aw_message_port_service.h32
-rw-r--r--android_webview/browser/jni_dependency_factory.h2
-rw-r--r--android_webview/common/android_webview_message_generator.h1
-rw-r--r--android_webview/common/aw_message_port_messages.h32
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java8
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContents.java21
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwMessagePortService.java136
-rw-r--r--android_webview/java/src/org/chromium/android_webview/MessageChannel.java12
-rw-r--r--android_webview/java/src/org/chromium/android_webview/MessagePort.java46
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/PostMessageTest.java76
-rw-r--r--android_webview/lib/main/aw_main_delegate.cc5
-rw-r--r--android_webview/lib/main/aw_main_delegate.h22
-rw-r--r--android_webview/native/android_webview_jni_registrar.cc2
-rw-r--r--android_webview/native/aw_contents.cc79
-rw-r--r--android_webview/native/aw_contents.h3
-rw-r--r--android_webview/native/aw_message_port_service_impl.cc161
-rw-r--r--android_webview/native/aw_message_port_service_impl.h65
-rw-r--r--android_webview/native/webview_native.gyp3
-rw-r--r--android_webview/renderer/DEPS2
-rw-r--r--android_webview/renderer/aw_content_renderer_client.cc2
-rw-r--r--android_webview/renderer/aw_message_port_client.cc70
-rw-r--r--android_webview/renderer/aw_message_port_client.h35
-rw-r--r--content/browser/message_port_message_filter.h4
-rw-r--r--content/browser/message_port_provider.cc80
-rw-r--r--content/browser/message_port_provider_browsertest.cc142
-rw-r--r--content/browser/message_port_service.cc2
-rw-r--r--content/browser/message_port_service.h3
-rw-r--r--content/browser/navigator_connect/navigator_connect_context.h2
-rw-r--r--content/content_browser.gypi2
-rw-r--r--content/content_tests.gypi1
-rw-r--r--content/public/browser/message_port_delegate.h (renamed from content/browser/message_port_delegate.h)11
-rw-r--r--content/public/browser/message_port_provider.h12
-rw-r--r--ipc/ipc_message_start.h1
38 files changed, 1066 insertions, 133 deletions
diff --git a/android_webview/android_webview.gyp b/android_webview/android_webview.gyp
index 6d0430c..4018c9f 100644
--- a/android_webview/android_webview.gyp
+++ b/android_webview/android_webview.gyp
@@ -120,6 +120,7 @@
'../third_party/WebKit/public/blink.gyp:blink',
'../ui/gl/gl.gyp:gl',
'../ui/shell_dialogs/shell_dialogs.gyp:shell_dialogs',
+ '../v8/tools/gyp/v8.gyp:v8',
'../webkit/common/gpu/webkit_gpu.gyp:webkit_gpu',
'android_webview_pak',
'android_webview_version',
@@ -156,6 +157,9 @@
'browser/aw_javascript_dialog_manager.h',
'browser/aw_login_delegate.cc',
'browser/aw_login_delegate.h',
+ 'browser/aw_message_port_message_filter.cc',
+ 'browser/aw_message_port_message_filter.h',
+ 'browser/aw_message_port_service.h',
'browser/aw_pref_store.cc',
'browser/aw_pref_store.h',
'browser/aw_printing_message_filter.cc',
@@ -226,6 +230,7 @@
'common/aw_crash_handler.h',
'common/aw_hit_test_data.cc',
'common/aw_hit_test_data.h',
+ 'common/aw_message_port_messages.h',
'common/aw_resource.h',
'common/aw_switches.cc',
'common/aw_switches.h',
@@ -245,6 +250,8 @@
'renderer/aw_content_renderer_client.h',
'renderer/aw_key_systems.cc',
'renderer/aw_key_systems.h',
+ 'renderer/aw_message_port_client.cc',
+ 'renderer/aw_message_port_client.h',
'renderer/aw_permission_client.cc',
'renderer/aw_permission_client.h',
'renderer/aw_render_process_observer.cc',
diff --git a/android_webview/browser/aw_browser_context.cc b/android_webview/browser/aw_browser_context.cc
index 1fea722..cd620c6 100644
--- a/android_webview/browser/aw_browser_context.cc
+++ b/android_webview/browser/aw_browser_context.cc
@@ -237,6 +237,14 @@ AwURLRequestContextGetter* AwBrowserContext::GetAwURLRequestContext() {
return url_request_context_getter_.get();
}
+AwMessagePortService* AwBrowserContext::GetMessagePortService() {
+ if (!message_port_service_.get()) {
+ message_port_service_.reset(
+ native_factory_->CreateAwMessagePortService());
+ }
+ return message_port_service_.get();
+}
+
// Create user pref service for autofill functionality.
void AwBrowserContext::CreateUserPrefServiceIfNecessary() {
if (user_pref_service_)
diff --git a/android_webview/browser/aw_browser_context.h b/android_webview/browser/aw_browser_context.h
index a821acf..d6e44b3 100644
--- a/android_webview/browser/aw_browser_context.h
+++ b/android_webview/browser/aw_browser_context.h
@@ -8,6 +8,7 @@
#include <vector>
#include "android_webview/browser/aw_download_manager_delegate.h"
+#include "android_webview/browser/aw_message_port_service.h"
#include "android_webview/browser/aw_ssl_host_state_delegate.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h"
@@ -101,6 +102,8 @@ class AwBrowserContext : public content::BrowserContext,
void CreateUserPrefServiceIfNecessary();
+ AwMessagePortService* GetMessagePortService();
+
// content::BrowserContext implementation.
scoped_ptr<content::ZoomLevelDelegate> CreateZoomLevelDelegate(
const base::FilePath& partition_path) override;
@@ -143,6 +146,7 @@ class AwBrowserContext : public content::BrowserContext,
scoped_refptr<AwURLRequestContextGetter> url_request_context_getter_;
scoped_refptr<AwQuotaManagerBridge> quota_manager_bridge_;
scoped_ptr<AwFormDatabaseService> form_database_service_;
+ scoped_ptr<AwMessagePortService> message_port_service_;
AwDownloadManagerDelegate download_manager_delegate_;
diff --git a/android_webview/browser/aw_message_port_message_filter.cc b/android_webview/browser/aw_message_port_message_filter.cc
new file mode 100644
index 0000000..74b1aa5
--- /dev/null
+++ b/android_webview/browser/aw_message_port_message_filter.cc
@@ -0,0 +1,60 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "android_webview/browser/aw_message_port_message_filter.h"
+
+#include "android_webview/browser/aw_browser_context.h"
+#include "android_webview/common/aw_message_port_messages.h"
+#include "content/public/browser/message_port_provider.h"
+
+using content::BrowserThread;
+using content::MessagePortProvider;
+
+namespace android_webview {
+
+AwMessagePortMessageFilter::AwMessagePortMessageFilter(int route_id)
+ : BrowserMessageFilter(AwMessagePortMsgStart), route_id_(route_id) {
+}
+
+AwMessagePortMessageFilter::~AwMessagePortMessageFilter() {
+}
+
+void AwMessagePortMessageFilter::OnChannelClosing() {
+ MessagePortProvider::OnMessagePortDelegateClosing(this);
+ AwBrowserContext::GetDefault()->GetMessagePortService()->
+ OnMessagePortMessageFilterClosing(this);
+}
+
+bool AwMessagePortMessageFilter::OnMessageReceived(
+ const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(AwMessagePortMessageFilter, message)
+ IPC_MESSAGE_FORWARD(AwMessagePortHostMsg_ConvertedMessage,
+ AwBrowserContext::GetDefault()->GetMessagePortService(),
+ AwMessagePortService::OnConvertedMessage)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void AwMessagePortMessageFilter::OnDestruct() const {
+ BrowserThread::DeleteOnIOThread::Destruct(this);
+}
+
+void AwMessagePortMessageFilter::SendMessage(
+ int msg_port_route_id,
+ const base::string16& message,
+ const std::vector<int>& sent_message_port_ids) {
+ Send(new AwMessagePortMsg_Message(route_id_,
+ msg_port_route_id, // same as the port id
+ message,
+ sent_message_port_ids));
+}
+
+void AwMessagePortMessageFilter::SendMessagesAreQueued(int route_id) {
+ // TODO(sgurun) implement
+ NOTREACHED();
+}
+
+} // namespace android_webview
diff --git a/android_webview/browser/aw_message_port_message_filter.h b/android_webview/browser/aw_message_port_message_filter.h
new file mode 100644
index 0000000..d63774b
--- /dev/null
+++ b/android_webview/browser/aw_message_port_message_filter.h
@@ -0,0 +1,45 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ANDROID_WEBVIEW_BROWSER_MESSAGE_PORT_MESSAGE_FILTER_H_
+#define ANDROID_WEBVIEW_BROWSER_MESSAGE_PORT_MESSAGE_FILTER_H_
+
+#include "base/callback.h"
+#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/message_port_delegate.h"
+
+namespace android_webview {
+
+// Filter for Aw specific MessagePort related IPC messages (creating and
+// destroying a MessagePort, sending a message via a MessagePort etc).
+class AwMessagePortMessageFilter : public content::BrowserMessageFilter,
+ public content::MessagePortDelegate {
+ public:
+ explicit AwMessagePortMessageFilter(int route_id);
+
+ // BrowserMessageFilter implementation.
+ void OnChannelClosing() override;
+ bool OnMessageReceived(const IPC::Message& message) override;
+ void OnDestruct() const override;
+
+ // MessagePortDelegate implementation.
+ void SendMessage(int msg_port_route_id,
+ const base::string16& message,
+ const std::vector<int>& sent_message_port_ids) override;
+ void SendMessagesAreQueued(int route_id) override;
+
+ private:
+ friend class content::BrowserThread;
+ friend class base::DeleteHelper<AwMessagePortMessageFilter>;
+
+ ~AwMessagePortMessageFilter() override;
+
+ int route_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(AwMessagePortMessageFilter);
+};
+
+} // namespace android_webview
+
+#endif // ANDROID_WEBVIEW_BROWSER_MESSAGE_PORT_MESSAGE_FILTER_H_
diff --git a/android_webview/browser/aw_message_port_service.h b/android_webview/browser/aw_message_port_service.h
new file mode 100644
index 0000000..086480e
--- /dev/null
+++ b/android_webview/browser/aw_message_port_service.h
@@ -0,0 +1,32 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ANDROID_WEBVIEW_BROWSER_AW_MESSAGE_PORT_SERVICE_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_MESSAGE_PORT_SERVICE_H_
+
+#include <vector>
+
+#include "base/values.h"
+
+namespace android_webview {
+
+class AwMessagePortMessageFilter;
+
+// The interface for AwMessagePortService
+class AwMessagePortService {
+ public:
+ virtual ~AwMessagePortService() { }
+
+ virtual void OnConvertedMessage(
+ int message_port_id,
+ const base::ListValue& message,
+ const std::vector<int>& sent_message_port_ids) = 0;
+
+ virtual void OnMessagePortMessageFilterClosing(
+ AwMessagePortMessageFilter* filter) = 0;
+};
+
+} // namespace android_webview
+
+#endif // ANDROID_WEBVIEW_BROWSER_AW_MESSAGE_PORT_SERVICE_H_
diff --git a/android_webview/browser/jni_dependency_factory.h b/android_webview/browser/jni_dependency_factory.h
index 983ef2a..d27e9b2 100644
--- a/android_webview/browser/jni_dependency_factory.h
+++ b/android_webview/browser/jni_dependency_factory.h
@@ -16,6 +16,7 @@ class WebContentsViewDelegate;
namespace android_webview {
class AwBrowserContext;
+class AwMessagePortService;
class AwQuotaManagerBridge;
class AwWebPreferencesPopulater;
@@ -29,6 +30,7 @@ class JniDependencyFactory {
virtual content::WebContentsViewDelegate* CreateViewDelegate(
content::WebContents* web_contents) = 0;
virtual AwWebPreferencesPopulater* CreateWebPreferencesPopulater() = 0;
+ virtual AwMessagePortService* CreateAwMessagePortService() = 0;
#if defined(VIDEO_HOLE)
virtual content::ExternalVideoSurfaceContainer*
CreateExternalVideoSurfaceContainer(content::WebContents* contents) = 0;
diff --git a/android_webview/common/android_webview_message_generator.h b/android_webview/common/android_webview_message_generator.h
index 1ac28dc..f5dcce8 100644
--- a/android_webview/common/android_webview_message_generator.h
+++ b/android_webview/common/android_webview_message_generator.h
@@ -4,5 +4,6 @@
// Multiply-included file, hence no include guard.
+#include "android_webview/common/aw_message_port_messages.h"
#include "android_webview/common/print_messages.h"
#include "android_webview/common/render_view_messages.h"
diff --git a/android_webview/common/aw_message_port_messages.h b/android_webview/common/aw_message_port_messages.h
new file mode 100644
index 0000000..866d713
--- /dev/null
+++ b/android_webview/common/aw_message_port_messages.h
@@ -0,0 +1,32 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Multiply-included file, no traditional include guard.
+#include <vector>
+
+#include "base/basictypes.h"
+#include "ipc/ipc_message_macros.h"
+
+#define IPC_MESSAGE_START AwMessagePortMsgStart
+
+//-----------------------------------------------------------------------------
+// MessagePort messages
+// These are messages sent from the browser to the renderer process.
+
+// Tells the renderer to convert the sent message from a WebSerializeScript
+// format to a base::ListValue. Due to the complexities of renderer/browser
+// relation, this can only be done in renderer for now.
+IPC_MESSAGE_ROUTED3(AwMessagePortMsg_Message,
+ int /* recipient message port id */,
+ base::string16 /* message */,
+ std::vector<int> /* sent message port_ids */)
+
+//-----------------------------------------------------------------------------
+// These are messages sent from the renderer to the browser process.
+
+// Response to AwMessagePortMessage_ConvertMessage
+IPC_MESSAGE_ROUTED3(AwMessagePortHostMsg_ConvertedMessage,
+ int /* recipient message port id */,
+ base::ListValue /* converted message */,
+ std::vector<int> /* sent message port_ids */)
diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java
index 77ad0ba..36463ed 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java
@@ -28,6 +28,7 @@ public class AwBrowserContext {
private AwFormDatabase mFormDatabase;
private HttpAuthDatabase mHttpAuthDatabase;
private DefaultAndroidKeyStore mLocalKeyStore;
+ private AwMessagePortService mMessagePortService;
public AwBrowserContext(SharedPreferences sharedPreferences) {
mSharedPreferences = sharedPreferences;
@@ -68,6 +69,13 @@ public class AwBrowserContext {
return mLocalKeyStore;
}
+ public AwMessagePortService createMessagePortService() {
+ if (mMessagePortService == null) {
+ mMessagePortService = new AwMessagePortService();
+ }
+ return mMessagePortService;
+ }
+
/**
* @see android.webkit.WebView#pauseTimers()
*/
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index 4d80be7..7039351 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -1790,9 +1790,16 @@ public class AwContents implements SmartClipProvider {
* message ports to pass.
*/
public void postMessageToFrame(String frameName, String message,
- String sourceOrigin, String targetOrigin, int[] msgPorts) {
+ String sourceOrigin, String targetOrigin, MessagePort[] msgPorts) {
+ if (isDestroyed()) return;
+ int[] portIds = null;
+ if (msgPorts != null) {
+ portIds = new int[msgPorts.length];
+ for (int i = 0; i < msgPorts.length; i++)
+ portIds[i] = msgPorts[i].portId();
+ }
nativePostMessageToFrame(mNativeAwContents, frameName, message, sourceOrigin,
- targetOrigin, msgPorts);
+ targetOrigin, portIds);
}
/**
@@ -1801,10 +1808,12 @@ public class AwContents implements SmartClipProvider {
* @param callback The message channel created.
*/
public void createMessageChannel(ValueCallback<MessageChannel> callback) {
+ if (isDestroyed()) return;
+ // Make sure the message port service is created.
+ mBrowserContext.createMessagePortService();
nativeCreateMessageChannel(mNativeAwContents, callback);
}
-
//--------------------------------------------------------------------------------------------
// View and ViewGroup method implementations
//--------------------------------------------------------------------------------------------
@@ -2217,12 +2226,6 @@ public class AwContents implements SmartClipProvider {
}
}
- @CalledByNative
- private static void onMessageChannelCreated(int portId1, int portId2,
- ValueCallback<MessageChannel> callback) {
- callback.onReceiveValue(new MessageChannel(portId1, portId2));
- }
-
// -------------------------------------------------------------------------------------------
// Helper methods
// -------------------------------------------------------------------------------------------
diff --git a/android_webview/java/src/org/chromium/android_webview/AwMessagePortService.java b/android_webview/java/src/org/chromium/android_webview/AwMessagePortService.java
new file mode 100644
index 0000000..df9e3b7
--- /dev/null
+++ b/android_webview/java/src/org/chromium/android_webview/AwMessagePortService.java
@@ -0,0 +1,136 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.android_webview;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.SparseArray;
+import android.webkit.ValueCallback;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+
+/**
+ * Provides the Message Channel functionality for Android Webview. Specifically
+ * manages the message ports that are associated with a message channel and
+ * handles posting/receiving messages to/from them.
+ * See https://html.spec.whatwg.org/multipage/comms.html#messagechannel for
+ * further information on message channels.
+ *
+ * The message ports have unique IDs. In Android webview implementation,
+ * the message ports are only known by their IDs at the native side.
+ * At the java side, the embedder deals with MessagePort objects. The mapping
+ * from an ID to an object is in AwMessagePortService. AwMessagePortService
+ * keeps a strong ref to MessagePort objects until they are closed.
+ *
+ * Ownership: The Java AwMessagePortService is owned by Java AwBrowserContext.
+ * The native AwMessagePortService is owned by native AwBrowserContext. The
+ * native peer maintains a weak ref to the java object and deregisters itself
+ * before being deleted.
+ *
+ * All methods are called on UI thread except as noted.
+ */
+@JNINamespace("android_webview")
+public class AwMessagePortService {
+
+ private static final String TAG = "AwMessagePortService";
+
+ private static final int POST_MESSAGE = 1;
+
+ // TODO(sgurun) implement transferring ports from JS to Java using message channels.
+ private static class PostMessage {
+ public MessagePort port;
+ public String message;
+
+ public PostMessage(MessagePort port, String message) {
+ this.port = port;
+ this.message = message;
+ }
+ }
+
+ // The messages from JS to Java are posted to a message port on a background thread.
+ // We do this to make any potential synchronization between Java and JS
+ // easier for user programs.
+ private static class MessageHandler extends Thread {
+ private Handler mHandler;
+
+ public Handler getHandler() {
+ return mHandler;
+ }
+
+ public void run() {
+ Looper.prepare();
+ mHandler = new Handler() {
+ public void handleMessage(Message msg) {
+ if (msg.what == POST_MESSAGE) {
+ PostMessage m = (PostMessage) msg.obj;
+ m.port.onMessage(m.message);
+ return;
+ }
+ throw new IllegalStateException("undefined message");
+ }
+ };
+ Looper.loop();
+ }
+ }
+
+ // A thread safe storage for Message Ports.
+ private static class MessagePortStorage {
+ private SparseArray<MessagePort> mMessagePorts = new SparseArray<MessagePort>();
+ private Object mLock = new Object();
+
+ public void put(int portId, MessagePort m) {
+ synchronized (mLock) {
+ mMessagePorts.put(portId, m);
+ }
+ }
+ public MessagePort get(int portId) {
+ synchronized (mLock) {
+ return mMessagePorts.get(portId);
+ }
+ }
+ }
+
+ private long mNativeMessagePortService;
+ private MessagePortStorage mPortStorage = new MessagePortStorage();
+ private MessageHandler mMessageHandler = new MessageHandler();
+
+ AwMessagePortService() {
+ mNativeMessagePortService = nativeInitAwMessagePortService();
+ mMessageHandler.start();
+ }
+
+ private MessagePort addPort(int portId) {
+ if (mPortStorage.get(portId) != null) {
+ throw new IllegalStateException("Port already exists");
+ }
+ MessagePort m = new MessagePort(portId);
+ mPortStorage.put(portId, m);
+ return m;
+ }
+
+ @CalledByNative
+ private void onMessageChannelCreated(int portId1, int portId2,
+ ValueCallback<MessageChannel> callback) {
+ callback.onReceiveValue(new MessageChannel(addPort(portId1), addPort(portId2)));
+ }
+
+ // Called on IO thread.
+ @CalledByNative
+ private void onPostMessage(int portId, String message, int[] ports) {
+ PostMessage m = new PostMessage(mPortStorage.get(portId), message);
+ Handler handler = mMessageHandler.getHandler();
+ Message msg = handler.obtainMessage(POST_MESSAGE, m);
+ handler.sendMessage(msg);
+ }
+
+ @CalledByNative
+ private void unregisterNativeAwMessagePortService() {
+ mNativeMessagePortService = 0;
+ }
+
+ private native long nativeInitAwMessagePortService();
+}
diff --git a/android_webview/java/src/org/chromium/android_webview/MessageChannel.java b/android_webview/java/src/org/chromium/android_webview/MessageChannel.java
index 9248624..d2957ce 100644
--- a/android_webview/java/src/org/chromium/android_webview/MessageChannel.java
+++ b/android_webview/java/src/org/chromium/android_webview/MessageChannel.java
@@ -9,20 +9,20 @@ package org.chromium.android_webview;
* http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html#message-channels
*/
public class MessageChannel {
- // The message port IDs of port1 and port2.
- private int mPort1;
- private int mPort2;
+ // The message ports of MessageChannel.
+ private MessagePort mPort1;
+ private MessagePort mPort2;
- public MessageChannel(int port1, int port2) {
+ public MessageChannel(MessagePort port1, MessagePort port2) {
mPort1 = port1;
mPort2 = port2;
}
- public int port1() {
+ public MessagePort port1() {
return mPort1;
}
- public int port2() {
+ public MessagePort port2() {
return mPort2;
}
}
diff --git a/android_webview/java/src/org/chromium/android_webview/MessagePort.java b/android_webview/java/src/org/chromium/android_webview/MessagePort.java
new file mode 100644
index 0000000..ef0e8d7
--- /dev/null
+++ b/android_webview/java/src/org/chromium/android_webview/MessagePort.java
@@ -0,0 +1,46 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.android_webview;
+
+import android.util.Log;
+
+/**
+ * Represents the MessageChannel MessagePort object. Inspired from
+ * http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html#message-channels
+ */
+public class MessagePort {
+
+ /**
+ * The interface for message handler for receiving messages. Called on a background thread.
+ */
+ public static interface MessageHandler {
+ void onMessage(String message);
+ };
+
+ private static final String TAG = "AwMessagePortService";
+
+ private int mPortId;
+ private MessageHandler mHandler;
+
+ public MessagePort(int portId) {
+ mPortId = portId;
+ }
+
+ public int portId() {
+ return mPortId;
+ }
+
+ public void setMessageHandler(MessageHandler handler) {
+ mHandler = handler;
+ }
+
+ public void onMessage(String message) {
+ if (mHandler == null) {
+ Log.w(TAG, "No handler set for port [" + mPortId + "], dropping message " + message);
+ return;
+ }
+ mHandler.onMessage(message);
+ }
+}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/PostMessageTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/PostMessageTest.java
index 7d7ea86..3be279c9 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/PostMessageTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/PostMessageTest.java
@@ -13,6 +13,7 @@ import static org.chromium.content.browser.test.util.TestCallbackHelperContainer
import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.MessageChannel;
+import org.chromium.android_webview.MessagePort;
import org.chromium.android_webview.test.util.CommonResources;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.MinAndroidSdkLevel;
@@ -25,12 +26,11 @@ import org.chromium.net.test.util.TestWebServer;
public class PostMessageTest extends AwTestBase {
private static final String SOURCE_ORIGIN = "android_webview";
+ // Timeout to failure, in milliseconds
+ private static final long TIMEOUT = scaleTimeout(5000);
// Inject to the page to verify received messages.
private static class MessageObject {
- // Timeout to failure, in milliseconds
- private static final long TIMEOUT = scaleTimeout(5000);
-
private boolean mReady;
private String mData;
private String mOrigin;
@@ -102,12 +102,16 @@ public class PostMessageTest extends AwTestBase {
}
private static final String WEBVIEW_MESSAGE = "from_webview";
+ private static final String JS_MESSAGE = "from_js";
private static final String TEST_PAGE =
"<!DOCTYPE html><html><body>"
+ " <script type=\"text/javascript\">"
+ " onmessage = function (e) {"
+ " messageObject.setMessageParams(e.data, e.origin, e.ports);"
+ + " if (e.ports != null && e.ports.length > 0) {"
+ + " e.ports[0].postMessage(\"" + JS_MESSAGE + "\");"
+ + " }"
+ " }"
+ " </script>"
+ "</body></html>";
@@ -137,22 +141,61 @@ public class PostMessageTest extends AwTestBase {
assertEquals(SOURCE_ORIGIN, mMessageObject.getOrigin());
}
- // TODO(sgurun) This test verifies a channel is created by posting one of the
- // ports of the channel to a MessagePort and verifying one port is received.
- // in a next CL we will update the JS to post messages back to Webview so
- // we could do a more thorough verification.
+ private static class ChannelContainer {
+ private boolean mReady;
+ private MessageChannel mChannel;
+ private Object mLock = new Object();
+ private String mMessage;
+
+ public void set(MessageChannel channel) {
+ mChannel = channel;
+ }
+ public MessageChannel get() {
+ return mChannel;
+ }
+
+ public void setMessage(String message) {
+ synchronized (mLock) {
+ mMessage = message;
+ mReady = true;
+ mLock.notify();
+ }
+ }
+
+ public String getMessage() {
+ return mMessage;
+ }
+
+ public void waitForMessage() throws InterruptedException {
+ synchronized (mLock) {
+ if (!mReady) mLock.wait(TIMEOUT);
+ }
+ }
+ }
+
+ // Verify that a channel can be created and basic full duplex communication
+ // can happen on it.
@SmallTest
@Feature({"AndroidWebView", "Android-PostMessage"})
public void testCreateChannel() throws Throwable {
loadPage(TEST_PAGE);
+ final ChannelContainer channelContainer = new ChannelContainer();
runTestOnUiThread(new Runnable() {
@Override
public void run() {
ValueCallback<MessageChannel> callback = new ValueCallback<MessageChannel>() {
@Override
public void onReceiveValue(MessageChannel channel) {
+ // verify communication from JS to Java.
+ channelContainer.set(channel);
+ channel.port1().setMessageHandler(new MessagePort.MessageHandler() {
+ @Override
+ public void onMessage(String message) {
+ channelContainer.setMessage(message);
+ }
+ });
mAwContents.postMessageToFrame(null, WEBVIEW_MESSAGE, SOURCE_ORIGIN,
- mWebServer.getBaseUrl(), new int[]{channel.port2()});
+ mWebServer.getBaseUrl(), new MessagePort[]{channel.port2()});
}
};
mAwContents.createMessageChannel(callback);
@@ -161,8 +204,21 @@ public class PostMessageTest extends AwTestBase {
mMessageObject.waitForMessage();
assertEquals(WEBVIEW_MESSAGE, mMessageObject.getData());
assertEquals(SOURCE_ORIGIN, mMessageObject.getOrigin());
- // verify that one message port is received.
+ // verify that one message port is received at the js side
assertEquals(1, mMessageObject.getPorts().length);
+ // wait until we receive a message from JS
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ channelContainer.waitForMessage();
+ } catch (InterruptedException e) {
+ // ignore.
+ }
+ }
+ });
+ assertEquals(JS_MESSAGE, channelContainer.getMessage());
+ // TODO(sgurun) verify communication from Java to JS on the created channel
}
private static final String WORKER_MESSAGE = "from_worker";
@@ -211,7 +267,7 @@ public class PostMessageTest extends AwTestBase {
public void onReceiveValue(MessageChannel channel) {
mAwContents.postMessageToFrame(null, WEBVIEW_MESSAGE, SOURCE_ORIGIN,
mWebServer.getBaseUrl(),
- new int[]{channel.port1(), channel.port2()});
+ new MessagePort[]{channel.port1(), channel.port2()});
}
};
mAwContents.createMessageChannel(callback);
diff --git a/android_webview/lib/main/aw_main_delegate.cc b/android_webview/lib/main/aw_main_delegate.cc
index 0f89e85..8ad7657 100644
--- a/android_webview/lib/main/aw_main_delegate.cc
+++ b/android_webview/lib/main/aw_main_delegate.cc
@@ -10,6 +10,7 @@
#include "android_webview/lib/aw_browser_dependency_factory_impl.h"
#include "android_webview/native/aw_assets.h"
#include "android_webview/native/aw_media_url_interceptor.h"
+#include "android_webview/native/aw_message_port_service_impl.h"
#include "android_webview/native/aw_quota_manager_bridge_impl.h"
#include "android_webview/native/aw_web_contents_view_delegate.h"
#include "android_webview/native/aw_web_preferences_populater_impl.h"
@@ -171,6 +172,10 @@ AwWebPreferencesPopulater* AwMainDelegate::CreateWebPreferencesPopulater() {
return new AwWebPreferencesPopulaterImpl();
}
+AwMessagePortService* AwMainDelegate::CreateAwMessagePortService() {
+ return new AwMessagePortServiceImpl();
+}
+
#if defined(VIDEO_HOLE)
content::ExternalVideoSurfaceContainer*
AwMainDelegate::CreateExternalVideoSurfaceContainer(
diff --git a/android_webview/lib/main/aw_main_delegate.h b/android_webview/lib/main/aw_main_delegate.h
index ebf25fc..167d921 100644
--- a/android_webview/lib/main/aw_main_delegate.h
+++ b/android_webview/lib/main/aw_main_delegate.h
@@ -30,23 +30,23 @@ class AwMainDelegate : public content::ContentMainDelegate,
private:
// content::ContentMainDelegate implementation:
- virtual bool BasicStartupComplete(int* exit_code) override;
- virtual void PreSandboxStartup() override;
- virtual void SandboxInitialized(const std::string& process_type) override;
- virtual int RunProcess(
+ bool BasicStartupComplete(int* exit_code) override;
+ void PreSandboxStartup() override;
+ void SandboxInitialized(const std::string& process_type) override;
+ int RunProcess(
const std::string& process_type,
const content::MainFunctionParams& main_function_params) override;
- virtual void ProcessExiting(const std::string& process_type) override;
- virtual content::ContentBrowserClient* CreateContentBrowserClient() override;
- virtual content::ContentRendererClient*
- CreateContentRendererClient() override;
+ void ProcessExiting(const std::string& process_type) override;
+ content::ContentBrowserClient* CreateContentBrowserClient() override;
+ content::ContentRendererClient* CreateContentRendererClient() override;
// JniDependencyFactory implementation.
- virtual scoped_refptr<AwQuotaManagerBridge> CreateAwQuotaManagerBridge(
+ scoped_refptr<AwQuotaManagerBridge> CreateAwQuotaManagerBridge(
AwBrowserContext* browser_context) override;
- virtual content::WebContentsViewDelegate* CreateViewDelegate(
+ content::WebContentsViewDelegate* CreateViewDelegate(
content::WebContents* web_contents) override;
- virtual AwWebPreferencesPopulater* CreateWebPreferencesPopulater() override;
+ AwWebPreferencesPopulater* CreateWebPreferencesPopulater() override;
+ AwMessagePortService* CreateAwMessagePortService() override;
#if defined(VIDEO_HOLE)
virtual content::ExternalVideoSurfaceContainer*
CreateExternalVideoSurfaceContainer(
diff --git a/android_webview/native/android_webview_jni_registrar.cc b/android_webview/native/android_webview_jni_registrar.cc
index 253a070..e81853f 100644
--- a/android_webview/native/android_webview_jni_registrar.cc
+++ b/android_webview/native/android_webview_jni_registrar.cc
@@ -14,6 +14,7 @@
#include "android_webview/native/aw_dev_tools_server.h"
#include "android_webview/native/aw_form_database.h"
#include "android_webview/native/aw_http_auth_handler.h"
+#include "android_webview/native/aw_message_port_service_impl.h"
#include "android_webview/native/aw_pdf_exporter.h"
#include "android_webview/native/aw_picture.h"
#include "android_webview/native/aw_quota_manager_bridge_impl.h"
@@ -58,6 +59,7 @@ static base::android::RegistrationMethod kWebViewRegisteredMethods[] = {
{ "AwWebResourceResponseImpl", RegisterAwWebResourceResponse },
{ "InputStream", RegisterInputStream },
{ "JavaBrowserViewRendererHelper", RegisterJavaBrowserViewRendererHelper },
+ { "AwMessagePortService", RegisterAwMessagePortService },
};
bool RegisterJni(JNIEnv* env) {
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index 2a9a35f..64cd9a9 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -21,6 +21,7 @@
#include "android_webview/native/aw_browser_dependency_factory.h"
#include "android_webview/native/aw_contents_client_bridge.h"
#include "android_webview/native/aw_contents_io_thread_client_impl.h"
+#include "android_webview/native/aw_message_port_service_impl.h"
#include "android_webview/native/aw_pdf_exporter.h"
#include "android_webview/native/aw_picture.h"
#include "android_webview/native/aw_web_contents_delegate.h"
@@ -133,23 +134,6 @@ void OnIoThreadClientReady(content::RenderFrameHost* rfh) {
render_process_id, render_frame_id);
}
-void OnMessageChannelCreated(ScopedJavaGlobalRef<jobject>* callback,
- int* port1,
- int* port2) {
- JNIEnv* env = AttachCurrentThread();
- Java_AwContents_onMessageChannelCreated(env, *port1, *port2,
- callback->obj());
-}
-
-void PostMessageToFrameOnIOThread(WebContents* web_contents,
- base::string16* source_origin,
- base::string16* target_origin,
- base::string16* data,
- std::vector<int>* ports) {
- content::MessagePortProvider::PostMessageToFrame(web_contents,
- *source_origin, *target_origin, *data, *ports);
-}
-
} // namespace
// static
@@ -1084,49 +1068,40 @@ void AwContents::PostMessageToFrame(JNIEnv* env, jobject obj,
jstring frame_name, jstring message, jstring source_origin,
jstring target_origin, jintArray msgPorts) {
- base::string16* j_source_origin = new base::string16;
- ConvertJavaStringToUTF16(env, source_origin, j_source_origin);
- base::string16* j_target_origin = new base::string16;
- ConvertJavaStringToUTF16(env, target_origin, j_target_origin);
- base::string16* j_message = new base::string16;
- ConvertJavaStringToUTF16(env, message, j_message);
- std::vector<int>* j_ports = new std::vector<int>;
-
+ base::string16 j_source_origin(ConvertJavaStringToUTF16(env, source_origin));
+ base::string16 j_target_origin(ConvertJavaStringToUTF16(env, target_origin));
+ base::string16 j_message(ConvertJavaStringToUTF16(env, message));
+ std::vector<int> j_ports;
if (msgPorts != nullptr)
- base::android::JavaIntArrayToIntVector(env, msgPorts, j_ports);
-
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&PostMessageToFrameOnIOThread,
- web_contents_.get(),
- base::Owned(j_source_origin),
- base::Owned(j_target_origin),
- base::Owned(j_message),
- base::Owned(j_ports)));
+ base::android::JavaIntArrayToIntVector(env, msgPorts, &j_ports);
+
+ content::MessagePortProvider::PostMessageToFrame(web_contents_.get(),
+ j_source_origin,
+ j_target_origin,
+ j_message,
+ j_ports);
+}
+
+scoped_refptr<AwMessagePortMessageFilter>
+AwContents::GetMessagePortMessageFilter() {
+ // Create a message port message filter if necessary
+ if (message_port_message_filter_.get() == nullptr) {
+ message_port_message_filter_ =
+ new AwMessagePortMessageFilter(
+ web_contents_->GetMainFrame()->GetRoutingID());
+ web_contents_->GetRenderProcessHost()->AddFilter(
+ message_port_message_filter_.get());
+ }
+ return message_port_message_filter_;
}
void AwContents::CreateMessageChannel(JNIEnv* env, jobject obj,
jobject callback) {
- ScopedJavaGlobalRef<jobject>* j_callback = new ScopedJavaGlobalRef<jobject>();
- j_callback->Reset(env, callback);
- int* port1 = new int;
- int* port2 = new int;
- BrowserThread::PostTaskAndReply(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&content::MessagePortProvider::CreateMessageChannel,
- web_contents_.get(),
- port1,
- port2),
- base::Bind(&OnMessageChannelCreated,
- base::Owned(j_callback),
- base::Owned(port1),
- base::Owned(port2)));
+ AwMessagePortServiceImpl::GetInstance()->CreateMessageChannel(env, callback,
+ GetMessagePortMessageFilter());
}
-
void SetShouldDownloadFavicons(JNIEnv* env, jclass jclazz) {
g_should_download_favicons = true;
}
diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h
index 4a4afbb..13ad67c 100644
--- a/android_webview/native/aw_contents.h
+++ b/android_webview/native/aw_contents.h
@@ -11,6 +11,7 @@
#include <utility>
#include "android_webview/browser/aw_browser_permission_request_delegate.h"
+#include "android_webview/browser/aw_message_port_message_filter.h"
#include "android_webview/browser/browser_view_renderer.h"
#include "android_webview/browser/browser_view_renderer_client.h"
#include "android_webview/browser/find_helper.h"
@@ -220,6 +221,7 @@ class AwContents : public FindHelper::Listener,
void SetJsOnlineProperty(JNIEnv* env, jobject obj, jboolean network_up);
void TrimMemory(JNIEnv* env, jobject obj, jint level, jboolean visible);
+ scoped_refptr<AwMessagePortMessageFilter> GetMessagePortMessageFilter();
void PostMessageToFrame(JNIEnv* env, jobject obj, jstring frame_id,
jstring message, jstring source_origin, jstring target_origin,
jintArray msgPorts);
@@ -244,6 +246,7 @@ class AwContents : public FindHelper::Listener,
BrowserViewRenderer browser_view_renderer_;
scoped_ptr<AwPdfExporter> pdf_exporter_;
scoped_ptr<PermissionRequestHandler> permission_request_handler_;
+ scoped_refptr<AwMessagePortMessageFilter> message_port_message_filter_;
// GURL is supplied by the content layer as requesting frame.
// Callback is supplied by the content layer, and is invoked with the result
diff --git a/android_webview/native/aw_message_port_service_impl.cc b/android_webview/native/aw_message_port_service_impl.cc
new file mode 100644
index 0000000..5fa4e1b
--- /dev/null
+++ b/android_webview/native/aw_message_port_service_impl.cc
@@ -0,0 +1,161 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "android_webview/native/aw_message_port_service_impl.h"
+
+#include "android_webview/browser/aw_browser_context.h"
+#include "android_webview/browser/aw_message_port_message_filter.h"
+#include "android_webview/native/aw_contents.h"
+#include "base/android/jni_array.h"
+#include "base/android/jni_string.h"
+#include "base/bind.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/message_port_provider.h"
+#include "jni/AwMessagePortService_jni.h"
+
+namespace android_webview {
+
+using base::android::AttachCurrentThread;
+using base::android::ConvertUTF16ToJavaString;
+using base::android::ScopedJavaGlobalRef;
+using base::android::ScopedJavaLocalRef;
+using base::android::ToJavaIntArray;
+using content::BrowserThread;
+using content::MessagePortProvider;
+
+//static
+AwMessagePortServiceImpl* AwMessagePortServiceImpl::GetInstance() {
+ return static_cast<AwMessagePortServiceImpl*>(
+ AwBrowserContext::GetDefault()->GetMessagePortService());
+}
+
+AwMessagePortServiceImpl::AwMessagePortServiceImpl() {
+}
+
+AwMessagePortServiceImpl::~AwMessagePortServiceImpl() {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+ if (obj.is_null())
+ return;
+ Java_AwMessagePortService_unregisterNativeAwMessagePortService(env,
+ obj.obj());
+}
+
+void AwMessagePortServiceImpl::Init(JNIEnv* env, jobject obj) {
+ java_ref_ = JavaObjectWeakGlobalRef(env, obj);
+}
+
+void AwMessagePortServiceImpl::CreateMessageChannel(
+ JNIEnv* env,
+ jobject callback,
+ scoped_refptr<AwMessagePortMessageFilter> filter) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ ScopedJavaGlobalRef<jobject>* j_callback = new ScopedJavaGlobalRef<jobject>();
+ j_callback->Reset(env, callback);
+
+ int* portId1 = new int;
+ int* portId2 = new int;
+ BrowserThread::PostTaskAndReply(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&AwMessagePortServiceImpl::CreateMessageChannelOnIOThread,
+ base::Unretained(this),
+ filter,
+ portId1,
+ portId2),
+ base::Bind(&AwMessagePortServiceImpl::OnMessageChannelCreated,
+ base::Unretained(this),
+ base::Owned(j_callback),
+ base::Owned(portId1),
+ base::Owned(portId2)));
+}
+
+void AwMessagePortServiceImpl::OnConvertedMessage(
+ int message_port_id,
+ const base::ListValue& message,
+ const std::vector<int>& sent_message_port_ids) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> jobj = java_ref_.get(env);
+ if (jobj.is_null())
+ return;
+
+ if (message.GetSize() != 1) {
+ NOTREACHED();
+ return;
+ }
+
+ base::string16 value;
+ if (!message.GetString(0, &value)) {
+ LOG(WARNING) << "Converting post message to a string failed for port "
+ << message_port_id;
+ return;
+ }
+ ScopedJavaLocalRef<jstring> jmsg = ConvertUTF16ToJavaString(env, value);
+ ScopedJavaLocalRef<jintArray> jports =
+ ToJavaIntArray(env, sent_message_port_ids);
+ Java_AwMessagePortService_onPostMessage(env,
+ jobj.obj(),
+ message_port_id,
+ jmsg.obj(),
+ jports.obj());
+}
+
+void AwMessagePortServiceImpl::OnMessagePortMessageFilterClosing(
+ AwMessagePortMessageFilter* filter) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ for (MessagePorts::iterator iter = ports_.begin();
+ iter != ports_.end(); iter++) {
+ if (iter->second == filter) {
+ ports_.erase(iter);
+ }
+ }
+}
+
+void AwMessagePortServiceImpl::CreateMessageChannelOnIOThread(
+ scoped_refptr<AwMessagePortMessageFilter> filter,
+ int* portId1,
+ int* portId2) {
+ content::MessagePortProvider::CreateMessageChannel(filter.get(), portId1,
+ portId2);
+ AddPort(*portId1, filter.get());
+ AddPort(*portId2, filter.get());
+}
+
+void AwMessagePortServiceImpl::OnMessageChannelCreated(
+ ScopedJavaGlobalRef<jobject>* callback,
+ int* port1,
+ int* port2) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+ if (obj.is_null())
+ return;
+ Java_AwMessagePortService_onMessageChannelCreated(env, obj.obj(), *port1,
+ *port2, callback->obj());
+}
+
+void AwMessagePortServiceImpl::AddPort(int message_port_id,
+ AwMessagePortMessageFilter* filter) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (ports_.count(message_port_id)) {
+ NOTREACHED();
+ return;
+ }
+ ports_[message_port_id] = filter;
+}
+
+bool RegisterAwMessagePortService(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+// static
+jlong InitAwMessagePortService(JNIEnv* env, jobject obj) {
+ AwMessagePortServiceImpl* service = AwMessagePortServiceImpl::GetInstance();
+ service->Init(env, obj);
+ return reinterpret_cast<intptr_t>(service);
+}
+
+} // namespace android_webview
diff --git a/android_webview/native/aw_message_port_service_impl.h b/android_webview/native/aw_message_port_service_impl.h
new file mode 100644
index 0000000..d938b6e
--- /dev/null
+++ b/android_webview/native/aw_message_port_service_impl.h
@@ -0,0 +1,65 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ANDROID_WEBVIEW_NATIVE_AW_MESSAGE_PORT_SERVICE_IMPL_H_
+#define ANDROID_WEBVIEW_NATIVE_AW_MESSAGE_PORT_SERVICE_IMPL_H_
+
+#include <jni.h>
+#include <map>
+
+#include "android_webview/browser/aw_message_port_service.h"
+#include "base/android/jni_weak_ref.h"
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/strings/string16.h"
+
+namespace android_webview {
+
+// This class is the native peer of AwMessagePortService.java. Please see the
+// java class for an explanation of use, ownership and lifetime.
+
+// Threading: Created and initialized on UI thread. For other methods, see
+// the method level DCHECKS or documentation.
+class AwMessagePortServiceImpl : public AwMessagePortService {
+ public:
+ static AwMessagePortServiceImpl* GetInstance();
+
+ AwMessagePortServiceImpl();
+ ~AwMessagePortServiceImpl();
+ void Init(JNIEnv* env, jobject object);
+
+ void CreateMessageChannel(JNIEnv* env, jobject callback,
+ scoped_refptr<AwMessagePortMessageFilter> filter);
+
+ // AwMessagePortService implementation
+ void OnConvertedMessage(
+ int message_port_id,
+ const base::ListValue& message,
+ const std::vector<int>& sent_message_port_ids) override;
+ void OnMessagePortMessageFilterClosing(
+ AwMessagePortMessageFilter* filter) override;
+
+private:
+ void CreateMessageChannelOnIOThread(
+ scoped_refptr<AwMessagePortMessageFilter> filter,
+ int* port1,
+ int* port2);
+ void OnMessageChannelCreated(
+ base::android::ScopedJavaGlobalRef<jobject>* callback,
+ int* port1,
+ int* port2);
+ void AddPort(int message_port_id, AwMessagePortMessageFilter* filter);
+
+ JavaObjectWeakGlobalRef java_ref_;
+ typedef std::map<int, AwMessagePortMessageFilter*> MessagePorts;
+ MessagePorts ports_; // Access on IO thread
+
+ DISALLOW_COPY_AND_ASSIGN(AwMessagePortServiceImpl);
+};
+
+bool RegisterAwMessagePortService(JNIEnv* env);
+
+} // namespace android_webview
+
+#endif // ANDROID_WEBVIEW_NATIVE_AW_MESSAGE_PORT_SERVICE_IMPL_H_
diff --git a/android_webview/native/webview_native.gyp b/android_webview/native/webview_native.gyp
index 52b3e45..34889e1 100644
--- a/android_webview/native/webview_native.gyp
+++ b/android_webview/native/webview_native.gyp
@@ -58,6 +58,8 @@
'aw_http_auth_handler.h',
'aw_media_url_interceptor.cc',
'aw_media_url_interceptor.h',
+ 'aw_message_port_service_impl.cc',
+ 'aw_messagE_port_service_impl.h',
'aw_pdf_exporter.cc',
'aw_pdf_exporter.h',
'aw_picture.cc',
@@ -131,6 +133,7 @@
'../java/src/org/chromium/android_webview/AwDevToolsServer.java',
'../java/src/org/chromium/android_webview/AwFormDatabase.java',
'../java/src/org/chromium/android_webview/AwHttpAuthHandler.java',
+ '../java/src/org/chromium/android_webview/AwMessagePortService.java',
'../java/src/org/chromium/android_webview/AwPdfExporter.java',
'../java/src/org/chromium/android_webview/AwPicture.java',
'../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java',
diff --git a/android_webview/renderer/DEPS b/android_webview/renderer/DEPS
index 055b5e0..6c1ad13 100644
--- a/android_webview/renderer/DEPS
+++ b/android_webview/renderer/DEPS
@@ -20,4 +20,6 @@ include_rules = [
"+ui/gfx",
"+ui/gl/gpu_memory_buffer.h",
+
+ "+v8/include/v8.h",
]
diff --git a/android_webview/renderer/aw_content_renderer_client.cc b/android_webview/renderer/aw_content_renderer_client.cc
index 24349cd..3771059 100644
--- a/android_webview/renderer/aw_content_renderer_client.cc
+++ b/android_webview/renderer/aw_content_renderer_client.cc
@@ -8,6 +8,7 @@
#include "android_webview/common/render_view_messages.h"
#include "android_webview/common/url_constants.h"
#include "android_webview/renderer/aw_key_systems.h"
+#include "android_webview/renderer/aw_message_port_client.h"
#include "android_webview/renderer/aw_permission_client.h"
#include "android_webview/renderer/aw_render_frame_ext.h"
#include "android_webview/renderer/aw_render_view_ext.h"
@@ -122,6 +123,7 @@ void AwContentRendererClient::RenderFrameCreated(
new AwPermissionClient(render_frame);
new PrintRenderFrameObserver(render_frame);
new AwRenderFrameExt(render_frame);
+ new AwMessagePortClient(render_frame);
// TODO(jam): when the frame tree moves into content and parent() works at
// RenderFrame construction, simplify this by just checking parent().
diff --git a/android_webview/renderer/aw_message_port_client.cc b/android_webview/renderer/aw_message_port_client.cc
new file mode 100644
index 0000000..c96f322
--- /dev/null
+++ b/android_webview/renderer/aw_message_port_client.cc
@@ -0,0 +1,70 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "android_webview/renderer/aw_message_port_client.h"
+
+#include "android_webview/common/aw_message_port_messages.h"
+#include "content/public/renderer/render_frame.h"
+#include "content/public/renderer/render_view.h"
+#include "content/public/renderer/v8_value_converter.h"
+#include "ipc/ipc_message_macros.h"
+#include "third_party/WebKit/public/web/WebFrame.h"
+#include "third_party/WebKit/public/web/WebKit.h"
+#include "third_party/WebKit/public/web/WebSerializedScriptValue.h"
+#include "third_party/WebKit/public/web/WebView.h"
+#include "v8/include/v8.h"
+
+using blink::WebSerializedScriptValue;
+using content::V8ValueConverter;
+using std::vector;
+
+namespace android_webview {
+
+AwMessagePortClient::AwMessagePortClient(content::RenderFrame* render_frame)
+ : content::RenderFrameObserver(render_frame) {
+}
+
+AwMessagePortClient::~AwMessagePortClient() {
+}
+
+bool AwMessagePortClient::OnMessageReceived(
+ const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(AwMessagePortClient, message)
+ IPC_MESSAGE_HANDLER(AwMessagePortMsg_Message, OnPostMessage)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+
+ return handled;
+}
+
+void AwMessagePortClient::OnPostMessage(
+ int message_port_id,
+ const base::string16& message,
+ const vector<int>& sent_message_port_ids) {
+ v8::HandleScope handle_scope(blink::mainThreadIsolate());
+ blink::WebFrame* main_frame =
+ render_frame()->GetRenderView()->GetWebView()->mainFrame();
+ if (main_frame == nullptr) {
+ return;
+ }
+ v8::Local<v8::Context> context = main_frame->mainWorldScriptContext();
+ v8::Context::Scope context_scope(context);
+ DCHECK(!context.IsEmpty());
+ WebSerializedScriptValue v = WebSerializedScriptValue::fromString(message);
+ v8::Handle<v8::Value> v8value = v.deserialize();
+
+ scoped_ptr<V8ValueConverter> converter;
+ converter.reset(V8ValueConverter::create());
+ converter->SetDateAllowed(true);
+ converter->SetRegExpAllowed(true);
+ base::ListValue result;
+ result.Append(converter->FromV8Value(v8value, context));
+ Send(new AwMessagePortHostMsg_ConvertedMessage(render_frame()->GetRoutingID(),
+ message_port_id,
+ result,
+ sent_message_port_ids));
+}
+
+}
diff --git a/android_webview/renderer/aw_message_port_client.h b/android_webview/renderer/aw_message_port_client.h
new file mode 100644
index 0000000..f3a337b
--- /dev/null
+++ b/android_webview/renderer/aw_message_port_client.h
@@ -0,0 +1,35 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ANDROID_WEBVIEW_RENDERER_AW_MESSAGE_PORT_CLIENT_H_
+#define ANDROID_WEBVIEW_RENDERER_AW_MESSAGE_PORT_CLIENT_H_
+
+#include <vector>
+
+#include "base/strings/string16.h"
+#include "content/public/renderer/render_frame_observer.h"
+
+namespace android_webview {
+
+// Renderer side of Android webview specific message port service. This service
+// is used to convert messages from WebSerializedScriptValue to a base value.
+class AwMessagePortClient : public content::RenderFrameObserver {
+ public:
+ explicit AwMessagePortClient(content::RenderFrame* render_frame);
+
+ private:
+ virtual ~AwMessagePortClient();
+
+ // RenderFrameObserver
+ bool OnMessageReceived(const IPC::Message& message) override;
+
+ void OnPostMessage(int message_port_id,
+ const base::string16& message,
+ const std::vector<int>& sent_message_port_ids);
+ DISALLOW_COPY_AND_ASSIGN(AwMessagePortClient);
+};
+
+}
+
+#endif // ANDROID_WEBVIEW_RENDERER_AW_MESSAGE_PORT_CLIENT_H_
diff --git a/content/browser/message_port_message_filter.h b/content/browser/message_port_message_filter.h
index 7acc141..cdc8628 100644
--- a/content/browser/message_port_message_filter.h
+++ b/content/browser/message_port_message_filter.h
@@ -6,16 +6,16 @@
#define CONTENT_BROWSER_MESSAGE_PORT_MESSAGE_FILTER_H_
#include "base/callback.h"
-#include "content/browser/message_port_delegate.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/message_port_delegate.h"
namespace content {
// Filter for MessagePort related IPC messages (creating and destroying a
// MessagePort, sending a message via a MessagePort etc).
class CONTENT_EXPORT MessagePortMessageFilter
- : NON_EXPORTED_BASE(public MessagePortDelegate),
+ : public MessagePortDelegate,
public BrowserMessageFilter {
public:
typedef base::Callback<int(void)> NextRoutingIDCallback;
diff --git a/content/browser/message_port_provider.cc b/content/browser/message_port_provider.cc
index 12be065..0fd141d 100644
--- a/content/browser/message_port_provider.cc
+++ b/content/browser/message_port_provider.cc
@@ -12,59 +12,77 @@
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/view_messages.h"
+#include "content/public/browser/message_port_delegate.h"
namespace content {
+namespace {
+
+void PostMessageOnIOThread(MessagePortMessageFilter* filter,
+ int routing_id,
+ ViewMsg_PostMessage_Params* params) {
+ if (!params->message_port_ids.empty()) {
+ filter->UpdateMessagePortsWithNewRoutes(params->message_port_ids,
+ &params->new_routing_ids);
+ }
+ filter->Send(new ViewMsg_PostMessageEvent(routing_id, *params));
+}
+
+} // namespace
+
+// static
void MessagePortProvider::PostMessageToFrame(
WebContents* web_contents,
const base::string16& source_origin,
const base::string16& target_origin,
const base::string16& data,
const std::vector<int>& ports) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
- RenderViewHost* rvh = web_contents->GetRenderViewHost();
- if (!rvh)
- return;
+ ViewMsg_PostMessage_Params* params = new ViewMsg_PostMessage_Params();
+ params->is_data_raw_string = true;
+ params->data = data;
+ // Blink requires a source frame to transfer ports. This is why a
+ // source routing id is set here. See WebDOMMessageEvent::initMessageEvent()
+ params->source_routing_id = web_contents->GetRoutingID();
+ params->source_origin = source_origin;
+ params->target_origin = target_origin;
+ params->message_port_ids = ports;
- ViewMsg_PostMessage_Params params;
- params.is_data_raw_string = true;
- params.data = data;
- params.source_routing_id = web_contents->GetRoutingID();
- params.source_origin = source_origin;
- params.target_origin = target_origin;
RenderProcessHostImpl* rph =
- static_cast<RenderProcessHostImpl*>(
- web_contents->GetRenderProcessHost());
+ static_cast<RenderProcessHostImpl*>(web_contents->GetRenderProcessHost());
MessagePortMessageFilter* mf = rph->message_port_message_filter();
-
- if (!ports.empty()) {
- params.message_port_ids = ports;
- mf->UpdateMessagePortsWithNewRoutes(params.message_port_ids,
- &params.new_routing_ids);
- }
- rvh->Send(new ViewMsg_PostMessageEvent(
- web_contents->GetRenderViewHost()->GetRoutingID(),
- params));
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&PostMessageOnIOThread,
+ make_scoped_refptr(mf),
+ web_contents->GetRoutingID(),
+ base::Owned(params)));
}
-void MessagePortProvider::CreateMessageChannel(WebContents* web_contents,
+// static
+void MessagePortProvider::CreateMessageChannel(MessagePortDelegate* delegate,
int* port1,
int* port2) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
*port1 = 0;
*port2 = 0;
-
- RenderProcessHostImpl* rph =
- static_cast<RenderProcessHostImpl*>(
- web_contents->GetRenderProcessHost());
- MessagePortMessageFilter* mf = rph->message_port_message_filter();
MessagePortService* msp = MessagePortService::GetInstance();
- msp->Create(mf->GetNextRoutingID(), mf, port1);
- msp->Create(mf->GetNextRoutingID(), mf, port2);
+ msp->Create(MSG_ROUTING_NONE, delegate, port1);
+ msp->Create(MSG_ROUTING_NONE, delegate, port2);
+ // Update the routing number of the message ports to be equal to the message
+ // port numbers.
+ msp->UpdateMessagePort(*port1, delegate, *port1);
+ msp->UpdateMessagePort(*port2, delegate, *port2);
msp->Entangle(*port1, *port2);
msp->Entangle(*port2, *port1);
}
+// static
+void MessagePortProvider::OnMessagePortDelegateClosing(
+ MessagePortDelegate* delegate) {
+ MessagePortService::GetInstance()->OnMessagePortDelegateClosing(delegate);
+}
+
} // namespace content
diff --git a/content/browser/message_port_provider_browsertest.cc b/content/browser/message_port_provider_browsertest.cc
new file mode 100644
index 0000000..3c9ea5d
--- /dev/null
+++ b/content/browser/message_port_provider_browsertest.cc
@@ -0,0 +1,142 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/synchronization/waitable_event.h"
+#include "content/browser/message_port_service.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/message_port_delegate.h"
+#include "content/public/browser/message_port_provider.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+
+namespace content {
+
+// This test verifies the functionality of the Message Port Provider API.
+
+// A mock class for testing message port provider.
+class MockMessagePortDelegate : public MessagePortDelegate {
+ public:
+ // A container to hold received messages
+ struct Message {
+ int route_id; // the routing id of the target port
+ base::string16 data; // the message data
+ std::vector<int> sent_ports; // any transferred ports
+ };
+
+ typedef std::vector<Message> Messages;
+
+ MockMessagePortDelegate() { }
+ ~MockMessagePortDelegate() override { }
+
+ // MessagePortDelegate implementation
+ void SendMessage(int route_id,
+ const base::string16& message,
+ const std::vector<int>& sent_message_port_ids) override {
+ Message m;
+ m.route_id = route_id;
+ m.data = message;
+ m.sent_ports = sent_message_port_ids;
+ messages_.push_back(m);
+ }
+
+ void SendMessagesAreQueued(int route_id) override { }
+
+ const Messages& getReceivedMessages() {
+ return messages_;
+ }
+ private:
+ Messages messages_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockMessagePortDelegate);
+};
+
+
+class MessagePortProviderBrowserTest : public ContentBrowserTest {
+};
+
+// Verify that messages can be posted to main frame.
+IN_PROC_BROWSER_TEST_F(MessagePortProviderBrowserTest, PostMessage) {
+ const std::string data =
+ "<!DOCTYPE html><html><body>"
+ " <script type=\"text/javascript\">"
+ " onmessage = function (e) { document.title = e.data; }"
+ " </script>"
+ "</body></html>";
+ const base::string16 target_origin(base::UTF8ToUTF16("http://baseurl"));
+ const GURL base_url(target_origin);
+ const GURL history_url;
+ // Load data. Blocks until it is done.
+ content::LoadDataWithBaseURL(shell(), history_url, data, base_url);
+ const base::string16 source_origin(base::UTF8ToUTF16("source"));
+ const base::string16 message(base::UTF8ToUTF16("success"));
+ const std::vector<int> ports;
+ content::TitleWatcher title_watcher(shell()->web_contents(), message);
+ MessagePortProvider::PostMessageToFrame(shell()->web_contents(),
+ source_origin,
+ target_origin,
+ message,
+ ports);
+ EXPECT_EQ(message, title_watcher.WaitAndGetTitle());
+}
+
+namespace {
+
+void VerifyCreateChannelOnIOThread(base::WaitableEvent* event) {
+
+ const base::char16 MESSAGE1[] = { 0x1000, 0 };
+ const base::char16 MESSAGE2[] = { 0x1001, 0 };
+
+ MockMessagePortDelegate delegate;
+ int port1;
+ int port2;
+
+ MessagePortProvider::CreateMessageChannel(&delegate, &port1, &port2);
+ MessagePortService* service = MessagePortService::GetInstance();
+ // Send a message to port1 transferring no ports.
+ std::vector<int> sent_ports;
+ service->PostMessage(port1, base::string16(MESSAGE1), sent_ports);
+ // Verify that message is received
+ const MockMessagePortDelegate::Messages& received =
+ delegate.getReceivedMessages();
+ EXPECT_EQ(received.size(), 1u);
+ // Verify that message sent to port1 is received by entangled port, which is
+ // port2.
+ EXPECT_EQ(received[0].route_id, port2);
+ EXPECT_EQ(received[0].data, MESSAGE1);
+ EXPECT_EQ(received[0].sent_ports.size(), 0u);
+
+ // Create a new channel, and transfer one of its ports to port2, making sure
+ // the transferred port is received.
+ int port3;
+ int port4;
+ MessagePortProvider::CreateMessageChannel(&delegate, &port3, &port4);
+ sent_ports.push_back(port3);
+ service->PostMessage(port1, base::string16(MESSAGE2), sent_ports);
+ EXPECT_EQ(received.size(), 2u);
+ EXPECT_EQ(received[1].route_id, port2);
+ EXPECT_EQ(received[1].data, MESSAGE2);
+ EXPECT_EQ(received[1].sent_ports.size(), 1u);
+ EXPECT_EQ(received[1].sent_ports[0], port3);
+
+ event->Signal();
+}
+
+} // namespace
+
+// Verify that a message channel can be created and used for exchanging
+// messages.
+IN_PROC_BROWSER_TEST_F(MessagePortProviderBrowserTest, CreateChannel) {
+ base::WaitableEvent event(true, false);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&VerifyCreateChannelOnIOThread, &event));
+ event.Wait();
+}
+
+} // namespace content
diff --git a/content/browser/message_port_service.cc b/content/browser/message_port_service.cc
index 42a3051..382f5b6 100644
--- a/content/browser/message_port_service.cc
+++ b/content/browser/message_port_service.cc
@@ -4,9 +4,9 @@
#include "content/browser/message_port_service.h"
-#include "content/browser/message_port_delegate.h"
#include "content/common/message_port_messages.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/message_port_delegate.h"
namespace content {
diff --git a/content/browser/message_port_service.h b/content/browser/message_port_service.h
index 623b26b..5623e94 100644
--- a/content/browser/message_port_service.h
+++ b/content/browser/message_port_service.h
@@ -12,12 +12,13 @@
#include "base/basictypes.h"
#include "base/memory/singleton.h"
#include "base/strings/string16.h"
+#include "content/common/content_export.h"
#include "ipc/ipc_message.h"
namespace content {
class MessagePortDelegate;
-class MessagePortService {
+class CONTENT_EXPORT MessagePortService {
public:
typedef std::vector<std::pair<base::string16, std::vector<int> > >
QueuedMessages;
diff --git a/content/browser/navigator_connect/navigator_connect_context.h b/content/browser/navigator_connect/navigator_connect_context.h
index db4edbc..3794867 100644
--- a/content/browser/navigator_connect/navigator_connect_context.h
+++ b/content/browser/navigator_connect/navigator_connect_context.h
@@ -7,8 +7,8 @@
#include <map>
#include "base/memory/ref_counted.h"
-#include "content/browser/message_port_delegate.h"
#include "content/common/service_worker/service_worker_status_code.h"
+#include "content/public/browser/message_port_delegate.h"
namespace content {
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 9fc7832..33d64df 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -150,6 +150,7 @@
'public/browser/media_device_id.cc',
'public/browser/media_device_id.h',
'public/browser/memory_pressure_observer.h',
+ 'public/browser/message_port_delegate.h',
'public/browser/message_port_provider.h',
'public/browser/native_web_keyboard_event.h',
'public/browser/navigation_controller.cc',
@@ -935,7 +936,6 @@
'browser/media/webrtc_identity_store_backend.h',
'browser/manifest/manifest_manager_host.cc',
'browser/manifest/manifest_manager_host.h',
- 'browser/message_port_delegate.h',
'browser/message_port_message_filter.cc',
'browser/message_port_message_filter.h',
'browser/message_port_provider.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index c1ff6e9..cbbfa23 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -218,6 +218,7 @@
'browser/media/media_browsertest.h',
'browser/media/media_canplaytype_browsertest.cc',
'browser/media/media_source_browsertest.cc',
+ 'browser/message_port_provider_browsertest.cc',
'browser/net_info_browsertest.cc',
'browser/plugin_browsertest.cc',
'browser/renderer_host/input/touch_action_browsertest.cc',
diff --git a/content/browser/message_port_delegate.h b/content/public/browser/message_port_delegate.h
index 8f6ad1b..70abbeb 100644
--- a/content/browser/message_port_delegate.h
+++ b/content/public/browser/message_port_delegate.h
@@ -2,12 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_BROWSER_MESSAGE_PORT_DELEGATE_H_
-#define CONTENT_BROWSER_MESSAGE_PORT_DELEGATE_H_
+#ifndef CONTENT_PUBLIC_BROWSER_MESSAGE_PORT_DELEGATE_H_
+#define CONTENT_PUBLIC_BROWSER_MESSAGE_PORT_DELEGATE_H_
#include <vector>
#include "base/strings/string16.h"
+#include "content/common/content_export.h"
namespace content {
@@ -15,7 +16,7 @@ namespace content {
// correct renderer. Delegates are responsible for managing their own lifetime,
// and should call MessagePortService::OnMessagePortDelegateClosing if they are
// destroyed while there are still message ports associated with them.
-class MessagePortDelegate {
+class CONTENT_EXPORT MessagePortDelegate {
public:
// Sends a message to the given route. Implementations are responsible for
// updating MessagePortService with new routes for the sent message ports.
@@ -23,7 +24,7 @@ class MessagePortDelegate {
const base::string16& message,
const std::vector<int>& sent_message_port_ids) = 0;
- // Sends a "messages are queued" IPC to the given route.
+ // Requests messages to the given route to be queued.
virtual void SendMessagesAreQueued(int route_id) = 0;
protected:
@@ -32,4 +33,4 @@ class MessagePortDelegate {
} // namespace content
-#endif // CONTENT_BROWSER_MESSAGE_PORT_DELEGATE_H_
+#endif // CONTENT_PUBLIC_BROWSER_MESSAGE_PORT_DELEGATE_H_
diff --git a/content/public/browser/message_port_provider.h b/content/public/browser/message_port_provider.h
index aab9269..70fbe11 100644
--- a/content/public/browser/message_port_provider.h
+++ b/content/public/browser/message_port_provider.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,6 +14,7 @@
namespace content {
+class MessagePortDelegate;
class WebContents;
// An interface consisting of methods that can be called to use Message ports.
@@ -24,7 +25,7 @@ class CONTENT_EXPORT MessagePortProvider {
// part of the message.
// See https://html.spec.whatwg.org/multipage/comms.html#messageevent for
// further information on message events.
- // Should be called on IO thread.
+ // Should be called on UI thread.
static void PostMessageToFrame(WebContents* web_contents,
const base::string16& source_origin,
const base::string16& target_origin,
@@ -35,10 +36,15 @@ class CONTENT_EXPORT MessagePortProvider {
// associated with this message channel.
// See https://html.spec.whatwg.org/multipage/comms.html#messagechannel
// Should be called on IO thread.
- static void CreateMessageChannel(WebContents* web_contents,
+ // The message ports that are created will have their routing id numbers equal
+ // to the message port numbers.
+ static void CreateMessageChannel(MessagePortDelegate* delegate,
int* port1,
int* port2);
+ // Cleanup the message ports that belong to the closing delegate.
+ static void OnMessagePortDelegateClosing(MessagePortDelegate * delegate);
+
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(MessagePortProvider);
};
diff --git a/ipc/ipc_message_start.h b/ipc/ipc_message_start.h
index b22c7b3..48dd9af 100644
--- a/ipc/ipc_message_start.h
+++ b/ipc/ipc_message_start.h
@@ -113,6 +113,7 @@ enum IPCMessageStart {
BluetoothMsgStart,
NavigatorConnectMsgStart,
CastMediaMsgStart,
+ AwMessagePortMsgStart,
LastIPCMsgStart // Must come last.
};