1 /*
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
17 #define LOG_TAG "input_classifier_hal_test"
18
19 #include <VtsHalHidlTargetTestBase.h>
20 #include <VtsHalHidlTargetTestEnvBase.h>
21 #include <android-base/logging.h>
22 #include <android/hardware/input/classifier/1.0/IInputClassifier.h>
23 #include <android/hardware/input/common/1.0/types.h>
24 #include <input/InputDevice.h>
25 #include <unistd.h>
26
27 using ::android::ReservedInputDeviceId;
28 using ::android::sp;
29 using ::android::hardware::Return;
30 using ::android::hardware::input::classifier::V1_0::IInputClassifier;
31 using ::android::hardware::input::common::V1_0::Action;
32 using ::android::hardware::input::common::V1_0::Axis;
33 using ::android::hardware::input::common::V1_0::Button;
34 using ::android::hardware::input::common::V1_0::EdgeFlag;
35 using ::android::hardware::input::common::V1_0::MotionEvent;
36 using ::android::hardware::input::common::V1_0::PointerCoords;
37 using ::android::hardware::input::common::V1_0::PointerProperties;
38 using ::android::hardware::input::common::V1_0::Source;
39 using ::android::hardware::input::common::V1_0::ToolType;
40 using ::android::hardware::input::common::V1_0::VideoFrame;
41
getSimpleMotionEvent()42 static MotionEvent getSimpleMotionEvent() {
43 MotionEvent event;
44 event.action = Action::DOWN;
45 event.actionButton = Button::NONE;
46 event.actionIndex = 0;
47 event.buttonState = 0;
48 event.deviceId = 0;
49 event.deviceTimestamp = 0;
50 event.displayId = 1;
51 event.downTime = 2;
52 event.edgeFlags = 0;
53 event.eventTime = 3;
54 event.flags = 0;
55 event.frames = {};
56 event.metaState = 0;
57 event.policyFlags = 0;
58 event.source = Source::TOUCHSCREEN;
59 event.xPrecision = 0;
60 event.yPrecision = 0;
61
62 PointerCoords coords;
63 coords.bits = Axis::X | Axis::Y;
64 coords.values = {1 /*X*/, 2 /*Y*/};
65 event.pointerCoords = {coords};
66
67 PointerProperties properties;
68 properties.id = 0;
69 properties.toolType = ToolType::FINGER;
70 event.pointerProperties = {properties};
71
72 return event;
73 }
74
75 // Test environment for Input Classifier HIDL HAL.
76 class InputClassifierHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
77 public:
78 // get the test environment singleton
Instance()79 static InputClassifierHidlEnvironment* Instance() {
80 static InputClassifierHidlEnvironment* instance = new InputClassifierHidlEnvironment;
81 return instance;
82 }
83
registerTestServices()84 virtual void registerTestServices() override { registerTestService<IInputClassifier>(); }
85
86 private:
InputClassifierHidlEnvironment()87 InputClassifierHidlEnvironment() {}
88 };
89
90 // The main test class for INPUT CLASSIFIER HIDL HAL 1.0.
91 class InputClassifierHidlTest_1_0 : public ::testing::VtsHalHidlTargetTestBase {
92 public:
SetUp()93 virtual void SetUp() override {
94 classifier = ::testing::VtsHalHidlTargetTestBase::getService<IInputClassifier>(
95 InputClassifierHidlEnvironment::Instance()->getServiceName<IInputClassifier>());
96 ASSERT_NE(classifier, nullptr);
97 }
98
TearDown()99 virtual void TearDown() override {}
100
101 sp<IInputClassifier> classifier;
102 };
103
104 /**
105 * Call resetDevice(..) for a few common device id values, and make sure that the HAL
106 * can handle the resets gracefully.
107 */
TEST_F(InputClassifierHidlTest_1_0,ResetDevice)108 TEST_F(InputClassifierHidlTest_1_0, ResetDevice) {
109 EXPECT_TRUE(classifier->resetDevice(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID).isOk());
110 EXPECT_TRUE(classifier->resetDevice(ReservedInputDeviceId::BUILT_IN_KEYBOARD_ID).isOk());
111 EXPECT_TRUE(classifier->resetDevice(1).isOk());
112 EXPECT_TRUE(classifier->resetDevice(2).isOk());
113 }
114
115 /**
116 * Call reset() on the HAL to ensure no fatal failure there.
117 */
TEST_F(InputClassifierHidlTest_1_0,ResetHal)118 TEST_F(InputClassifierHidlTest_1_0, ResetHal) {
119 EXPECT_TRUE(classifier->reset().isOk());
120 }
121
122 /**
123 * Classify an event without any video frames.
124 */
TEST_F(InputClassifierHidlTest_1_0,Classify_NoVideoFrame)125 TEST_F(InputClassifierHidlTest_1_0, Classify_NoVideoFrame) {
126 // Create a MotionEvent that does not have any video data
127 MotionEvent event = getSimpleMotionEvent();
128
129 EXPECT_TRUE(classifier->classify(event).isOk());
130 // We are not checking the actual classification here,
131 // because the HAL operation is highly device-specific.
132
133 // Return HAL to a consistent state by doing a reset
134 classifier->reset();
135 }
136
137 /**
138 * Classify an event with one video frame. Should be the most common scenario.
139 */
TEST_F(InputClassifierHidlTest_1_0,Classify_OneVideoFrame)140 TEST_F(InputClassifierHidlTest_1_0, Classify_OneVideoFrame) {
141 MotionEvent event = getSimpleMotionEvent();
142 VideoFrame frame;
143 frame.data = {1, 2, 3, 4};
144 frame.height = 2;
145 frame.width = 2;
146 frame.timestamp = event.eventTime;
147 event.frames = {frame};
148
149 EXPECT_TRUE(classifier->classify(event).isOk());
150 // We are not checking the actual classification here,
151 // because the HAL operation is highly device-specific.
152
153 // Return HAL to a consistent state by doing a reset
154 classifier->reset();
155 }
156
157 /**
158 * Classify an event with 2 video frames. This could happen if there's slowness in the system,
159 * or if simply the video rate is somehow higher that the input event rate.
160 * The HAL should be able to handle events with more than 1 video frame.
161 *
162 * The frames should be in chronological order, but it is not guaranteed that they will have
163 * monotonically increasing timestamps. Still, we provide consistent timestamps here since that
164 * is the most realistic mode of operation.
165 */
TEST_F(InputClassifierHidlTest_1_0,Classify_TwoVideoFrames)166 TEST_F(InputClassifierHidlTest_1_0, Classify_TwoVideoFrames) {
167 MotionEvent event = getSimpleMotionEvent();
168 VideoFrame frame1;
169 frame1.data = {1, 2, 3, 4};
170 frame1.height = 2;
171 frame1.width = 2;
172 frame1.timestamp = event.eventTime;
173 VideoFrame frame2 = frame1;
174 frame2.data = {5, 5, 5, -1};
175 frame2.timestamp += 1;
176 event.frames = {frame1, frame2};
177
178 EXPECT_TRUE(classifier->classify(event).isOk());
179 // We are not checking the actual classification here,
180 // because the HAL operation is highly device-specific.
181
182 // Return HAL to a consistent state by doing a reset
183 classifier->reset();
184 }
185
main(int argc,char ** argv)186 int main(int argc, char** argv) {
187 ::testing::AddGlobalTestEnvironment(InputClassifierHidlEnvironment::Instance());
188 ::testing::InitGoogleTest(&argc, argv);
189 InputClassifierHidlEnvironment::Instance()->init(&argc, argv);
190 int status = RUN_ALL_TESTS();
191 LOG(INFO) << "Test result = " << status;
192 return status;
193 }
194