From d3b7a177945e3134bb17d667d277e4dead7afeca Mon Sep 17 00:00:00 2001
From: Asmita Poddar <asmitapoddar@google.com>
Date: Mon, 26 Feb 2024 14:11:02 +0000
Subject: [PATCH] Log device bus for keyboard metrics

Since the same vendor ID could mean different vendors depending on
whether the device is connected over bluetooth or USB, we require to know
the device bus to disambiguate the vendor IDs.
Also fixed some formatting issues.

Bug: 308918242
Test: atest InputTests:KeyboardMetricsCollectorTests
Test: atest ShortcutLoggingTests
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:03a1658c6dbfadfeb57a408aa9fcfbdc5213a740)
Merged-In: Id96d86242ab239c7df0efe74bf13fb97eb97f482
Change-Id: Id96d86242ab239c7df0efe74bf13fb97eb97f482

NOTE FOR REVIEWERS - errors occurred while applying the patch.
PLEASE REVIEW CAREFULLY.
Errors:
Error applying patch in services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java, hunk HunkHeader[30,13->30,13]: Hunk cannot be applied
Error applying patch in services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java, hunk HunkHeader[483,10->483,15]: Hunk cannot be applied
Error applying patch in tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt: Cannot perform UNIFIED action on a non-existent file
Error applying patch in tests/Input/src/com/android/server/input/KeyboardMetricsCollectorTests.kt: Cannot perform UNIFIED action on a non-existent file

Original patch:
 From 03a1658c6dbfadfeb57a408aa9fcfbdc5213a740 Mon Sep 17 00:00:00 2001
From: Asmita Poddar <asmitapoddar@google.com>
Date: Mon, 27 Nov 2023 17:03:03 +0000
Subject: [PATCH] Log device bus for keyboard metrics

Since the same vendor ID could mean different vendors depending on
whether the device is connected over bluetooth or USB, we require to know
the device bus to disambiguate the vendor IDs.
Also fixed some formatting issues.

Bug: 308918242
Test: atest InputTests:KeyboardMetricsCollectorTests
Test: atest ShortcutLoggingTests

Change-Id: Id96d86242ab239c7df0efe74bf13fb97eb97f482
---
---
 .../server/input/KeyboardMetricsCollector.java  | 13 +++++++++----
 .../input/KeyboardMetricsCollectorTests.kt      | 12 ++++++++++++
 .../server/policy/ShortcutLoggingTests.java     |  6 ++++--
 .../server/policy/TestPhoneWindowManager.java   | 17 +++++++++++------
 4 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
