Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88daa900 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Allow values from SourceClass inside rust Source

Inside ViewTest::testOnTouchEventScroll, some MotionEvents are created
without a valid source. During injection, they get appended with
SourceClass::Pointer.

If these events are sent into the InputVerifier, it's basically being
asked to convert 0x2 === AINPUT_SOURCE_CLASS_POINTER into rust's
input::Source.

This fails during unwrap:

$ TEST=libinput_tests; m $TEST && $ANDROID_HOST_OUT/nativetest64/$TEST/$TEST
[ RUN      ] InputVerifierTest.BadSourceProcess
thread '<unnamed>' panicked at 'called `Option::unwrap()` on a `None` value', frameworks/native/libs/input/rust/lib.rs:84:35
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
fatal runtime error: failed to initiate panic, error 5
Aborted

To mitigate this, add the SourceClass definitions into Source, thus
allowing such conversions.

Bug: 303143553
Bug: 211379801
Test: TEST=libinput_rust_test; m $TEST && $ANDROID_HOST_OUT/nativetest64/$TEST/$TEST
Test: TEST=libinput_tests; m $TEST && $ANDROID_HOST_OUT/nativetest64/$TEST/$TEST
Change-Id: I46415d88251937959104bb82a3976e72ffcfcaf9
parent cc89e85f
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -35,7 +35,20 @@ pub enum SourceClass {

bitflags! {
    /// Source of the input device or input events.
    #[derive(Debug, PartialEq)]
    pub struct Source: u32 {
        // Constants from SourceClass, added here for compatibility reasons
        /// SourceClass::Button
        const SourceClassButton = SourceClass::Button as u32;
        /// SourceClass::Pointer
        const SourceClassPointer = SourceClass::Pointer as u32;
        /// SourceClass::Navigation
        const SourceClassNavigation = SourceClass::Navigation as u32;
        /// SourceClass::Position
        const SourceClassPosition = SourceClass::Position as u32;
        /// SourceClass::Joystick
        const SourceClassJoystick = SourceClass::Joystick as u32;

        /// SOURCE_UNKNOWN
        const Unknown = input_bindgen::AINPUT_SOURCE_UNKNOWN;
        /// SOURCE_KEYBOARD
@@ -190,3 +203,14 @@ impl Source {
        self.bits() & class_bits == class_bits
    }
}

#[cfg(test)]
mod tests {
    use crate::input::SourceClass;
    use crate::Source;
    #[test]
    fn convert_source_class_pointer() {
        let source = Source::from_bits(input_bindgen::AINPUT_SOURCE_CLASS_POINTER).unwrap();
        assert!(source.is_from_class(SourceClass::Pointer));
    }
}
+25 −0
Original line number Diff line number Diff line
@@ -20,10 +20,35 @@

namespace android {

using android::base::Result;

TEST(InputVerifierTest, CreationWithInvalidUtfStringDoesNotCrash) {
    constexpr char bytes[] = {static_cast<char>(0xC0), static_cast<char>(0x80)};
    const std::string name(bytes, sizeof(bytes));
    InputVerifier verifier(name);
}

TEST(InputVerifierTest, ProcessSourceClassPointer) {
    InputVerifier verifier("Verify testOnTouchEventScroll");

    std::vector<PointerProperties> properties;
    properties.push_back({});
    properties.back().clear();
    properties.back().id = 0;
    properties.back().toolType = ToolType::UNKNOWN;

    std::vector<PointerCoords> coords;
    coords.push_back({});
    coords.back().clear();
    coords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 75);
    coords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 300);

    const Result<void> result =
            verifier.processMovement(/*deviceId=*/0, AINPUT_SOURCE_CLASS_POINTER,
                                     AMOTION_EVENT_ACTION_DOWN,
                                     /*pointerCount=*/properties.size(), properties.data(),
                                     coords.data(), /*flags=*/0);
    ASSERT_TRUE(result.ok());
}

} // namespace android