blob: 1fd6cee1eb8d4eba07e58d9b4ce6e2273050658d [file] [log] [blame]
/*
* Copyright 2025 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.
*/
#include "../dispatcher/trace/AndroidInputEventProtoConverter.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
namespace android::inputdispatcher::trace {
namespace {
using testing::Return, testing::_;
class MockProtoAxisValue {
public:
MOCK_METHOD(void, set_axis, (int32_t));
MOCK_METHOD(void, set_value, (float));
};
class MockProtoPointer {
public:
MOCK_METHOD(void, set_pointer_id, (uint32_t));
MOCK_METHOD(void, set_tool_type, (int32_t));
MOCK_METHOD(MockProtoAxisValue*, add_axis_value, ());
};
class MockProtoMotion {
public:
MOCK_METHOD(void, set_event_id, (uint32_t));
MOCK_METHOD(void, set_event_time_nanos, (int64_t));
MOCK_METHOD(void, set_down_time_nanos, (int64_t));
MOCK_METHOD(void, set_source, (uint32_t));
MOCK_METHOD(void, set_action, (int32_t));
MOCK_METHOD(void, set_device_id, (uint32_t));
MOCK_METHOD(void, set_display_id, (uint32_t));
MOCK_METHOD(void, set_classification, (int32_t));
MOCK_METHOD(void, set_flags, (uint32_t));
MOCK_METHOD(void, set_policy_flags, (uint32_t));
MOCK_METHOD(void, set_button_state, (uint32_t));
MOCK_METHOD(void, set_action_button, (uint32_t));
MOCK_METHOD(void, set_cursor_position_x, (float));
MOCK_METHOD(void, set_cursor_position_y, (float));
MOCK_METHOD(void, set_meta_state, (uint32_t));
MOCK_METHOD(void, set_precision_x, (float));
MOCK_METHOD(void, set_precision_y, (float));
MOCK_METHOD(MockProtoPointer*, add_pointer, ());
};
class MockProtoKey {
public:
MOCK_METHOD(void, set_event_id, (uint32_t));
MOCK_METHOD(void, set_event_time_nanos, (int64_t));
MOCK_METHOD(void, set_down_time_nanos, (int64_t));
MOCK_METHOD(void, set_source, (uint32_t));
MOCK_METHOD(void, set_action, (int32_t));
MOCK_METHOD(void, set_device_id, (uint32_t));
MOCK_METHOD(void, set_display_id, (uint32_t));
MOCK_METHOD(void, set_repeat_count, (uint32_t));
MOCK_METHOD(void, set_flags, (uint32_t));
MOCK_METHOD(void, set_policy_flags, (uint32_t));
MOCK_METHOD(void, set_key_code, (uint32_t));
MOCK_METHOD(void, set_scan_code, (uint32_t));
MOCK_METHOD(void, set_meta_state, (uint32_t));
};
class MockProtoDispatchPointer {
public:
MOCK_METHOD(void, set_pointer_id, (uint32_t));
MOCK_METHOD(void, set_x_in_display, (float));
MOCK_METHOD(void, set_y_in_display, (float));
MOCK_METHOD(MockProtoAxisValue*, add_axis_value_in_window, ());
};
class MockProtoDispatch {
public:
MOCK_METHOD(void, set_event_id, (uint32_t));
MOCK_METHOD(void, set_vsync_id, (uint32_t));
MOCK_METHOD(void, set_window_id, (uint32_t));
MOCK_METHOD(void, set_resolved_flags, (uint32_t));
MOCK_METHOD(MockProtoDispatchPointer*, add_dispatched_pointer, ());
};
using TestProtoConverter =
AndroidInputEventProtoConverter<MockProtoMotion, MockProtoKey, MockProtoDispatch,
proto::AndroidInputEventConfig::Decoder>;
TEST(AndroidInputEventProtoConverterTest, ToProtoMotionEvent) {
TracedMotionEvent event{};
event.id = 1;
event.eventTime = 2;
event.downTime = 3;
event.source = AINPUT_SOURCE_MOUSE;
event.action = AMOTION_EVENT_ACTION_BUTTON_PRESS;
event.deviceId = 4;
event.displayId = ui::LogicalDisplayId(5);
event.classification = MotionClassification::PINCH;
event.flags = 6;
event.policyFlags = 7;
event.buttonState = 8;
event.actionButton = 9;
event.xCursorPosition = 10.0f;
event.yCursorPosition = 11.0f;
event.metaState = 12;
event.xPrecision = 13.0f;
event.yPrecision = 14.0f;
event.pointerProperties.emplace_back(PointerProperties{
.id = 15,
.toolType = ToolType::MOUSE,
});
event.pointerProperties.emplace_back(PointerProperties{
.id = 16,
.toolType = ToolType::FINGER,
});
event.pointerCoords.emplace_back();
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 17.0f);
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 18.0f);
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 19.0f);
event.pointerCoords.emplace_back();
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 20.0f);
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 21.0f);
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 22.0f);
testing::StrictMock<MockProtoMotion> proto;
testing::StrictMock<MockProtoPointer> pointer1;
testing::StrictMock<MockProtoPointer> pointer2;
testing::StrictMock<MockProtoAxisValue> axisValue1;
testing::StrictMock<MockProtoAxisValue> axisValue2;
testing::StrictMock<MockProtoAxisValue> axisValue3;
testing::StrictMock<MockProtoAxisValue> axisValue4;
testing::StrictMock<MockProtoAxisValue> axisValue5;
testing::StrictMock<MockProtoAxisValue> axisValue6;
EXPECT_CALL(proto, set_event_id(1));
EXPECT_CALL(proto, set_event_time_nanos(2));
EXPECT_CALL(proto, set_down_time_nanos(3));
EXPECT_CALL(proto, set_source(AINPUT_SOURCE_MOUSE));
EXPECT_CALL(proto, set_action(AMOTION_EVENT_ACTION_BUTTON_PRESS));
EXPECT_CALL(proto, set_device_id(4));
EXPECT_CALL(proto, set_display_id(5));
EXPECT_CALL(proto, set_classification(AMOTION_EVENT_CLASSIFICATION_PINCH));
EXPECT_CALL(proto, set_flags(6));
EXPECT_CALL(proto, set_policy_flags(7));
EXPECT_CALL(proto, set_button_state(8));
EXPECT_CALL(proto, set_action_button(9));
EXPECT_CALL(proto, set_cursor_position_x(10.0f));
EXPECT_CALL(proto, set_cursor_position_y(11.0f));
EXPECT_CALL(proto, set_meta_state(12));
EXPECT_CALL(proto, set_precision_x(13.0f));
EXPECT_CALL(proto, set_precision_y(14.0f));
EXPECT_CALL(proto, add_pointer()).WillOnce(Return(&pointer1)).WillOnce(Return(&pointer2));
EXPECT_CALL(pointer1, set_pointer_id(15));
EXPECT_CALL(pointer1, set_tool_type(AMOTION_EVENT_TOOL_TYPE_MOUSE));
EXPECT_CALL(pointer1, add_axis_value())
.WillOnce(Return(&axisValue1))
.WillOnce(Return(&axisValue2))
.WillOnce(Return(&axisValue3));
EXPECT_CALL(axisValue1, set_axis(AMOTION_EVENT_AXIS_X));
EXPECT_CALL(axisValue1, set_value(17.0f));
EXPECT_CALL(axisValue2, set_axis(AMOTION_EVENT_AXIS_Y));
EXPECT_CALL(axisValue2, set_value(18.0f));
EXPECT_CALL(axisValue3, set_axis(AMOTION_EVENT_AXIS_PRESSURE));
EXPECT_CALL(axisValue3, set_value(19.0f));
EXPECT_CALL(pointer2, set_pointer_id(16));
EXPECT_CALL(pointer2, set_tool_type(AMOTION_EVENT_TOOL_TYPE_FINGER));
EXPECT_CALL(pointer2, add_axis_value())
.WillOnce(Return(&axisValue4))
.WillOnce(Return(&axisValue5))
.WillOnce(Return(&axisValue6));
EXPECT_CALL(axisValue4, set_axis(AMOTION_EVENT_AXIS_X));
EXPECT_CALL(axisValue4, set_value(20.0f));
EXPECT_CALL(axisValue5, set_axis(AMOTION_EVENT_AXIS_Y));
EXPECT_CALL(axisValue5, set_value(21.0f));
EXPECT_CALL(axisValue6, set_axis(AMOTION_EVENT_AXIS_PRESSURE));
EXPECT_CALL(axisValue6, set_value(22.0f));
TestProtoConverter::toProtoMotionEvent(event, proto, /*isRedacted=*/false);
}
TEST(AndroidInputEventProtoConverterTest, ToProtoMotionEvent_Redacted) {
TracedMotionEvent event{};
event.id = 1;
event.eventTime = 2;
event.downTime = 3;
event.source = AINPUT_SOURCE_MOUSE;
event.action = AMOTION_EVENT_ACTION_BUTTON_PRESS;
event.deviceId = 4;
event.displayId = ui::LogicalDisplayId(5);
event.classification = MotionClassification::PINCH;
event.flags = 6;
event.policyFlags = 7;
event.buttonState = 8;
event.actionButton = 9;
event.xCursorPosition = 10.0f;
event.yCursorPosition = 11.0f;
event.metaState = 12;
event.xPrecision = 13.0f;
event.yPrecision = 14.0f;
event.pointerProperties.emplace_back(PointerProperties{
.id = 15,
.toolType = ToolType::MOUSE,
});
event.pointerProperties.emplace_back(PointerProperties{
.id = 16,
.toolType = ToolType::FINGER,
});
event.pointerCoords.emplace_back();
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 17.0f);
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 18.0f);
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 19.0f);
event.pointerCoords.emplace_back();
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 20.0f);
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 21.0f);
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 22.0f);
testing::StrictMock<MockProtoMotion> proto;
testing::StrictMock<MockProtoPointer> pointer1;
testing::StrictMock<MockProtoPointer> pointer2;
testing::StrictMock<MockProtoAxisValue> axisValue1;
testing::StrictMock<MockProtoAxisValue> axisValue2;
testing::StrictMock<MockProtoAxisValue> axisValue3;
testing::StrictMock<MockProtoAxisValue> axisValue4;
testing::StrictMock<MockProtoAxisValue> axisValue5;
testing::StrictMock<MockProtoAxisValue> axisValue6;
EXPECT_CALL(proto, set_event_id(1));
EXPECT_CALL(proto, set_event_time_nanos(2));
EXPECT_CALL(proto, set_down_time_nanos(3));
EXPECT_CALL(proto, set_source(AINPUT_SOURCE_MOUSE));
EXPECT_CALL(proto, set_action(AMOTION_EVENT_ACTION_BUTTON_PRESS));
EXPECT_CALL(proto, set_device_id(4));
EXPECT_CALL(proto, set_display_id(5));
EXPECT_CALL(proto, set_classification(AMOTION_EVENT_CLASSIFICATION_PINCH));
EXPECT_CALL(proto, set_flags(6));
EXPECT_CALL(proto, set_policy_flags(7));
EXPECT_CALL(proto, set_button_state(8));
EXPECT_CALL(proto, set_action_button(9));
EXPECT_CALL(proto, add_pointer()).WillOnce(Return(&pointer1)).WillOnce(Return(&pointer2));
EXPECT_CALL(pointer1, set_pointer_id(15));
EXPECT_CALL(pointer1, set_tool_type(AMOTION_EVENT_TOOL_TYPE_MOUSE));
EXPECT_CALL(pointer1, add_axis_value())
.WillOnce(Return(&axisValue1))
.WillOnce(Return(&axisValue2))
.WillOnce(Return(&axisValue3));
EXPECT_CALL(axisValue1, set_axis(AMOTION_EVENT_AXIS_X));
EXPECT_CALL(axisValue2, set_axis(AMOTION_EVENT_AXIS_Y));
EXPECT_CALL(axisValue3, set_axis(AMOTION_EVENT_AXIS_PRESSURE));
EXPECT_CALL(pointer2, set_pointer_id(16));
EXPECT_CALL(pointer2, set_tool_type(AMOTION_EVENT_TOOL_TYPE_FINGER));
EXPECT_CALL(pointer2, add_axis_value())
.WillOnce(Return(&axisValue4))
.WillOnce(Return(&axisValue5))
.WillOnce(Return(&axisValue6));
EXPECT_CALL(axisValue4, set_axis(AMOTION_EVENT_AXIS_X));
EXPECT_CALL(axisValue5, set_axis(AMOTION_EVENT_AXIS_Y));
EXPECT_CALL(axisValue6, set_axis(AMOTION_EVENT_AXIS_PRESSURE));
// Redacted fields
EXPECT_CALL(proto, set_meta_state(_)).Times(0);
EXPECT_CALL(proto, set_cursor_position_x(_)).Times(0);
EXPECT_CALL(proto, set_cursor_position_y(_)).Times(0);
EXPECT_CALL(proto, set_precision_x(_)).Times(0);
EXPECT_CALL(proto, set_precision_y(_)).Times(0);
EXPECT_CALL(axisValue1, set_value(_)).Times(0);
EXPECT_CALL(axisValue2, set_value(_)).Times(0);
EXPECT_CALL(axisValue3, set_value(_)).Times(0);
EXPECT_CALL(axisValue4, set_value(_)).Times(0);
EXPECT_CALL(axisValue5, set_value(_)).Times(0);
EXPECT_CALL(axisValue6, set_value(_)).Times(0);
TestProtoConverter::toProtoMotionEvent(event, proto, /*isRedacted=*/true);
}
// Test any special handling for zero values for pointer events.
TEST(AndroidInputEventProtoConverterTest, ToProtoMotionEvent_ZeroValues) {
TracedMotionEvent event{};
event.id = 0;
event.eventTime = 0;
event.downTime = 0;
event.source = AINPUT_SOURCE_MOUSE;
event.action = AMOTION_EVENT_ACTION_BUTTON_PRESS;
event.deviceId = 0;
event.displayId = ui::LogicalDisplayId(0);
event.classification = {};
event.flags = 0;
event.policyFlags = 0;
event.buttonState = 0;
event.actionButton = 0;
event.xCursorPosition = 0.0f;
event.yCursorPosition = 0.0f;
event.metaState = 0;
event.xPrecision = 0.0f;
event.yPrecision = 0.0f;
event.pointerProperties.emplace_back(PointerProperties{
.id = 0,
.toolType = ToolType::MOUSE,
});
event.pointerProperties.emplace_back(PointerProperties{
.id = 1,
.toolType = ToolType::FINGER,
});
// Zero values for x and y axes are always traced for pointer events.
// However, zero values for other axes may not necessarily be traced.
event.pointerCoords.emplace_back();
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 0.0f);
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 1.0f);
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.0f);
event.pointerCoords.emplace_back();
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 0.0f);
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 0.0f);
event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.0f);
testing::StrictMock<MockProtoMotion> proto;
testing::StrictMock<MockProtoPointer> pointer1;
testing::StrictMock<MockProtoPointer> pointer2;
testing::StrictMock<MockProtoAxisValue> axisValue1;
testing::StrictMock<MockProtoAxisValue> axisValue2;
testing::StrictMock<MockProtoAxisValue> axisValue3;
testing::StrictMock<MockProtoAxisValue> axisValue4;
EXPECT_CALL(proto, set_event_id(0));
EXPECT_CALL(proto, set_event_time_nanos(0));
EXPECT_CALL(proto, set_down_time_nanos(0));
EXPECT_CALL(proto, set_source(AINPUT_SOURCE_MOUSE));
EXPECT_CALL(proto, set_action(AMOTION_EVENT_ACTION_BUTTON_PRESS));
EXPECT_CALL(proto, set_device_id(0));
EXPECT_CALL(proto, set_display_id(0));
EXPECT_CALL(proto, set_classification(0));
EXPECT_CALL(proto, set_flags(0));
EXPECT_CALL(proto, set_policy_flags(0));
EXPECT_CALL(proto, set_button_state(0));
EXPECT_CALL(proto, set_action_button(0));
EXPECT_CALL(proto, set_cursor_position_x(0.0f));
EXPECT_CALL(proto, set_cursor_position_y(0.0f));
EXPECT_CALL(proto, set_meta_state(0));
EXPECT_CALL(proto, set_precision_x(0.0f));
EXPECT_CALL(proto, set_precision_y(0.0f));
EXPECT_CALL(proto, add_pointer()).WillOnce(Return(&pointer1)).WillOnce(Return(&pointer2));
EXPECT_CALL(pointer1, set_pointer_id(0));
EXPECT_CALL(pointer1, set_tool_type(AMOTION_EVENT_TOOL_TYPE_MOUSE));
EXPECT_CALL(pointer1, add_axis_value())
.WillOnce(Return(&axisValue1))
.WillOnce(Return(&axisValue2));
EXPECT_CALL(axisValue1, set_axis(AMOTION_EVENT_AXIS_X));
EXPECT_CALL(axisValue1, set_value(0.0f));
EXPECT_CALL(axisValue2, set_axis(AMOTION_EVENT_AXIS_Y));
EXPECT_CALL(axisValue2, set_value(1.0f));
EXPECT_CALL(pointer2, set_pointer_id(1));
EXPECT_CALL(pointer2, set_tool_type(AMOTION_EVENT_TOOL_TYPE_FINGER));
EXPECT_CALL(pointer2, add_axis_value())
.WillOnce(Return(&axisValue3))
.WillOnce(Return(&axisValue4));
EXPECT_CALL(axisValue3, set_axis(AMOTION_EVENT_AXIS_X));
EXPECT_CALL(axisValue3, set_value(0.0f));
EXPECT_CALL(axisValue4, set_axis(AMOTION_EVENT_AXIS_Y));
EXPECT_CALL(axisValue4, set_value(0.0f));
TestProtoConverter::toProtoMotionEvent(event, proto, /*isRedacted=*/false);
}
TEST(AndroidInputEventProtoConverterTest, ToProtoKeyEvent) {
TracedKeyEvent event{};
event.id = 1;
event.eventTime = 2;
event.downTime = 3;
event.source = AINPUT_SOURCE_KEYBOARD;
event.action = AKEY_EVENT_ACTION_DOWN;
event.deviceId = 4;
event.displayId = ui::LogicalDisplayId(5);
event.repeatCount = 6;
event.flags = 7;
event.policyFlags = 8;
event.keyCode = 9;
event.scanCode = 10;
event.metaState = 11;
testing::StrictMock<MockProtoKey> proto;
EXPECT_CALL(proto, set_event_id(1));
EXPECT_CALL(proto, set_event_time_nanos(2));
EXPECT_CALL(proto, set_down_time_nanos(3));
EXPECT_CALL(proto, set_source(AINPUT_SOURCE_KEYBOARD));
EXPECT_CALL(proto, set_action(AKEY_EVENT_ACTION_DOWN));
EXPECT_CALL(proto, set_device_id(4));
EXPECT_CALL(proto, set_display_id(5));
EXPECT_CALL(proto, set_repeat_count(6));
EXPECT_CALL(proto, set_flags(7));
EXPECT_CALL(proto, set_policy_flags(8));
EXPECT_CALL(proto, set_key_code(9));
EXPECT_CALL(proto, set_scan_code(10));
EXPECT_CALL(proto, set_meta_state(11));
TestProtoConverter::toProtoKeyEvent(event, proto, /*isRedacted=*/false);
}
TEST(AndroidInputEventProtoConverterTest, ToProtoKeyEvent_Redacted) {
TracedKeyEvent event{};
event.id = 1;
event.eventTime = 2;
event.downTime = 3;
event.source = AINPUT_SOURCE_KEYBOARD;
event.action = AKEY_EVENT_ACTION_DOWN;
event.deviceId = 4;
event.displayId = ui::LogicalDisplayId(5);
event.repeatCount = 6;
event.flags = 7;
event.policyFlags = 8;
event.keyCode = 9;
event.scanCode = 10;
event.metaState = 11;
testing::StrictMock<MockProtoKey> proto;
EXPECT_CALL(proto, set_event_id(1));
EXPECT_CALL(proto, set_event_time_nanos(2));
EXPECT_CALL(proto, set_down_time_nanos(3));
EXPECT_CALL(proto, set_source(AINPUT_SOURCE_KEYBOARD));
EXPECT_CALL(proto, set_action(AKEY_EVENT_ACTION_DOWN));
EXPECT_CALL(proto, set_device_id(4));
EXPECT_CALL(proto, set_display_id(5));
EXPECT_CALL(proto, set_repeat_count(6));
EXPECT_CALL(proto, set_flags(7));
EXPECT_CALL(proto, set_policy_flags(8));
// Redacted fields
EXPECT_CALL(proto, set_key_code(_)).Times(0);
EXPECT_CALL(proto, set_scan_code(_)).Times(0);
EXPECT_CALL(proto, set_meta_state(_)).Times(0);
TestProtoConverter::toProtoKeyEvent(event, proto, /*isRedacted=*/true);
}
TEST(AndroidInputEventProtoConverterTest, ToProtoWindowDispatchEvent_Motion_IdentityTransform) {
TracedMotionEvent motion{};
motion.pointerProperties.emplace_back(PointerProperties{
.id = 4,
.toolType = ToolType::MOUSE,
});
motion.pointerCoords.emplace_back();
motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 5.0f);
motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 6.0f);
WindowDispatchArgs args{};
args.eventEntry = motion;
args.vsyncId = 1;
args.windowId = 2;
args.resolvedFlags = 3;
args.rawTransform = ui::Transform{};
args.transform = ui::Transform{};
testing::StrictMock<MockProtoDispatch> proto;
testing::StrictMock<MockProtoDispatchPointer> pointer;
EXPECT_CALL(proto, set_event_id(0));
EXPECT_CALL(proto, set_vsync_id(1));
EXPECT_CALL(proto, set_window_id(2));
EXPECT_CALL(proto, set_resolved_flags(3));
EXPECT_CALL(proto, add_dispatched_pointer()).WillOnce(Return(&pointer));
EXPECT_CALL(pointer, set_pointer_id(4));
// Since we are using identity transforms, the axis values will be identical to those in the
// traced event, so they should not be traced here.
EXPECT_CALL(pointer, add_axis_value_in_window()).Times(0);
EXPECT_CALL(pointer, set_x_in_display(_)).Times(0);
EXPECT_CALL(pointer, set_y_in_display(_)).Times(0);
TestProtoConverter::toProtoWindowDispatchEvent(args, proto, /*isRedacted=*/false);
}
TEST(AndroidInputEventProtoConverterTest, ToProtoWindowDispatchEvent_Motion_CustomTransform) {
TracedMotionEvent motion{};
motion.pointerProperties.emplace_back(PointerProperties{
.id = 4,
.toolType = ToolType::MOUSE,
});
motion.pointerCoords.emplace_back();
motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 8.0f);
motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 6.0f);
WindowDispatchArgs args{};
args.eventEntry = motion;
args.vsyncId = 1;
args.windowId = 2;
args.resolvedFlags = 3;
args.rawTransform.set(2, 0, 0, 0.5);
args.transform.set(1.0, 0, 0, 0.5);
testing::StrictMock<MockProtoDispatch> proto;
testing::StrictMock<MockProtoDispatchPointer> pointer;
testing::StrictMock<MockProtoAxisValue> axisValue1;
EXPECT_CALL(proto, set_event_id(0));
EXPECT_CALL(proto, set_vsync_id(1));
EXPECT_CALL(proto, set_window_id(2));
EXPECT_CALL(proto, set_resolved_flags(3));
EXPECT_CALL(proto, add_dispatched_pointer()).WillOnce(Return(&pointer));
EXPECT_CALL(pointer, set_pointer_id(4));
// Only the transformed axis-values that differ from the traced event will be traced.
EXPECT_CALL(pointer, add_axis_value_in_window()).WillOnce(Return(&axisValue1));
EXPECT_CALL(pointer, set_x_in_display(16.0f)); // MotionEvent::getRawX
EXPECT_CALL(pointer, set_y_in_display(3.0f)); // MotionEvent::getRawY
EXPECT_CALL(axisValue1, set_axis(AMOTION_EVENT_AXIS_Y));
EXPECT_CALL(axisValue1, set_value(3.0f));
TestProtoConverter::toProtoWindowDispatchEvent(args, proto, /*isRedacted=*/false);
}
TEST(AndroidInputEventProtoConverterTest, ToProtoWindowDispatchEvent_Motion_Redacted) {
TracedMotionEvent motion{};
motion.pointerProperties.emplace_back(PointerProperties{
.id = 4,
.toolType = ToolType::MOUSE,
});
motion.pointerCoords.emplace_back();
motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 5.0f);
motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 6.0f);
WindowDispatchArgs args{};
args.eventEntry = motion;
args.vsyncId = 1;
args.windowId = 2;
args.resolvedFlags = 3;
args.rawTransform = ui::Transform{};
args.transform = ui::Transform{};
testing::StrictMock<MockProtoDispatch> proto;
EXPECT_CALL(proto, set_event_id(0));
EXPECT_CALL(proto, set_vsync_id(1));
EXPECT_CALL(proto, set_window_id(2));
EXPECT_CALL(proto, set_resolved_flags(3));
// Redacted fields
EXPECT_CALL(proto, add_dispatched_pointer()).Times(0);
TestProtoConverter::toProtoWindowDispatchEvent(args, proto, /*isRedacted=*/true);
}
TEST(AndroidInputEventProtoConverterTest, ToProtoWindowDispatchEvent_Key) {
TracedKeyEvent key{};
WindowDispatchArgs args{};
args.eventEntry = key;
args.vsyncId = 1;
args.windowId = 2;
args.resolvedFlags = 3;
args.rawTransform = ui::Transform{};
args.transform = ui::Transform{};
testing::StrictMock<MockProtoDispatch> proto;
EXPECT_CALL(proto, set_event_id(0));
EXPECT_CALL(proto, set_vsync_id(1));
EXPECT_CALL(proto, set_window_id(2));
EXPECT_CALL(proto, set_resolved_flags(3));
TestProtoConverter::toProtoWindowDispatchEvent(args, proto, /*isRedacted=*/true);
}
} // namespace
} // namespace android::inputdispatcher::trace