Home | History | Annotate | Download | only in tests
      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 #include "../InputClassifier.h"
     18 #include <gtest/gtest.h>
     19 
     20 #include "TestInputListener.h"
     21 
     22 #include <android/hardware/input/classifier/1.0/IInputClassifier.h>
     23 
     24 using namespace android::hardware::input;
     25 
     26 namespace android {
     27 
     28 // --- InputClassifierTest ---
     29 
     30 static NotifyMotionArgs generateBasicMotionArgs() {
     31     // Create a basic motion event for testing
     32     PointerProperties properties;
     33     properties.id = 0;
     34     properties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
     35 
     36     PointerCoords coords;
     37     coords.clear();
     38     coords.setAxisValue(AMOTION_EVENT_AXIS_X, 1);
     39     coords.setAxisValue(AMOTION_EVENT_AXIS_Y, 1);
     40     static constexpr nsecs_t downTime = 2;
     41     NotifyMotionArgs motionArgs(1/*sequenceNum*/, downTime/*eventTime*/, 3/*deviceId*/,
     42             AINPUT_SOURCE_ANY, ADISPLAY_ID_DEFAULT, 4/*policyFlags*/, AMOTION_EVENT_ACTION_DOWN,
     43             0/*actionButton*/, 0/*flags*/, AMETA_NONE, 0/*buttonState*/, MotionClassification::NONE,
     44             AMOTION_EVENT_EDGE_FLAG_NONE, 5/*deviceTimestamp*/,
     45             1/*pointerCount*/, &properties, &coords, 0/*xPrecision*/, 0/*yPrecision*/,
     46             downTime, {}/*videoFrames*/);
     47     return motionArgs;
     48 }
     49 
     50 class InputClassifierTest : public testing::Test {
     51 protected:
     52     sp<InputClassifierInterface> mClassifier;
     53     sp<TestInputListener> mTestListener;
     54 
     55     virtual void SetUp() override {
     56         mTestListener = new TestInputListener();
     57         mClassifier = new InputClassifier(mTestListener);
     58     }
     59 
     60     virtual void TearDown() override {
     61         mClassifier.clear();
     62         mTestListener.clear();
     63     }
     64 };
     65 
     66 /**
     67  * Create a basic configuration change and send it to input classifier.
     68  * Expect that the event is received by the next input stage, unmodified.
     69  */
     70 TEST_F(InputClassifierTest, SendToNextStage_NotifyConfigurationChangedArgs) {
     71     // Create a basic configuration change and send to classifier
     72     NotifyConfigurationChangedArgs args(1/*sequenceNum*/, 2/*eventTime*/);
     73 
     74     mClassifier->notifyConfigurationChanged(&args);
     75     NotifyConfigurationChangedArgs outArgs;
     76     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled(&outArgs));
     77     ASSERT_EQ(args, outArgs);
     78 }
     79 
     80 TEST_F(InputClassifierTest, SendToNextStage_NotifyKeyArgs) {
     81     // Create a basic key event and send to classifier
     82     NotifyKeyArgs args(1/*sequenceNum*/, 2/*eventTime*/, 3/*deviceId*/, AINPUT_SOURCE_KEYBOARD,
     83             ADISPLAY_ID_DEFAULT, 0/*policyFlags*/, AKEY_EVENT_ACTION_DOWN, 4/*flags*/,
     84             AKEYCODE_HOME, 5/*scanCode*/, AMETA_NONE, 6/*downTime*/);
     85 
     86     mClassifier->notifyKey(&args);
     87     NotifyKeyArgs outArgs;
     88     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&outArgs));
     89     ASSERT_EQ(args, outArgs);
     90 }
     91 
     92 
     93 /**
     94  * Create a basic motion event and send it to input classifier.
     95  * Expect that the event is received by the next input stage, unmodified.
     96  */
     97 TEST_F(InputClassifierTest, SendToNextStage_NotifyMotionArgs) {
     98     NotifyMotionArgs motionArgs = generateBasicMotionArgs();
     99     mClassifier->notifyMotion(&motionArgs);
    100     NotifyMotionArgs args;
    101     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
    102     ASSERT_EQ(motionArgs, args);
    103 }
    104 
    105 /**
    106  * Create a basic switch event and send it to input classifier.
    107  * Expect that the event is received by the next input stage, unmodified.
    108  */
    109 TEST_F(InputClassifierTest, SendToNextStage_NotifySwitchArgs) {
    110     NotifySwitchArgs args(1/*sequenceNum*/, 2/*eventTime*/, 3/*policyFlags*/, 4/*switchValues*/,
    111             5/*switchMask*/);
    112 
    113     mClassifier->notifySwitch(&args);
    114     NotifySwitchArgs outArgs;
    115     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifySwitchWasCalled(&outArgs));
    116     ASSERT_EQ(args, outArgs);
    117 }
    118 
    119 /**
    120  * Create a basic device reset event and send it to input classifier.
    121  * Expect that the event is received by the next input stage, unmodified.
    122  */
    123 TEST_F(InputClassifierTest, SendToNextStage_NotifyDeviceResetArgs) {
    124     NotifyDeviceResetArgs args(1/*sequenceNum*/, 2/*eventTime*/, 3/*deviceId*/);
    125 
    126     mClassifier->notifyDeviceReset(&args);
    127     NotifyDeviceResetArgs outArgs;
    128     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyDeviceResetWasCalled(&outArgs));
    129     ASSERT_EQ(args, outArgs);
    130 }
    131 
    132 // --- MotionClassifierTest ---
    133 
    134 class MotionClassifierTest : public testing::Test {
    135 protected:
    136     std::unique_ptr<MotionClassifierInterface> mMotionClassifier;
    137 
    138     virtual void SetUp() override {
    139         mMotionClassifier = std::make_unique<MotionClassifier>();
    140     }
    141 };
    142 
    143 /**
    144  * Since MotionClassifier creates a new thread to communicate with HAL,
    145  * it's not really expected to ever exit. However, for testing purposes,
    146  * we need to ensure that it is able to exit cleanly.
    147  * If the thread is not properly cleaned up, it will generate SIGABRT.
    148  * The logic for exiting the thread and cleaning up the resources is inside
    149  * the destructor. Here, we just make sure the destructor does not crash.
    150  */
    151 TEST_F(MotionClassifierTest, Destructor_DoesNotCrash) {
    152     mMotionClassifier = nullptr;
    153 }
    154 
    155 /**
    156  * Make sure MotionClassifier can handle events that don't have any
    157  * video frames.
    158  */
    159 TEST_F(MotionClassifierTest, Classify_NoVideoFrames) {
    160     NotifyMotionArgs motionArgs = generateBasicMotionArgs();
    161 
    162     // We are not checking the return value, because we can't be making assumptions
    163     // about the HAL operation, since it will be highly hardware-dependent
    164     ASSERT_NO_FATAL_FAILURE(mMotionClassifier->classify(motionArgs));
    165 }
    166 
    167 /**
    168  * Make sure nothing crashes when a videoFrame is sent.
    169  */
    170 TEST_F(MotionClassifierTest, Classify_OneVideoFrame) {
    171     NotifyMotionArgs motionArgs = generateBasicMotionArgs();
    172 
    173     std::vector<int16_t> videoData = {1, 2, 3, 4};
    174     timeval timestamp = { 1, 1};
    175     TouchVideoFrame frame(2, 2, std::move(videoData), timestamp);
    176     motionArgs.videoFrames = {frame};
    177 
    178     // We are not checking the return value, because we can't be making assumptions
    179     // about the HAL operation, since it will be highly hardware-dependent
    180     ASSERT_NO_FATAL_FAILURE(mMotionClassifier->classify(motionArgs));
    181 }
    182 
    183 /**
    184  * Make sure nothing crashes when 2 videoFrames are sent.
    185  */
    186 TEST_F(MotionClassifierTest, Classify_TwoVideoFrames) {
    187     NotifyMotionArgs motionArgs = generateBasicMotionArgs();
    188 
    189     std::vector<int16_t> videoData1 = {1, 2, 3, 4};
    190     timeval timestamp1 = { 1, 1};
    191     TouchVideoFrame frame1(2, 2, std::move(videoData1), timestamp1);
    192 
    193     std::vector<int16_t> videoData2 = {6, 6, 6, 6};
    194     timeval timestamp2 = { 1, 2};
    195     TouchVideoFrame frame2(2, 2, std::move(videoData2), timestamp2);
    196 
    197     motionArgs.videoFrames = {frame1, frame2};
    198 
    199     // We are not checking the return value, because we can't be making assumptions
    200     // about the HAL operation, since it will be highly hardware-dependent
    201     ASSERT_NO_FATAL_FAILURE(mMotionClassifier->classify(motionArgs));
    202 }
    203 
    204 /**
    205  * Make sure MotionClassifier does not crash when it is reset.
    206  */
    207 TEST_F(MotionClassifierTest, Reset_DoesNotCrash) {
    208     ASSERT_NO_FATAL_FAILURE(mMotionClassifier->reset());
    209 }
    210 
    211 /**
    212  * Make sure MotionClassifier does not crash when a device is reset.
    213  */
    214 TEST_F(MotionClassifierTest, DeviceReset_DoesNotCrash) {
    215     NotifyDeviceResetArgs args(1/*sequenceNum*/, 2/*eventTime*/, 3/*deviceId*/);
    216     ASSERT_NO_FATAL_FAILURE(mMotionClassifier->reset(args));
    217 }
    218 
    219 } // namespace android
    220