Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1505)

Unified Diff: android_webview/java/src/org/chromium/android_webview/MessagePort.java

Issue 961393002: Implement the plumbing to handle messages in a separate handler (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address code review Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: android_webview/java/src/org/chromium/android_webview/MessagePort.java
diff --git a/android_webview/java/src/org/chromium/android_webview/MessagePort.java b/android_webview/java/src/org/chromium/android_webview/MessagePort.java
index 620cbbbcb95428cd2d00c64a321b0af2b1ecb2d5..fc41de39bc4d64bca0121ede55c500c37af18269 100644
--- a/android_webview/java/src/org/chromium/android_webview/MessagePort.java
+++ b/android_webview/java/src/org/chromium/android_webview/MessagePort.java
@@ -4,6 +4,9 @@
package org.chromium.android_webview;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.util.Log;
/**
@@ -32,7 +35,10 @@ import android.util.Log;
* since the ownership is also transferred during the transfer. Closing a transferred port will
* throw an exception.
*
- * TODO(sgurun) implement queueing messages while a port is in transfer
+ * The fact that messages can be handled on a separate thread means that thread
+ * synchronization is important. All methods are called on UI thread except as noted.
+ *
+ * TODO(sgurun) implement queueing messages while a port is in transfer.
*/
public class MessagePort implements PostMessageSender.PostMessageSenderDelegate {
@@ -41,16 +47,53 @@ public class MessagePort implements PostMessageSender.PostMessageSenderDelegate
*/
public abstract static class WebEventHandler {
public abstract void onMessage(String message);
- };
+ }
private static final String TAG = "MessagePort";
private static final int PENDING = -1;
+
+ // the what value for POST_MESSAGE
+ private static final int POST_MESSAGE = 1;
+
+ private static class PostMessageFromWeb {
+ public MessagePort port;
+ public String message;
+
+ public PostMessageFromWeb(MessagePort port, String message) {
+ this.port = port;
+ this.message = message;
+ }
+ }
+
+ // Implements the handler to handle messageport messages received from web.
+ // These messages are received on IO thread and normally handled in main
+ // thread however, alternatively application can pass a handler to execute them.
+ private static class MessageHandler extends Handler {
+ public MessageHandler(Looper looper) {
+ super(looper);
+ }
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == POST_MESSAGE) {
+ PostMessageFromWeb m = (PostMessageFromWeb) msg.obj;
+ m.port.onMessage(m.message);
+ return;
+ }
+ throw new IllegalStateException("undefined message");
+ }
+ }
+ // The default message handler
+ private static final MessageHandler sDefaultHandler =
+ new MessageHandler(Looper.getMainLooper());
+
private int mPortId = PENDING;
private WebEventHandler mWebEventHandler;
private AwMessagePortService mMessagePortService;
private boolean mClosed;
private boolean mTransferred;
private PostMessageSender mPostMessageSender;
+ private MessageHandler mHandler;
+ private Object mLock = new Object();
public MessagePort(AwMessagePortService messagePortService) {
mMessagePortService = messagePortService;
@@ -74,8 +117,10 @@ public class MessagePort implements PostMessageSender.PostMessageSenderDelegate
if (mTransferred) {
throw new IllegalStateException("Port is already transferred");
}
- if (mClosed) return;
- mClosed = true;
+ synchronized (mLock) {
+ if (mClosed) return;
+ mClosed = true;
+ }
// If the port is already ready, and no messages are waiting in the
// queue to be transferred, onPostMessageQueueEmpty() callback is not
// received (it is received only after messages are purged). In this
@@ -97,20 +142,39 @@ public class MessagePort implements PostMessageSender.PostMessageSenderDelegate
mTransferred = true;
}
- public void setWebEventHandler(WebEventHandler webEventHandler) {
- mWebEventHandler = webEventHandler;
+ public void setWebEventHandler(WebEventHandler webEventHandler, Handler handler) {
+ synchronized (mLock) {
+ mWebEventHandler = webEventHandler;
+ if (handler != null) {
+ mHandler = new MessageHandler(handler.getLooper());
+ }
+ }
}
- public void onMessage(String message) {
- if (isClosed()) {
- Log.w(TAG, "Port [" + mPortId + "] received message in closed state");
- return;
+ // Called on IO thread.
+ public void onReceivedMessage(String message) {
+ synchronized (mLock) {
+ PostMessageFromWeb m = new PostMessageFromWeb(this, message);
+ Handler handler = mHandler != null ? mHandler : sDefaultHandler;
+ Message msg = handler.obtainMessage(POST_MESSAGE, m);
+ handler.sendMessage(msg);
}
- if (mWebEventHandler == null) {
- Log.w(TAG, "No handler set for port [" + mPortId + "], dropping message " + message);
- return;
+ }
+
+ // This method may be called on a different thread than UI thread.
+ public void onMessage(String message) {
+ synchronized (mLock) {
+ if (isClosed()) {
+ Log.w(TAG, "Port [" + mPortId + "] received message in closed state");
+ return;
+ }
+ if (mWebEventHandler == null) {
+ Log.w(TAG, "No handler set for port [" + mPortId + "], dropping message "
+ + message);
+ return;
+ }
+ mWebEventHandler.onMessage(message);
}
- mWebEventHandler.onMessage(message);
}
public void postMessage(String message, MessagePort[] msgPorts) throws IllegalStateException {

Powered by Google App Engine
This is Rietveld 408576698