| Index: content/public/android/java/src/org/chromium/content/browser/AppWebMessagePort.java
|
| diff --git a/content/public/android/java/src/org/chromium/content/browser/AppWebMessagePort.java b/content/public/android/java/src/org/chromium/content/browser/AppWebMessagePort.java
|
| index 30e50d02e8a3cdbd6f60a0ac75b155cf90cd1162..361988dc181ad1ab7d9e869b3e4c1bb94e758b34 100644
|
| --- a/content/public/android/java/src/org/chromium/content/browser/AppWebMessagePort.java
|
| +++ b/content/public/android/java/src/org/chromium/content/browser/AppWebMessagePort.java
|
| @@ -9,6 +9,8 @@ import android.os.Looper;
|
| import android.os.Message;
|
|
|
| import org.chromium.base.Log;
|
| +import org.chromium.base.annotations.CalledByNative;
|
| +import org.chromium.base.annotations.JNINamespace;
|
| import org.chromium.content_public.browser.MessagePort;
|
|
|
| import java.util.Arrays;
|
| @@ -73,25 +75,13 @@ import java.util.Arrays;
|
| * transferring data. As a return, it simplifies implementation and prevents hard
|
| * to debug, racy corner cases while receiving/sending data.
|
| */
|
| -public class AppWebMessagePort implements MessagePort, PostMessageSender.PostMessageSenderDelegate {
|
| - private static final String TAG = "MessagePort";
|
| - private static final int PENDING = -1;
|
| +@JNINamespace("content")
|
| +public class AppWebMessagePort implements MessagePort {
|
| + private static final String TAG = "AppWebMessagePort";
|
| + private static final long UNINITIALIZED_PORT = -1;
|
|
|
| - // the what value for POST_MESSAGE
|
| - private static final int POST_MESSAGE = 1;
|
| -
|
| - private static class PostMessageFromWeb {
|
| - public AppWebMessagePort port;
|
| - public String message;
|
| - public AppWebMessagePort[] sentPorts;
|
| -
|
| - public PostMessageFromWeb(
|
| - AppWebMessagePort port, String message, AppWebMessagePort[] sentPorts) {
|
| - this.port = port;
|
| - this.message = message;
|
| - this.sentPorts = sentPorts;
|
| - }
|
| - }
|
| + // The |what| value for handleMessage.
|
| + private static final int MESSAGES_AVAILABLE = 1;
|
|
|
| // Implements the handler to handle messageport messages received from web.
|
| // These messages are received on IO thread and normally handled in main
|
| @@ -102,9 +92,9 @@ public class AppWebMessagePort implements MessagePort, PostMessageSender.PostMes
|
| }
|
| @Override
|
| public void handleMessage(Message msg) {
|
| - if (msg.what == POST_MESSAGE) {
|
| - PostMessageFromWeb m = (PostMessageFromWeb) msg.obj;
|
| - m.port.onMessage(m.message, m.sentPorts);
|
| + if (msg.what == MESSAGES_AVAILABLE) {
|
| + AppWebMessagePort port = (AppWebMessagePort) msg.obj;
|
| + port.dispatchReceivedMessages();
|
| return;
|
| }
|
| throw new IllegalStateException("undefined message");
|
| @@ -114,35 +104,34 @@ public class AppWebMessagePort implements MessagePort, PostMessageSender.PostMes
|
| private static final MessageHandler sDefaultHandler =
|
| new MessageHandler(Looper.getMainLooper());
|
|
|
| - private int mPortId = PENDING;
|
| + private long mNativeAppWebMessagePort = UNINITIALIZED_PORT;
|
| +
|
| private MessageCallback mMessageCallback;
|
| - private AppWebMessagePortService mMessagePortService;
|
| private boolean mClosed;
|
| private boolean mTransferred;
|
| private boolean mStarted;
|
| - private boolean mReleasedMessages;
|
| - private PostMessageSender mPostMessageSender;
|
| private MessageHandler mHandler;
|
| private final Object mLock = new Object();
|
|
|
| - public AppWebMessagePort(AppWebMessagePortService messagePortService) {
|
| - mMessagePortService = messagePortService;
|
| - mPostMessageSender = new PostMessageSender(this, mMessagePortService);
|
| - mMessagePortService.addObserver(mPostMessageSender);
|
| + public AppWebMessagePort() {
|
| }
|
|
|
| @Override
|
| public boolean isReady() {
|
| - return mPortId != PENDING;
|
| + return mNativeAppWebMessagePort != UNINITIALIZED_PORT;
|
| }
|
|
|
| - public int portId() {
|
| - return mPortId;
|
| + @CalledByNative
|
| + private void setNativeAppWebMessagePort(long nativeAppWebMessagePort) {
|
| + mNativeAppWebMessagePort = nativeAppWebMessagePort;
|
| }
|
|
|
| - public void setPortId(int id) {
|
| - mPortId = id;
|
| - releaseMessages();
|
| + @CalledByNative
|
| + private long releaseNativePortForTransfer() {
|
| + mTransferred = true;
|
| + long port = mNativeAppWebMessagePort;
|
| + mNativeAppWebMessagePort = UNINITIALIZED_PORT;
|
| + return port;
|
| }
|
|
|
| @Override
|
| @@ -154,18 +143,16 @@ public class AppWebMessagePort implements MessagePort, PostMessageSender.PostMes
|
| 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()) {
|
| + if (isReady()) {
|
| cleanup();
|
| }
|
| }
|
|
|
| @Override
|
| public boolean isClosed() {
|
| - return mClosed;
|
| + synchronized (mLock) {
|
| + return mClosed;
|
| + }
|
| }
|
|
|
| @Override
|
| @@ -173,10 +160,6 @@ public class AppWebMessagePort implements MessagePort, PostMessageSender.PostMes
|
| return mTransferred;
|
| }
|
|
|
| - public void setTransferred() {
|
| - mTransferred = true;
|
| - }
|
| -
|
| @Override
|
| public boolean isStarted() {
|
| return mStarted;
|
| @@ -192,43 +175,41 @@ public class AppWebMessagePort implements MessagePort, PostMessageSender.PostMes
|
| mHandler = new MessageHandler(handler.getLooper());
|
| }
|
| }
|
| - releaseMessages();
|
| + nativeStartReceivingMessages(mNativeAppWebMessagePort);
|
| }
|
|
|
| - // Only called on IO thread.
|
| - public void onReceivedMessage(String message, AppWebMessagePort[] sentPorts) {
|
| + // Called on a background thread.
|
| + @CalledByNative
|
| + private void onMessagesAvailable() {
|
| synchronized (mLock) {
|
| - PostMessageFromWeb m = new PostMessageFromWeb(this, message, sentPorts);
|
| Handler handler = mHandler != null ? mHandler : sDefaultHandler;
|
| - Message msg = handler.obtainMessage(POST_MESSAGE, m);
|
| + Message msg = handler.obtainMessage(MESSAGES_AVAILABLE, this);
|
| handler.sendMessage(msg);
|
| }
|
| }
|
|
|
| - private void releaseMessages() {
|
| - if (mReleasedMessages || !isReady() || mMessageCallback == null) {
|
| - return;
|
| - }
|
| - mReleasedMessages = true;
|
| - mMessagePortService.releaseMessages(mPortId);
|
| - }
|
| -
|
| // This method may be called on a different thread than UI thread.
|
| - public void onMessage(String message, AppWebMessagePort[] ports) {
|
| + @CalledByNative
|
| + private void onReceivedMessage(String message, AppWebMessagePort[] ports) {
|
| synchronized (mLock) {
|
| if (isClosed()) {
|
| - Log.w(TAG, "Port [" + mPortId + "] received message in closed state");
|
| + Log.w(TAG, "Port [" + mNativeAppWebMessagePort
|
| + + "] received message in closed state");
|
| return;
|
| }
|
| if (mMessageCallback == null) {
|
| - Log.w(TAG,
|
| - "No handler set for port [" + mPortId + "], dropping message " + message);
|
| + Log.w(TAG, "No handler set for port [" + mNativeAppWebMessagePort
|
| + + "], dropping message " + message);
|
| return;
|
| }
|
| mMessageCallback.onMessage(message, ports);
|
| }
|
| }
|
|
|
| + public void dispatchReceivedMessages() {
|
| + nativeDispatchReceivedMessages(mNativeAppWebMessagePort);
|
| + }
|
| +
|
| @Override
|
| public void postMessage(String message, MessagePort[] sentPorts) throws IllegalStateException {
|
| if (isClosed() || isTransferred()) {
|
| @@ -240,37 +221,27 @@ public class AppWebMessagePort implements MessagePort, PostMessageSender.PostMes
|
| if (port.equals(this)) {
|
| throw new IllegalStateException("Source port cannot be transferred");
|
| }
|
| + if (port.isClosed() || port.isTransferred()) {
|
| + throw new IllegalStateException("Port is already closed or transferred");
|
| + }
|
| + if (port.isStarted()) {
|
| + throw new IllegalStateException("Port is already started");
|
| + }
|
| }
|
| ports = Arrays.copyOf(sentPorts, sentPorts.length, AppWebMessagePort[].class);
|
| }
|
| mStarted = true;
|
| - mPostMessageSender.postMessage(null, message, null, ports);
|
| - }
|
| -
|
| - // 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);
|
| + nativePostMessage(mNativeAppWebMessagePort, message, ports);
|
| }
|
|
|
| private void cleanup() {
|
| - mMessagePortService.removeObserver(mPostMessageSender);
|
| - mPostMessageSender = null;
|
| - mMessagePortService.closePort(mPortId);
|
| + nativeCloseMessagePort(mNativeAppWebMessagePort);
|
| + mNativeAppWebMessagePort = UNINITIALIZED_PORT;
|
| }
|
| +
|
| + private native void nativeCloseMessagePort(long nativeAppWebMessagePort);
|
| + private native void nativePostMessage(long nativeAppWebMessagePort, String message,
|
| + AppWebMessagePort[] ports);
|
| + private native void nativeDispatchReceivedMessages(long nativeAppWebMessagePort);
|
| + private native void nativeStartReceivingMessages(long nativeAppWebMessagePort);
|
| }
|
|
|