1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.mojo.bindings;
6
7import android.test.suitebuilder.annotation.SmallTest;
8
9import org.chromium.mojo.MojoTestCase;
10import org.chromium.mojo.bindings.BindingsTestUtils.CapturingErrorHandler;
11import org.chromium.mojo.bindings.BindingsTestUtils.RecordingMessageReceiverWithResponder;
12import org.chromium.mojo.system.Core;
13import org.chromium.mojo.system.Handle;
14import org.chromium.mojo.system.MessagePipeHandle;
15import org.chromium.mojo.system.MojoResult;
16import org.chromium.mojo.system.Pair;
17import org.chromium.mojo.system.impl.CoreImpl;
18
19import java.nio.ByteBuffer;
20import java.util.ArrayList;
21
22/**
23 * Testing {@link Router}
24 */
25public class RouterTest extends MojoTestCase {
26
27    private static final long RUN_LOOP_TIMEOUT_MS = 25;
28
29    private MessagePipeHandle mHandle;
30    private Router mRouter;
31    private RecordingMessageReceiverWithResponder mReceiver;
32    private CapturingErrorHandler mErrorHandler;
33
34    /**
35     * @see MojoTestCase#setUp()
36     */
37    @Override
38    protected void setUp() throws Exception {
39        super.setUp();
40        Core core = CoreImpl.getInstance();
41        Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
42        mHandle = handles.first;
43        mRouter = new RouterImpl(handles.second);
44        mReceiver = new RecordingMessageReceiverWithResponder();
45        mRouter.setIncomingMessageReceiver(mReceiver);
46        mErrorHandler = new CapturingErrorHandler();
47        mRouter.setErrorHandler(mErrorHandler);
48        mRouter.start();
49    }
50
51    /**
52     * Testing sending a message via the router that expected a response.
53     */
54    @SmallTest
55    public void testSendingToRouterWithResponse() {
56        final int requestMessageType = 0xdead;
57        final int responseMessageType = 0xbeaf;
58
59        // Sending a message expecting a response.
60        MessageHeader header = new MessageHeader(requestMessageType,
61                MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG, 0);
62        Encoder encoder = new Encoder(CoreImpl.getInstance(), header.getSize());
63        header.encode(encoder);
64        mRouter.acceptWithResponder(encoder.getMessage(), mReceiver);
65        ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(header.getSize());
66        MessagePipeHandle.ReadMessageResult result = mHandle.readMessage(receiveBuffer, 0,
67                MessagePipeHandle.ReadFlags.NONE);
68
69        assertEquals(MojoResult.OK, result.getMojoResult());
70        MessageHeader receivedHeader = new Message(
71                receiveBuffer, new ArrayList<Handle>()).asServiceMessage().getHeader();
72
73        assertEquals(header.getType(), receivedHeader.getType());
74        assertEquals(header.getFlags(), receivedHeader.getFlags());
75        assertTrue(receivedHeader.getRequestId() != 0);
76
77        // Sending the response.
78        MessageHeader responseHeader = new MessageHeader(responseMessageType,
79                MessageHeader.MESSAGE_IS_RESPONSE_FLAG, receivedHeader.getRequestId());
80        encoder = new Encoder(CoreImpl.getInstance(), header.getSize());
81        responseHeader.encode(encoder);
82        Message responseMessage = encoder.getMessage();
83        mHandle.writeMessage(responseMessage.getData(), new ArrayList<Handle>(),
84                MessagePipeHandle.WriteFlags.NONE);
85        nativeRunLoop(RUN_LOOP_TIMEOUT_MS);
86
87        assertEquals(1, mReceiver.messages.size());
88        ServiceMessage receivedResponseMessage = mReceiver.messages.get(0).asServiceMessage();
89        assertEquals(MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
90                receivedResponseMessage.getHeader().getFlags());
91        assertEquals(responseMessage.getData(), receivedResponseMessage.getData());
92    }
93
94    /**
95     * Testing receiving a message via the router that expected a response.
96     */
97    @SmallTest
98    public void testReceivingViaRouterWithResponse() {
99        final int requestMessageType = 0xdead;
100        final int responseMessageType = 0xbeef;
101        final int requestId = 0xdeadbeaf;
102
103        // Sending a message expecting a response.
104        MessageHeader header = new MessageHeader(requestMessageType,
105                MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG, requestId);
106        Encoder encoder = new Encoder(CoreImpl.getInstance(), header.getSize());
107        header.encode(encoder);
108        Message headerMessage = encoder.getMessage();
109        mHandle.writeMessage(headerMessage.getData(), new ArrayList<Handle>(),
110                MessagePipeHandle.WriteFlags.NONE);
111        nativeRunLoop(RUN_LOOP_TIMEOUT_MS);
112
113        assertEquals(1, mReceiver.messagesWithReceivers.size());
114        Pair<Message, MessageReceiver> receivedMessage =
115                mReceiver.messagesWithReceivers.get(0);
116        assertEquals(headerMessage.getData(), receivedMessage.first.getData());
117
118        // Sending the response.
119        MessageHeader responseHeader = new MessageHeader(responseMessageType,
120                MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG, requestId);
121        encoder = new Encoder(CoreImpl.getInstance(), header.getSize());
122        responseHeader.encode(encoder);
123        Message message = encoder.getMessage();
124        receivedMessage.second.accept(message);
125        ByteBuffer receivedResponseMessage = ByteBuffer.allocateDirect(responseHeader.getSize());
126        MessagePipeHandle.ReadMessageResult result = mHandle.readMessage(receivedResponseMessage, 0,
127                MessagePipeHandle.ReadFlags.NONE);
128
129        assertEquals(MojoResult.OK, result.getMojoResult());
130        assertEquals(message.getData(), receivedResponseMessage);
131    }
132}
133