Commit 65eb66aa authored by qsr's avatar qsr Committed by Commit bot

MessageReceiver must handle Message and not MessageWithHeader.

MessageReceiver were given MessageWithHeader. This is incorrect as this
force validation code at the Connector level, while Connector should not
impose any format on the message it receives.

R=ppi@chromium.org

Review URL: https://codereview.chromium.org/525383002

Cr-Commit-Position: refs/heads/master@{#292888}
parent a5f25ade
...@@ -24,13 +24,13 @@ public class BindingsTestUtils { ...@@ -24,13 +24,13 @@ public class BindingsTestUtils {
public static class RecordingMessageReceiver extends SideEffectFreeCloseable public static class RecordingMessageReceiver extends SideEffectFreeCloseable
implements MessageReceiver { implements MessageReceiver {
public final List<MessageWithHeader> messages = new ArrayList<MessageWithHeader>(); public final List<Message> messages = new ArrayList<Message>();
/** /**
* @see MessageReceiver#accept(MessageWithHeader) * @see MessageReceiver#accept(Message)
*/ */
@Override @Override
public boolean accept(MessageWithHeader message) { public boolean accept(Message message) {
messages.add(message); messages.add(message);
return true; return true;
} }
...@@ -42,15 +42,14 @@ public class BindingsTestUtils { ...@@ -42,15 +42,14 @@ public class BindingsTestUtils {
public static class RecordingMessageReceiverWithResponder extends RecordingMessageReceiver public static class RecordingMessageReceiverWithResponder extends RecordingMessageReceiver
implements MessageReceiverWithResponder { implements MessageReceiverWithResponder {
public final List<Pair<MessageWithHeader, MessageReceiver>> messagesWithReceivers = public final List<Pair<Message, MessageReceiver>> messagesWithReceivers =
new ArrayList<Pair<MessageWithHeader, MessageReceiver>>(); new ArrayList<Pair<Message, MessageReceiver>>();
/** /**
* @see MessageReceiverWithResponder#acceptWithResponder(MessageWithHeader, * @see MessageReceiverWithResponder#acceptWithResponder(Message, MessageReceiver)
* MessageReceiver)
*/ */
@Override @Override
public boolean acceptWithResponder(MessageWithHeader message, MessageReceiver responder) { public boolean acceptWithResponder(Message message, MessageReceiver responder) {
messagesWithReceivers.add(Pair.create(message, responder)); messagesWithReceivers.add(Pair.create(message, responder));
return true; return true;
} }
...@@ -91,6 +90,6 @@ public class BindingsTestUtils { ...@@ -91,6 +90,6 @@ public class BindingsTestUtils {
message.putInt(4 * i, headerAsInts[i]); message.putInt(4 * i, headerAsInts[i]);
} }
message.position(0); message.position(0);
return new MessageWithHeader(new Message(message, new ArrayList<Handle>())); return new SimpleMessage(message, new ArrayList<Handle>()).asMojoMessage();
} }
} }
...@@ -30,7 +30,7 @@ public class ConnectorTest extends MojoTestCase { ...@@ -30,7 +30,7 @@ public class ConnectorTest extends MojoTestCase {
private MessagePipeHandle mHandle; private MessagePipeHandle mHandle;
private Connector mConnector; private Connector mConnector;
private MessageWithHeader mTestMessage; private Message mTestMessage;
private RecordingMessageReceiver mReceiver; private RecordingMessageReceiver mReceiver;
private CapturingErrorHandler mErrorHandler; private CapturingErrorHandler mErrorHandler;
...@@ -77,7 +77,7 @@ public class ConnectorTest extends MojoTestCase { ...@@ -77,7 +77,7 @@ public class ConnectorTest extends MojoTestCase {
MessagePipeHandle.ReadFlags.NONE); MessagePipeHandle.ReadFlags.NONE);
assertEquals(MojoResult.OK, result.getMojoResult()); assertEquals(MojoResult.OK, result.getMojoResult());
assertEquals(DATA_LENGTH, result.getMessageSize()); assertEquals(DATA_LENGTH, result.getMessageSize());
assertEquals(mTestMessage.getMessage().buffer, received); assertEquals(mTestMessage.getData(), received);
} }
/** /**
...@@ -85,14 +85,14 @@ public class ConnectorTest extends MojoTestCase { ...@@ -85,14 +85,14 @@ public class ConnectorTest extends MojoTestCase {
*/ */
@SmallTest @SmallTest
public void testReceivingMessage() { public void testReceivingMessage() {
mHandle.writeMessage(mTestMessage.getMessage().buffer, new ArrayList<Handle>(), mHandle.writeMessage(mTestMessage.getData(), new ArrayList<Handle>(),
MessagePipeHandle.WriteFlags.NONE); MessagePipeHandle.WriteFlags.NONE);
nativeRunLoop(RUN_LOOP_TIMEOUT_MS); nativeRunLoop(RUN_LOOP_TIMEOUT_MS);
assertNull(mErrorHandler.getLastMojoException()); assertNull(mErrorHandler.getLastMojoException());
assertEquals(1, mReceiver.messages.size()); assertEquals(1, mReceiver.messages.size());
MessageWithHeader received = mReceiver.messages.get(0); Message received = mReceiver.messages.get(0);
assertEquals(0, received.getMessage().handles.size()); assertEquals(0, received.getHandles().size());
assertEquals(mTestMessage.getMessage().buffer, received.getMessage().buffer); assertEquals(mTestMessage.getData(), received.getData());
} }
/** /**
......
...@@ -23,9 +23,9 @@ import java.util.Arrays; ...@@ -23,9 +23,9 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
* Testing {@link MessageWithHeader}. * Testing {@link Connector#readAndDispatchMessage}.
*/ */
public class MessageWithHeaderTest extends MojoTestCase { public class ReadAndDispatchMessageTest extends MojoTestCase {
private static final int DATA_SIZE = 1024; private static final int DATA_SIZE = 1024;
...@@ -42,7 +42,7 @@ public class MessageWithHeaderTest extends MojoTestCase { ...@@ -42,7 +42,7 @@ public class MessageWithHeaderTest extends MojoTestCase {
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
Core core = CoreImpl.getInstance(); Core core = CoreImpl.getInstance();
mData = BindingsTestUtils.newRandomMessageWithHeader(DATA_SIZE).getMessage().buffer; mData = BindingsTestUtils.newRandomMessageWithHeader(DATA_SIZE).getData();
mMessageReceiver = new RecordingMessageReceiver(); mMessageReceiver = new RecordingMessageReceiver();
mHandles = core.createMessagePipe(new MessagePipeHandle.CreateOptions()); mHandles = core.createMessagePipe(new MessagePipeHandle.CreateOptions());
Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> datapipe = core.createDataPipe(null); Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> datapipe = core.createDataPipe(null);
...@@ -63,43 +63,43 @@ public class MessageWithHeaderTest extends MojoTestCase { ...@@ -63,43 +63,43 @@ public class MessageWithHeaderTest extends MojoTestCase {
} }
/** /**
* Testing {@link MessageWithHeader#readAndDispatchMessage(MessagePipeHandle, MessageReceiver)} * Testing {@link Connector#readAndDispatchMessage(MessagePipeHandle, MessageReceiver)}
*/ */
@SmallTest @SmallTest
public void testReadAndDispatchMessage() { public void testReadAndDispatchMessage() {
mHandles.first.writeMessage(mData, mHandlesToSend, MessagePipeHandle.WriteFlags.NONE); mHandles.first.writeMessage(mData, mHandlesToSend, MessagePipeHandle.WriteFlags.NONE);
assertEquals(MojoResult.OK, assertEquals(MojoResult.OK,
MessageWithHeader.readAndDispatchMessage(mHandles.second, mMessageReceiver)); Connector.readAndDispatchMessage(mHandles.second, mMessageReceiver));
assertEquals(1, mMessageReceiver.messages.size()); assertEquals(1, mMessageReceiver.messages.size());
MessageWithHeader message = mMessageReceiver.messages.get(0); Message message = mMessageReceiver.messages.get(0);
mHandlesToClose.addAll(message.getMessage().handles); mHandlesToClose.addAll(message.getHandles());
assertEquals(mData, message.getMessage().buffer); assertEquals(mData, message.getData());
assertEquals(2, message.getMessage().handles.size()); assertEquals(2, message.getHandles().size());
for (Handle handle : message.getMessage().handles) { for (Handle handle : message.getHandles()) {
assertTrue(handle.isValid()); assertTrue(handle.isValid());
} }
} }
/** /**
* Testing {@link MessageWithHeader#readAndDispatchMessage(MessagePipeHandle, MessageReceiver)} * Testing {@link Connector#readAndDispatchMessage(MessagePipeHandle, MessageReceiver)}
* with no message available. * with no message available.
*/ */
@SmallTest @SmallTest
public void testReadAndDispatchMessageOnEmptyHandle() { public void testReadAndDispatchMessageOnEmptyHandle() {
assertEquals(MojoResult.SHOULD_WAIT, assertEquals(MojoResult.SHOULD_WAIT,
MessageWithHeader.readAndDispatchMessage(mHandles.second, mMessageReceiver)); Connector.readAndDispatchMessage(mHandles.second, mMessageReceiver));
assertEquals(0, mMessageReceiver.messages.size()); assertEquals(0, mMessageReceiver.messages.size());
} }
/** /**
* Testing {@link MessageWithHeader#readAndDispatchMessage(MessagePipeHandle, MessageReceiver)} * Testing {@link Connector#readAndDispatchMessage(MessagePipeHandle, MessageReceiver)}
* on closed handle. * on closed handle.
*/ */
@SmallTest @SmallTest
public void testReadAndDispatchMessageOnClosedHandle() { public void testReadAndDispatchMessageOnClosedHandle() {
mHandles.first.close(); mHandles.first.close();
try { try {
MessageWithHeader.readAndDispatchMessage(mHandles.second, mMessageReceiver); Connector.readAndDispatchMessage(mHandles.second, mMessageReceiver);
fail("MojoException should have been thrown"); fail("MojoException should have been thrown");
} catch (MojoException expected) { } catch (MojoException expected) {
assertEquals(MojoResult.FAILED_PRECONDITION, expected.getMojoResult()); assertEquals(MojoResult.FAILED_PRECONDITION, expected.getMojoResult());
......
...@@ -61,16 +61,14 @@ public class RouterTest extends MojoTestCase { ...@@ -61,16 +61,14 @@ public class RouterTest extends MojoTestCase {
MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG, 0); MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG, 0);
Encoder encoder = new Encoder(CoreImpl.getInstance(), header.getSize()); Encoder encoder = new Encoder(CoreImpl.getInstance(), header.getSize());
header.encode(encoder); header.encode(encoder);
MessageWithHeader headerMessage = new MessageWithHeader(encoder.getMessage()); mRouter.acceptWithResponder(encoder.getMessage(), mReceiver);
mRouter.acceptWithResponder(headerMessage, mReceiver);
ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(header.getSize()); ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(header.getSize());
MessagePipeHandle.ReadMessageResult result = mHandle.readMessage(receiveBuffer, 0, MessagePipeHandle.ReadMessageResult result = mHandle.readMessage(receiveBuffer, 0,
MessagePipeHandle.ReadFlags.NONE); MessagePipeHandle.ReadFlags.NONE);
assertEquals(MojoResult.OK, result.getMojoResult()); assertEquals(MojoResult.OK, result.getMojoResult());
MessageHeader receivedHeader = new MessageWithHeader( MessageHeader receivedHeader = new SimpleMessage(
new Message(receiveBuffer, new ArrayList<Handle>())) receiveBuffer, new ArrayList<Handle>()).asMojoMessage().getHeader();
.getHeader();
assertEquals(header.getType(), receivedHeader.getType()); assertEquals(header.getType(), receivedHeader.getType());
assertEquals(header.getFlags(), receivedHeader.getFlags()); assertEquals(header.getFlags(), receivedHeader.getFlags());
...@@ -82,15 +80,15 @@ public class RouterTest extends MojoTestCase { ...@@ -82,15 +80,15 @@ public class RouterTest extends MojoTestCase {
encoder = new Encoder(CoreImpl.getInstance(), header.getSize()); encoder = new Encoder(CoreImpl.getInstance(), header.getSize());
responseHeader.encode(encoder); responseHeader.encode(encoder);
Message responseMessage = encoder.getMessage(); Message responseMessage = encoder.getMessage();
mHandle.writeMessage(responseMessage.buffer, new ArrayList<Handle>(), mHandle.writeMessage(responseMessage.getData(), new ArrayList<Handle>(),
MessagePipeHandle.WriteFlags.NONE); MessagePipeHandle.WriteFlags.NONE);
nativeRunLoop(RUN_LOOP_TIMEOUT_MS); nativeRunLoop(RUN_LOOP_TIMEOUT_MS);
assertEquals(1, mReceiver.messages.size()); assertEquals(1, mReceiver.messages.size());
MessageWithHeader receivedResponseMessage = mReceiver.messages.get(0); MessageWithHeader receivedResponseMessage = mReceiver.messages.get(0).asMojoMessage();
assertEquals(MessageHeader.MESSAGE_IS_RESPONSE_FLAG, assertEquals(MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
receivedResponseMessage.getHeader().getFlags()); receivedResponseMessage.getHeader().getFlags());
assertEquals(responseMessage.buffer, receivedResponseMessage.getMessage().buffer); assertEquals(responseMessage.getData(), receivedResponseMessage.getData());
} }
/** /**
...@@ -108,27 +106,27 @@ public class RouterTest extends MojoTestCase { ...@@ -108,27 +106,27 @@ public class RouterTest extends MojoTestCase {
Encoder encoder = new Encoder(CoreImpl.getInstance(), header.getSize()); Encoder encoder = new Encoder(CoreImpl.getInstance(), header.getSize());
header.encode(encoder); header.encode(encoder);
Message headerMessage = encoder.getMessage(); Message headerMessage = encoder.getMessage();
mHandle.writeMessage(headerMessage.buffer, new ArrayList<Handle>(), mHandle.writeMessage(headerMessage.getData(), new ArrayList<Handle>(),
MessagePipeHandle.WriteFlags.NONE); MessagePipeHandle.WriteFlags.NONE);
nativeRunLoop(RUN_LOOP_TIMEOUT_MS); nativeRunLoop(RUN_LOOP_TIMEOUT_MS);
assertEquals(1, mReceiver.messagesWithReceivers.size()); assertEquals(1, mReceiver.messagesWithReceivers.size());
Pair<MessageWithHeader, MessageReceiver> receivedMessage = Pair<Message, MessageReceiver> receivedMessage =
mReceiver.messagesWithReceivers.get(0); mReceiver.messagesWithReceivers.get(0);
assertEquals(headerMessage.buffer, receivedMessage.first.getMessage().buffer); assertEquals(headerMessage.getData(), receivedMessage.first.getData());
// Sending the response. // Sending the response.
MessageHeader responseHeader = new MessageHeader(responseMessageType, MessageHeader responseHeader = new MessageHeader(responseMessageType,
MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG, requestId); MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG, requestId);
encoder = new Encoder(CoreImpl.getInstance(), header.getSize()); encoder = new Encoder(CoreImpl.getInstance(), header.getSize());
responseHeader.encode(encoder); responseHeader.encode(encoder);
MessageWithHeader responseHeaderMessage = new MessageWithHeader(encoder.getMessage()); Message message = encoder.getMessage();
receivedMessage.second.accept(responseHeaderMessage); receivedMessage.second.accept(message);
ByteBuffer receivedResponseMessage = ByteBuffer.allocateDirect(responseHeader.getSize()); ByteBuffer receivedResponseMessage = ByteBuffer.allocateDirect(responseHeader.getSize());
MessagePipeHandle.ReadMessageResult result = mHandle.readMessage(receivedResponseMessage, 0, MessagePipeHandle.ReadMessageResult result = mHandle.readMessage(receivedResponseMessage, 0,
MessagePipeHandle.ReadFlags.NONE); MessagePipeHandle.ReadFlags.NONE);
assertEquals(MojoResult.OK, result.getMojoResult()); assertEquals(MojoResult.OK, result.getMojoResult());
assertEquals(responseHeaderMessage.getMessage().buffer, receivedResponseMessage); assertEquals(message.getData(), receivedResponseMessage);
} }
} }
...@@ -46,6 +46,7 @@ android_library("bindings") { ...@@ -46,6 +46,7 @@ android_library("bindings") {
"bindings/src/org/chromium/mojo/bindings/Router.java", "bindings/src/org/chromium/mojo/bindings/Router.java",
"bindings/src/org/chromium/mojo/bindings/SerializationException.java", "bindings/src/org/chromium/mojo/bindings/SerializationException.java",
"bindings/src/org/chromium/mojo/bindings/SideEffectFreeCloseable.java", "bindings/src/org/chromium/mojo/bindings/SideEffectFreeCloseable.java",
"bindings/src/org/chromium/mojo/bindings/SimpleMessage.java",
"bindings/src/org/chromium/mojo/bindings/Struct.java", "bindings/src/org/chromium/mojo/bindings/Struct.java",
] ]
......
...@@ -54,18 +54,18 @@ class AutoCloseableRouter implements Router { ...@@ -54,18 +54,18 @@ class AutoCloseableRouter implements Router {
} }
/** /**
* @see MessageReceiver#accept(MessageWithHeader) * @see MessageReceiver#accept(Message)
*/ */
@Override @Override
public boolean accept(MessageWithHeader message) { public boolean accept(Message message) {
return mRouter.accept(message); return mRouter.accept(message);
} }
/** /**
* @see MessageReceiverWithResponder#acceptWithResponder(MessageWithHeader, MessageReceiver) * @see MessageReceiverWithResponder#acceptWithResponder(Message, MessageReceiver)
*/ */
@Override @Override
public boolean acceptWithResponder(MessageWithHeader message, MessageReceiver responder) { public boolean acceptWithResponder(Message message, MessageReceiver responder) {
return mRouter.acceptWithResponder(message, responder); return mRouter.acceptWithResponder(message, responder);
} }
......
...@@ -7,9 +7,12 @@ package org.chromium.mojo.bindings; ...@@ -7,9 +7,12 @@ package org.chromium.mojo.bindings;
import org.chromium.mojo.system.AsyncWaiter; import org.chromium.mojo.system.AsyncWaiter;
import org.chromium.mojo.system.Core; import org.chromium.mojo.system.Core;
import org.chromium.mojo.system.MessagePipeHandle; import org.chromium.mojo.system.MessagePipeHandle;
import org.chromium.mojo.system.MessagePipeHandle.ReadMessageResult;
import org.chromium.mojo.system.MojoException; import org.chromium.mojo.system.MojoException;
import org.chromium.mojo.system.MojoResult; import org.chromium.mojo.system.MojoResult;
import java.nio.ByteBuffer;
/** /**
* A {@link Connector} owns a {@link MessagePipeHandle} and will send any received messages to the * A {@link Connector} owns a {@link MessagePipeHandle} and will send any received messages to the
* registered {@link MessageReceiver}. It also acts as a {@link MessageReceiver} and will send any * registered {@link MessageReceiver}. It also acts as a {@link MessageReceiver} and will send any
...@@ -92,13 +95,13 @@ public class Connector implements MessageReceiver, HandleOwner<MessagePipeHandle ...@@ -92,13 +95,13 @@ public class Connector implements MessageReceiver, HandleOwner<MessagePipeHandle
} }
/** /**
* @see MessageReceiver#accept(MessageWithHeader) * @see MessageReceiver#accept(Message)
*/ */
@Override @Override
public boolean accept(MessageWithHeader message) { public boolean accept(Message message) {
try { try {
mMessagePipeHandle.writeMessage(message.getMessage().buffer, mMessagePipeHandle.writeMessage(message.getData(),
message.getMessage().handles, MessagePipeHandle.WriteFlags.NONE); message.getHandles(), MessagePipeHandle.WriteFlags.NONE);
return true; return true;
} catch (MojoException e) { } catch (MojoException e) {
onError(e); onError(e);
...@@ -194,8 +197,7 @@ public class Connector implements MessageReceiver, HandleOwner<MessagePipeHandle ...@@ -194,8 +197,7 @@ public class Connector implements MessageReceiver, HandleOwner<MessagePipeHandle
int result; int result;
do { do {
try { try {
result = MessageWithHeader.readAndDispatchMessage(mMessagePipeHandle, result = readAndDispatchMessage(mMessagePipeHandle, mIncomingMessageReceiver);
mIncomingMessageReceiver);
} catch (MojoException e) { } catch (MojoException e) {
onError(e); onError(e);
return; return;
...@@ -214,4 +216,26 @@ public class Connector implements MessageReceiver, HandleOwner<MessagePipeHandle ...@@ -214,4 +216,26 @@ public class Connector implements MessageReceiver, HandleOwner<MessagePipeHandle
mCancellable = null; mCancellable = null;
} }
} }
/**
* Read a message, and pass it to the given |MessageReceiver| if not null. If the
* |MessageReceiver| is null, the message is lost.
*
* @param receiver The {@link MessageReceiver} that will receive the read {@link Message}. Can
* be <code>null</code>, in which case the message is discarded.
*/
static int readAndDispatchMessage(MessagePipeHandle handle, MessageReceiver receiver) {
// TODO(qsr) Allow usage of a pool of pre-allocated buffer for performance.
ReadMessageResult result = handle.readMessage(null, 0, MessagePipeHandle.ReadFlags.NONE);
if (result.getMojoResult() != MojoResult.RESOURCE_EXHAUSTED) {
return result.getMojoResult();
}
ByteBuffer buffer = ByteBuffer.allocateDirect(result.getMessageSize());
result = handle.readMessage(buffer, result.getHandlesCount(),
MessagePipeHandle.ReadFlags.NONE);
if (receiver != null && result.getMojoResult() == MojoResult.OK) {
receiver.accept(new SimpleMessage(buffer, result.getHandles()));
}
return result.getMojoResult();
}
} }
...@@ -103,12 +103,12 @@ public class Decoder { ...@@ -103,12 +103,12 @@ public class Decoder {
* @param message The message to decode. * @param message The message to decode.
*/ */
public Decoder(Message message) { public Decoder(Message message) {
this(message, new Validator(message.buffer.limit(), message.handles.size()), 0); this(message, new Validator(message.getData().limit(), message.getHandles().size()), 0);
} }
private Decoder(Message message, Validator validator, int baseOffset) { private Decoder(Message message, Validator validator, int baseOffset) {
mMessage = message; mMessage = message;
mMessage.buffer.order(ByteOrder.nativeOrder()); mMessage.getData().order(ByteOrder.nativeOrder());
mBaseOffset = baseOffset; mBaseOffset = baseOffset;
mValidator = validator; mValidator = validator;
} }
...@@ -146,7 +146,7 @@ public class Decoder { ...@@ -146,7 +146,7 @@ public class Decoder {
* Deserializes a byte at the given offset. * Deserializes a byte at the given offset.
*/ */
public byte readByte(int offset) { public byte readByte(int offset) {
return mMessage.buffer.get(mBaseOffset + offset); return mMessage.getData().get(mBaseOffset + offset);
} }
/** /**
...@@ -160,35 +160,35 @@ public class Decoder { ...@@ -160,35 +160,35 @@ public class Decoder {
* Deserializes a short at the given offset. * Deserializes a short at the given offset.
*/ */
public short readShort(int offset) { public short readShort(int offset) {
return mMessage.buffer.getShort(mBaseOffset + offset); return mMessage.getData().getShort(mBaseOffset + offset);
} }
/** /**
* Deserializes an int at the given offset. * Deserializes an int at the given offset.
*/ */
public int readInt(int offset) { public int readInt(int offset) {
return mMessage.buffer.getInt(mBaseOffset + offset); return mMessage.getData().getInt(mBaseOffset + offset);
} }
/** /**
* Deserializes a float at the given offset. * Deserializes a float at the given offset.
*/ */
public float readFloat(int offset) { public float readFloat(int offset) {
return mMessage.buffer.getFloat(mBaseOffset + offset); return mMessage.getData().getFloat(mBaseOffset + offset);
} }
/** /**
* Deserializes a long at the given offset. * Deserializes a long at the given offset.
*/ */
public long readLong(int offset) { public long readLong(int offset) {
return mMessage.buffer.getLong(mBaseOffset + offset); return mMessage.getData().getLong(mBaseOffset + offset);
} }
/** /**
* Deserializes a double at the given offset. * Deserializes a double at the given offset.
*/ */
public double readDouble(int offset) { public double readDouble(int offset) {
return mMessage.buffer.getDouble(mBaseOffset + offset); return mMessage.getData().getDouble(mBaseOffset + offset);
} }
/** /**
...@@ -221,8 +221,8 @@ public class Decoder { ...@@ -221,8 +221,8 @@ public class Decoder {
} }
DataHeader si = d.readArrayDataHeader(expectedLength); DataHeader si = d.readArrayDataHeader(expectedLength);
byte[] bytes = new byte[si.numFields + 7 / BindingsHelper.ALIGNMENT]; byte[] bytes = new byte[si.numFields + 7 / BindingsHelper.ALIGNMENT];
d.mMessage.buffer.position(d.mBaseOffset + DataHeader.HEADER_SIZE); d.mMessage.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE);
d.mMessage.buffer.get(bytes); d.mMessage.getData().get(bytes);
boolean[] result = new boolean[si.numFields]; boolean[] result = new boolean[si.numFields];
for (int i = 0; i < bytes.length; ++i) { for (int i = 0; i < bytes.length; ++i) {
for (int j = 0; j < BindingsHelper.ALIGNMENT; ++j) { for (int j = 0; j < BindingsHelper.ALIGNMENT; ++j) {
...@@ -245,8 +245,8 @@ public class Decoder { ...@@ -245,8 +245,8 @@ public class Decoder {
} }
DataHeader si = d.readArrayDataHeader(expectedLength); DataHeader si = d.readArrayDataHeader(expectedLength);
byte[] result = new byte[si.numFields]; byte[] result = new byte[si.numFields];
d.mMessage.buffer.position(d.mBaseOffset + DataHeader.HEADER_SIZE); d.mMessage.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE);
d.mMessage.buffer.get(result); d.mMessage.getData().get(result);
return result; return result;
} }
...@@ -260,8 +260,8 @@ public class Decoder { ...@@ -260,8 +260,8 @@ public class Decoder {
} }
DataHeader si = d.readArrayDataHeader(expectedLength); DataHeader si = d.readArrayDataHeader(expectedLength);
short[] result = new short[si.numFields]; short[] result = new short[si.numFields];
d.mMessage.buffer.position(d.mBaseOffset + DataHeader.HEADER_SIZE); d.mMessage.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE);
d.mMessage.buffer.asShortBuffer().get(result); d.mMessage.getData().asShortBuffer().get(result);
return result; return result;
} }
...@@ -275,8 +275,8 @@ public class Decoder { ...@@ -275,8 +275,8 @@ public class Decoder {
} }
DataHeader si = d.readArrayDataHeader(expectedLength); DataHeader si = d.readArrayDataHeader(expectedLength);
int[] result = new int[si.numFields]; int[] result = new int[si.numFields];
d.mMessage.buffer.position(d.mBaseOffset + DataHeader.HEADER_SIZE); d.mMessage.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE);
d.mMessage.buffer.asIntBuffer().get(result); d.mMessage.getData().asIntBuffer().get(result);
return result; return result;
} }
...@@ -290,8 +290,8 @@ public class Decoder { ...@@ -290,8 +290,8 @@ public class Decoder {
} }
DataHeader si = d.readArrayDataHeader(expectedLength); DataHeader si = d.readArrayDataHeader(expectedLength);
float[] result = new float[si.numFields]; float[] result = new float[si.numFields];
d.mMessage.buffer.position(d.mBaseOffset + DataHeader.HEADER_SIZE); d.mMessage.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE);
d.mMessage.buffer.asFloatBuffer().get(result); d.mMessage.getData().asFloatBuffer().get(result);
return result; return result;
} }
...@@ -305,8 +305,8 @@ public class Decoder { ...@@ -305,8 +305,8 @@ public class Decoder {
} }
DataHeader si = d.readArrayDataHeader(expectedLength); DataHeader si = d.readArrayDataHeader(expectedLength);
long[] result = new long[si.numFields]; long[] result = new long[si.numFields];
d.mMessage.buffer.position(d.mBaseOffset + DataHeader.HEADER_SIZE); d.mMessage.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE);
d.mMessage.buffer.asLongBuffer().get(result); d.mMessage.getData().asLongBuffer().get(result);
return result; return result;
} }
...@@ -320,8 +320,8 @@ public class Decoder { ...@@ -320,8 +320,8 @@ public class Decoder {
} }
DataHeader si = d.readArrayDataHeader(expectedLength); DataHeader si = d.readArrayDataHeader(expectedLength);
double[] result = new double[si.numFields]; double[] result = new double[si.numFields];
d.mMessage.buffer.position(d.mBaseOffset + DataHeader.HEADER_SIZE); d.mMessage.getData().position(d.mBaseOffset + DataHeader.HEADER_SIZE);
d.mMessage.buffer.asDoubleBuffer().get(result); d.mMessage.getData().asDoubleBuffer().get(result);
return result; return result;
} }
...@@ -338,7 +338,7 @@ public class Decoder { ...@@ -338,7 +338,7 @@ public class Decoder {
return InvalidHandle.INSTANCE; return InvalidHandle.INSTANCE;
} }
mValidator.claimHandle(index); mValidator.claimHandle(index);
return mMessage.handles.get(index); return mMessage.getHandles().get(index);
} }
/** /**
...@@ -579,5 +579,4 @@ public class Decoder { ...@@ -579,5 +579,4 @@ public class Decoder {
private Decoder getDecoderAtPosition(int offset) { private Decoder getDecoderAtPosition(int offset) {
return new Decoder(mMessage, mValidator, offset); return new Decoder(mMessage, mValidator, offset);
} }
} }
...@@ -112,7 +112,7 @@ public class Encoder { ...@@ -112,7 +112,7 @@ public class Encoder {
public Message getMessage() { public Message getMessage() {
mEncoderState.byteBuffer.position(0); mEncoderState.byteBuffer.position(0);
mEncoderState.byteBuffer.limit(mEncoderState.dataEnd); mEncoderState.byteBuffer.limit(mEncoderState.dataEnd);
return new Message(mEncoderState.byteBuffer, mEncoderState.handles); return new SimpleMessage(mEncoderState.byteBuffer, mEncoderState.handles);
} }
/** /**
......
...@@ -11,29 +11,25 @@ import java.nio.ByteBuffer; ...@@ -11,29 +11,25 @@ import java.nio.ByteBuffer;
import java.util.List; import java.util.List;
/** /**
* A raw message to be sent/received from a {@link MessagePipeHandle}. * A raw message to be sent/received from a {@link MessagePipeHandle}. Note that this can contain
* any data, not necessarily a Mojo message with a proper header. See also {@link MessageWithHeader}
* and {@link SimpleMessage}.
*/ */
public final class Message { public interface Message {
/** /**
* The data of the message. * The data part of the message.
*/ */
public final ByteBuffer buffer; public ByteBuffer getData();
/** /**
* The handles of the message. * The handles part of the message.
*/ */
public final List<? extends Handle> handles; public List<? extends Handle> getHandles();
/** /**
* Constructor. * Returns the message considered as a message with a header.
*
* @param buffer The buffer containing the bytes to send. This must be a direct buffer.
* @param handles The list of handles to send.
*/ */
public Message(ByteBuffer buffer, List<? extends Handle> handles) { public MessageWithHeader asMojoMessage();
assert buffer.isDirect();
this.buffer = buffer;
this.handles = handles;
}
} }
...@@ -15,7 +15,7 @@ public interface MessageReceiver extends Closeable { ...@@ -15,7 +15,7 @@ public interface MessageReceiver extends Closeable {
* Receive a {@link MessageWithHeader}. The {@link MessageReceiver} is allowed to mutable the * Receive a {@link MessageWithHeader}. The {@link MessageReceiver} is allowed to mutable the
* message. Returns |true| if the message has been handled, |false| otherwise. * message. Returns |true| if the message has been handled, |false| otherwise.
*/ */
boolean accept(MessageWithHeader message); boolean accept(Message message);
/** /**
* @see java.io.Closeable#close() * @see java.io.Closeable#close()
......
...@@ -11,11 +11,11 @@ package org.chromium.mojo.bindings; ...@@ -11,11 +11,11 @@ package org.chromium.mojo.bindings;
public interface MessageReceiverWithResponder extends MessageReceiver { public interface MessageReceiverWithResponder extends MessageReceiver {
/** /**
* A variant on {@link #accept(MessageWithHeader)} that registers a {@link MessageReceiver} * A variant on {@link #accept(Message)} that registers a {@link MessageReceiver}
* (known as the responder) to handle the response message generated from the given message. The * (known as the responder) to handle the response message generated from the given message. The
* responder's {@link #accept(MessageWithHeader)} method may be called as part of the call to * responder's {@link #accept(Message)} method may be called as part of the call to
* {@link #acceptWithResponder(MessageWithHeader, MessageReceiver)}, or some time after its * {@link #acceptWithResponder(Message, MessageReceiver)}, or some time after its
* return. * return.
*/ */
boolean acceptWithResponder(MessageWithHeader message, MessageReceiver responder); boolean acceptWithResponder(Message message, MessageReceiver responder);
} }
...@@ -4,18 +4,17 @@ ...@@ -4,18 +4,17 @@
package org.chromium.mojo.bindings; package org.chromium.mojo.bindings;
import org.chromium.mojo.system.MessagePipeHandle; import org.chromium.mojo.system.Handle;
import org.chromium.mojo.system.MessagePipeHandle.ReadMessageResult;
import org.chromium.mojo.system.MojoResult;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.List;
/** /**
* Represents a {@link Message} which contains a {@link MessageHeader}. Deals with parsing the * Represents a {@link Message} which contains a {@link MessageHeader}. Deals with parsing the
* {@link MessageHeader} for a message. * {@link MessageHeader} for a message.
*/ */
public class MessageWithHeader { public class MessageWithHeader implements Message {
private final Message mBaseMessage; private final Message mBaseMessage;
private final MessageHeader mHeader; private final MessageHeader mHeader;
...@@ -35,10 +34,34 @@ public class MessageWithHeader { ...@@ -35,10 +34,34 @@ public class MessageWithHeader {
* Reinterpret the given |message| as a message with a header. The |message| must contain a * Reinterpret the given |message| as a message with a header. The |message| must contain a
* header as the start of it's raw data, which will be parsed by this constructor. * header as the start of it's raw data, which will be parsed by this constructor.
*/ */
public MessageWithHeader(Message baseMessage) { MessageWithHeader(Message baseMessage) {
this(baseMessage, new org.chromium.mojo.bindings.MessageHeader(baseMessage)); this(baseMessage, new org.chromium.mojo.bindings.MessageHeader(baseMessage));
} }
/**
* @see Message#getData()
*/
@Override
public ByteBuffer getData() {
return mBaseMessage.getData();
}
/**
* @see Message#getHandles()
*/
@Override
public List<? extends Handle> getHandles() {
return mBaseMessage.getHandles();
}
/**
* @see Message#asMojoMessage()
*/
@Override
public MessageWithHeader asMojoMessage() {
return this;
}
/** /**
* Returns the header of the given message. This will throw a {@link DeserializationException} * Returns the header of the given message. This will throw a {@link DeserializationException}
* if the start of the message is not a valid header. * if the start of the message is not a valid header.
...@@ -52,47 +75,19 @@ public class MessageWithHeader { ...@@ -52,47 +75,19 @@ public class MessageWithHeader {
*/ */
public Message getPayload() { public Message getPayload() {
if (mPayload == null) { if (mPayload == null) {
ByteBuffer truncatedBuffer = ((ByteBuffer) mBaseMessage.buffer.position( ByteBuffer truncatedBuffer = ((ByteBuffer) mBaseMessage.getData().position(
getHeader().getSize())).slice(); getHeader().getSize())).slice();
truncatedBuffer.order(ByteOrder.nativeOrder()); truncatedBuffer.order(ByteOrder.nativeOrder());
mPayload = new Message(truncatedBuffer, mBaseMessage.handles); mPayload = new SimpleMessage(truncatedBuffer, mBaseMessage.getHandles());
} }
return mPayload; return mPayload;
} }
/**
* Returns the raw message.
*/
public Message getMessage() {
return mBaseMessage;
}
/** /**
* Set the request identifier on the message. * Set the request identifier on the message.
*/ */
void setRequestId(long requestId) { void setRequestId(long requestId) {
mHeader.setRequestId(mBaseMessage.buffer, requestId); mHeader.setRequestId(mBaseMessage.getData(), requestId);
} }
/**
* Read a message, and pass it to the given |MessageReceiver| if not null. If the
* |MessageReceiver| is null, the message is lost.
*
* @param receiver The {@link MessageReceiver} that will receive the read {@link Message}. Can
* be <code>null</code>, in which case the message is discarded.
*/
public static int readAndDispatchMessage(MessagePipeHandle handle, MessageReceiver receiver) {
// TODO(qsr) Allow usage of a pool of pre-allocated buffer for performance.
ReadMessageResult result = handle.readMessage(null, 0, MessagePipeHandle.ReadFlags.NONE);
if (result.getMojoResult() != MojoResult.RESOURCE_EXHAUSTED) {
return result.getMojoResult();
}
ByteBuffer buffer = ByteBuffer.allocateDirect(result.getMessageSize());
result = handle.readMessage(buffer, result.getHandlesCount(),
MessagePipeHandle.ReadFlags.NONE);
if (receiver != null && result.getMojoResult() == MojoResult.OK) {
receiver.accept(new MessageWithHeader(new Message(buffer, result.getHandles())));
}
return result.getMojoResult();
}
} }
...@@ -21,10 +21,10 @@ public class RouterImpl implements Router { ...@@ -21,10 +21,10 @@ public class RouterImpl implements Router {
private class ResponderThunk implements MessageReceiver { private class ResponderThunk implements MessageReceiver {
/** /**
* @see MessageReceiver#accept(MessageWithHeader) * @see MessageReceiver#accept(Message)
*/ */
@Override @Override
public boolean accept(MessageWithHeader message) { public boolean accept(Message message) {
return handleIncomingMessage(message); return handleIncomingMessage(message);
} }
...@@ -97,21 +97,23 @@ public class RouterImpl implements Router { ...@@ -97,21 +97,23 @@ public class RouterImpl implements Router {
} }
/** /**
* @see MessageReceiver#accept(MessageWithHeader) * @see MessageReceiver#accept(Message)
*/ */
@Override @Override
public boolean accept(MessageWithHeader message) { public boolean accept(Message message) {
// A message without responder is directly forwarded to the connector. // A message without responder is directly forwarded to the connector.
return mConnector.accept(message); return mConnector.accept(message);
} }
/** /**
* @see MessageReceiverWithResponder#acceptWithResponder(MessageWithHeader, MessageReceiver) * @see MessageReceiverWithResponder#acceptWithResponder(Message, MessageReceiver)
*/ */
@Override @Override
public boolean acceptWithResponder(MessageWithHeader message, MessageReceiver responder) { public boolean acceptWithResponder(Message message, MessageReceiver responder) {
// The message must have a header.
MessageWithHeader messageWithHeader = message.asMojoMessage();
// Checking the message expects a response. // Checking the message expects a response.
assert message.getHeader().hasFlag(MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG); assert messageWithHeader.getHeader().hasFlag(MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG);
// Compute a request id for being able to route the response. // Compute a request id for being able to route the response.
long requestId = mNextRequestId++; long requestId = mNextRequestId++;
...@@ -122,8 +124,8 @@ public class RouterImpl implements Router { ...@@ -122,8 +124,8 @@ public class RouterImpl implements Router {
if (mResponders.containsKey(requestId)) { if (mResponders.containsKey(requestId)) {
throw new IllegalStateException("Unable to find a new request identifier."); throw new IllegalStateException("Unable to find a new request identifier.");
} }
message.setRequestId(requestId); messageWithHeader.setRequestId(requestId);
if (!mConnector.accept(message)) { if (!mConnector.accept(messageWithHeader)) {
return false; return false;
} }
// Only keep the responder is the message has been accepted. // Only keep the responder is the message has been accepted.
...@@ -158,8 +160,8 @@ public class RouterImpl implements Router { ...@@ -158,8 +160,8 @@ public class RouterImpl implements Router {
/** /**
* Receive a message from the connector. Returns |true| if the message has been handled. * Receive a message from the connector. Returns |true| if the message has been handled.
*/ */
private boolean handleIncomingMessage(MessageWithHeader message) { private boolean handleIncomingMessage(Message message) {
MessageHeader header = message.getHeader(); MessageHeader header = message.asMojoMessage().getHeader();
if (header.hasFlag(MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG)) { if (header.hasFlag(MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG)) {
if (mIncomingMessageReceiver != null) { if (mIncomingMessageReceiver != null) {
return mIncomingMessageReceiver.acceptWithResponder(message, this); return mIncomingMessageReceiver.acceptWithResponder(message, this);
......
// 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.
package org.chromium.mojo.bindings;
import org.chromium.mojo.system.Handle;
import org.chromium.mojo.system.MessagePipeHandle;
import java.nio.ByteBuffer;
import java.util.List;
/**
* A raw message to be sent/received from a {@link MessagePipeHandle}.
*/
public final class SimpleMessage implements Message {
/**
* The data of the message.
*/
private final ByteBuffer mBuffer;
/**
* The handles of the message.
*/
private final List<? extends Handle> mHandle;
/**
* This message interpreted with headers.
*/
private MessageWithHeader mWithHeader = null;
/**
* Constructor.
*
* @param buffer The buffer containing the bytes to send. This must be a direct buffer.
* @param handles The list of handles to send.
*/
public SimpleMessage(ByteBuffer buffer, List<? extends Handle> handles) {
assert buffer.isDirect();
mBuffer = buffer;
mHandle = handles;
}
/**
* @see Message#getData()
*/
@Override
public ByteBuffer getData() {
return mBuffer;
}
/**
* @see Message#getHandles()
*/
@Override
public List<? extends Handle> getHandles() {
return mHandle;
}
/**
* @see Message#asMojoMessage()
*/
@Override
public MessageWithHeader asMojoMessage() {
if (mWithHeader == null) {
mWithHeader = new MessageWithHeader(this);
}
return mWithHeader;
}
}
...@@ -93,7 +93,9 @@ public static final {{manager_class(interface, client, True)}} MANAGER = ...@@ -93,7 +93,9 @@ public static final {{manager_class(interface, client, True)}} MANAGER =
{% if (interface|has_method_with_response and with_response) or {% if (interface|has_method_with_response and with_response) or
(interface|has_method_without_response and not with_response) %} (interface|has_method_without_response and not with_response) %}
try { try {
org.chromium.mojo.bindings.MessageHeader header = message.getHeader(); org.chromium.mojo.bindings.MessageWithHeader messageWithHeader =
message.asMojoMessage();
org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
if (!header.validateHeader({{flags(with_response, True)}})) { if (!header.validateHeader({{flags(with_response, True)}})) {
return false; return false;
} }
...@@ -108,9 +110,9 @@ try { ...@@ -108,9 +110,9 @@ try {
case {{method|method_ordinal_name}}: { case {{method|method_ordinal_name}}: {
{% if method.parameters %} {% if method.parameters %}
{{request_struct|name}} data = {{request_struct|name}} data =
{{request_struct|name}}.deserialize(message.getPayload()); {{request_struct|name}}.deserialize(messageWithHeader.getPayload());
{% else %} {% else %}
{{request_struct|name}}.deserialize(message.getPayload()); {{request_struct|name}}.deserialize(messageWithHeader.getPayload());
{% endif %} {% endif %}
getImpl().{{method|name}}({{run_callback('data', method.parameters)}}{% if with_response %}{% if method.parameters %}, {% endif %}new {{response_struct|name}}ProxyToResponder(getCore(), receiver, header.getRequestId()){% endif %}); getImpl().{{method|name}}({{run_callback('data', method.parameters)}}{% if with_response %}{% if method.parameters %}, {% endif %}new {{response_struct|name}}ProxyToResponder(getCore(), receiver, header.getRequestId()){% endif %});
return true; return true;
...@@ -204,12 +206,12 @@ class {{interface|name}}_Internal { ...@@ -204,12 +206,12 @@ class {{interface|name}}_Internal {
} }
@Override @Override
public boolean accept(org.chromium.mojo.bindings.MessageWithHeader message) { public boolean accept(org.chromium.mojo.bindings.Message message) {
{{accept_body(interface, False)|indent(12)}} {{accept_body(interface, False)|indent(12)}}
} }
@Override @Override
public boolean acceptWithResponder(org.chromium.mojo.bindings.MessageWithHeader message, org.chromium.mojo.bindings.MessageReceiver receiver) { public boolean acceptWithResponder(org.chromium.mojo.bindings.Message message, org.chromium.mojo.bindings.MessageReceiver receiver) {
{{accept_body(interface, True)|indent(12)}} {{accept_body(interface, True)|indent(12)}}
} }
} }
...@@ -230,14 +232,16 @@ class {{interface|name}}_Internal { ...@@ -230,14 +232,16 @@ class {{interface|name}}_Internal {
} }
@Override @Override
public boolean accept(org.chromium.mojo.bindings.MessageWithHeader message) { public boolean accept(org.chromium.mojo.bindings.Message message) {
try { try {
org.chromium.mojo.bindings.MessageHeader header = message.getHeader(); org.chromium.mojo.bindings.MessageWithHeader messageWithHeader =
message.asMojoMessage();
org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
if (!header.validateHeader({{method|method_ordinal_name}}, if (!header.validateHeader({{method|method_ordinal_name}},
{{flags_for_method(method, False)}})) { {{flags_for_method(method, False)}})) {
return false; return false;
} }
{{response_struct|name}} response = {{response_struct|name}}.deserialize(message.getPayload()); {{response_struct|name}} response = {{response_struct|name}}.deserialize(messageWithHeader.getPayload());
mCallback.call({{run_callback('response', method.response_parameters)}}); mCallback.call({{run_callback('response', method.response_parameters)}});
return true; return true;
} catch (org.chromium.mojo.bindings.DeserializationException e) { } catch (org.chromium.mojo.bindings.DeserializationException e) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment