blob: 5606a91a0bdd68a288428149e06fe988d762f0b7 [file] [log] [blame]
Siarhei Vishniakou473174e2017-12-27 16:44:42 -08001/*
2 * Copyright (C) 2019 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
Siarhei Vishniakou98996032022-08-03 11:54:47 -070017#include "../InputProcessor.h"
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080018#include <gtest/gtest.h>
19
20#include "TestInputListener.h"
21
Siarhei Vishniakou34d6fef2022-02-01 19:03:45 -080022#include <aidl/android/hardware/input/processor/BnInputProcessor.h>
23#include <aidl/android/hardware/input/processor/IInputProcessor.h>
24#include <android/binder_manager.h>
25#include <android/binder_process.h>
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080026
Siarhei Vishniakou34d6fef2022-02-01 19:03:45 -080027using namespace aidl::android::hardware::input;
28using aidl::android::hardware::input::common::Classification;
29using aidl::android::hardware::input::processor::IInputProcessor;
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080030
31namespace android {
32
Siarhei Vishniakou98996032022-08-03 11:54:47 -070033// --- InputProcessorTest ---
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080034
35static NotifyMotionArgs generateBasicMotionArgs() {
36 // Create a basic motion event for testing
Siarhei Vishniakoufd3718c2019-02-28 08:16:26 -080037 PointerProperties properties;
38 properties.id = 0;
Siarhei Vishniakou09a8fe42022-07-21 17:27:03 -070039 properties.toolType = ToolType::FINGER;
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080040
Siarhei Vishniakoufd3718c2019-02-28 08:16:26 -080041 PointerCoords coords;
42 coords.clear();
43 coords.setAxisValue(AMOTION_EVENT_AXIS_X, 1);
44 coords.setAxisValue(AMOTION_EVENT_AXIS_Y, 1);
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080045 static constexpr nsecs_t downTime = 2;
Harry Cutts33476232023-01-30 19:57:29 +000046 NotifyMotionArgs motionArgs(/*sequenceNum=*/1, /*eventTime=*/downTime, /*readTime=*/2,
Linnan Li13bf76a2024-05-05 19:18:02 +080047 /*deviceId=*/3, AINPUT_SOURCE_ANY, ui::ADISPLAY_ID_DEFAULT,
Harry Cutts33476232023-01-30 19:57:29 +000048 /*policyFlags=*/4, AMOTION_EVENT_ACTION_DOWN, /*actionButton=*/0,
49 /*flags=*/0, AMETA_NONE, /*buttonState=*/0,
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +000050 MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
Harry Cutts33476232023-01-30 19:57:29 +000051 /*pointerCount=*/1, &properties, &coords, /*xPrecision=*/0,
52 /*yPrecision=*/0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
Garfield Tan00f511d2019-06-12 16:55:40 -070053 AMOTION_EVENT_INVALID_CURSOR_POSITION, downTime,
Harry Cutts33476232023-01-30 19:57:29 +000054 /*videoFrames=*/{});
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080055 return motionArgs;
56}
57
Siarhei Vishniakou98996032022-08-03 11:54:47 -070058class InputProcessorTest : public testing::Test {
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080059protected:
Siarhei Vishniakou18050092021-09-01 13:32:49 -070060 TestInputListener mTestListener;
Siarhei Vishniakou98996032022-08-03 11:54:47 -070061 std::unique_ptr<InputProcessorInterface> mProcessor;
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080062
Siarhei Vishniakou98996032022-08-03 11:54:47 -070063 void SetUp() override { mProcessor = std::make_unique<InputProcessor>(mTestListener); }
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080064};
65
66/**
Siarhei Vishniakou98996032022-08-03 11:54:47 -070067 * Create a basic configuration change and send it to input processor.
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080068 * Expect that the event is received by the next input stage, unmodified.
69 */
Siarhei Vishniakou98996032022-08-03 11:54:47 -070070TEST_F(InputProcessorTest, SendToNextStage_NotifyConfigurationChangedArgs) {
71 // Create a basic configuration change and send to processor
Harry Cutts33476232023-01-30 19:57:29 +000072 NotifyConfigurationChangedArgs args(/*sequenceNum=*/1, /*eventTime=*/2);
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080073
Prabir Pradhanc392d8f2023-04-13 19:32:51 +000074 mProcessor->notifyConfigurationChanged(args);
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080075 NotifyConfigurationChangedArgs outArgs;
Siarhei Vishniakou18050092021-09-01 13:32:49 -070076 ASSERT_NO_FATAL_FAILURE(mTestListener.assertNotifyConfigurationChangedWasCalled(&outArgs));
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080077 ASSERT_EQ(args, outArgs);
78}
79
Siarhei Vishniakou98996032022-08-03 11:54:47 -070080TEST_F(InputProcessorTest, SendToNextStage_NotifyKeyArgs) {
81 // Create a basic key event and send to processor
Harry Cutts33476232023-01-30 19:57:29 +000082 NotifyKeyArgs args(/*sequenceNum=*/1, /*eventTime=*/2, /*readTime=*/21, /*deviceId=*/3,
Linnan Li13bf76a2024-05-05 19:18:02 +080083 AINPUT_SOURCE_KEYBOARD, ui::ADISPLAY_ID_DEFAULT, /*policyFlags=*/0,
Harry Cutts33476232023-01-30 19:57:29 +000084 AKEY_EVENT_ACTION_DOWN, /*flags=*/4, AKEYCODE_HOME, /*scanCode=*/5,
85 AMETA_NONE, /*downTime=*/6);
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080086
Prabir Pradhanc392d8f2023-04-13 19:32:51 +000087 mProcessor->notifyKey(args);
88 ASSERT_NO_FATAL_FAILURE(mTestListener.assertNotifyKeyWasCalled(testing::Eq(args)));
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080089}
90
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080091/**
Siarhei Vishniakou98996032022-08-03 11:54:47 -070092 * Create a basic motion event and send it to input processor.
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080093 * Expect that the event is received by the next input stage, unmodified.
94 */
Siarhei Vishniakou98996032022-08-03 11:54:47 -070095TEST_F(InputProcessorTest, SendToNextStage_NotifyMotionArgs) {
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080096 NotifyMotionArgs motionArgs = generateBasicMotionArgs();
Prabir Pradhanc392d8f2023-04-13 19:32:51 +000097 mProcessor->notifyMotion(motionArgs);
98 ASSERT_NO_FATAL_FAILURE(mTestListener.assertNotifyMotionWasCalled(testing::Eq(motionArgs)));
Siarhei Vishniakou473174e2017-12-27 16:44:42 -080099}
100
101/**
Siarhei Vishniakou98996032022-08-03 11:54:47 -0700102 * Create a basic switch event and send it to input processor.
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800103 * Expect that the event is received by the next input stage, unmodified.
104 */
Siarhei Vishniakou98996032022-08-03 11:54:47 -0700105TEST_F(InputProcessorTest, SendToNextStage_NotifySwitchArgs) {
Harry Cutts33476232023-01-30 19:57:29 +0000106 NotifySwitchArgs args(/*sequenceNum=*/1, /*eventTime=*/2, /*policyFlags=*/3,
107 /*switchValues=*/4, /*switchMask=*/5);
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800108
Prabir Pradhanc392d8f2023-04-13 19:32:51 +0000109 mProcessor->notifySwitch(args);
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800110 NotifySwitchArgs outArgs;
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700111 ASSERT_NO_FATAL_FAILURE(mTestListener.assertNotifySwitchWasCalled(&outArgs));
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800112 ASSERT_EQ(args, outArgs);
113}
114
115/**
Siarhei Vishniakou98996032022-08-03 11:54:47 -0700116 * Create a basic device reset event and send it to input processor.
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800117 * Expect that the event is received by the next input stage, unmodified.
118 */
Siarhei Vishniakou98996032022-08-03 11:54:47 -0700119TEST_F(InputProcessorTest, SendToNextStage_NotifyDeviceResetArgs) {
Harry Cutts33476232023-01-30 19:57:29 +0000120 NotifyDeviceResetArgs args(/*sequenceNum=*/1, /*eventTime=*/2, /*deviceId=*/3);
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800121
Prabir Pradhanc392d8f2023-04-13 19:32:51 +0000122 mProcessor->notifyDeviceReset(args);
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800123 NotifyDeviceResetArgs outArgs;
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700124 ASSERT_NO_FATAL_FAILURE(mTestListener.assertNotifyDeviceResetWasCalled(&outArgs));
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800125 ASSERT_EQ(args, outArgs);
126}
127
Siarhei Vishniakou98996032022-08-03 11:54:47 -0700128TEST_F(InputProcessorTest, SetMotionClassifier_Enabled) {
129 mProcessor->setMotionClassifierEnabled(true);
Siarhei Vishniakouc9ac19e2020-03-19 11:55:01 -0700130}
131
Siarhei Vishniakou98996032022-08-03 11:54:47 -0700132TEST_F(InputProcessorTest, SetMotionClassifier_Disabled) {
133 mProcessor->setMotionClassifierEnabled(false);
Siarhei Vishniakouc9ac19e2020-03-19 11:55:01 -0700134}
135
136/**
137 * Try to break it by calling setMotionClassifierEnabled multiple times.
138 */
Siarhei Vishniakou98996032022-08-03 11:54:47 -0700139TEST_F(InputProcessorTest, SetMotionClassifier_Multiple) {
140 mProcessor->setMotionClassifierEnabled(true);
141 mProcessor->setMotionClassifierEnabled(true);
142 mProcessor->setMotionClassifierEnabled(true);
143 mProcessor->setMotionClassifierEnabled(false);
144 mProcessor->setMotionClassifierEnabled(false);
145 mProcessor->setMotionClassifierEnabled(true);
146 mProcessor->setMotionClassifierEnabled(true);
147 mProcessor->setMotionClassifierEnabled(true);
Siarhei Vishniakouc9ac19e2020-03-19 11:55:01 -0700148}
149
Siarhei Vishniakou16523972020-03-04 17:48:39 -0800150/**
Siarhei Vishniakou98996032022-08-03 11:54:47 -0700151 * A minimal implementation of IInputProcessor.
Siarhei Vishniakou16523972020-03-04 17:48:39 -0800152 */
Siarhei Vishniakou34d6fef2022-02-01 19:03:45 -0800153class TestHal : public aidl::android::hardware::input::processor::BnInputProcessor {
154 ::ndk::ScopedAStatus classify(
155 const ::aidl::android::hardware::input::common::MotionEvent& in_event,
156 ::aidl::android::hardware::input::common::Classification* _aidl_return) override {
157 *_aidl_return = Classification::NONE;
158 return ndk::ScopedAStatus::ok();
159 }
160 ::ndk::ScopedAStatus reset() override { return ndk::ScopedAStatus::ok(); }
161 ::ndk::ScopedAStatus resetDevice(int32_t in_deviceId) override {
162 return ndk::ScopedAStatus::ok();
163 }
Siarhei Vishniakou16523972020-03-04 17:48:39 -0800164};
165
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800166// --- MotionClassifierTest ---
167
168class MotionClassifierTest : public testing::Test {
169protected:
170 std::unique_ptr<MotionClassifierInterface> mMotionClassifier;
171
Siarhei Vishniakou34d6fef2022-02-01 19:03:45 -0800172 void SetUp() override {
173 std::shared_ptr<IInputProcessor> service = ndk::SharedRefBase::make<TestHal>();
174 mMotionClassifier = MotionClassifier::create(std::move(service));
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800175 }
176};
177
178/**
179 * Since MotionClassifier creates a new thread to communicate with HAL,
180 * it's not really expected to ever exit. However, for testing purposes,
181 * we need to ensure that it is able to exit cleanly.
182 * If the thread is not properly cleaned up, it will generate SIGABRT.
183 * The logic for exiting the thread and cleaning up the resources is inside
184 * the destructor. Here, we just make sure the destructor does not crash.
185 */
186TEST_F(MotionClassifierTest, Destructor_DoesNotCrash) {
187 mMotionClassifier = nullptr;
188}
189
190/**
191 * Make sure MotionClassifier can handle events that don't have any
192 * video frames.
193 */
194TEST_F(MotionClassifierTest, Classify_NoVideoFrames) {
195 NotifyMotionArgs motionArgs = generateBasicMotionArgs();
196
197 // We are not checking the return value, because we can't be making assumptions
198 // about the HAL operation, since it will be highly hardware-dependent
Siarhei Vishniakou4bdbb6a2019-04-11 09:42:09 -0700199 ASSERT_NO_FATAL_FAILURE(mMotionClassifier->classify(motionArgs));
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800200}
201
202/**
203 * Make sure nothing crashes when a videoFrame is sent.
204 */
205TEST_F(MotionClassifierTest, Classify_OneVideoFrame) {
206 NotifyMotionArgs motionArgs = generateBasicMotionArgs();
207
208 std::vector<int16_t> videoData = {1, 2, 3, 4};
Siarhei Vishniakou98996032022-08-03 11:54:47 -0700209 timeval timestamp = {1, 1};
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800210 TouchVideoFrame frame(2, 2, std::move(videoData), timestamp);
211 motionArgs.videoFrames = {frame};
212
213 // We are not checking the return value, because we can't be making assumptions
214 // about the HAL operation, since it will be highly hardware-dependent
Siarhei Vishniakou4bdbb6a2019-04-11 09:42:09 -0700215 ASSERT_NO_FATAL_FAILURE(mMotionClassifier->classify(motionArgs));
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800216}
217
218/**
219 * Make sure nothing crashes when 2 videoFrames are sent.
220 */
221TEST_F(MotionClassifierTest, Classify_TwoVideoFrames) {
222 NotifyMotionArgs motionArgs = generateBasicMotionArgs();
223
224 std::vector<int16_t> videoData1 = {1, 2, 3, 4};
Siarhei Vishniakou98996032022-08-03 11:54:47 -0700225 timeval timestamp1 = {1, 1};
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800226 TouchVideoFrame frame1(2, 2, std::move(videoData1), timestamp1);
227
228 std::vector<int16_t> videoData2 = {6, 6, 6, 6};
Siarhei Vishniakou98996032022-08-03 11:54:47 -0700229 timeval timestamp2 = {1, 2};
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800230 TouchVideoFrame frame2(2, 2, std::move(videoData2), timestamp2);
231
232 motionArgs.videoFrames = {frame1, frame2};
233
234 // We are not checking the return value, because we can't be making assumptions
235 // about the HAL operation, since it will be highly hardware-dependent
Siarhei Vishniakou4bdbb6a2019-04-11 09:42:09 -0700236 ASSERT_NO_FATAL_FAILURE(mMotionClassifier->classify(motionArgs));
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800237}
238
239/**
240 * Make sure MotionClassifier does not crash when it is reset.
241 */
242TEST_F(MotionClassifierTest, Reset_DoesNotCrash) {
Siarhei Vishniakou4bdbb6a2019-04-11 09:42:09 -0700243 ASSERT_NO_FATAL_FAILURE(mMotionClassifier->reset());
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800244}
245
246/**
247 * Make sure MotionClassifier does not crash when a device is reset.
248 */
249TEST_F(MotionClassifierTest, DeviceReset_DoesNotCrash) {
Harry Cutts33476232023-01-30 19:57:29 +0000250 NotifyDeviceResetArgs args(/*sequenceNum=*/1, /*eventTime=*/2, /*deviceId=*/3);
Siarhei Vishniakou4bdbb6a2019-04-11 09:42:09 -0700251 ASSERT_NO_FATAL_FAILURE(mMotionClassifier->reset(args));
Siarhei Vishniakou473174e2017-12-27 16:44:42 -0800252}
253
254} // namespace android