1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <androidfw/InputTransport.h>
18#include <utils/Timers.h>
19#include <utils/StopWatch.h>
20#include <utils/StrongPointer.h>
21#include <gtest/gtest.h>
22#include <unistd.h>
23#include <time.h>
24#include <errno.h>
25
26#include "TestHelpers.h"
27
28namespace android {
29
30class InputChannelTest : public testing::Test {
31protected:
32    virtual void SetUp() { }
33    virtual void TearDown() { }
34};
35
36
37TEST_F(InputChannelTest, ConstructorAndDestructor_TakesOwnershipOfFileDescriptors) {
38    // Our purpose here is to verify that the input channel destructor closes the
39    // file descriptor provided to it.  One easy way is to provide it with one end
40    // of a pipe and to check for EPIPE on the other end after the channel is destroyed.
41    Pipe pipe;
42
43    sp<InputChannel> inputChannel = new InputChannel(String8("channel name"), pipe.sendFd);
44
45    EXPECT_STREQ("channel name", inputChannel->getName().string())
46            << "channel should have provided name";
47    EXPECT_EQ(pipe.sendFd, inputChannel->getFd())
48            << "channel should have provided fd";
49
50    inputChannel.clear(); // destroys input channel
51
52    EXPECT_EQ(-EPIPE, pipe.readSignal())
53            << "channel should have closed fd when destroyed";
54
55    // clean up fds of Pipe endpoints that were closed so we don't try to close them again
56    pipe.sendFd = -1;
57}
58
59TEST_F(InputChannelTest, OpenInputChannelPair_ReturnsAPairOfConnectedChannels) {
60    sp<InputChannel> serverChannel, clientChannel;
61
62    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
63            serverChannel, clientChannel);
64
65    ASSERT_EQ(OK, result)
66            << "should have successfully opened a channel pair";
67
68    // Name
69    EXPECT_STREQ("channel name (server)", serverChannel->getName().string())
70            << "server channel should have suffixed name";
71    EXPECT_STREQ("channel name (client)", clientChannel->getName().string())
72            << "client channel should have suffixed name";
73
74    // Server->Client communication
75    InputMessage serverMsg;
76    memset(&serverMsg, 0, sizeof(InputMessage));
77    serverMsg.header.type = InputMessage::TYPE_KEY;
78    serverMsg.body.key.action = AKEY_EVENT_ACTION_DOWN;
79    EXPECT_EQ(OK, serverChannel->sendMessage(&serverMsg))
80            << "server channel should be able to send message to client channel";
81
82    InputMessage clientMsg;
83    EXPECT_EQ(OK, clientChannel->receiveMessage(&clientMsg))
84            << "client channel should be able to receive message from server channel";
85    EXPECT_EQ(serverMsg.header.type, clientMsg.header.type)
86            << "client channel should receive the correct message from server channel";
87    EXPECT_EQ(serverMsg.body.key.action, clientMsg.body.key.action)
88            << "client channel should receive the correct message from server channel";
89
90    // Client->Server communication
91    InputMessage clientReply;
92    memset(&clientReply, 0, sizeof(InputMessage));
93    clientReply.header.type = InputMessage::TYPE_FINISHED;
94    clientReply.body.finished.seq = 0x11223344;
95    clientReply.body.finished.handled = true;
96    EXPECT_EQ(OK, clientChannel->sendMessage(&clientReply))
97            << "client channel should be able to send message to server channel";
98
99    InputMessage serverReply;
100    EXPECT_EQ(OK, serverChannel->receiveMessage(&serverReply))
101            << "server channel should be able to receive message from client channel";
102    EXPECT_EQ(clientReply.header.type, serverReply.header.type)
103            << "server channel should receive the correct message from client channel";
104    EXPECT_EQ(clientReply.body.finished.seq, serverReply.body.finished.seq)
105            << "server channel should receive the correct message from client channel";
106    EXPECT_EQ(clientReply.body.finished.handled, serverReply.body.finished.handled)
107            << "server channel should receive the correct message from client channel";
108}
109
110TEST_F(InputChannelTest, ReceiveSignal_WhenNoSignalPresent_ReturnsAnError) {
111    sp<InputChannel> serverChannel, clientChannel;
112
113    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
114            serverChannel, clientChannel);
115
116    ASSERT_EQ(OK, result)
117            << "should have successfully opened a channel pair";
118
119    InputMessage msg;
120    EXPECT_EQ(WOULD_BLOCK, clientChannel->receiveMessage(&msg))
121            << "receiveMessage should have returned WOULD_BLOCK";
122}
123
124TEST_F(InputChannelTest, ReceiveSignal_WhenPeerClosed_ReturnsAnError) {
125    sp<InputChannel> serverChannel, clientChannel;
126
127    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
128            serverChannel, clientChannel);
129
130    ASSERT_EQ(OK, result)
131            << "should have successfully opened a channel pair";
132
133    serverChannel.clear(); // close server channel
134
135    InputMessage msg;
136    EXPECT_EQ(DEAD_OBJECT, clientChannel->receiveMessage(&msg))
137            << "receiveMessage should have returned DEAD_OBJECT";
138}
139
140TEST_F(InputChannelTest, SendSignal_WhenPeerClosed_ReturnsAnError) {
141    sp<InputChannel> serverChannel, clientChannel;
142
143    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
144            serverChannel, clientChannel);
145
146    ASSERT_EQ(OK, result)
147            << "should have successfully opened a channel pair";
148
149    serverChannel.clear(); // close server channel
150
151    InputMessage msg;
152    msg.header.type = InputMessage::TYPE_KEY;
153    EXPECT_EQ(DEAD_OBJECT, clientChannel->sendMessage(&msg))
154            << "sendMessage should have returned DEAD_OBJECT";
155}
156
157
158} // namespace android
159