blob: eff22ee5f0eb4eb66e805e788d33743d28c9977d [file] [log] [blame]
Jeff Brownb2d44352011-02-17 13:01:34 -08001/*
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 */
Jeff Brownf4a4ec22010-06-16 01:53:36 -070016
17#include <ui/InputTransport.h>
18#include <utils/Timers.h>
19#include <utils/StopWatch.h>
20#include <gtest/gtest.h>
21#include <unistd.h>
22#include <time.h>
23#include <sys/mman.h>
24#include <cutils/ashmem.h>
25
26#include "../../utils/tests/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 descriptors 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 fakeAshmem, sendPipe, receivePipe;
42
43 sp<InputChannel> inputChannel = new InputChannel(String8("channel name"),
44 fakeAshmem.sendFd, receivePipe.receiveFd, sendPipe.sendFd);
45
46 EXPECT_STREQ("channel name", inputChannel->getName().string())
47 << "channel should have provided name";
48 EXPECT_EQ(fakeAshmem.sendFd, inputChannel->getAshmemFd())
49 << "channel should have provided ashmem fd";
50 EXPECT_EQ(receivePipe.receiveFd, inputChannel->getReceivePipeFd())
51 << "channel should have provided receive pipe fd";
52 EXPECT_EQ(sendPipe.sendFd, inputChannel->getSendPipeFd())
53 << "channel should have provided send pipe fd";
54
55 inputChannel.clear(); // destroys input channel
56
57 EXPECT_EQ(-EPIPE, fakeAshmem.readSignal())
58 << "channel should have closed ashmem fd when destroyed";
59 EXPECT_EQ(-EPIPE, receivePipe.writeSignal())
60 << "channel should have closed receive pipe fd when destroyed";
61 EXPECT_EQ(-EPIPE, sendPipe.readSignal())
62 << "channel should have closed send pipe fd when destroyed";
63
64 // clean up fds of Pipe endpoints that were closed so we don't try to close them again
65 fakeAshmem.sendFd = -1;
66 receivePipe.receiveFd = -1;
67 sendPipe.sendFd = -1;
68}
69
70TEST_F(InputChannelTest, OpenInputChannelPair_ReturnsAPairOfConnectedChannels) {
71 sp<InputChannel> serverChannel, clientChannel;
72
73 status_t result = InputChannel::openInputChannelPair(String8("channel name"),
74 serverChannel, clientChannel);
75
76 ASSERT_EQ(OK, result)
77 << "should have successfully opened a channel pair";
78
79 // Name
80 EXPECT_STREQ("channel name (server)", serverChannel->getName().string())
81 << "server channel should have suffixed name";
82 EXPECT_STREQ("channel name (client)", clientChannel->getName().string())
83 << "client channel should have suffixed name";
84
85 // Ashmem uniqueness
86 EXPECT_NE(serverChannel->getAshmemFd(), clientChannel->getAshmemFd())
87 << "server and client channel should have different ashmem fds because it was dup'd";
88
89 // Ashmem usability
90 ssize_t serverAshmemSize = ashmem_get_size_region(serverChannel->getAshmemFd());
91 ssize_t clientAshmemSize = ashmem_get_size_region(clientChannel->getAshmemFd());
92 uint32_t* serverAshmem = static_cast<uint32_t*>(mmap(NULL, serverAshmemSize,
93 PROT_READ | PROT_WRITE, MAP_SHARED, serverChannel->getAshmemFd(), 0));
94 uint32_t* clientAshmem = static_cast<uint32_t*>(mmap(NULL, clientAshmemSize,
95 PROT_READ | PROT_WRITE, MAP_SHARED, clientChannel->getAshmemFd(), 0));
96 ASSERT_TRUE(serverAshmem != NULL)
97 << "server channel ashmem should be mappable";
98 ASSERT_TRUE(clientAshmem != NULL)
99 << "client channel ashmem should be mappable";
100 *serverAshmem = 0xf00dd00d;
101 EXPECT_EQ(0xf00dd00d, *clientAshmem)
102 << "ashmem buffer should be shared by client and server";
103 munmap(serverAshmem, serverAshmemSize);
104 munmap(clientAshmem, clientAshmemSize);
105
106 // Server->Client communication
107 EXPECT_EQ(OK, serverChannel->sendSignal('S'))
108 << "server channel should be able to send signal to client channel";
109 char signal;
110 EXPECT_EQ(OK, clientChannel->receiveSignal(& signal))
111 << "client channel should be able to receive signal from server channel";
112 EXPECT_EQ('S', signal)
113 << "client channel should receive the correct signal from server channel";
114
115 // Client->Server communication
116 EXPECT_EQ(OK, clientChannel->sendSignal('c'))
117 << "client channel should be able to send signal to server channel";
118 EXPECT_EQ(OK, serverChannel->receiveSignal(& signal))
119 << "server channel should be able to receive signal from client channel";
120 EXPECT_EQ('c', signal)
121 << "server channel should receive the correct signal from client channel";
122}
123
124TEST_F(InputChannelTest, ReceiveSignal_WhenNoSignalPresent_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 char signal;
134 EXPECT_EQ(WOULD_BLOCK, clientChannel->receiveSignal(& signal))
135 << "receiveSignal should have returned WOULD_BLOCK";
136}
137
138TEST_F(InputChannelTest, ReceiveSignal_WhenPeerClosed_ReturnsAnError) {
139 sp<InputChannel> serverChannel, clientChannel;
140
141 status_t result = InputChannel::openInputChannelPair(String8("channel name"),
142 serverChannel, clientChannel);
143
144 ASSERT_EQ(OK, result)
145 << "should have successfully opened a channel pair";
146
147 serverChannel.clear(); // close server channel
148
149 char signal;
150 EXPECT_EQ(DEAD_OBJECT, clientChannel->receiveSignal(& signal))
151 << "receiveSignal should have returned DEAD_OBJECT";
152}
153
154TEST_F(InputChannelTest, SendSignal_WhenPeerClosed_ReturnsAnError) {
155 sp<InputChannel> serverChannel, clientChannel;
156
157 status_t result = InputChannel::openInputChannelPair(String8("channel name"),
158 serverChannel, clientChannel);
159
160 ASSERT_EQ(OK, result)
161 << "should have successfully opened a channel pair";
162
163 serverChannel.clear(); // close server channel
164
165 EXPECT_EQ(DEAD_OBJECT, clientChannel->sendSignal('S'))
166 << "sendSignal should have returned DEAD_OBJECT";
167}
168
169
170} // namespace android