index 08e597701ea2..8e2484e616ab 100644
--- a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
+++ b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
@@ -369,15 +369,15 @@ public final class KeyboardMetricsCollector {
         if (inputDevice == null || inputDevice.isVirtual() || !inputDevice.isFullKeyboard()) {
             return;
         }
-        int vendorId = inputDevice.getVendorId();
-        int productId = inputDevice.getProductId();
         if (keyboardSystemEvent == null) {
             Slog.w(TAG, "Invalid keyboard event logging, keycode = " + Arrays.toString(keyCodes)
                     + ", modifier state = " + modifierState);
             return;
         }
         FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED,
-                vendorId, productId, keyboardSystemEvent.getIntValue(), keyCodes, modifierState);
+                inputDevice.getVendorId(), inputDevice.getProductId(),
+                keyboardSystemEvent.getIntValue(), keyCodes, modifierState,
+                inputDevice.getDeviceBus());
 
         if (DEBUG) {
             Slog.d(TAG, "Logging Keyboard system event: " + keyboardSystemEvent.mName);
@@ -402,7 +402,7 @@ public final class KeyboardMetricsCollector {
         // Push the atom to Statsd
         FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_CONFIGURED,
                 event.isFirstConfiguration(), event.getVendorId(), event.getProductId(),
-                proto.getBytes());
+                proto.getBytes(), event.getDeviceBus());
 
         if (DEBUG) {
             Slog.d(TAG, "Logging Keyboard configuration event: " + event);
@@ -467,6 +467,10 @@ public final class KeyboardMetricsCollector {
             return mInputDevice.getProductId();
         }
 
+        public int getDeviceBus() {
+            return mInputDevice.getDeviceBus();
+        }
+
         public boolean isFirstConfiguration() {
             return mIsFirstConfiguration;
         }
@@ -479,6 +483,7 @@ public final class KeyboardMetricsCollector {
         public String toString() {
             return "InputDevice = {VendorId = " + Integer.toHexString(getVendorId())
                     + ", ProductId = " + Integer.toHexString(getProductId())
+                    + ", Device Bus = " + Integer.toHexString(getDeviceBus())
                     + "}, isFirstConfiguration = " + mIsFirstConfiguration
                     + ", LayoutConfigurations = " + mLayoutConfigurations;
         }
diff --git a/services/tests/servicestests/src/com/android/server/input/KeyboardMetricsCollectorTests.kt b/services/tests/servicestests/src/com/android/server/input/KeyboardMetricsCollectorTests.kt
index 84af9dd75571..218b7c07b3dc 100644
--- a/services/tests/servicestests/src/com/android/server/input/KeyboardMetricsCollectorTests.kt
+++ b/services/tests/servicestests/src/com/android/server/input/KeyboardMetricsCollectorTests.kt
@@ -30,6 +30,7 @@ private fun createKeyboard(
     deviceId: Int,
     vendorId: Int,
     productId: Int,
+    deviceBus: Int,
     languageTag: String?,
     layoutType: String?
 ): InputDevice =
@@ -42,6 +43,7 @@ private fun createKeyboard(
         .setExternal(true)
         .setVendorId(vendorId)
         .setProductId(productId)
+        .setDeviceBus(deviceBus)
         .setKeyboardLanguageTag(languageTag)
         .setKeyboardLayoutType(layoutType)
         .build()
@@ -67,6 +69,7 @@ class KeyboardMetricsCollectorTests {
         const val DEVICE_ID = 1
         const val DEFAULT_VENDOR_ID = 123
         const val DEFAULT_PRODUCT_ID = 456
+        const val DEFAULT_DEVICE_BUS = 789
     }
 
     @Test
@@ -77,6 +80,7 @@ class KeyboardMetricsCollectorTests {
                     DEVICE_ID,
                     DEFAULT_VENDOR_ID,
                     DEFAULT_PRODUCT_ID,
+                    DEFAULT_DEVICE_BUS,
                     null,
                     null
                 )
@@ -92,6 +96,7 @@ class KeyboardMetricsCollectorTests {
                     DEVICE_ID,
                     DEFAULT_VENDOR_ID,
                     DEFAULT_PRODUCT_ID,
+                    DEFAULT_DEVICE_BUS,
                     null,
                     null
                 )
@@ -107,6 +112,7 @@ class KeyboardMetricsCollectorTests {
                 DEVICE_ID,
                 DEFAULT_VENDOR_ID,
                 DEFAULT_PRODUCT_ID,
+                DEFAULT_DEVICE_BUS,
                 "de-CH",
                 "qwertz"
             )
@@ -135,6 +141,11 @@ class KeyboardMetricsCollectorTests {
             DEFAULT_PRODUCT_ID,
             event.productId
         )
+        assertEquals(
+             "KeyboardConfigurationEvent should pick device bus from provided InputDevice",
+             DEFAULT_DEVICE_BUS,
+             event.deviceBus
+        )
         assertTrue(event.isFirstConfiguration)
 
         assertEquals(
@@ -178,6 +189,7 @@ class KeyboardMetricsCollectorTests {
                 DEVICE_ID,
                 DEFAULT_VENDOR_ID,
                 DEFAULT_PRODUCT_ID,
+                DEFAULT_DEVICE_BUS,
                 "und", // Undefined language tag
                 "azerty"
             )
diff --git a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
index feca3268a95c..84925f933c5f 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
@@ -38,6 +38,7 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase {
 
     private static final int VENDOR_ID = 0x123;
     private static final int PRODUCT_ID = 0x456;
+    private static final int DEVICE_BUS = 0x789;
     private static final int META_KEY = KeyEvent.KEYCODE_META_LEFT;
     private static final int META_ON = MODIFIER.get(KeyEvent.KEYCODE_META_LEFT);
     private static final int ALT_KEY = KeyEvent.KEYCODE_ALT_LEFT;
@@ -224,7 +225,7 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase {
     @Override
     public void setUp() {
         super.setUp();
-        mPhoneWindowManager.overrideKeyEventSource(VENDOR_ID, PRODUCT_ID);
+        mPhoneWindowManager.overrideKeyEventSource(VENDOR_ID, PRODUCT_ID, DEVICE_BUS);
         mPhoneWindowManager.overrideLaunchHome();
         mPhoneWindowManager.overrideSearchKeyBehavior(
                 PhoneWindowManager.SEARCH_BEHAVIOR_TARGET_ACTIVITY);
@@ -240,6 +241,7 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase {
             int expectedKey, int expectedModifierState) {
         sendKeyCombination(testKeys, 0);
         mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent,
-                expectedKey, expectedModifierState, "Failed while executing " + testName);
+                expectedKey, expectedModifierState, DEVICE_BUS,
+                "Failed while executing " + testName);
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
index 186676772a6a..9aaf291a82ba 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -423,10 +423,15 @@ class TestPhoneWindowManager {
         doReturn(isShowing).when(mKeyguardServiceDelegate).isShowing();
     }
 
-    void overrideKeyEventSource(int vendorId, int productId) {
-        InputDevice device = new InputDevice.Builder().setId(1).setVendorId(vendorId).setProductId(
-                productId).setSources(InputDevice.SOURCE_KEYBOARD).setKeyboardType(
-                InputDevice.KEYBOARD_TYPE_ALPHABETIC).build();
+    void overrideKeyEventSource(int vendorId, int productId, int deviceBus) {
+        InputDevice device = new InputDevice.Builder()
+                .setId(1)
+                .setVendorId(vendorId)
+                .setProductId(productId)
+                .setDeviceBus(deviceBus)
+                .setSources(InputDevice.SOURCE_KEYBOARD)
+                .setKeyboardType(InputDevice.KEYBOARD_TYPE_ALPHABETIC)
+                .build();
         doReturn(mInputManager).when(mContext).getSystemService(eq(InputManager.class));
         doReturn(device).when(mInputManager).getInputDevice(anyInt());
     }
@@ -604,10 +609,10 @@ class TestPhoneWindowManager {
     }
 
     void assertShortcutLogged(int vendorId, int productId, KeyboardLogEvent logEvent,
-            int expectedKey, int expectedModifierState, String errorMsg) {
+            int expectedKey, int expectedModifierState, int deviceBus, String errorMsg) {
         waitForIdle();
         verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED,
                         vendorId, productId, logEvent.getIntValue(), new int[]{expectedKey},
-                        expectedModifierState), description(errorMsg));
+                        expectedModifierState, deviceBus), description(errorMsg));
     }
 }
-- 
GitLab