Logging for fields added in KeyboardConfigured atom

Added logging for the ime_language_tag and ime_layout_type fields added
in the KeyboardCongigured atom. Also added default value for the
LayoutSelectionCriteria.
Added handling for null language tags.

Bug: 280421650
Test: atest FrameworksServicesTests:KeyboardMetricsCollectorTests
Change-Id: Ia83da586093f146201082d07750d27bc02546655
diff --git a/core/proto/android/input/keyboard_configured.proto b/core/proto/android/input/keyboard_configured.proto
index 1699008..0b4bf8e 100644
--- a/core/proto/android/input/keyboard_configured.proto
+++ b/core/proto/android/input/keyboard_configured.proto
@@ -47,4 +47,8 @@
   // IntDef annotation at:
   // services/core/java/com/android/server/input/KeyboardMetricsCollector.java
   optional int32 layout_selection_criteria = 4;
+  // Keyboard layout type provided by IME
+  optional int32 ime_layout_type = 5;
+  // Language tag provided by IME (e.g. en-US, ru-Cyrl etc.)
+  optional string ime_language_tag = 6;
 }
diff --git a/services/core/java/com/android/server/input/KeyboardLayoutManager.java b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
index 3ac1594..6368a7b 100644
--- a/services/core/java/com/android/server/input/KeyboardLayoutManager.java
+++ b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
@@ -16,6 +16,7 @@
 
 package com.android.server.input;
 
+import static com.android.server.input.KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEFAULT;
 import static com.android.server.input.KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEVICE;
 import static com.android.server.input.KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_USER;
 import static com.android.server.input.KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD;
@@ -1269,7 +1270,7 @@
             boolean noLayoutFound = layoutInfo == null || layoutInfo.mDescriptor == null;
             configurationEventBuilder.addLayoutSelection(imeInfoList.get(i).mImeSubtype,
                     noLayoutFound ? null : getKeyboardLayout(layoutInfo.mDescriptor),
-                    noLayoutFound ? LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD
+                    noLayoutFound ? LAYOUT_SELECTION_CRITERIA_DEFAULT
                             : layoutInfo.mSelectionCriteria);
         }
         KeyboardMetricsCollector.logKeyboardConfiguredAtom(configurationEventBuilder.build());
diff --git a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
index 19fa7a8..eb2da34 100644
--- a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
+++ b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
@@ -53,7 +53,8 @@
     @IntDef(prefix = { "LAYOUT_SELECTION_CRITERIA_" }, value = {
             LAYOUT_SELECTION_CRITERIA_USER,
             LAYOUT_SELECTION_CRITERIA_DEVICE,
-            LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD
+            LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD,
+            LAYOUT_SELECTION_CRITERIA_DEFAULT
     })
     public @interface LayoutSelectionCriteria {}
 
@@ -66,9 +67,15 @@
     /** Auto-detection based on IME provided language tag and layout type */
     public static final int LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD = 2;
 
+    /** Default selection */
+    public static final int LAYOUT_SELECTION_CRITERIA_DEFAULT = 3;
+
     @VisibleForTesting
     static final String DEFAULT_LAYOUT = "Default";
 
