diff options
author | 2023-10-03 10:22:07 +0000 | |
---|---|---|
committer | 2023-10-04 11:04:15 +0000 | |
commit | 631a14e89b5a2d6c47ab001de5ec1333b67c7962 (patch) | |
tree | 80112332001e8ab9f521f87e0b587a1667655756 | |
parent | e3062abf3ad49a74ffb4f8e9cee2eeb8c46720be (diff) |
Move common device metrics code to InputDeviceMetricsSource
Move common device metrics code from InputDeviceMetricsCollector to
InputDeviceMetricsSource.
The common code moved is:
* enum class InputDeviceUsageSource
* InputDeviceUsageSource getUsageSourceForKeyArgs(int32_t, const NotifyKeyArgs&)
* set<InputDeviceUsageSource> getUsageSourcesForMotionArgs(const NotifyMotionArgs&)
This code will be used by both InputDeviceMetricsCollector,
which is a part of inputflinger as well as LatencyTracker,
which is a part of the dispatcher.
InputDeviceMetricsSource can be included in the places using the common code.
Bug: 303059859
Test: atest inputflinger_tests:InputDeviceMetricsSourceDeviceClassificationTest
Change-Id: Ia8528e641cd162d5025495d5bf6903b2dbab2ed3
-rw-r--r-- | services/inputflinger/Android.bp | 2 | ||||
-rw-r--r-- | services/inputflinger/InputDeviceMetricsCollector.cpp | 93 | ||||
-rw-r--r-- | services/inputflinger/InputDeviceMetricsCollector.h | 34 | ||||
-rw-r--r-- | services/inputflinger/InputDeviceMetricsSource.cpp | 118 | ||||
-rw-r--r-- | services/inputflinger/InputDeviceMetricsSource.h | 58 | ||||
-rw-r--r-- | services/inputflinger/tests/Android.bp | 1 | ||||
-rw-r--r-- | services/inputflinger/tests/InputDeviceMetricsCollector_test.cpp | 257 | ||||
-rw-r--r-- | services/inputflinger/tests/InputDeviceMetricsSource_test.cpp | 296 |
8 files changed, 477 insertions, 382 deletions
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp index 5d1d4af44c..76729efb0a 100644 --- a/services/inputflinger/Android.bp +++ b/services/inputflinger/Android.bp @@ -182,6 +182,7 @@ cc_library_headers { filegroup { name: "libinputflinger_base_sources", srcs: [ + "InputDeviceMetricsSource.cpp", "InputListener.cpp", "InputReaderBase.cpp", "InputThread.cpp", @@ -199,6 +200,7 @@ cc_defaults { "libcutils", "libinput", "liblog", + "libstatslog", "libutils", ], header_libs: [ diff --git a/services/inputflinger/InputDeviceMetricsCollector.cpp b/services/inputflinger/InputDeviceMetricsCollector.cpp index 8e04150efa..cefb14059c 100644 --- a/services/inputflinger/InputDeviceMetricsCollector.cpp +++ b/services/inputflinger/InputDeviceMetricsCollector.cpp @@ -17,11 +17,10 @@ #define LOG_TAG "InputDeviceMetricsCollector" #include "InputDeviceMetricsCollector.h" -#include "KeyCodeClassifications.h" +#include "InputDeviceMetricsSource.h" #include <android-base/stringprintf.h> #include <input/PrintTools.h> -#include <linux/input.h> namespace android { @@ -113,96 +112,6 @@ bool isIgnoredInputDeviceId(int32_t deviceId) { } // namespace -InputDeviceUsageSource getUsageSourceForKeyArgs(int32_t keyboardType, - const NotifyKeyArgs& keyArgs) { - if (!isFromSource(keyArgs.source, AINPUT_SOURCE_KEYBOARD)) { - return InputDeviceUsageSource::UNKNOWN; - } - - if (isFromSource(keyArgs.source, AINPUT_SOURCE_DPAD) && - DPAD_ALL_KEYCODES.count(keyArgs.keyCode) != 0) { - return InputDeviceUsageSource::DPAD; - } - - if (isFromSource(keyArgs.source, AINPUT_SOURCE_GAMEPAD) && - GAMEPAD_KEYCODES.count(keyArgs.keyCode) != 0) { - return InputDeviceUsageSource::GAMEPAD; - } - - if (keyboardType == AINPUT_KEYBOARD_TYPE_ALPHABETIC) { - return InputDeviceUsageSource::KEYBOARD; - } - - return InputDeviceUsageSource::BUTTONS; -} - -std::set<InputDeviceUsageSource> getUsageSourcesForMotionArgs(const NotifyMotionArgs& motionArgs) { - LOG_ALWAYS_FATAL_IF(motionArgs.getPointerCount() < 1, "Received motion args without pointers"); - std::set<InputDeviceUsageSource> sources; - - for (uint32_t i = 0; i < motionArgs.getPointerCount(); i++) { - const auto toolType = motionArgs.pointerProperties[i].toolType; - if (isFromSource(motionArgs.source, AINPUT_SOURCE_MOUSE)) { - if (toolType == ToolType::MOUSE) { - sources.emplace(InputDeviceUsageSource::MOUSE); - continue; - } - if (toolType == ToolType::FINGER) { - sources.emplace(InputDeviceUsageSource::TOUCHPAD); - continue; - } - if (isStylusToolType(toolType)) { - sources.emplace(InputDeviceUsageSource::STYLUS_INDIRECT); - continue; - } - } - if (isFromSource(motionArgs.source, AINPUT_SOURCE_MOUSE_RELATIVE) && - toolType == ToolType::MOUSE) { - sources.emplace(InputDeviceUsageSource::MOUSE_CAPTURED); - continue; - } - if (isFromSource(motionArgs.source, AINPUT_SOURCE_TOUCHPAD) && - toolType == ToolType::FINGER) { - sources.emplace(InputDeviceUsageSource::TOUCHPAD_CAPTURED); - continue; - } - if (isFromSource(motionArgs.source, AINPUT_SOURCE_BLUETOOTH_STYLUS) && - isStylusToolType(toolType)) { - sources.emplace(InputDeviceUsageSource::STYLUS_FUSED); - continue; - } - if (isFromSource(motionArgs.source, AINPUT_SOURCE_STYLUS) && isStylusToolType(toolType)) { - sources.emplace(InputDeviceUsageSource::STYLUS_DIRECT); - continue; - } - if (isFromSource(motionArgs.source, AINPUT_SOURCE_TOUCH_NAVIGATION)) { - sources.emplace(InputDeviceUsageSource::TOUCH_NAVIGATION); - continue; - } - if (isFromSource(motionArgs.source, AINPUT_SOURCE_JOYSTICK)) { - sources.emplace(InputDeviceUsageSource::JOYSTICK); - continue; - } - if (isFromSource(motionArgs.source, AINPUT_SOURCE_ROTARY_ENCODER)) { - sources.emplace(InputDeviceUsageSource::ROTARY_ENCODER); - continue; - } - if (isFromSource(motionArgs.source, AINPUT_SOURCE_TRACKBALL)) { - sources.emplace(InputDeviceUsageSource::TRACKBALL); - continue; - } - if (isFromSource(motionArgs.source, AINPUT_SOURCE_TOUCHSCREEN)) { - sources.emplace(InputDeviceUsageSource::TOUCHSCREEN); - continue; - } - sources.emplace(InputDeviceUsageSource::UNKNOWN); - } - - return sources; -} - -// --- InputDeviceMetricsCollector --- - InputDeviceMetricsCollector::InputDeviceMetricsCollector(InputListenerInterface& listener) : InputDeviceMetricsCollector(listener, sStatsdLogger, DEFAULT_USAGE_SESSION_TIMEOUT) {} diff --git a/services/inputflinger/InputDeviceMetricsCollector.h b/services/inputflinger/InputDeviceMetricsCollector.h index 7775087530..9633664a0e 100644 --- a/services/inputflinger/InputDeviceMetricsCollector.h +++ b/services/inputflinger/InputDeviceMetricsCollector.h @@ -16,6 +16,7 @@ #pragma once +#include "InputDeviceMetricsSource.h" #include "InputListener.h" #include "NotifyArgs.h" #include "SyncQueue.h" @@ -23,7 +24,6 @@ #include <ftl/mixins.h> #include <gui/WindowInfo.h> #include <input/InputDevice.h> -#include <statslog.h> #include <chrono> #include <functional> #include <map> @@ -52,38 +52,6 @@ public: virtual void dump(std::string& dump) = 0; }; -/** - * Enum representation of the InputDeviceUsageSource. - */ -enum class InputDeviceUsageSource : int32_t { - UNKNOWN = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__UNKNOWN, - BUTTONS = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__BUTTONS, - KEYBOARD = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__KEYBOARD, - DPAD = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__DPAD, - GAMEPAD = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__GAMEPAD, - JOYSTICK = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__JOYSTICK, - MOUSE = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__MOUSE, - MOUSE_CAPTURED = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__MOUSE_CAPTURED, - TOUCHPAD = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__TOUCHPAD, - TOUCHPAD_CAPTURED = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__TOUCHPAD_CAPTURED, - ROTARY_ENCODER = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__ROTARY_ENCODER, - STYLUS_DIRECT = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__STYLUS_DIRECT, - STYLUS_INDIRECT = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__STYLUS_INDIRECT, - STYLUS_FUSED = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__STYLUS_FUSED, - TOUCH_NAVIGATION = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__TOUCH_NAVIGATION, - TOUCHSCREEN = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__TOUCHSCREEN, - TRACKBALL = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__TRACKBALL, - - ftl_first = UNKNOWN, - ftl_last = TRACKBALL, -}; - -/** Returns the InputDeviceUsageSource that corresponds to the key event. */ -InputDeviceUsageSource getUsageSourceForKeyArgs(int32_t keyboardType, const NotifyKeyArgs&); - -/** Returns the InputDeviceUsageSources that correspond to the motion event. */ -std::set<InputDeviceUsageSource> getUsageSourcesForMotionArgs(const NotifyMotionArgs&); - /** The logging interface for the metrics collector, injected for testing. */ class InputDeviceMetricsLogger { public: diff --git a/services/inputflinger/InputDeviceMetricsSource.cpp b/services/inputflinger/InputDeviceMetricsSource.cpp new file mode 100644 index 0000000000..dee4cb836e --- /dev/null +++ b/services/inputflinger/InputDeviceMetricsSource.cpp @@ -0,0 +1,118 @@ +/* + * Copyright 2023 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 "InputDeviceMetricsSource.h" + +#include "KeyCodeClassifications.h" + +#include <android/input.h> +#include <input/Input.h> +#include <linux/input.h> +#include <log/log_main.h> + +#include <set> + +namespace android { + +InputDeviceUsageSource getUsageSourceForKeyArgs(int32_t keyboardType, + const NotifyKeyArgs& keyArgs) { + if (!isFromSource(keyArgs.source, AINPUT_SOURCE_KEYBOARD)) { + return InputDeviceUsageSource::UNKNOWN; + } + + if (isFromSource(keyArgs.source, AINPUT_SOURCE_DPAD) && + DPAD_ALL_KEYCODES.count(keyArgs.keyCode) != 0) { + return InputDeviceUsageSource::DPAD; + } + + if (isFromSource(keyArgs.source, AINPUT_SOURCE_GAMEPAD) && + GAMEPAD_KEYCODES.count(keyArgs.keyCode) != 0) { + return InputDeviceUsageSource::GAMEPAD; + } + + if (keyboardType == AINPUT_KEYBOARD_TYPE_ALPHABETIC) { + return InputDeviceUsageSource::KEYBOARD; + } + + return InputDeviceUsageSource::BUTTONS; +} + +std::set<InputDeviceUsageSource> getUsageSourcesForMotionArgs(const NotifyMotionArgs& motionArgs) { + LOG_ALWAYS_FATAL_IF(motionArgs.getPointerCount() < 1, "Received motion args without pointers"); + std::set<InputDeviceUsageSource> sources; + + for (uint32_t i = 0; i < motionArgs.getPointerCount(); i++) { + const auto toolType = motionArgs.pointerProperties[i].toolType; + if (isFromSource(motionArgs.source, AINPUT_SOURCE_MOUSE)) { + if (toolType == ToolType::MOUSE) { + sources.emplace(InputDeviceUsageSource::MOUSE); + continue; + } + if (toolType == ToolType::FINGER) { + sources.emplace(InputDeviceUsageSource::TOUCHPAD); + continue; + } + if (isStylusToolType(toolType)) { + sources.emplace(InputDeviceUsageSource::STYLUS_INDIRECT); + continue; + } + } + if (isFromSource(motionArgs.source, AINPUT_SOURCE_MOUSE_RELATIVE) && + toolType == ToolType::MOUSE) { + sources.emplace(InputDeviceUsageSource::MOUSE_CAPTURED); + continue; + } + if (isFromSource(motionArgs.source, AINPUT_SOURCE_TOUCHPAD) && + toolType == ToolType::FINGER) { + sources.emplace(InputDeviceUsageSource::TOUCHPAD_CAPTURED); + continue; + } + if (isFromSource(motionArgs.source, AINPUT_SOURCE_BLUETOOTH_STYLUS) && + isStylusToolType(toolType)) { + sources.emplace(InputDeviceUsageSource::STYLUS_FUSED); + continue; + } + if (isFromSource(motionArgs.source, AINPUT_SOURCE_STYLUS) && isStylusToolType(toolType)) { + sources.emplace(InputDeviceUsageSource::STYLUS_DIRECT); + continue; + } + if (isFromSource(motionArgs.source, AINPUT_SOURCE_TOUCH_NAVIGATION)) { + sources.emplace(InputDeviceUsageSource::TOUCH_NAVIGATION); + continue; + } + if (isFromSource(motionArgs.source, AINPUT_SOURCE_JOYSTICK)) { + sources.emplace(InputDeviceUsageSource::JOYSTICK); + continue; + } + if (isFromSource(motionArgs.source, AINPUT_SOURCE_ROTARY_ENCODER)) { + sources.emplace(InputDeviceUsageSource::ROTARY_ENCODER); + continue; + } + if (isFromSource(motionArgs.source, AINPUT_SOURCE_TRACKBALL)) { + sources.emplace(InputDeviceUsageSource::TRACKBALL); + continue; + } + if (isFromSource(motionArgs.source, AINPUT_SOURCE_TOUCHSCREEN)) { + sources.emplace(InputDeviceUsageSource::TOUCHSCREEN); + continue; + } + sources.emplace(InputDeviceUsageSource::UNKNOWN); + } + + return sources; +} + +} // namespace android diff --git a/services/inputflinger/InputDeviceMetricsSource.h b/services/inputflinger/InputDeviceMetricsSource.h new file mode 100644 index 0000000000..3ac91c812a --- /dev/null +++ b/services/inputflinger/InputDeviceMetricsSource.h @@ -0,0 +1,58 @@ +/* + * Copyright 2023 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. + */ + +#pragma once + +#include "NotifyArgs.h" + +#include <linux/input.h> +#include <statslog.h> + +namespace android { + +/** + * Enum representation of the InputDeviceUsageSource. + */ +enum class InputDeviceUsageSource : int32_t { + UNKNOWN = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__UNKNOWN, + BUTTONS = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__BUTTONS, + KEYBOARD = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__KEYBOARD, + DPAD = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__DPAD, + GAMEPAD = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__GAMEPAD, + JOYSTICK = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__JOYSTICK, + MOUSE = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__MOUSE, + MOUSE_CAPTURED = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__MOUSE_CAPTURED, + TOUCHPAD = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__TOUCHPAD, + TOUCHPAD_CAPTURED = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__TOUCHPAD_CAPTURED, + ROTARY_ENCODER = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__ROTARY_ENCODER, + STYLUS_DIRECT = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__STYLUS_DIRECT, + STYLUS_INDIRECT = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__STYLUS_INDIRECT, + STYLUS_FUSED = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__STYLUS_FUSED, + TOUCH_NAVIGATION = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__TOUCH_NAVIGATION, + TOUCHSCREEN = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__TOUCHSCREEN, + TRACKBALL = util::INPUT_DEVICE_USAGE_REPORTED__USAGE_SOURCES__TRACKBALL, + + ftl_first = UNKNOWN, + ftl_last = TRACKBALL, +}; + +/** Returns the InputDeviceUsageSource that corresponds to the key event. */ +InputDeviceUsageSource getUsageSourceForKeyArgs(int32_t keyboardType, const NotifyKeyArgs&); + +/** Returns the InputDeviceUsageSources that correspond to the motion event. */ +std::set<InputDeviceUsageSource> getUsageSourcesForMotionArgs(const NotifyMotionArgs&); + +} // namespace android diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp index d87a5a7337..c0353af117 100644 --- a/services/inputflinger/tests/Android.bp +++ b/services/inputflinger/tests/Android.bp @@ -50,6 +50,7 @@ cc_test { "HardwareProperties_test.cpp", "HardwareStateConverter_test.cpp", "InputDeviceMetricsCollector_test.cpp", + "InputDeviceMetricsSource_test.cpp", "InputMapperTest.cpp", "InputProcessor_test.cpp", "InputProcessorConverter_test.cpp", diff --git a/services/inputflinger/tests/InputDeviceMetricsCollector_test.cpp b/services/inputflinger/tests/InputDeviceMetricsCollector_test.cpp index fdf9ed13b9..85e055d98e 100644 --- a/services/inputflinger/tests/InputDeviceMetricsCollector_test.cpp +++ b/services/inputflinger/tests/InputDeviceMetricsCollector_test.cpp @@ -36,7 +36,6 @@ namespace { constexpr auto USAGE_TIMEOUT = 8765309ns; constexpr auto TIME = 999999ns; -constexpr auto ALL_USAGE_SOURCES = ftl::enum_range<InputDeviceUsageSource>(); constexpr int32_t DEVICE_ID = 3; constexpr int32_t DEVICE_ID_2 = 4; @@ -48,10 +47,6 @@ const std::string LOCATION = "California"; const std::string UNIQUE_ID = "Yosemite"; constexpr uint32_t TOUCHSCREEN = AINPUT_SOURCE_TOUCHSCREEN; constexpr uint32_t STYLUS = AINPUT_SOURCE_STYLUS; -constexpr uint32_t KEY_SOURCES = - AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD | AINPUT_SOURCE_GAMEPAD; -constexpr int32_t POINTER_1_DOWN = - AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); InputDeviceIdentifier generateTestIdentifier(int32_t id = DEVICE_ID) { InputDeviceIdentifier identifier; @@ -87,258 +82,6 @@ std::set<gui::Uid> uids(std::initializer_list<int32_t> vals) { } // namespace -// --- InputDeviceMetricsCollectorDeviceClassificationTest --- - -class DeviceClassificationFixture : public ::testing::Test, - public ::testing::WithParamInterface<InputDeviceUsageSource> {}; - -TEST_P(DeviceClassificationFixture, ValidClassifications) { - const InputDeviceUsageSource usageSource = GetParam(); - - // Use a switch to ensure a test is added for all source classifications. - switch (usageSource) { - case InputDeviceUsageSource::UNKNOWN: { - ASSERT_EQ(InputDeviceUsageSource::UNKNOWN, - getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_NONE, - KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, TOUCHSCREEN) - .build())); - - std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::UNKNOWN}; - ASSERT_EQ(srcs, - getUsageSourcesForMotionArgs( - MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_KEYBOARD) - .pointer(PointerBuilder(/*id=*/1, ToolType::PALM) - .x(100) - .y(200)) - .build())); - break; - } - - case InputDeviceUsageSource::BUTTONS: { - ASSERT_EQ(InputDeviceUsageSource::BUTTONS, - getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, - KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES) - .keyCode(AKEYCODE_STYLUS_BUTTON_TAIL) - .build())); - break; - } - - case InputDeviceUsageSource::KEYBOARD: { - ASSERT_EQ(InputDeviceUsageSource::KEYBOARD, - getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_ALPHABETIC, - KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES) - .build())); - break; - } - - case InputDeviceUsageSource::DPAD: { - ASSERT_EQ(InputDeviceUsageSource::DPAD, - getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, - KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES) - .keyCode(AKEYCODE_DPAD_CENTER) - .build())); - - ASSERT_EQ(InputDeviceUsageSource::DPAD, - getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_ALPHABETIC, - KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES) - .keyCode(AKEYCODE_DPAD_CENTER) - .build())); - break; - } - - case InputDeviceUsageSource::GAMEPAD: { - ASSERT_EQ(InputDeviceUsageSource::GAMEPAD, - getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, - KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES) - .keyCode(AKEYCODE_BUTTON_A) - .build())); - - ASSERT_EQ(InputDeviceUsageSource::GAMEPAD, - getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_ALPHABETIC, - KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES) - .keyCode(AKEYCODE_BUTTON_A) - .build())); - break; - } - - case InputDeviceUsageSource::JOYSTICK: { - std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::JOYSTICK}; - ASSERT_EQ(srcs, - getUsageSourcesForMotionArgs( - MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_JOYSTICK) - .pointer(PointerBuilder(/*id=*/1, ToolType::UNKNOWN) - .axis(AMOTION_EVENT_AXIS_GAS, 1.f)) - .build())); - break; - } - - case InputDeviceUsageSource::MOUSE: { - std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::MOUSE}; - ASSERT_EQ(srcs, - getUsageSourcesForMotionArgs( - MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE, - AINPUT_SOURCE_MOUSE) - .pointer(PointerBuilder(/*id=*/1, ToolType::MOUSE) - .x(100) - .y(200)) - .build())); - break; - } - - case InputDeviceUsageSource::MOUSE_CAPTURED: { - std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::MOUSE_CAPTURED}; - ASSERT_EQ(srcs, - getUsageSourcesForMotionArgs( - MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, - AINPUT_SOURCE_MOUSE_RELATIVE) - .pointer(PointerBuilder(/*id=*/1, ToolType::MOUSE) - .x(100) - .y(200) - .axis(AMOTION_EVENT_AXIS_RELATIVE_X, 100) - .axis(AMOTION_EVENT_AXIS_RELATIVE_Y, 200)) - .build())); - break; - } - - case InputDeviceUsageSource::TOUCHPAD: { - std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::TOUCHPAD}; - ASSERT_EQ(srcs, - getUsageSourcesForMotionArgs( - MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE) - .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER) - .x(100) - .y(200)) - .build())); - break; - } - - case InputDeviceUsageSource::TOUCHPAD_CAPTURED: { - std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::TOUCHPAD_CAPTURED}; - ASSERT_EQ(srcs, - getUsageSourcesForMotionArgs( - MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHPAD) - .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER) - .x(100) - .y(200) - .axis(AMOTION_EVENT_AXIS_RELATIVE_X, 1) - .axis(AMOTION_EVENT_AXIS_RELATIVE_Y, 2)) - .build())); - break; - } - - case InputDeviceUsageSource::ROTARY_ENCODER: { - std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::ROTARY_ENCODER}; - ASSERT_EQ(srcs, - getUsageSourcesForMotionArgs( - MotionArgsBuilder(AMOTION_EVENT_ACTION_SCROLL, - AINPUT_SOURCE_ROTARY_ENCODER) - .pointer(PointerBuilder(/*id=*/1, ToolType::UNKNOWN) - .axis(AMOTION_EVENT_AXIS_SCROLL, 10) - .axis(AMOTION_EVENT_AXIS_VSCROLL, 10)) - .build())); - break; - } - - case InputDeviceUsageSource::STYLUS_DIRECT: { - std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::STYLUS_DIRECT}; - ASSERT_EQ(srcs, - getUsageSourcesForMotionArgs( - MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER, - STYLUS | TOUCHSCREEN) - .pointer(PointerBuilder(/*id=*/1, ToolType::STYLUS) - .x(100) - .y(200)) - .build())); - break; - } - - case InputDeviceUsageSource::STYLUS_INDIRECT: { - std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::STYLUS_INDIRECT}; - ASSERT_EQ(srcs, - getUsageSourcesForMotionArgs( - MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER, - STYLUS | TOUCHSCREEN | AINPUT_SOURCE_MOUSE) - .pointer(PointerBuilder(/*id=*/1, ToolType::STYLUS) - .x(100) - .y(200)) - .build())); - break; - } - - case InputDeviceUsageSource::STYLUS_FUSED: { - std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::STYLUS_FUSED}; - ASSERT_EQ(srcs, - getUsageSourcesForMotionArgs( - MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER, - AINPUT_SOURCE_BLUETOOTH_STYLUS | TOUCHSCREEN) - .pointer(PointerBuilder(/*id=*/1, ToolType::STYLUS) - .x(100) - .y(200)) - .build())); - break; - } - - case InputDeviceUsageSource::TOUCH_NAVIGATION: { - std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::TOUCH_NAVIGATION}; - ASSERT_EQ(srcs, - getUsageSourcesForMotionArgs( - MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, - AINPUT_SOURCE_TOUCH_NAVIGATION) - .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER) - .x(100) - .y(200)) - .build())); - break; - } - - case InputDeviceUsageSource::TOUCHSCREEN: { - std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::TOUCHSCREEN}; - ASSERT_EQ(srcs, - getUsageSourcesForMotionArgs( - MotionArgsBuilder(POINTER_1_DOWN, TOUCHSCREEN) - .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER) - .x(100) - .y(200)) - .pointer(PointerBuilder(/*id=*/2, ToolType::FINGER) - .x(300) - .y(400)) - .build())); - break; - } - - case InputDeviceUsageSource::TRACKBALL: { - std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::TRACKBALL}; - ASSERT_EQ(srcs, - getUsageSourcesForMotionArgs( - MotionArgsBuilder(AMOTION_EVENT_ACTION_SCROLL, - AINPUT_SOURCE_TRACKBALL) - .pointer(PointerBuilder(/*id=*/1, ToolType::UNKNOWN) - .axis(AMOTION_EVENT_AXIS_VSCROLL, 100) - .axis(AMOTION_EVENT_AXIS_HSCROLL, 200)) - .build())); - break; - } - } -} - -INSTANTIATE_TEST_SUITE_P(InputDeviceMetricsCollectorDeviceClassificationTest, - DeviceClassificationFixture, - ::testing::ValuesIn(ALL_USAGE_SOURCES.begin(), ALL_USAGE_SOURCES.end()), - [](const testing::TestParamInfo<InputDeviceUsageSource>& testParamInfo) { - return ftl::enum_string(testParamInfo.param); - }); - -TEST(InputDeviceMetricsCollectorDeviceClassificationTest, MixedClassificationTouchscreenStylus) { - std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::TOUCHSCREEN, - InputDeviceUsageSource::STYLUS_DIRECT}; - ASSERT_EQ(srcs, - getUsageSourcesForMotionArgs( - MotionArgsBuilder(POINTER_1_DOWN, TOUCHSCREEN | STYLUS) - .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(100).y(200)) - .pointer(PointerBuilder(/*id=*/2, ToolType::STYLUS).x(300).y(400)) - .build())); -} - // --- InputDeviceMetricsCollectorTest --- class InputDeviceMetricsCollectorTest : public testing::Test, public InputDeviceMetricsLogger { diff --git a/services/inputflinger/tests/InputDeviceMetricsSource_test.cpp b/services/inputflinger/tests/InputDeviceMetricsSource_test.cpp new file mode 100644 index 0000000000..84ef52c148 --- /dev/null +++ b/services/inputflinger/tests/InputDeviceMetricsSource_test.cpp @@ -0,0 +1,296 @@ +/* + * Copyright 2023 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 "../InputDeviceMetricsSource.h" + +#include <NotifyArgsBuilders.h> + +#include <android/input.h> +#include <ftl/enum.h> +#include <gtest/gtest.h> +#include <input/Input.h> +#include <input/InputEventBuilders.h> +#include <linux/input.h> + +#include <set> + +namespace android { + +namespace { + +constexpr auto ALL_USAGE_SOURCES = ftl::enum_range<InputDeviceUsageSource>(); +constexpr uint32_t TOUCHSCREEN = AINPUT_SOURCE_TOUCHSCREEN; +constexpr uint32_t STYLUS = AINPUT_SOURCE_STYLUS; +constexpr uint32_t KEY_SOURCES = + AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD | AINPUT_SOURCE_GAMEPAD; +constexpr int32_t POINTER_1_DOWN = + AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); + +} // namespace + +// --- InputDeviceMetricsSourceDeviceClassificationTest --- + +class DeviceClassificationFixture : public ::testing::Test, + public ::testing::WithParamInterface<InputDeviceUsageSource> {}; + +TEST_P(DeviceClassificationFixture, ValidClassifications) { + const InputDeviceUsageSource usageSource = GetParam(); + + // Use a switch to ensure a test is added for all source classifications. + switch (usageSource) { + case InputDeviceUsageSource::UNKNOWN: { + ASSERT_EQ(InputDeviceUsageSource::UNKNOWN, + getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_NONE, + KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, TOUCHSCREEN) + .build())); + + std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::UNKNOWN}; + ASSERT_EQ(srcs, + getUsageSourcesForMotionArgs( + MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_KEYBOARD) + .pointer(PointerBuilder(/*id=*/1, ToolType::PALM) + .x(100) + .y(200)) + .build())); + break; + } + + case InputDeviceUsageSource::BUTTONS: { + ASSERT_EQ(InputDeviceUsageSource::BUTTONS, + getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, + KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES) + .keyCode(AKEYCODE_STYLUS_BUTTON_TAIL) + .build())); + break; + } + + case InputDeviceUsageSource::KEYBOARD: { + ASSERT_EQ(InputDeviceUsageSource::KEYBOARD, + getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_ALPHABETIC, + KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES) + .build())); + break; + } + + case InputDeviceUsageSource::DPAD: { + ASSERT_EQ(InputDeviceUsageSource::DPAD, + getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, + KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES) + .keyCode(AKEYCODE_DPAD_CENTER) + .build())); + + ASSERT_EQ(InputDeviceUsageSource::DPAD, + getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_ALPHABETIC, + KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES) + .keyCode(AKEYCODE_DPAD_CENTER) + .build())); + break; + } + + case InputDeviceUsageSource::GAMEPAD: { + ASSERT_EQ(InputDeviceUsageSource::GAMEPAD, + getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, + KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES) + .keyCode(AKEYCODE_BUTTON_A) + .build())); + + ASSERT_EQ(InputDeviceUsageSource::GAMEPAD, + getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_ALPHABETIC, + KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES) + .keyCode(AKEYCODE_BUTTON_A) + .build())); + break; + } + + case InputDeviceUsageSource::JOYSTICK: { + std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::JOYSTICK}; + ASSERT_EQ(srcs, + getUsageSourcesForMotionArgs( + MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_JOYSTICK) + .pointer(PointerBuilder(/*id=*/1, ToolType::UNKNOWN) + .axis(AMOTION_EVENT_AXIS_GAS, 1.f)) + .build())); + break; + } + + case InputDeviceUsageSource::MOUSE: { + std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::MOUSE}; + ASSERT_EQ(srcs, + getUsageSourcesForMotionArgs( + MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE, + AINPUT_SOURCE_MOUSE) + .pointer(PointerBuilder(/*id=*/1, ToolType::MOUSE) + .x(100) + .y(200)) + .build())); + break; + } + + case InputDeviceUsageSource::MOUSE_CAPTURED: { + std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::MOUSE_CAPTURED}; + ASSERT_EQ(srcs, + getUsageSourcesForMotionArgs( + MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, + AINPUT_SOURCE_MOUSE_RELATIVE) + .pointer(PointerBuilder(/*id=*/1, ToolType::MOUSE) + .x(100) + .y(200) + .axis(AMOTION_EVENT_AXIS_RELATIVE_X, 100) + .axis(AMOTION_EVENT_AXIS_RELATIVE_Y, 200)) + .build())); + break; + } + + case InputDeviceUsageSource::TOUCHPAD: { + std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::TOUCHPAD}; + ASSERT_EQ(srcs, + getUsageSourcesForMotionArgs( + MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE) + .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER) + .x(100) + .y(200)) + .build())); + break; + } + + case InputDeviceUsageSource::TOUCHPAD_CAPTURED: { + std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::TOUCHPAD_CAPTURED}; + ASSERT_EQ(srcs, + getUsageSourcesForMotionArgs( + MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHPAD) + .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER) + .x(100) + .y(200) + .axis(AMOTION_EVENT_AXIS_RELATIVE_X, 1) + .axis(AMOTION_EVENT_AXIS_RELATIVE_Y, 2)) + .build())); + break; + } + + case InputDeviceUsageSource::ROTARY_ENCODER: { + std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::ROTARY_ENCODER}; + ASSERT_EQ(srcs, + getUsageSourcesForMotionArgs( + MotionArgsBuilder(AMOTION_EVENT_ACTION_SCROLL, + AINPUT_SOURCE_ROTARY_ENCODER) + .pointer(PointerBuilder(/*id=*/1, ToolType::UNKNOWN) + .axis(AMOTION_EVENT_AXIS_SCROLL, 10) + .axis(AMOTION_EVENT_AXIS_VSCROLL, 10)) + .build())); + break; + } + + case InputDeviceUsageSource::STYLUS_DIRECT: { + std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::STYLUS_DIRECT}; + ASSERT_EQ(srcs, + getUsageSourcesForMotionArgs( + MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER, + STYLUS | TOUCHSCREEN) + .pointer(PointerBuilder(/*id=*/1, ToolType::STYLUS) + .x(100) + .y(200)) + .build())); + break; + } + + case InputDeviceUsageSource::STYLUS_INDIRECT: { + std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::STYLUS_INDIRECT}; + ASSERT_EQ(srcs, + getUsageSourcesForMotionArgs( + MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER, + STYLUS | TOUCHSCREEN | AINPUT_SOURCE_MOUSE) + .pointer(PointerBuilder(/*id=*/1, ToolType::STYLUS) + .x(100) + .y(200)) + .build())); + break; + } + + case InputDeviceUsageSource::STYLUS_FUSED: { + std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::STYLUS_FUSED}; + ASSERT_EQ(srcs, + getUsageSourcesForMotionArgs( + MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER, + AINPUT_SOURCE_BLUETOOTH_STYLUS | TOUCHSCREEN) + .pointer(PointerBuilder(/*id=*/1, ToolType::STYLUS) + .x(100) + .y(200)) + .build())); + break; + } + + case InputDeviceUsageSource::TOUCH_NAVIGATION: { + std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::TOUCH_NAVIGATION}; + ASSERT_EQ(srcs, + getUsageSourcesForMotionArgs( + MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, + AINPUT_SOURCE_TOUCH_NAVIGATION) + .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER) + .x(100) + .y(200)) + .build())); + break; + } + + case InputDeviceUsageSource::TOUCHSCREEN: { + std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::TOUCHSCREEN}; + ASSERT_EQ(srcs, + getUsageSourcesForMotionArgs( + MotionArgsBuilder(POINTER_1_DOWN, TOUCHSCREEN) + .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER) + .x(100) + .y(200)) + .pointer(PointerBuilder(/*id=*/2, ToolType::FINGER) + .x(300) + .y(400)) + .build())); + break; + } + + case InputDeviceUsageSource::TRACKBALL: { + std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::TRACKBALL}; + ASSERT_EQ(srcs, + getUsageSourcesForMotionArgs( + MotionArgsBuilder(AMOTION_EVENT_ACTION_SCROLL, + AINPUT_SOURCE_TRACKBALL) + .pointer(PointerBuilder(/*id=*/1, ToolType::UNKNOWN) + .axis(AMOTION_EVENT_AXIS_VSCROLL, 100) + .axis(AMOTION_EVENT_AXIS_HSCROLL, 200)) + .build())); + break; + } + } +} + +INSTANTIATE_TEST_SUITE_P(InputDeviceMetricsSourceDeviceClassificationTest, + DeviceClassificationFixture, + ::testing::ValuesIn(ALL_USAGE_SOURCES.begin(), ALL_USAGE_SOURCES.end()), + [](const testing::TestParamInfo<InputDeviceUsageSource>& testParamInfo) { + return ftl::enum_string(testParamInfo.param); + }); + +TEST(InputDeviceMetricsSourceDeviceClassificationTest, MixedClassificationTouchscreenStylus) { + std::set<InputDeviceUsageSource> srcs{InputDeviceUsageSource::TOUCHSCREEN, + InputDeviceUsageSource::STYLUS_DIRECT}; + ASSERT_EQ(srcs, + getUsageSourcesForMotionArgs( + MotionArgsBuilder(POINTER_1_DOWN, TOUCHSCREEN | STYLUS) + .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(100).y(200)) + .pointer(PointerBuilder(/*id=*/2, ToolType::STYLUS).x(300).y(400)) + .build())); +} + +} // namespace android |