| 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 2d0e3939d6f3b61ab6188591edce912b598008a3..620cbbbcb95428cd2d00c64a321b0af2b1ecb2d5 100644
|
| --- a/android_webview/java/src/org/chromium/android_webview/MessagePort.java
|
| +++ b/android_webview/java/src/org/chromium/android_webview/MessagePort.java
|
| @@ -22,17 +22,17 @@ import android.util.Log;
|
| * 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 app when it is not needed any more. This will free
|
| - * 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. An
|
| * application cannot use a transferred port to post messages. If a transferred port
|
| * receives messages, they will be queued. This state is not visible to embedder app.
|
| *
|
| + * A message port should be closed by the app when it is not needed any more. This will free
|
| + * any resources used by it. A closed port cannot receive/send messages and cannot be transferred.
|
| + * close() can be called multiple times. A transferred port cannot be closed by the application,
|
| + * 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
|
| - * TODO(sgurun) implement freeing resources in content/message_port_service when a port is
|
| - * closed
|
| */
|
| public class MessagePort implements PostMessageSender.PostMessageSenderDelegate {
|
|
|
| @@ -43,23 +43,6 @@ public class MessagePort implements PostMessageSender.PostMessageSenderDelegate
|
| public abstract void onMessage(String message);
|
| };
|
|
|
| - /**
|
| - * A specialized PostMessageSender for message channel message port.
|
| - */
|
| - private static class MessagePortPostMessageSender extends PostMessageSender {
|
| -
|
| - 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;
|
| @@ -67,11 +50,11 @@ public class MessagePort implements PostMessageSender.PostMessageSenderDelegate
|
| private AwMessagePortService mMessagePortService;
|
| private boolean mClosed;
|
| private boolean mTransferred;
|
| - private MessagePortPostMessageSender mPostMessageSender;
|
| + private PostMessageSender mPostMessageSender;
|
|
|
| public MessagePort(AwMessagePortService messagePortService) {
|
| mMessagePortService = messagePortService;
|
| - mPostMessageSender = new MessagePortPostMessageSender(this, mMessagePortService);
|
| + mPostMessageSender = new PostMessageSender(this, mMessagePortService);
|
| mMessagePortService.addObserver(mPostMessageSender);
|
| }
|
|
|
| @@ -88,11 +71,17 @@ public class MessagePort implements PostMessageSender.PostMessageSenderDelegate
|
| }
|
|
|
| public void close() {
|
| - if (!mClosed) {
|
| - mClosed = true;
|
| - mMessagePortService.removeObserver(mPostMessageSender);
|
| - // TODO(sgurun) remove the port from AwMessagePortService and write a test
|
| - // to verify it.
|
| + if (mTransferred) {
|
| + throw new IllegalStateException("Port is already transferred");
|
| + }
|
| + 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
|
| + // case do the cleanup here.
|
| + if (isReady() && mPostMessageSender.isMessageQueueEmpty()) {
|
| + cleanup();
|
| }
|
| }
|
|
|
| @@ -130,7 +119,7 @@ public class MessagePort implements PostMessageSender.PostMessageSenderDelegate
|
| }
|
| if (msgPorts != null) {
|
| for (MessagePort port : msgPorts) {
|
| - if (port.portId() == mPortId) {
|
| + if (port.equals(this)) {
|
| throw new IllegalStateException("Source port cannot be transferred");
|
| }
|
| }
|
| @@ -138,9 +127,30 @@ public class MessagePort implements PostMessageSender.PostMessageSenderDelegate
|
| mPostMessageSender.postMessage(null, message, null, msgPorts);
|
| }
|
|
|
| + // Implements PostMessageSender.PostMessageSenderDelegate interface method.
|
| + @Override
|
| + public boolean isPostMessageSenderReady() {
|
| + return isReady();
|
| + }
|
| +
|
| + // Implements PostMessageSender.PostMessageSenderDelegate interface method.
|
| + @Override
|
| + public void onPostMessageQueueEmpty() {
|
| + if (isClosed()) {
|
| + cleanup();
|
| + }
|
| + }
|
| +
|
| + // Implements PostMessageSender.PostMessageSenderDelegate interface method.
|
| @Override
|
| public void postMessageToWeb(String frameName, String message, String targetOrigin,
|
| int[] sentPortIds) {
|
| mMessagePortService.postMessage(mPortId, message, sentPortIds);
|
| }
|
| +
|
| + private void cleanup() {
|
| + mMessagePortService.removeObserver(mPostMessageSender);
|
| + mPostMessageSender = null;
|
| + mMessagePortService.closePort(mPortId);
|
| + }
|
| }
|
|
|