Modify PK Settings page to make it more user friendly

PK Settings page:
    - Show current PK layout selected for the current user profile and current IME language instead of a list of IMEs

PK layout mapping page:
    - Show IME name in header only if multiple active IMEs
    - Show the PK layout selection criteria (Automatic v/s User selected)

Bug: 325925410
Bug: 326195401
Test: manual
Change-Id: I93a2e169742a800fa116fa5d55e1a91e5548cebb
This commit is contained in:
Vaibhav Devmurari
2024-02-27 20:35:14 +00:00
parent 8371b4314b
commit 8754f114ac
5 changed files with 85 additions and 38 deletions

View File

@@ -4478,8 +4478,14 @@
<!-- Summary for the modifier key picker dialog page [CHAR LIMIT=35] --> <!-- Summary for the modifier key picker dialog page [CHAR LIMIT=35] -->
<string name="modifier_keys_picker_summary">Choose a new key for <xliff:g id="modifier_key_default_name">%1$s</xliff:g>:</string> <string name="modifier_keys_picker_summary">Choose a new key for <xliff:g id="modifier_key_default_name">%1$s</xliff:g>:</string>
<!-- Title text for per IME subtype keyboard layout. [CHAR LIMIT=35] -->
<string name="ime_label_title"><xliff:g id="ime_label" example="Gboard">%s</xliff:g> layout</string>
<!-- Summary text for keyboards when no layout has been selected. [CHAR LIMIT=35] --> <!-- Summary text for keyboards when no layout has been selected. [CHAR LIMIT=35] -->
<string name="default_keyboard_layout">Default</string> <string name="default_keyboard_layout">Default</string>
<!-- Summary text for keyboards when a layout is automatically selected. [CHAR LIMIT=35] -->
<string name="automatic_keyboard_layout_label">Automatic: <xliff:g id="layout_label" example="English(US)">%s</xliff:g></string>
<!-- Summary text for keyboards when a layout is user selected. [CHAR LIMIT=35] -->
<string name="user_selected_keyboard_layout_label">User selected: <xliff:g id="layout_label" example="English(US)">%s</xliff:g></string>
<!-- Title for the 'Speech' preference category. [CHAR LIMIT=45] --> <!-- Title for the 'Speech' preference category. [CHAR LIMIT=45] -->
<string name="speech_category_title">Speech</string> <string name="speech_category_title">Speech</string>

View File

