Chromium Code Reviews| 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 4025c4507264c56d4fd753c4bd53be8e57955ece..0cc6ef05ffa1add03cf233f9f8cd85781fba55f2 100644 |
| --- a/android_webview/java/src/org/chromium/android_webview/MessagePort.java |
| +++ b/android_webview/java/src/org/chromium/android_webview/MessagePort.java |
| @@ -9,8 +9,32 @@ 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 |
| + * |
| + * State management: |
| + * |
| + * Initially a message port will be in a pending state. It will be ready once it is created in |
| + * content/ (in IO thread) and a message port id is assigned. |
| + * A pending message port cannnot be transferred, and cannot send or receive messages. However, |
| + * these details are hidden from the user. If a message port is in the pending state: |
| + * 1. Any messages posted in this port will be queued until the port is ready |
| + * 2. Transferring the port using a message channel will cause the message (and any subsequent |
| + * messages sent) to be queued until the port is ready |
| + * 3. Transferring the pending port via postMessageToFrame will cause the message (and all |
| + * subsequent messages posted via postMessageToFrame) to be queued until the port is ready. |
| + * |
| + * A message port should be closed by the using app when it is not needed any more. This will free |
|
hush (inactive)
2015/02/13 03:25:08
"closed by the app"?
sgurun-gerrit only
2015/02/13 05:11:59
Done.
|
| + * any resources used by it. A closed port cannot receive/send messages and cannot be transferred. |
| + * close() can be called multiple times. |
| + * |
| + * A message port can be in transferred state while a transfer is pending or complete. A transferred |
| + * port cannot send messages and any received messages will be queued. This state is not visible |
|
hush (inactive)
2015/02/13 03:25:08
The app cannot send messages from the transferred
sgurun-gerrit only
2015/02/13 05:11:59
clarified.
|
| + * to embedder app. |
| + * |
| + * TODO(sgurun) implement queueing messages while a port is in transfer |
| + * TODO(sgurun) implement freeing resources in content/message_port_service when a port is |
| + * closed |
| */ |
| -public class MessagePort { |
| +public class MessagePort implements PostMessageSender.PostMessageSenderDelegate { |
| /** |
| * The interface for message handler for receiving messages. Called on a background thread. |
| @@ -19,33 +43,71 @@ public class MessagePort { |
| void onMessage(String message); |
| }; |
| - private static final String TAG = "MessagePort"; |
| + /** |
| + * A specialized PostMessageSender for message channel message port. |
| + */ |
| + private static class MessagePortPostMessageSender extends PostMessageSender { |
| - private int mPortId; |
| + private MessagePort mSender; |
| + |
| + public MessagePortPostMessageSender(MessagePort sender, AwMessagePortService service) { |
| + super(sender, service); |
| + mSender = sender; |
| + } |
| + @Override |
| + protected boolean senderIsReady() { |
| + return mSender.isReady(); |
| + } |
| + } |
| + |
| + private static final String TAG = "MessagePort"; |
| + private static final int PENDING = -1; |
| + private int mPortId = PENDING; |
| private MessageHandler mHandler; |
| private AwMessagePortService mMessagePortService; |
| - // A port is put into a closed state when transferred. Such a port can no longer |
| - // send or receive messages. |
| private boolean mClosed; |
| + private boolean mTransferred; |
| + private MessagePortPostMessageSender mPostMessageSender; |
| - public MessagePort(int portId, AwMessagePortService messagePortService) { |
| - mPortId = portId; |
| + public MessagePort(AwMessagePortService messagePortService) { |
| mMessagePortService = messagePortService; |
| + mPostMessageSender = new MessagePortPostMessageSender(this, mMessagePortService); |
| + mMessagePortService.addObserver(mPostMessageSender); |
| + } |
| + |
| + public boolean isReady() { |
| + return mPortId != PENDING; |
| } |
| public int portId() { |
| return mPortId; |
| } |
| + public void setPortId(int id) { |
| + mPortId = id; |
| + } |
| + |
| public void close() { |
| - assert !mClosed; |
| - mClosed = true; |
| + if (!mClosed) { |
| + mClosed = true; |
| + mMessagePortService.removeObserver(mPostMessageSender); |
| + // TODO(sgurun) remove the port from AwMessagePortService and write a test |
| + // to verify it. |
| + } |
| } |
| public boolean isClosed() { |
| return mClosed; |
| } |
| + public boolean isTransferred() { |
| + return mTransferred; |
| + } |
| + |
| + public void setTransferred() { |
| + mTransferred = true; |
| + } |
| + |
| public void setMessageHandler(MessageHandler handler) { |
| mHandler = handler; |
| } |
| @@ -63,20 +125,22 @@ public class MessagePort { |
| } |
| public void postMessage(String message, MessagePort[] msgPorts) throws IllegalStateException { |
| - if (isClosed()) { |
| - throw new IllegalStateException("Messageport is already closed"); |
| + if (isClosed() || isTransferred()) { |
| + throw new IllegalStateException("Port is already closed or transferred"); |
| } |
| - int[] portIds = null; |
| if (msgPorts != null) { |
| - portIds = new int[msgPorts.length]; |
| - for (int i = 0; i < msgPorts.length; i++) { |
| - int sentId = msgPorts[i].portId(); |
| - if (sentId == mPortId) { |
| + for (MessagePort port : msgPorts) { |
| + if (port.portId() == mPortId) { |
| throw new IllegalStateException("Source port cannot be transferred"); |
| } |
| - portIds[i] = sentId; |
| } |
| } |
| - mMessagePortService.postMessage(mPortId, message, portIds); |
| + mPostMessageSender.postMessage(null, message, null, null, msgPorts); |
| + } |
| + |
| + @Override |
| + public void postMessageToWeb(String frameName, String message, |
| + String sourceOrigin, String targetOrigin, int[] sentPorts) { |
| + mMessagePortService.postMessage(mPortId, message, sentPorts); |
| } |
| } |