176 lines
6.0 KiB
C++
176 lines
6.0 KiB
C++
/*
|
|
* Copyright (C) 2019 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#define LOG_TAG "input_classifier_hal_test"
|
|
|
|
#include <android-base/logging.h>
|
|
#include <android/hardware/input/classifier/1.0/IInputClassifier.h>
|
|
#include <android/hardware/input/common/1.0/types.h>
|
|
#include <gtest/gtest.h>
|
|
#include <hidl/GtestPrinter.h>
|
|
#include <hidl/ServiceManagement.h>
|
|
#include <input/InputDevice.h>
|
|
#include <unistd.h>
|
|
|
|
using ::android::ReservedInputDeviceId;
|
|
using ::android::sp;
|
|
using ::android::hardware::Return;
|
|
using ::android::hardware::input::classifier::V1_0::IInputClassifier;
|
|
using ::android::hardware::input::common::V1_0::Action;
|
|
using ::android::hardware::input::common::V1_0::Axis;
|
|
using ::android::hardware::input::common::V1_0::Button;
|
|
using ::android::hardware::input::common::V1_0::EdgeFlag;
|
|
using ::android::hardware::input::common::V1_0::MotionEvent;
|
|
using ::android::hardware::input::common::V1_0::PointerCoords;
|
|
using ::android::hardware::input::common::V1_0::PointerProperties;
|
|
using ::android::hardware::input::common::V1_0::Source;
|
|
using ::android::hardware::input::common::V1_0::ToolType;
|
|
using ::android::hardware::input::common::V1_0::VideoFrame;
|
|
|
|
static MotionEvent getSimpleMotionEvent() {
|
|
MotionEvent event;
|
|
event.action = Action::DOWN;
|
|
event.actionButton = Button::NONE;
|
|
event.actionIndex = 0;
|
|
event.buttonState = 0;
|
|
event.deviceId = 0;
|
|
event.deviceTimestamp = 0;
|
|
event.displayId = 1;
|
|
event.downTime = 2;
|
|
event.edgeFlags = 0;
|
|
event.eventTime = 3;
|
|
event.flags = 0;
|
|
event.frames = {};
|
|
event.metaState = 0;
|
|
event.policyFlags = 0;
|
|
event.source = Source::TOUCHSCREEN;
|
|
event.xPrecision = 0;
|
|
event.yPrecision = 0;
|
|
|
|
PointerCoords coords;
|
|
coords.bits = Axis::X | Axis::Y;
|
|
coords.values = {1 /*X*/, 2 /*Y*/};
|
|
event.pointerCoords = {coords};
|
|
|
|
PointerProperties properties;
|
|
properties.id = 0;
|
|
properties.toolType = ToolType::FINGER;
|
|
event.pointerProperties = {properties};
|
|
|
|
return event;
|
|
}
|
|
|
|
// The main test class for INPUT CLASSIFIER HIDL HAL 1.0.
|
|
class InputClassifierHidlTest_1_0 : public ::testing::TestWithParam<std::string> {
|
|
public:
|
|
virtual void SetUp() override {
|
|
classifier = IInputClassifier::getService(GetParam());
|
|
ASSERT_NE(classifier, nullptr);
|
|
}
|
|
|
|
virtual void TearDown() override {}
|
|
|
|
sp<IInputClassifier> classifier;
|
|
};
|
|
|
|
/**
|
|
* Call resetDevice(..) for a few common device id values, and make sure that the HAL
|
|
* can handle the resets gracefully.
|
|
*/
|
|
TEST_P(InputClassifierHidlTest_1_0, ResetDevice) {
|
|
EXPECT_TRUE(classifier->resetDevice(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID).isOk());
|
|
EXPECT_TRUE(classifier->resetDevice(ReservedInputDeviceId::BUILT_IN_KEYBOARD_ID).isOk());
|
|
EXPECT_TRUE(classifier->resetDevice(1).isOk());
|
|
EXPECT_TRUE(classifier->resetDevice(2).isOk());
|
|
}
|
|
|
|
/**
|
|
* Call reset() on the HAL to ensure no fatal failure there.
|
|
*/
|
|
TEST_P(InputClassifierHidlTest_1_0, ResetHal) {
|
|
EXPECT_TRUE(classifier->reset().isOk());
|
|
}
|
|
|
|
/**
|
|
* Classify an event without any video frames.
|
|
*/
|
|
TEST_P(InputClassifierHidlTest_1_0, Classify_NoVideoFrame) {
|
|
// Create a MotionEvent that does not have any video data
|
|
MotionEvent event = getSimpleMotionEvent();
|
|
|
|
EXPECT_TRUE(classifier->classify(event).isOk());
|
|
// We are not checking the actual classification here,
|
|
// because the HAL operation is highly device-specific.
|
|
|
|
// Return HAL to a consistent state by doing a reset
|
|
classifier->reset();
|
|
}
|
|
|
|
/**
|
|
* Classify an event with one video frame. Should be the most common scenario.
|
|
*/
|
|
TEST_P(InputClassifierHidlTest_1_0, Classify_OneVideoFrame) {
|
|
MotionEvent event = getSimpleMotionEvent();
|
|
VideoFrame frame;
|
|
frame.data = {1, 2, 3, 4};
|
|
frame.height = 2;
|
|
frame.width = 2;
|
|
frame.timestamp = event.eventTime;
|
|
event.frames = {frame};
|
|
|
|
EXPECT_TRUE(classifier->classify(event).isOk());
|
|
// We are not checking the actual classification here,
|
|
// because the HAL operation is highly device-specific.
|
|
|
|
// Return HAL to a consistent state by doing a reset
|
|
classifier->reset();
|
|
}
|
|
|
|
/**
|
|
* Classify an event with 2 video frames. This could happen if there's slowness in the system,
|
|
* or if simply the video rate is somehow higher that the input event rate.
|
|
* The HAL should be able to handle events with more than 1 video frame.
|
|
*
|
|
* The frames should be in chronological order, but it is not guaranteed that they will have
|
|
* monotonically increasing timestamps. Still, we provide consistent timestamps here since that
|
|
* is the most realistic mode of operation.
|
|
*/
|
|
TEST_P(InputClassifierHidlTest_1_0, Classify_TwoVideoFrames) {
|
|
MotionEvent event = getSimpleMotionEvent();
|
|
VideoFrame frame1;
|
|
frame1.data = {1, 2, 3, 4};
|
|
frame1.height = 2;
|
|
frame1.width = 2;
|
|
frame1.timestamp = event.eventTime;
|
|
VideoFrame frame2 = frame1;
|
|
frame2.data = {5, 5, 5, -1};
|
|
frame2.timestamp += 1;
|
|
event.frames = {frame1, frame2};
|
|
|
|
EXPECT_TRUE(classifier->classify(event).isOk());
|
|
// We are not checking the actual classification here,
|
|
// because the HAL operation is highly device-specific.
|
|
|
|
// Return HAL to a consistent state by doing a reset
|
|
classifier->reset();
|
|
}
|
|
|
|
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InputClassifierHidlTest_1_0);
|
|
INSTANTIATE_TEST_SUITE_P(
|
|
PerInstance, InputClassifierHidlTest_1_0,
|
|
testing::ValuesIn(android::hardware::getAllHalInstanceNames(IInputClassifier::descriptor)),
|
|
android::hardware::PrintInstanceNameToString);
|