• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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