• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2010 The Android Open Source Project
3 //
4 
5 #include <ui/InputTransport.h>
6 #include <utils/Timers.h>
7 #include <utils/StopWatch.h>
8 #include <gtest/gtest.h>
9 #include <unistd.h>
10 #include <time.h>
11 #include <sys/mman.h>
12 #include <cutils/ashmem.h>
13 
14 #include "../../utils/tests/TestHelpers.h"
15 
16 namespace android {
17 
18 class InputChannelTest : public testing::Test {
19 protected:
SetUp()20     virtual void SetUp() { }
TearDown()21     virtual void TearDown() { }
22 };
23 
24 
TEST_F(InputChannelTest,ConstructorAndDestructor_TakesOwnershipOfFileDescriptors)25 TEST_F(InputChannelTest, ConstructorAndDestructor_TakesOwnershipOfFileDescriptors) {
26     // Our purpose here is to verify that the input channel destructor closes the
27     // file descriptors provided to it.  One easy way is to provide it with one end
28     // of a pipe and to check for EPIPE on the other end after the channel is destroyed.
29     Pipe fakeAshmem, sendPipe, receivePipe;
30 
31     sp<InputChannel> inputChannel = new InputChannel(String8("channel name"),
32             fakeAshmem.sendFd, receivePipe.receiveFd, sendPipe.sendFd);
33 
34     EXPECT_STREQ("channel name", inputChannel->getName().string())
35             << "channel should have provided name";
36     EXPECT_EQ(fakeAshmem.sendFd, inputChannel->getAshmemFd())
37             << "channel should have provided ashmem fd";
38     EXPECT_EQ(receivePipe.receiveFd, inputChannel->getReceivePipeFd())
39             << "channel should have provided receive pipe fd";
40     EXPECT_EQ(sendPipe.sendFd, inputChannel->getSendPipeFd())
41             << "channel should have provided send pipe fd";
42 
43     inputChannel.clear(); // destroys input channel
44 
45     EXPECT_EQ(-EPIPE, fakeAshmem.readSignal())
46             << "channel should have closed ashmem fd when destroyed";
47     EXPECT_EQ(-EPIPE, receivePipe.writeSignal())
48             << "channel should have closed receive pipe fd when destroyed";
49     EXPECT_EQ(-EPIPE, sendPipe.readSignal())
50             << "channel should have closed send pipe fd when destroyed";
51 
52     // clean up fds of Pipe endpoints that were closed so we don't try to close them again
53     fakeAshmem.sendFd = -1;
54     receivePipe.receiveFd = -1;
55     sendPipe.sendFd = -1;
56 }
57 
TEST_F(InputChannelTest,OpenInputChannelPair_ReturnsAPairOfConnectedChannels)58 TEST_F(InputChannelTest, OpenInputChannelPair_ReturnsAPairOfConnectedChannels) {
59     sp<InputChannel> serverChannel, clientChannel;
60 
61     status_t result = InputChannel::openInputChannelPair(String8("channel name"),
62             serverChannel, clientChannel);
63 
64     ASSERT_EQ(OK, result)
65             << "should have successfully opened a channel pair";
66 
67     // Name
68     EXPECT_STREQ("channel name (server)", serverChannel->getName().string())
69             << "server channel should have suffixed name";
70     EXPECT_STREQ("channel name (client)", clientChannel->getName().string())
71             << "client channel should have suffixed name";
72 
73     // Ashmem uniqueness
74     EXPECT_NE(serverChannel->getAshmemFd(), clientChannel->getAshmemFd())
75             << "server and client channel should have different ashmem fds because it was dup'd";
76 
77     // Ashmem usability
78     ssize_t serverAshmemSize = ashmem_get_size_region(serverChannel->getAshmemFd());
79     ssize_t clientAshmemSize = ashmem_get_size_region(clientChannel->getAshmemFd());
80     uint32_t* serverAshmem = static_cast<uint32_t*>(mmap(NULL, serverAshmemSize,
81             PROT_READ | PROT_WRITE, MAP_SHARED, serverChannel->getAshmemFd(), 0));
82     uint32_t* clientAshmem = static_cast<uint32_t*>(mmap(NULL, clientAshmemSize,
83             PROT_READ | PROT_WRITE, MAP_SHARED, clientChannel->getAshmemFd(), 0));
84     ASSERT_TRUE(serverAshmem != NULL)
85             << "server channel ashmem should be mappable";
86     ASSERT_TRUE(clientAshmem != NULL)
87             << "client channel ashmem should be mappable";
88     *serverAshmem = 0xf00dd00d;
89     EXPECT_EQ(0xf00dd00d, *clientAshmem)
90             << "ashmem buffer should be shared by client and server";
91     munmap(serverAshmem, serverAshmemSize);
92     munmap(clientAshmem, clientAshmemSize);
93 
94     // Server->Client communication
95     EXPECT_EQ(OK, serverChannel->sendSignal('S'))
96             << "server channel should be able to send signal to client channel";
97     char signal;
98     EXPECT_EQ(OK, clientChannel->receiveSignal(& signal))
99             << "client channel should be able to receive signal from server channel";
100     EXPECT_EQ('S', signal)
101             << "client channel should receive the correct signal from server channel";
102 
103     // Client->Server communication
104     EXPECT_EQ(OK, clientChannel->sendSignal('c'))
105             << "client channel should be able to send signal to server channel";
106     EXPECT_EQ(OK, serverChannel->receiveSignal(& signal))
107             << "server channel should be able to receive signal from client channel";
108     EXPECT_EQ('c', signal)
109             << "server channel should receive the correct signal from client channel";
110 }
111 
TEST_F(InputChannelTest,ReceiveSignal_WhenNoSignalPresent_ReturnsAnError)112 TEST_F(InputChannelTest, ReceiveSignal_WhenNoSignalPresent_ReturnsAnError) {
113     sp<InputChannel> serverChannel, clientChannel;
114 
115     status_t result = InputChannel::openInputChannelPair(String8("channel name"),
116             serverChannel, clientChannel);
117 
118     ASSERT_EQ(OK, result)
119             << "should have successfully opened a channel pair";
120 
121     char signal;
122     EXPECT_EQ(WOULD_BLOCK, clientChannel->receiveSignal(& signal))
123             << "receiveSignal should have returned WOULD_BLOCK";
124 }
125 
TEST_F(InputChannelTest,ReceiveSignal_WhenPeerClosed_ReturnsAnError)126 TEST_F(InputChannelTest, ReceiveSignal_WhenPeerClosed_ReturnsAnError) {
127     sp<InputChannel> serverChannel, clientChannel;
128 
129     status_t result = InputChannel::openInputChannelPair(String8("channel name"),
130             serverChannel, clientChannel);
131 
132     ASSERT_EQ(OK, result)
133             << "should have successfully opened a channel pair";
134 
135     serverChannel.clear(); // close server channel
136 
137     char signal;
138     EXPECT_EQ(DEAD_OBJECT, clientChannel->receiveSignal(& signal))
139             << "receiveSignal should have returned DEAD_OBJECT";
140 }
141 
TEST_F(InputChannelTest,SendSignal_WhenPeerClosed_ReturnsAnError)142 TEST_F(InputChannelTest, SendSignal_WhenPeerClosed_ReturnsAnError) {
143     sp<InputChannel> serverChannel, clientChannel;
144 
145     status_t result = InputChannel::openInputChannelPair(String8("channel name"),
146             serverChannel, clientChannel);
147 
148     ASSERT_EQ(OK, result)
149             << "should have successfully opened a channel pair";
150 
151     serverChannel.clear(); // close server channel
152 
153     EXPECT_EQ(DEAD_OBJECT, clientChannel->sendSignal('S'))
154             << "sendSignal should have returned DEAD_OBJECT";
155 }
156 
157 
158 } // namespace android
159