Home | History | Annotate | Download | only in tests
      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 <array>
     18 
     19 #include "TestHelpers.h"
     20 
     21 #include <unistd.h>
     22 #include <time.h>
     23 #include <errno.h>
     24 
     25 #include <gtest/gtest.h>
     26 #include <input/InputTransport.h>
     27 #include <utils/Timers.h>
     28 #include <utils/StopWatch.h>
     29 #include <utils/StrongPointer.h>
     30 
     31 namespace android {
     32 
     33 class InputChannelTest : public testing::Test {
     34 protected:
     35     virtual void SetUp() { }
     36     virtual void TearDown() { }
     37 };
     38 
     39 
     40 TEST_F(InputChannelTest, ConstructorAndDestructor_TakesOwnershipOfFileDescriptors) {
     41     // Our purpose here is to verify that the input channel destructor closes the
     42     // file descriptor provided to it.  One easy way is to provide it with one end
     43     // of a pipe and to check for EPIPE on the other end after the channel is destroyed.
     44     Pipe pipe;
     45 
     46     sp<InputChannel> inputChannel = new InputChannel("channel name", pipe.sendFd);
     47 
     48     EXPECT_STREQ("channel name", inputChannel->getName().c_str())
     49             << "channel should have provided name";
     50     EXPECT_EQ(pipe.sendFd, inputChannel->getFd())
     51             << "channel should have provided fd";
     52 
     53     inputChannel.clear(); // destroys input channel
     54 
     55     EXPECT_EQ(-EPIPE, pipe.readSignal())
     56             << "channel should have closed fd when destroyed";
     57 
     58     // clean up fds of Pipe endpoints that were closed so we don't try to close them again
     59     pipe.sendFd = -1;
     60 }
     61 
     62 TEST_F(InputChannelTest, OpenInputChannelPair_ReturnsAPairOfConnectedChannels) {
     63     sp<InputChannel> serverChannel, clientChannel;
     64 
     65     status_t result = InputChannel::openInputChannelPair("channel name",
     66             serverChannel, clientChannel);
     67 
     68     ASSERT_EQ(OK, result)
     69             << "should have successfully opened a channel pair";
     70 
     71     // Name
     72     EXPECT_STREQ("channel name (server)", serverChannel->getName().c_str())
     73             << "server channel should have suffixed name";
     74     EXPECT_STREQ("channel name (client)", clientChannel->getName().c_str())
     75             << "client channel should have suffixed name";
     76 
     77     // Server->Client communication
     78     InputMessage serverMsg;
     79     memset(&serverMsg, 0, sizeof(InputMessage));
     80     serverMsg.header.type = InputMessage::TYPE_KEY;
     81     serverMsg.body.key.action = AKEY_EVENT_ACTION_DOWN;
     82     EXPECT_EQ(OK, serverChannel->sendMessage(&serverMsg))
     83             << "server channel should be able to send message to client channel";
     84 
     85     InputMessage clientMsg;
     86     EXPECT_EQ(OK, clientChannel->receiveMessage(&clientMsg))
     87             << "client channel should be able to receive message from server channel";
     88     EXPECT_EQ(serverMsg.header.type, clientMsg.header.type)
     89             << "client channel should receive the correct message from server channel";
     90     EXPECT_EQ(serverMsg.body.key.action, clientMsg.body.key.action)
     91             << "client channel should receive the correct message from server channel";
     92 
     93     // Client->Server communication
     94     InputMessage clientReply;
     95     memset(&clientReply, 0, sizeof(InputMessage));
     96     clientReply.header.type = InputMessage::TYPE_FINISHED;
     97     clientReply.body.finished.seq = 0x11223344;
     98     clientReply.body.finished.handled = true;
     99     EXPECT_EQ(OK, clientChannel->sendMessage(&clientReply))
    100             << "client channel should be able to send message to server channel";
    101 
    102     InputMessage serverReply;
    103     EXPECT_EQ(OK, serverChannel->receiveMessage(&serverReply))
    104             << "server channel should be able to receive message from client channel";
    105     EXPECT_EQ(clientReply.header.type, serverReply.header.type)
    106             << "server channel should receive the correct message from client channel";
    107     EXPECT_EQ(clientReply.body.finished.seq, serverReply.body.finished.seq)
    108             << "server channel should receive the correct message from client channel";
    109     EXPECT_EQ(clientReply.body.finished.handled, serverReply.body.finished.handled)
    110             << "server channel should receive the correct message from client channel";
    111 }
    112 
    113 TEST_F(InputChannelTest, ReceiveSignal_WhenNoSignalPresent_ReturnsAnError) {
    114     sp<InputChannel> serverChannel, clientChannel;
    115 
    116     status_t result = InputChannel::openInputChannelPair("channel name",
    117             serverChannel, clientChannel);
    118 
    119     ASSERT_EQ(OK, result)
    120             << "should have successfully opened a channel pair";
    121 
    122     InputMessage msg;
    123     EXPECT_EQ(WOULD_BLOCK, clientChannel->receiveMessage(&msg))
    124             << "receiveMessage should have returned WOULD_BLOCK";
    125 }
    126 
    127 TEST_F(InputChannelTest, ReceiveSignal_WhenPeerClosed_ReturnsAnError) {
    128     sp<InputChannel> serverChannel, clientChannel;
    129 
    130     status_t result = InputChannel::openInputChannelPair("channel name",
    131             serverChannel, clientChannel);
    132 
    133     ASSERT_EQ(OK, result)
    134             << "should have successfully opened a channel pair";
    135 
    136     serverChannel.clear(); // close server channel
    137 
    138     InputMessage msg;
    139     EXPECT_EQ(DEAD_OBJECT, clientChannel->receiveMessage(&msg))
    140             << "receiveMessage should have returned DEAD_OBJECT";
    141 }
    142 
    143 TEST_F(InputChannelTest, SendSignal_WhenPeerClosed_ReturnsAnError) {
    144     sp<InputChannel> serverChannel, clientChannel;
    145 
    146     status_t result = InputChannel::openInputChannelPair("channel name",
    147             serverChannel, clientChannel);
    148 
    149     ASSERT_EQ(OK, result)
    150             << "should have successfully opened a channel pair";
    151 
    152     serverChannel.clear(); // close server channel
    153 
    154     InputMessage msg;
    155     msg.header.type = InputMessage::TYPE_KEY;
    156     EXPECT_EQ(DEAD_OBJECT, clientChannel->sendMessage(&msg))
    157             << "sendMessage should have returned DEAD_OBJECT";
    158 }
    159 
    160 TEST_F(InputChannelTest, SendAndReceive_MotionClassification) {
    161     sp<InputChannel> serverChannel, clientChannel;
    162     status_t result = InputChannel::openInputChannelPair("channel name",
    163             serverChannel, clientChannel);
    164     ASSERT_EQ(OK, result)
    165             << "should have successfully opened a channel pair";
    166 
    167     std::array<MotionClassification, 3> classifications = {
    168         MotionClassification::NONE,
    169         MotionClassification::AMBIGUOUS_GESTURE,
    170         MotionClassification::DEEP_PRESS,
    171     };
    172 
    173     InputMessage serverMsg = {}, clientMsg;
    174     serverMsg.header.type = InputMessage::TYPE_MOTION;
    175     serverMsg.body.motion.seq = 1;
    176     serverMsg.body.motion.pointerCount = 1;
    177 
    178     for (MotionClassification classification : classifications) {
    179         // Send and receive a message with classification
    180         serverMsg.body.motion.classification = classification;
    181         EXPECT_EQ(OK, serverChannel->sendMessage(&serverMsg))
    182                 << "server channel should be able to send message to client channel";
    183 
    184         EXPECT_EQ(OK, clientChannel->receiveMessage(&clientMsg))
    185                 << "client channel should be able to receive message from server channel";
    186         EXPECT_EQ(serverMsg.header.type, clientMsg.header.type);
    187         EXPECT_EQ(classification, clientMsg.body.motion.classification) <<
    188                 "Expected to receive " << motionClassificationToString(classification);
    189     }
    190 }
    191 
    192 
    193 } // namespace android
    194