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