| Index: mojo/android/javatests/src/org/chromium/mojo/bindings/RouterTest.java
|
| diff --git a/mojo/android/javatests/src/org/chromium/mojo/bindings/RouterTest.java b/mojo/android/javatests/src/org/chromium/mojo/bindings/RouterTest.java
|
| index f976e590da3f803dbcf1b24d70bf1b3ba6417640..e6140086c2c562facb8c13735dd327f11a7c1b99 100644
|
| --- a/mojo/android/javatests/src/org/chromium/mojo/bindings/RouterTest.java
|
| +++ b/mojo/android/javatests/src/org/chromium/mojo/bindings/RouterTest.java
|
| @@ -10,6 +10,8 @@ import org.chromium.mojo.MojoTestCase;
|
| import org.chromium.mojo.bindings.BindingsTestUtils.CapturingErrorHandler;
|
| import org.chromium.mojo.bindings.BindingsTestUtils.RecordingMessageReceiverWithResponder;
|
| import org.chromium.mojo.system.Core;
|
| +import org.chromium.mojo.system.Core.HandleSignals;
|
| +import org.chromium.mojo.system.Core.WaitResult;
|
| import org.chromium.mojo.system.Handle;
|
| import org.chromium.mojo.system.MessagePipeHandle;
|
| import org.chromium.mojo.system.MojoResult;
|
| @@ -91,17 +93,16 @@ public class RouterTest extends MojoTestCase {
|
| }
|
|
|
| /**
|
| - * Testing receiving a message via the router that expected a response.
|
| + * Sends a message to the Router.
|
| + *
|
| + * @param messageIndex Used when sending multiple messages to indicate the index of this
|
| + * message.
|
| + * @param requestMessageType The message type to use in the header of the sent message.
|
| + * @param requestId The requestId to use in the header of the sent message.
|
| */
|
| - @SmallTest
|
| - public void testReceivingViaRouterWithResponse() {
|
| - final int requestMessageType = 0xdead;
|
| - final int responseMessageType = 0xbeef;
|
| - final int requestId = 0xdeadbeaf;
|
| -
|
| - // Sending a message expecting a response.
|
| - MessageHeader header = new MessageHeader(requestMessageType,
|
| - MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG, requestId);
|
| + private void sendMessageToRouter(int messageIndex, int requestMessageType, int requestId) {
|
| + MessageHeader header = new MessageHeader(
|
| + requestMessageType, MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG, requestId);
|
| Encoder encoder = new Encoder(CoreImpl.getInstance(), header.getSize());
|
| header.encode(encoder);
|
| Message headerMessage = encoder.getMessage();
|
| @@ -109,18 +110,32 @@ public class RouterTest extends MojoTestCase {
|
| MessagePipeHandle.WriteFlags.NONE);
|
| runLoopUntilIdle();
|
|
|
| - assertEquals(1, mReceiver.messagesWithReceivers.size());
|
| + assertEquals(messageIndex + 1, mReceiver.messagesWithReceivers.size());
|
| Pair<Message, MessageReceiver> receivedMessage =
|
| - mReceiver.messagesWithReceivers.get(0);
|
| + mReceiver.messagesWithReceivers.get(messageIndex);
|
| assertEquals(headerMessage.getData(), receivedMessage.first.getData());
|
| + }
|
|
|
| - // Sending the response.
|
| - MessageHeader responseHeader = new MessageHeader(responseMessageType,
|
| - MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG, requestId);
|
| - encoder = new Encoder(CoreImpl.getInstance(), header.getSize());
|
| + /**
|
| + * Sends a response message from the Router.
|
| + *
|
| + * @param messageIndex Used when sending responses to multiple messages to indicate the index
|
| + * of the message that this message is a response to.
|
| + * @param responseMessageType The message type to use in the header of the response message.
|
| + */
|
| + private void sendResponseFromRouter(int messageIndex, int responseMessageType) {
|
| + Pair<Message, MessageReceiver> receivedMessage =
|
| + mReceiver.messagesWithReceivers.get(messageIndex);
|
| +
|
| + long requestId = receivedMessage.first.asServiceMessage().getHeader().getRequestId();
|
| +
|
| + MessageHeader responseHeader = new MessageHeader(
|
| + responseMessageType, MessageHeader.MESSAGE_IS_RESPONSE_FLAG, requestId);
|
| + Encoder encoder = new Encoder(CoreImpl.getInstance(), responseHeader.getSize());
|
| responseHeader.encode(encoder);
|
| Message message = encoder.getMessage();
|
| receivedMessage.second.accept(message);
|
| +
|
| ByteBuffer receivedResponseMessage = ByteBuffer.allocateDirect(responseHeader.getSize());
|
| ResultAnd<MessagePipeHandle.ReadMessageResult> result =
|
| mHandle.readMessage(receivedResponseMessage, 0, MessagePipeHandle.ReadFlags.NONE);
|
| @@ -128,4 +143,90 @@ public class RouterTest extends MojoTestCase {
|
| assertEquals(MojoResult.OK, result.getMojoResult());
|
| assertEquals(message.getData(), receivedResponseMessage);
|
| }
|
| +
|
| + /**
|
| + * Clears {@code mReceiver.messagesWithReceivers} allowing all message receivers to be
|
| + * finalized.
|
| + * <p>
|
| + * Since there is no way to force the Garbage Collector to actually call finalize and we want to
|
| + * test the effects of the finalize() method, we explicitly call finalize() on all of the
|
| + * message receivers. We do this in a custom thread to better approximate what the JVM does.
|
| + */
|
| + private void clearAllMessageReceivers() {
|
| + Thread myFinalizerThread = new Thread() {
|
| + @Override
|
| + public void run() {
|
| + for (Pair<Message, MessageReceiver> receivedMessage :
|
| + mReceiver.messagesWithReceivers) {
|
| + RouterImpl.ResponderThunk thunk =
|
| + (RouterImpl.ResponderThunk) receivedMessage.second;
|
| + try {
|
| + thunk.finalize();
|
| + } catch (Throwable e) {
|
| + throw new RuntimeException(e);
|
| + }
|
| + }
|
| + }
|
| + };
|
| + myFinalizerThread.start();
|
| + try {
|
| + myFinalizerThread.join();
|
| + } catch (InterruptedException e) {
|
| + // ignore.
|
| + }
|
| + mReceiver.messagesWithReceivers.clear();
|
| + }
|
| +
|
| + /**
|
| + * Testing receiving a message via the router that expected a response.
|
| + */
|
| + @SmallTest
|
| + public void testReceivingViaRouterWithResponse() {
|
| + final int requestMessageType = 0xdead;
|
| + final int responseMessageType = 0xbeef;
|
| + final int requestId = 0xdeadbeaf;
|
| +
|
| + // Send a message expecting a response.
|
| + sendMessageToRouter(0, requestMessageType, requestId);
|
| +
|
| + // Sending the response.
|
| + sendResponseFromRouter(0, responseMessageType);
|
| + }
|
| +
|
| + /**
|
| + * Tests that if a callback is dropped (i.e. becomes unreachable and is finalized
|
| + * without being used), then the message pipe will be closed.
|
| + */
|
| + @SmallTest
|
| + public void testDroppingReceiverWithoutUsingIt() {
|
| + // Send 10 messages to the router without sending a response.
|
| + for (int i = 0; i < 10; i++) {
|
| + sendMessageToRouter(i, i, i);
|
| + }
|
| +
|
| + // Now send the 10 responses. This should work fine.
|
| + for (int i = 0; i < 10; i++) {
|
| + sendResponseFromRouter(i, i);
|
| + }
|
| +
|
| + // Clear all MessageRecievers so that the ResponderThunks will
|
| + // be finalized.
|
| + clearAllMessageReceivers();
|
| +
|
| + // Send another message to the router without sending a response.
|
| + sendMessageToRouter(0, 0, 0);
|
| +
|
| + // Clear the MessageReciever so that the ResponderThunk will
|
| + // be finalized. Since the RespondeThunk was never used, this
|
| + // should close the pipe.
|
| + clearAllMessageReceivers();
|
| + // The close() occurs asynchronously on this thread.
|
| + runLoopUntilIdle();
|
| +
|
| + // Confirm that the pipe was closed on the Router side.
|
| + HandleSignals closedFlag = HandleSignals.none().setPeerClosed(true);
|
| + WaitResult result = mHandle.wait(closedFlag, 0);
|
| + assertEquals(MojoResult.OK, result.getMojoResult());
|
| + assertEquals(closedFlag, result.getHandleSignalsState().getSatisfiedSignals());
|
| + }
|
| }
|
|
|