• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <gtest/gtest.h>
21 #include <unistd.h>
22 #include <time.h>
23 #include <sys/mman.h>
24 #include <cutils/ashmem.h>
25 
26 #include "TestHelpers.h"
27 
28 namespace android {
29 
30 class InputPublisherAndConsumerTest : public testing::Test {
31 protected:
32     sp<InputChannel> serverChannel, clientChannel;
33     InputPublisher* mPublisher;
34     InputConsumer* mConsumer;
35     PreallocatedInputEventFactory mEventFactory;
36 
SetUp()37     virtual void SetUp() {
38         status_t result = InputChannel::openInputChannelPair(String8("channel name"),
39                 serverChannel, clientChannel);
40 
41         mPublisher = new InputPublisher(serverChannel);
42         mConsumer = new InputConsumer(clientChannel);
43     }
44 
TearDown()45     virtual void TearDown() {
46         if (mPublisher) {
47             delete mPublisher;
48             mPublisher = NULL;
49         }
50 
51         if (mConsumer) {
52             delete mConsumer;
53             mConsumer = NULL;
54         }
55 
56         serverChannel.clear();
57         clientChannel.clear();
58     }
59 
60     void PublishAndConsumeKeyEvent();
61     void PublishAndConsumeMotionEvent();
62 };
63 
TEST_F(InputPublisherAndConsumerTest,GetChannel_ReturnsTheChannel)64 TEST_F(InputPublisherAndConsumerTest, GetChannel_ReturnsTheChannel) {
65     EXPECT_EQ(serverChannel.get(), mPublisher->getChannel().get());
66     EXPECT_EQ(clientChannel.get(), mConsumer->getChannel().get());
67 }
68 
PublishAndConsumeKeyEvent()69 void InputPublisherAndConsumerTest::PublishAndConsumeKeyEvent() {
70     status_t status;
71 
72     const uint32_t seq = 15;
73     const int32_t deviceId = 1;
74     const int32_t source = AINPUT_SOURCE_KEYBOARD;
75     const int32_t action = AKEY_EVENT_ACTION_DOWN;
76     const int32_t flags = AKEY_EVENT_FLAG_FROM_SYSTEM;
77     const int32_t keyCode = AKEYCODE_ENTER;
78     const int32_t scanCode = 13;
79     const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
80     const int32_t repeatCount = 1;
81     const nsecs_t downTime = 3;
82     const nsecs_t eventTime = 4;
83 
84     status = mPublisher->publishKeyEvent(seq, deviceId, source, action, flags,
85             keyCode, scanCode, metaState, repeatCount, downTime, eventTime);
86     ASSERT_EQ(OK, status)
87             << "publisher publishKeyEvent should return OK";
88 
89     uint32_t consumeSeq;
90     InputEvent* event;
91     status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq, &event);
92     ASSERT_EQ(OK, status)
93             << "consumer consume should return OK";
94 
95     ASSERT_TRUE(event != NULL)
96             << "consumer should have returned non-NULL event";
97     ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, event->getType())
98             << "consumer should have returned a key event";
99 
100     KeyEvent* keyEvent = static_cast<KeyEvent*>(event);
101     EXPECT_EQ(seq, consumeSeq);
102     EXPECT_EQ(deviceId, keyEvent->getDeviceId());
103     EXPECT_EQ(source, keyEvent->getSource());
104     EXPECT_EQ(action, keyEvent->getAction());
105     EXPECT_EQ(flags, keyEvent->getFlags());
106     EXPECT_EQ(keyCode, keyEvent->getKeyCode());
107     EXPECT_EQ(scanCode, keyEvent->getScanCode());
108     EXPECT_EQ(metaState, keyEvent->getMetaState());
109     EXPECT_EQ(repeatCount, keyEvent->getRepeatCount());
110     EXPECT_EQ(downTime, keyEvent->getDownTime());
111     EXPECT_EQ(eventTime, keyEvent->getEventTime());
112 
113     status = mConsumer->sendFinishedSignal(seq, true);
114     ASSERT_EQ(OK, status)
115             << "consumer sendFinishedSignal should return OK";
116 
117     uint32_t finishedSeq = 0;
118     bool handled = false;
119     status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled);
120     ASSERT_EQ(OK, status)
121             << "publisher receiveFinishedSignal should return OK";
122     ASSERT_EQ(seq, finishedSeq)
123             << "publisher receiveFinishedSignal should have returned the original sequence number";
124     ASSERT_TRUE(handled)
125             << "publisher receiveFinishedSignal should have set handled to consumer's reply";
126 }
127 
PublishAndConsumeMotionEvent()128 void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() {
129     status_t status;
130 
131     const uint32_t seq = 15;
132     const int32_t deviceId = 1;
133     const int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
134     const int32_t action = AMOTION_EVENT_ACTION_MOVE;
135     const int32_t flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
136     const int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_TOP;
137     const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
138     const int32_t buttonState = AMOTION_EVENT_BUTTON_PRIMARY;
139     const float xOffset = -10;
140     const float yOffset = -20;
141     const float xPrecision = 0.25;
142     const float yPrecision = 0.5;
143     const nsecs_t downTime = 3;
144     const size_t pointerCount = 3;
145     const nsecs_t eventTime = 4;
146     PointerProperties pointerProperties[pointerCount];
147     PointerCoords pointerCoords[pointerCount];
148     for (size_t i = 0; i < pointerCount; i++) {
149         pointerProperties[i].clear();
150         pointerProperties[i].id = (i + 2) % pointerCount;
151         pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
152 
153         pointerCoords[i].clear();
154         pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, 100 * i);
155         pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, 200 * i);
156         pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.5 * i);
157         pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 0.7 * i);
158         pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 1.5 * i);
159         pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 1.7 * i);
160         pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.5 * i);
161         pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.7 * i);
162         pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 3.5 * i);
163     }
164 
165     status = mPublisher->publishMotionEvent(seq, deviceId, source, action, flags, edgeFlags,
166             metaState, buttonState, xOffset, yOffset, xPrecision, yPrecision,
167             downTime, eventTime, pointerCount,
168             pointerProperties, pointerCoords);
169     ASSERT_EQ(OK, status)
170             << "publisher publishMotionEvent should return OK";
171 
172     uint32_t consumeSeq;
173     InputEvent* event;
174     status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq, &event);
175     ASSERT_EQ(OK, status)
176             << "consumer consume should return OK";
177 
178     ASSERT_TRUE(event != NULL)
179             << "consumer should have returned non-NULL event";
180     ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType())
181             << "consumer should have returned a motion event";
182 
183     MotionEvent* motionEvent = static_cast<MotionEvent*>(event);
184     EXPECT_EQ(seq, consumeSeq);
185     EXPECT_EQ(deviceId, motionEvent->getDeviceId());
186     EXPECT_EQ(source, motionEvent->getSource());
187     EXPECT_EQ(action, motionEvent->getAction());
188     EXPECT_EQ(flags, motionEvent->getFlags());
189     EXPECT_EQ(edgeFlags, motionEvent->getEdgeFlags());
190     EXPECT_EQ(metaState, motionEvent->getMetaState());
191     EXPECT_EQ(buttonState, motionEvent->getButtonState());
192     EXPECT_EQ(xPrecision, motionEvent->getXPrecision());
193     EXPECT_EQ(yPrecision, motionEvent->getYPrecision());
194     EXPECT_EQ(downTime, motionEvent->getDownTime());
195     EXPECT_EQ(eventTime, motionEvent->getEventTime());
196     EXPECT_EQ(pointerCount, motionEvent->getPointerCount());
197     EXPECT_EQ(0U, motionEvent->getHistorySize());
198 
199     for (size_t i = 0; i < pointerCount; i++) {
200         SCOPED_TRACE(i);
201         EXPECT_EQ(pointerProperties[i].id, motionEvent->getPointerId(i));
202         EXPECT_EQ(pointerProperties[i].toolType, motionEvent->getToolType(i));
203 
204         EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
205                 motionEvent->getRawX(i));
206         EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
207                 motionEvent->getRawY(i));
208         EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset,
209                 motionEvent->getX(i));
210         EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset,
211                 motionEvent->getY(i));
212         EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
213                 motionEvent->getPressure(i));
214         EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
215                 motionEvent->getSize(i));
216         EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
217                 motionEvent->getTouchMajor(i));
218         EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
219                 motionEvent->getTouchMinor(i));
220         EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
221                 motionEvent->getToolMajor(i));
222         EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
223                 motionEvent->getToolMinor(i));
224         EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
225                 motionEvent->getOrientation(i));
226     }
227 
228     status = mConsumer->sendFinishedSignal(seq, false);
229     ASSERT_EQ(OK, status)
230             << "consumer sendFinishedSignal should return OK";
231 
232     uint32_t finishedSeq = 0;
233     bool handled = true;
234     status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled);
235     ASSERT_EQ(OK, status)
236             << "publisher receiveFinishedSignal should return OK";
237     ASSERT_EQ(seq, finishedSeq)
238             << "publisher receiveFinishedSignal should have returned the original sequence number";
239     ASSERT_FALSE(handled)
240             << "publisher receiveFinishedSignal should have set handled to consumer's reply";
241 }
242 
TEST_F(InputPublisherAndConsumerTest,PublishKeyEvent_EndToEnd)243 TEST_F(InputPublisherAndConsumerTest, PublishKeyEvent_EndToEnd) {
244     ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
245 }
246 
TEST_F(InputPublisherAndConsumerTest,PublishMotionEvent_EndToEnd)247 TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_EndToEnd) {
248     ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
249 }
250 
TEST_F(InputPublisherAndConsumerTest,PublishMotionEvent_WhenPointerCountLessThan1_ReturnsError)251 TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountLessThan1_ReturnsError) {
252     status_t status;
253     const size_t pointerCount = 0;
254     PointerProperties pointerProperties[pointerCount];
255     PointerCoords pointerCoords[pointerCount];
256 
257     status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
258             pointerCount, pointerProperties, pointerCoords);
259     ASSERT_EQ(BAD_VALUE, status)
260             << "publisher publishMotionEvent should return BAD_VALUE";
261 }
262 
TEST_F(InputPublisherAndConsumerTest,PublishMotionEvent_WhenPointerCountGreaterThanMax_ReturnsError)263 TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountGreaterThanMax_ReturnsError) {
264     status_t status;
265     const size_t pointerCount = MAX_POINTERS + 1;
266     PointerProperties pointerProperties[pointerCount];
267     PointerCoords pointerCoords[pointerCount];
268     for (size_t i = 0; i < pointerCount; i++) {
269         pointerProperties[i].clear();
270         pointerCoords[i].clear();
271     }
272 
273     status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
274             pointerCount, pointerProperties, pointerCoords);
275     ASSERT_EQ(BAD_VALUE, status)
276             << "publisher publishMotionEvent should return BAD_VALUE";
277 }
278 
TEST_F(InputPublisherAndConsumerTest,PublishMultipleEvents_EndToEnd)279 TEST_F(InputPublisherAndConsumerTest, PublishMultipleEvents_EndToEnd) {
280     ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
281     ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
282     ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
283     ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
284     ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
285 }
286 
287 } // namespace android
288