@@ -21,6 +21,7 @@ import android.content.Context;
import android.hardware.input.InputDeviceIdentifier; import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.InputManager; import android.hardware.input.InputManager;
import android.hardware.input.KeyboardLayout; import android.hardware.input.KeyboardLayout;
import android.hardware.input.KeyboardLayoutSelectionResult;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
@@ -180,7 +181,7 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
mapLanguageWithLayout(info, subtype); mapLanguageWithLayout(info, subtype);
} }
} }
updatePreferenceLayout(preferenceScreen, info); updatePreferenceLayout(preferenceScreen, info, infoList.size() > 1);
} }
} }
@@ -189,14 +190,15 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
KeyboardLayout[] keyboardLayouts = KeyboardLayout[] keyboardLayouts =
NewKeyboardSettingsUtils.getKeyboardLayouts( NewKeyboardSettingsUtils.getKeyboardLayouts(
mIm, mUserId, mInputDeviceIdentifier, info, subtype); mIm, mUserId, mInputDeviceIdentifier, info, subtype);
String layout = NewKeyboardSettingsUtils.getKeyboardLayout( KeyboardLayoutSelectionResult result = NewKeyboardSettingsUtils.getKeyboardLayout(
mIm, mUserId, mInputDeviceIdentifier, info, subtype); mIm, mUserId, mInputDeviceIdentifier, info, subtype);
if (layout != null) { if (result.getLayoutDescriptor() != null) {
for (int i = 0; i < keyboardLayouts.length; i++) { for (int i = 0; i < keyboardLayouts.length; i++) {
if (keyboardLayouts[i].getDescriptor().equals(layout)) { if (keyboardLayouts[i].getDescriptor().equals(result.getLayoutDescriptor())) {
KeyboardInfo keyboardInfo = new KeyboardInfo( KeyboardInfo keyboardInfo = new KeyboardInfo(
subtypeLabel, subtypeLabel,
keyboardLayouts[i].getLabel(), keyboardLayouts[i].getLabel(),
result.getSelectionCriteria(),
info, info,
subtype); subtype);
mKeyboardInfoList.add(keyboardInfo); mKeyboardInfoList.add(keyboardInfo);
@@ -208,18 +210,22 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
KeyboardInfo keyboardInfo = new KeyboardInfo( KeyboardInfo keyboardInfo = new KeyboardInfo(
subtypeLabel, subtypeLabel,
mContext.getString(R.string.keyboard_default_layout), mContext.getString(R.string.keyboard_default_layout),
KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_UNSPECIFIED,
info, info,
subtype); subtype);
mKeyboardInfoList.add(keyboardInfo); mKeyboardInfoList.add(keyboardInfo);
} }
} }
private void updatePreferenceLayout(PreferenceScreen preferenceScreen, InputMethodInfo info) { private void updatePreferenceLayout(PreferenceScreen preferenceScreen, InputMethodInfo info,
boolean hasMultipleImes) {
if (mKeyboardInfoList.isEmpty()) { if (mKeyboardInfoList.isEmpty()) {
return; return;
} }
PreferenceCategory preferenceCategory = new PreferenceCategory(mContext); PreferenceCategory preferenceCategory = new PreferenceCategory(mContext);
preferenceCategory.setTitle(info.loadLabel(mContext.getPackageManager())); preferenceCategory.setTitle(hasMultipleImes ? mContext.getString(R.string.ime_label_title,
info.loadLabel(mContext.getPackageManager()))
: mContext.getString(R.string.enabled_locales_keyboard_layout));
preferenceCategory.setKey(info.getPackageName()); preferenceCategory.setKey(info.getPackageName());
preferenceScreen.addPreference(preferenceCategory); preferenceScreen.addPreference(preferenceCategory);
Collections.sort(mKeyboardInfoList, new Comparator<KeyboardInfo>() { Collections.sort(mKeyboardInfoList, new Comparator<KeyboardInfo>() {
@@ -234,7 +240,7 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
final Preference pref = new Preference(mContext); final Preference pref = new Preference(mContext);
pref.setKey(keyboardInfo.getPrefId()); pref.setKey(keyboardInfo.getPrefId());
pref.setTitle(keyboardInfo.getSubtypeLabel()); pref.setTitle(keyboardInfo.getSubtypeLabel());
pref.setSummary(keyboardInfo.getLayout()); pref.setSummary(keyboardInfo.getLayoutSummaryText(mContext));
pref.setOnPreferenceClickListener( pref.setOnPreferenceClickListener(
preference -> { preference -> {
showKeyboardLayoutPicker( showKeyboardLayoutPicker(

View File

@@ -21,6 +21,7 @@ import android.content.Context;
import android.hardware.input.InputDeviceIdentifier; import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.InputManager; import android.hardware.input.InputManager;
import android.hardware.input.KeyboardLayout; import android.hardware.input.KeyboardLayout;
import android.hardware.input.KeyboardLayoutSelectionResult;
import android.os.Bundle; import android.os.Bundle;
import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype; import android.view.inputmethod.InputMethodSubtype;
@@ -201,13 +202,13 @@ public class NewKeyboardLayoutPickerController extends BasePreferenceController
private String getSelectedLayoutLabel() { private String getSelectedLayoutLabel() {
String label = mContext.getString(R.string.keyboard_default_layout); String label = mContext.getString(R.string.keyboard_default_layout);
String layout = NewKeyboardSettingsUtils.getKeyboardLayout( KeyboardLayoutSelectionResult result = NewKeyboardSettingsUtils.getKeyboardLayout(
mIm, mUserId, mInputDeviceIdentifier, mInputMethodInfo, mInputMethodSubtype); mIm, mUserId, mInputDeviceIdentifier, mInputMethodInfo, mInputMethodSubtype);
KeyboardLayout[] keyboardLayouts = NewKeyboardSettingsUtils.getKeyboardLayouts( KeyboardLayout[] keyboardLayouts = NewKeyboardSettingsUtils.getKeyboardLayouts(
mIm, mUserId, mInputDeviceIdentifier, mInputMethodInfo, mInputMethodSubtype); mIm, mUserId, mInputDeviceIdentifier, mInputMethodInfo, mInputMethodSubtype);
if (layout != null) { if (result.getLayoutDescriptor() != null) {
for (KeyboardLayout keyboardLayout : keyboardLayouts) { for (KeyboardLayout keyboardLayout : keyboardLayouts) {
if (keyboardLayout.getDescriptor().equals(layout)) { if (keyboardLayout.getDescriptor().equals(result.getLayoutDescriptor())) {
label = keyboardLayout.getLabel(); label = keyboardLayout.getLabel();
break; break;
} }

View File

@@ -16,20 +16,30 @@
package com.android.settings.inputmethod; package com.android.settings.inputmethod;
import static android.hardware.input.KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_USER;
import static android.hardware.input.KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_DEVICE;
import static android.hardware.input.KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.UserIdInt;
import android.content.Context; import android.content.Context;
import android.hardware.input.InputDeviceIdentifier; import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.InputManager; import android.hardware.input.InputManager;
import android.hardware.input.KeyboardLayout; import android.hardware.input.KeyboardLayout;
import android.hardware.input.KeyboardLayoutSelectionResult;
import android.hardware.input.KeyboardLayoutSelectionResult.LayoutSelectionCriteria;
import android.os.UserHandle; import android.os.UserHandle;
import android.view.InputDevice; import android.view.InputDevice;
import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype; import android.view.inputmethod.InputMethodSubtype;
import java.util.ArrayList; import com.android.settings.R;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.List;
/** /**
* Utilities of keyboard settings * Utilities of keyboard settings
@@ -56,36 +66,47 @@ public class NewKeyboardSettingsUtils {
return false; return false;
} }
static List<String> getSuitableImeLabels(Context context, InputMethodManager imm, int userId) { @SuppressLint("MissingPermission")
List<String> suitableInputMethodInfoLabels = new ArrayList<>(); @Nullable
List<InputMethodInfo> infoList = imm.getEnabledInputMethodListAsUser(UserHandle.of(userId)); static String getSelectedKeyboardLayoutLabelForUser(Context context, @UserIdInt int userId,
for (InputMethodInfo info : infoList) { InputDeviceIdentifier inputDeviceIdentifier) {
List<InputMethodSubtype> subtypes = InputMethodManager imm = context.getSystemService(InputMethodManager.class);
imm.getEnabledInputMethodSubtypeList(info, true); InputManager im = context.getSystemService(InputManager.class);
for (InputMethodSubtype subtype : subtypes) { if (imm == null || im == null) {
if (subtype.isSuitableForPhysicalKeyboardLayoutMapping()) { return null;
suitableInputMethodInfoLabels.add( }
info.loadLabel(context.getPackageManager()).toString()); InputMethodInfo imeInfo = imm.getCurrentInputMethodInfoAsUser(UserHandle.of(userId));
break; InputMethodSubtype subtype = imm.getCurrentInputMethodSubtype();
KeyboardLayout[] keyboardLayouts = getKeyboardLayouts(im, userId, inputDeviceIdentifier,
imeInfo, subtype);
KeyboardLayoutSelectionResult result = getKeyboardLayout(im, userId, inputDeviceIdentifier,
imeInfo, subtype);
if (result != null) {
for (KeyboardLayout keyboardLayout : keyboardLayouts) {
if (keyboardLayout.getDescriptor().equals(result.getLayoutDescriptor())) {
return keyboardLayout.getLabel();
} }
} }
} }
return suitableInputMethodInfoLabels; return null;
} }
static class KeyboardInfo { static class KeyboardInfo {
CharSequence mSubtypeLabel; CharSequence mSubtypeLabel;
String mLayout; String mLayout;
@LayoutSelectionCriteria int mSelectionCriteria;
InputMethodInfo mInputMethodInfo; InputMethodInfo mInputMethodInfo;
InputMethodSubtype mInputMethodSubtype; InputMethodSubtype mInputMethodSubtype;
KeyboardInfo( KeyboardInfo(
CharSequence subtypeLabel, CharSequence subtypeLabel,
String layout, String layout,
@LayoutSelectionCriteria int selectionCriteria,
InputMethodInfo inputMethodInfo, InputMethodInfo inputMethodInfo,
InputMethodSubtype inputMethodSubtype) { InputMethodSubtype inputMethodSubtype) {
mSubtypeLabel = subtypeLabel; mSubtypeLabel = subtypeLabel;
mLayout = layout; mLayout = layout;
mSelectionCriteria = selectionCriteria;
mInputMethodInfo = inputMethodInfo; mInputMethodInfo = inputMethodInfo;
mInputMethodSubtype = inputMethodSubtype; mInputMethodSubtype = inputMethodSubtype;
} }
@@ -102,6 +123,17 @@ public class NewKeyboardSettingsUtils {
return mLayout; return mLayout;
} }
String getLayoutSummaryText(Context context) {
if (isAutomaticSelection(mSelectionCriteria)) {
return context.getResources().getString(R.string.automatic_keyboard_layout_label,
mLayout);
} else if (isUserSelection(mSelectionCriteria)) {
return context.getResources().getString(
R.string.user_selected_keyboard_layout_label, mLayout);
}
return mLayout;
}
InputMethodInfo getInputMethodInfo() { InputMethodInfo getInputMethodInfo() {
return mInputMethodInfo; return mInputMethodInfo;
} }
@@ -121,11 +153,21 @@ public class NewKeyboardSettingsUtils {
return inputManager.getKeyboardLayoutListForInputDevice(identifier, userId, info, subtype); return inputManager.getKeyboardLayoutListForInputDevice(identifier, userId, info, subtype);
} }
static String getKeyboardLayout(InputManager inputManager, int userId, @NonNull
static KeyboardLayoutSelectionResult getKeyboardLayout(InputManager inputManager, int userId,
InputDeviceIdentifier identifier, InputMethodInfo info, InputMethodSubtype subtype) { InputDeviceIdentifier identifier, InputMethodInfo info, InputMethodSubtype subtype) {
return inputManager.getKeyboardLayoutForInputDevice(identifier, userId, info, subtype); return inputManager.getKeyboardLayoutForInputDevice(identifier, userId, info, subtype);
} }
static boolean isAutomaticSelection(@LayoutSelectionCriteria int criteria) {
return criteria == LAYOUT_SELECTION_CRITERIA_DEVICE
|| criteria == LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD;
}
static boolean isUserSelection(@LayoutSelectionCriteria int criteria) {
return criteria == LAYOUT_SELECTION_CRITERIA_USER;
}
static void sortKeyboardLayoutsByLabel(KeyboardLayout[] keyboardLayouts) { static void sortKeyboardLayoutsByLabel(KeyboardLayout[] keyboardLayouts) {
Arrays.sort( Arrays.sort(
keyboardLayouts, keyboardLayouts,

View File

@@ -280,19 +280,11 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
final Preference pref = new Preference(getPrefContext()); final Preference pref = new Preference(getPrefContext());
pref.setTitle(hardKeyboardDeviceInfo.mDeviceName); pref.setTitle(hardKeyboardDeviceInfo.mDeviceName);
if (mIsNewKeyboardSettings) { if (mIsNewKeyboardSettings) {
List<String> suitableImes = new ArrayList<>(); String currentLayout =
suitableImes.addAll( NewKeyboardSettingsUtils.getSelectedKeyboardLayoutLabelForUser(getContext(),
NewKeyboardSettingsUtils.getSuitableImeLabels( UserHandle.myUserId(), hardKeyboardDeviceInfo.mDeviceIdentifier);
getContext(), mImm, UserHandle.myUserId())); if (currentLayout != null) {
if (!suitableImes.isEmpty()) { pref.setSummary(currentLayout);
String summary = suitableImes.get(0);
StringBuilder result = new StringBuilder(summary);
for (int i = 1; i < suitableImes.size(); i++) {
result.append(", ").append(suitableImes.get(i));
}
pref.setSummary(result.toString());
} else {
pref.setSummary(hardKeyboardDeviceInfo.mLayoutLabel);
} }
pref.setOnPreferenceClickListener( pref.setOnPreferenceClickListener(
preference -> { preference -> {