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
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index 5d1d4af..76729ef 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -182,6 +182,7 @@
filegroup {
name: "libinputflinger_base_sources",
srcs: [
+ "InputDeviceMetricsSource.cpp",
"InputListener.cpp",
"InputReaderBase.cpp",
"InputThread.cpp",
@@ -199,6 +200,7 @@
"libcutils",
"libinput",
"liblog",
+ "libstatslog",
"libutils",
],
header_libs: [
diff --git a/services/inputflinger/InputDeviceMetricsCollector.cpp b/services/inputflinger/InputDeviceMetricsCollector.cpp
index 8e04150..cefb140 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 @@
} // 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 7775087..9633664 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 @@
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 0000000..dee4cb8
--- /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 0000000..3ac91c8
--- /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 d87a5a7..c0353af 100644
--- a/services/inputflinger/tests/Android.bp
+++ b/services/inputflinger/tests/Android.bp
@@ -50,6 +50,7 @@
"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 fdf9ed1..85e055d 100644
--- a/services/inputflinger/tests/InputDeviceMetricsCollector_test.cpp
+++ b/services/inputflinger/tests/InputDeviceMetricsCollector_test.cpp
@@ -36,7 +36,6 @@
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 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 @@
} // 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 0000000..84ef52c
--- /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