+    @VisibleForTesting
+    static final String DEFAULT_LANGUAGE_TAG = "None";
+
     /**
      * Log keyboard system shortcuts for the proto
      * {@link com.android.os.input.KeyboardSystemsEventReported}
@@ -131,6 +138,10 @@
                 layoutConfiguration.keyboardLayoutName);
         proto.write(KeyboardLayoutConfig.LAYOUT_SELECTION_CRITERIA,
                 layoutConfiguration.layoutSelectionCriteria);
+        proto.write(KeyboardLayoutConfig.IME_LANGUAGE_TAG,
+                layoutConfiguration.imeLanguageTag);
+        proto.write(KeyboardLayoutConfig.IME_LAYOUT_TYPE,
+                layoutConfiguration.imeLayoutType);
         proto.end(keyboardLayoutConfigToken);
     }
 
@@ -231,27 +242,29 @@
                     @LayoutSelectionCriteria int layoutSelectionCriteria =
                             mLayoutSelectionCriteriaList.get(i);
                     InputMethodSubtype imeSubtype =  mImeSubtypeList.get(i);
-                    String keyboardLanguageTag;
-                    String keyboardLayoutStringType;
-                    if (layoutSelectionCriteria == LAYOUT_SELECTION_CRITERIA_DEVICE) {
-                        keyboardLanguageTag = mInputDevice.getKeyboardLanguageTag();
-                        keyboardLayoutStringType = mInputDevice.getKeyboardLayoutType();
-                    } else {
-                        ULocale pkLocale = imeSubtype.getPhysicalKeyboardHintLanguageTag();
-                        keyboardLanguageTag = pkLocale != null ? pkLocale.toLanguageTag()
-                                : imeSubtype.getCanonicalizedLanguageTag();
-                        keyboardLayoutStringType = imeSubtype.getPhysicalKeyboardHintLayoutType();
-                    }
+                    String keyboardLanguageTag = mInputDevice.getKeyboardLanguageTag();
+                    keyboardLanguageTag = keyboardLanguageTag == null ? DEFAULT_LANGUAGE_TAG
+                            : keyboardLanguageTag;
+                    int keyboardLayoutType = KeyboardLayout.LayoutType.getLayoutTypeEnumValue(
+                            mInputDevice.getKeyboardLayoutType());
+
+                    ULocale pkLocale = imeSubtype.getPhysicalKeyboardHintLanguageTag();
+                    String canonicalizedLanguageTag =
+                            imeSubtype.getCanonicalizedLanguageTag().equals("")
+                            ? DEFAULT_LANGUAGE_TAG : imeSubtype.getCanonicalizedLanguageTag();
+                    String imeLanguageTag = pkLocale != null ? pkLocale.toLanguageTag()
+                            : canonicalizedLanguageTag;
+                    int imeLayoutType = KeyboardLayout.LayoutType.getLayoutTypeEnumValue(
+                            imeSubtype.getPhysicalKeyboardHintLayoutType());
+
                     // Sanitize null values
                     String keyboardLayoutName =
                             selectedLayout == null ? DEFAULT_LAYOUT : selectedLayout.getLabel();
-                    keyboardLanguageTag = keyboardLanguageTag == null ? "" : keyboardLanguageTag;
-                    int keyboardLayoutType = KeyboardLayout.LayoutType.getLayoutTypeEnumValue(
-                            keyboardLayoutStringType);
 
                     configurationList.add(
                             new LayoutConfiguration(keyboardLayoutType, keyboardLanguageTag,
-                                    keyboardLayoutName, layoutSelectionCriteria));
+                                    keyboardLayoutName, layoutSelectionCriteria,
+                                    imeLayoutType, imeLanguageTag));
                 }
                 return new KeyboardConfigurationEvent(mInputDevice, mIsFirstConfiguration,
                         configurationList);
@@ -267,13 +280,18 @@
         public final String keyboardLayoutName;
         @LayoutSelectionCriteria
         public final int layoutSelectionCriteria;
+        public final int imeLayoutType;
+        public final String imeLanguageTag;
 
         private LayoutConfiguration(int keyboardLayoutType, String keyboardLanguageTag,
-                String keyboardLayoutName, @LayoutSelectionCriteria int layoutSelectionCriteria) {
+                String keyboardLayoutName, @LayoutSelectionCriteria int layoutSelectionCriteria,
+                int imeLayoutType, String imeLanguageTag) {
             this.keyboardLayoutType = keyboardLayoutType;
             this.keyboardLanguageTag = keyboardLanguageTag;
             this.keyboardLayoutName = keyboardLayoutName;
             this.layoutSelectionCriteria = layoutSelectionCriteria;
+            this.imeLayoutType = imeLayoutType;
+            this.imeLanguageTag = imeLanguageTag;
         }
 
         @Override
@@ -281,7 +299,9 @@
             return "{keyboardLanguageTag = " + keyboardLanguageTag + " keyboardLayoutType = "
                     + KeyboardLayout.LayoutType.getLayoutNameFromValue(keyboardLayoutType)
                     + " keyboardLayoutName = " + keyboardLayoutName + " layoutSelectionCriteria = "
-                    + getStringForSelectionCriteria(layoutSelectionCriteria) + "}";
+                    + getStringForSelectionCriteria(layoutSelectionCriteria)
+                    + "imeLanguageTag = " + imeLanguageTag + " imeLayoutType = "
+                    + KeyboardLayout.LayoutType.getLayoutNameFromValue(imeLayoutType) + "}";
         }
     }
 
@@ -294,6 +314,8 @@
                 return "LAYOUT_SELECTION_CRITERIA_DEVICE";
             case LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD:
                 return "LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD";
+            case LAYOUT_SELECTION_CRITERIA_DEFAULT:
+                return "LAYOUT_SELECTION_CRITERIA_DEFAULT";
             default:
                 return "INVALID_CRITERIA";
         }
@@ -302,7 +324,8 @@
     private static boolean isValidSelectionCriteria(int layoutSelectionCriteria) {
         return layoutSelectionCriteria == LAYOUT_SELECTION_CRITERIA_USER
                 || layoutSelectionCriteria == LAYOUT_SELECTION_CRITERIA_DEVICE
-                || layoutSelectionCriteria == LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD;
+                || layoutSelectionCriteria == LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD
+                || layoutSelectionCriteria == LAYOUT_SELECTION_CRITERIA_DEFAULT;
     }
 }
 
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 c9724a3..a435d60 100644
--- a/services/tests/servicestests/src/com/android/server/input/KeyboardMetricsCollectorTests.kt
+++ b/services/tests/servicestests/src/com/android/server/input/KeyboardMetricsCollectorTests.kt
@@ -48,11 +48,11 @@
 
 private fun createImeSubtype(
     imeSubtypeId: Int,
-    languageTag: String,
+    languageTag: ULocale?,
     layoutType: String
 ): InputMethodSubtype =
     InputMethodSubtype.InputMethodSubtypeBuilder().setSubtypeId(imeSubtypeId)
-        .setPhysicalKeyboardHint(ULocale.forLanguageTag(languageTag), layoutType).build()
+        .setPhysicalKeyboardHint(languageTag, layoutType).build()
 
 /**
  * Tests for {@link KeyboardMetricsCollector}.
@@ -95,7 +95,8 @@
                     null,
                     null
                 )
-            ).addLayoutSelection(createImeSubtype(1, "en-US", "qwerty"), null, 123).build()
+            ).addLayoutSelection(createImeSubtype(1, ULocale.forLanguageTag("en-US"), "qwerty"),
+             null, 123).build()
         }
     }
 
@@ -111,15 +112,19 @@
             )
         )
         val event = builder.addLayoutSelection(
-            createImeSubtype(1, "en-US", "qwerty"),
+            createImeSubtype(1, ULocale.forLanguageTag("en-US"), "qwerty"),
             KeyboardLayout(null, "English(US)(Qwerty)", null, 0, null, 0, 0, 0),
             KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD
         ).addLayoutSelection(
-            createImeSubtype(2, "en-US", "azerty"),
-            null,
+            createImeSubtype(2, ULocale.forLanguageTag("en-US"), "azerty"),
+            null, // Default layout type
             KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_USER
         ).addLayoutSelection(
-            createImeSubtype(3, "en-US", "qwerty"),
+            createImeSubtype(3, ULocale.forLanguageTag("en-US"), "qwerty"),
+            KeyboardLayout(null, "German", null, 0, null, 0, 0, 0),
+            KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEVICE
+        ).addLayoutSelection(
+            createImeSubtype(4, null, "qwerty"), // Default language tag
             KeyboardLayout(null, "German", null, 0, null, 0, 0, 0),
             KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEVICE
         ).setIsFirstTimeConfiguration(true).build()
@@ -137,43 +142,62 @@
         assertTrue(event.isFirstConfiguration)
 
         assertEquals(
-            "KeyboardConfigurationEvent should contain 3 configurations provided",
-            3,
+            "KeyboardConfigurationEvent should contain 4 configurations provided",
+            4,
             event.layoutConfigurations.size
         )
         assertExpectedLayoutConfiguration(
             event.layoutConfigurations[0],
+            "de-CH",
+            KeyboardLayout.LayoutType.getLayoutTypeEnumValue("qwertz"),
+            "English(US)(Qwerty)",
+            KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD,
             "en-US",
             KeyboardLayout.LayoutType.getLayoutTypeEnumValue("qwerty"),
-            "English(US)(Qwerty)",
-            KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD
         )
         assertExpectedLayoutConfiguration(
             event.layoutConfigurations[1],
+            "de-CH",
+            KeyboardLayout.LayoutType.getLayoutTypeEnumValue("qwertz"),
+            KeyboardMetricsCollector.DEFAULT_LAYOUT,
+            KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_USER,
             "en-US",
             KeyboardLayout.LayoutType.getLayoutTypeEnumValue("azerty"),
-            KeyboardMetricsCollector.DEFAULT_LAYOUT,
-            KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_USER
         )
         assertExpectedLayoutConfiguration(
             event.layoutConfigurations[2],
             "de-CH",
             KeyboardLayout.LayoutType.getLayoutTypeEnumValue("qwertz"),
             "German",
-            KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEVICE
+            KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEVICE,
+            "en-US",
+            KeyboardLayout.LayoutType.getLayoutTypeEnumValue("qwerty"),
+        )
+        assertExpectedLayoutConfiguration(
+            event.layoutConfigurations[3],
+            "de-CH",
+            KeyboardLayout.LayoutType.getLayoutTypeEnumValue("qwertz"),
+            "German",
+            KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEVICE,
+            KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
+            KeyboardLayout.LayoutType.getLayoutTypeEnumValue("qwerty"),
         )
     }
 
     private fun assertExpectedLayoutConfiguration(
         configuration: KeyboardMetricsCollector.LayoutConfiguration,
-        expectedLanguageTag: String,
-        expectedLayoutType: Int,
+        expectedKeyboardLanguageTag: String,
+        expectedKeyboardLayoutType: Int,
         expectedSelectedLayout: String,
-        expectedLayoutSelectionCriteria: Int
+        expectedLayoutSelectionCriteria: Int,
+        expectedImeLanguageTag: String,
+        expectedImeLayoutType: Int
     ) {
-        assertEquals(expectedLanguageTag, configuration.keyboardLanguageTag)
-        assertEquals(expectedLayoutType, configuration.keyboardLayoutType)
+        assertEquals(expectedKeyboardLanguageTag, configuration.keyboardLanguageTag)
+        assertEquals(expectedKeyboardLayoutType, configuration.keyboardLayoutType)
         assertEquals(expectedSelectedLayout, configuration.keyboardLayoutName)
         assertEquals(expectedLayoutSelectionCriteria, configuration.layoutSelectionCriteria)
+        assertEquals(expectedImeLanguageTag, configuration.imeLanguageTag)
+        assertEquals(expectedImeLayoutType, configuration.imeLayoutType)
     }
-}
\ No newline at end of file
+}