diff --git a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java index 2dd2a16bed641ddf837c7104c3daf8516c518f44..ebc784d763eff80a0b7d8f1821081a33bd38a86b 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/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java index 71098aa5e88307246d783554d852b2af0cb070fa..e05ecccc9983539c0430f9c09d4e66d7f9d77644 100644 --- a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java +++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java @@ -30,13 +30,13 @@ import androidx.test.filters.MediumTest; import com.android.internal.annotations.Keep; import com.android.server.input.KeyboardMetricsCollector.KeyboardLogEvent; +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import junitparams.JUnitParamsRunner; -import junitparams.Parameters; - @Presubmit @MediumTest @RunWith(JUnitParamsRunner.class) @@ -44,6 +44,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; @@ -298,7 +299,7 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase { @Before public void setUp() { setUpPhoneWindowManager(/*supportSettingsUpdate*/ true); - mPhoneWindowManager.overrideKeyEventSource(VENDOR_ID, PRODUCT_ID); + mPhoneWindowManager.overrideKeyEventSource(VENDOR_ID, PRODUCT_ID, DEVICE_BUS); mPhoneWindowManager.overrideLaunchHome(); mPhoneWindowManager.overrideSearchKeyBehavior( PhoneWindowManager.SEARCH_BEHAVIOR_TARGET_ACTIVITY); @@ -318,7 +319,8 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase { int expectedKey, int expectedModifierState) { sendKeyCombination(testKeys, 0 /* duration */); mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent, - expectedKey, expectedModifierState, "Failed while executing " + testName); + expectedKey, expectedModifierState, DEVICE_BUS, + "Failed while executing " + testName); } @Test @@ -328,7 +330,8 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase { mPhoneWindowManager.overrideLongPressOnHomeBehavior(longPressOnHomeBehavior); sendLongPressKeyCombination(testKeys); mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent, - expectedKey, expectedModifierState, "Failed while executing " + testName); + expectedKey, expectedModifierState, DEVICE_BUS, + "Failed while executing " + testName); } @Test @@ -340,7 +343,8 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase { sendKeyCombination(testKeys, 0 /* duration */); sendKeyCombination(testKeys, 0 /* duration */); mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent, - expectedKey, expectedModifierState, "Failed while executing " + testName); + expectedKey, expectedModifierState, DEVICE_BUS, + "Failed while executing " + testName); } @Test @@ -351,6 +355,7 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase { mPhoneWindowManager.overrideShortPressOnSettingsBehavior(shortPressOnSettingsBehavior); sendKeyCombination(testKeys, 0 /* duration */); 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 7788b339738bf09ee92d521403209457c6968650..43c47458d19f630c58427bb99f8aedd5e5917df1 100644 --- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java +++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java @@ -483,10 +483,15 @@ class TestPhoneWindowManager { doReturn(mPackageManager).when(mContext).getPackageManager(); } - 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()); } @@ -682,11 +687,11 @@ class TestPhoneWindowManager { } void assertShortcutLogged(int vendorId, int productId, KeyboardLogEvent logEvent, - int expectedKey, int expectedModifierState, String errorMsg) { + int expectedKey, int expectedModifierState, int deviceBus, String errorMsg) { mTestLooper.dispatchAll(); verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED, vendorId, productId, logEvent.getIntValue(), new int[]{expectedKey}, - expectedModifierState), description(errorMsg)); + expectedModifierState, deviceBus), description(errorMsg)); } void assertSwitchToRecent(int persistentId) throws RemoteException { diff --git a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt index 44de6a6ecbc3ff325cf290837d1805544ad86bf7..9c335768de55b77a5327d4c65100fb6b8561d48f 100644 --- a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt +++ b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt @@ -63,6 +63,7 @@ private fun createKeyboard( deviceId: Int, vendorId: Int, productId: Int, + deviceBus: Int, languageTag: String, layoutType: String ): InputDevice = @@ -75,6 +76,7 @@ private fun createKeyboard( .setExternal(true) .setVendorId(vendorId) .setProductId(productId) + .setDeviceBus(deviceBus) .setKeyboardLanguageTag(languageTag) .setKeyboardLayoutType(layoutType) .build() @@ -94,6 +96,7 @@ class KeyboardLayoutManagerTests { const val ENGLISH_QWERTY_DEVICE_ID = 4 const val DEFAULT_VENDOR_ID = 123 const val DEFAULT_PRODUCT_ID = 456 + const val DEFAULT_DEVICE_BUS = 789 const val USER_ID = 4 const val IME_ID = "ime_id" const val PACKAGE_NAME = "KeyboardLayoutManagerTests" @@ -177,12 +180,14 @@ class KeyboardLayoutManagerTests { Mockito.`when`(context.getSystemService(Mockito.eq(Context.INPUT_SERVICE))) .thenReturn(inputManager) - keyboardDevice = createKeyboard(DEVICE_ID, DEFAULT_VENDOR_ID, DEFAULT_PRODUCT_ID, "", "") - vendorSpecificKeyboardDevice = createKeyboard(VENDOR_SPECIFIC_DEVICE_ID, 1, 1, "", "") + keyboardDevice = createKeyboard(DEVICE_ID, DEFAULT_VENDOR_ID, DEFAULT_PRODUCT_ID, + DEFAULT_DEVICE_BUS, "", "") + vendorSpecificKeyboardDevice = createKeyboard(VENDOR_SPECIFIC_DEVICE_ID, 1, 1, + 1, "", "") englishDvorakKeyboardDevice = createKeyboard(ENGLISH_DVORAK_DEVICE_ID, DEFAULT_VENDOR_ID, - DEFAULT_PRODUCT_ID, "en", "dvorak") + DEFAULT_PRODUCT_ID, DEFAULT_DEVICE_BUS, "en", "dvorak") englishQwertyKeyboardDevice = createKeyboard(ENGLISH_QWERTY_DEVICE_ID, DEFAULT_VENDOR_ID, - DEFAULT_PRODUCT_ID, "en", "qwerty") + DEFAULT_PRODUCT_ID, DEFAULT_DEVICE_BUS, "en", "qwerty") Mockito.`when`(iInputManager.inputDeviceIds) .thenReturn(intArrayOf( DEVICE_ID, @@ -861,7 +866,9 @@ class KeyboardLayoutManagerTests { GERMAN_LAYOUT_NAME, KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD, "de-Latn", - LAYOUT_TYPE_QWERTZ)) + LAYOUT_TYPE_QWERTZ), + ), + ArgumentMatchers.eq(keyboardDevice.deviceBus), ) } } @@ -887,7 +894,8 @@ class KeyboardLayoutManagerTests { ENGLISH_US_LAYOUT_NAME, KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEVICE, "de-Latn", - LAYOUT_TYPE_QWERTZ)) + LAYOUT_TYPE_QWERTZ)), + ArgumentMatchers.eq(keyboardDevice.deviceBus), ) } } @@ -911,7 +919,9 @@ class KeyboardLayoutManagerTests { "Default", KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEFAULT, KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG, - LAYOUT_TYPE_DEFAULT)) + LAYOUT_TYPE_DEFAULT), + ), + ArgumentMatchers.eq(keyboardDevice.deviceBus), ) } } @@ -929,7 +939,8 @@ class KeyboardLayoutManagerTests { ArgumentMatchers.anyBoolean(), ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt(), - ArgumentMatchers.any(ByteArray::class.java) + ArgumentMatchers.any(ByteArray::class.java), + ArgumentMatchers.anyInt(), ) }, Mockito.times(0)) } @@ -972,8 +983,13 @@ class KeyboardLayoutManagerTests { } private fun createByteArray( - expectedLanguageTag: String, expectedLayoutType: Int, expectedLayoutName: String, - expectedCriteria: Int, expectedImeLanguageTag: String, expectedImeLayoutType: Int): ByteArray { + expectedLanguageTag: String, + expectedLayoutType: Int, + expectedLayoutName: String, + expectedCriteria: Int, + expectedImeLanguageTag: String, + expectedImeLayoutType: Int + ): ByteArray { val proto = ProtoOutputStream() val keyboardLayoutConfigToken = proto.start( KeyboardConfiguredProto.RepeatedKeyboardLayoutConfig.KEYBOARD_LAYOUT_CONFIG) @@ -1001,7 +1017,7 @@ class KeyboardLayoutManagerTests { KeyboardConfiguredProto.KeyboardLayoutConfig.IME_LAYOUT_TYPE, expectedImeLayoutType ) - proto.end(keyboardLayoutConfigToken); + proto.end(keyboardLayoutConfigToken) return proto.bytes } diff --git a/tests/Input/src/com/android/server/input/KeyboardMetricsCollectorTests.kt b/tests/Input/src/com/android/server/input/KeyboardMetricsCollectorTests.kt index 33ff09b5553426c3469f1edc1aca7c46f0619666..89a47b9b736a193fef0335ac3314c5d5dc11d8fc 100644 --- a/tests/Input/src/com/android/server/input/KeyboardMetricsCollectorTests.kt +++ b/tests/Input/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" )