diff --git a/res/drawable/ic_check_24dp.xml b/res/drawable/ic_check_24dp.xml
new file mode 100644
index 00000000000..5801e701e0a
--- /dev/null
+++ b/res/drawable/ic_check_24dp.xml
@@ -0,0 +1,25 @@
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/keyboard_layout_picker.xml b/res/layout/keyboard_layout_picker.xml
new file mode 100644
index 00000000000..6b163da250c
--- /dev/null
+++ b/res/layout/keyboard_layout_picker.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/preference_check_icon.xml b/res/layout/preference_check_icon.xml
new file mode 100644
index 00000000000..5652ac65997
--- /dev/null
+++ b/res/layout/preference_check_icon.xml
@@ -0,0 +1,23 @@
+
+
+
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2cfec6e4d10..6534e3ee81b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1281,6 +1281,8 @@
Device details
+
+ Keyboard settings
Device\'s Bluetooth address: %1$s
@@ -3592,8 +3594,8 @@
Available On-screen keyboard
Manage on-screen keyboards
-
- Keyboard assistance
+
+ Options
Physical keyboard
@@ -3603,7 +3605,7 @@
Keyboard shortcuts
- Display available shortcuts
+ Show list of shortcuts
Work profile keyboards & tools
@@ -3638,6 +3640,8 @@
Keyboard layouts
+
+ Physical keyboard layouts
@@ -3693,6 +3697,9 @@
Physical keyboard
+
+ Layout
+
diff --git a/res/xml/bluetooth_device_details_fragment.xml b/res/xml/bluetooth_device_details_fragment.xml
index 0528973d676..8a0c32b6b86 100644
--- a/res/xml/bluetooth_device_details_fragment.xml
+++ b/res/xml/bluetooth_device_details_fragment.xml
@@ -85,6 +85,12 @@
settings:controller="com.android.settings.accessibility.LiveCaptionPreferenceController"/>
+
+
+ android:key="keyboards_category">
+
+
+
+
+
\ No newline at end of file
diff --git a/res/xml/new_keyboard_layout_picker_fragment.xml b/res/xml/new_keyboard_layout_picker_fragment.xml
new file mode 100644
index 00000000000..0a76984014b
--- /dev/null
+++ b/res/xml/new_keyboard_layout_picker_fragment.xml
@@ -0,0 +1,21 @@
+
+
+
+
\ No newline at end of file
diff --git a/res/xml/new_keyboard_layout_picker_title.xml b/res/xml/new_keyboard_layout_picker_title.xml
new file mode 100644
index 00000000000..cd03b918738
--- /dev/null
+++ b/res/xml/new_keyboard_layout_picker_title.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/xml/physical_keyboard_settings.xml b/res/xml/physical_keyboard_settings.xml
index 96946a9030e..54a5c65337c 100644
--- a/res/xml/physical_keyboard_settings.xml
+++ b/res/xml/physical_keyboard_settings.xml
@@ -19,8 +19,8 @@
+ android:key="keyboard_options_category"
+ android:title="@string/keyboard_options_category">
newHardKeyboards =
+ PhysicalKeyboardFragment.getHardKeyboards(mContext);
+ if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI)
+ && !newHardKeyboards.isEmpty()) {
+ for (HardKeyboardDeviceInfo hardKeyboardDeviceInfo : newHardKeyboards) {
+ if (mCachedDevice.getAddress() != null
+ && hardKeyboardDeviceInfo.mBluetoothAddress != null
+ && mCachedDevice.getAddress().equals(
+ hardKeyboardDeviceInfo.mBluetoothAddress)) {
+ return AVAILABLE;
+ }
+ }
+ }
+ return CONDITIONALLY_UNAVAILABLE;
+ }
+}
diff --git a/src/com/android/settings/inputmethod/NewKeyboardLayoutEnabledLocalesFragment.java b/src/com/android/settings/inputmethod/NewKeyboardLayoutEnabledLocalesFragment.java
new file mode 100644
index 00000000000..5c0f88fbcd0
--- /dev/null
+++ b/src/com/android/settings/inputmethod/NewKeyboardLayoutEnabledLocalesFragment.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package com.android.settings.inputmethod;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.hardware.input.InputDeviceIdentifier;
+import android.hardware.input.InputManager;
+import android.os.Bundle;
+import android.view.InputDevice;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+
+import com.android.settings.R;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.dashboard.DashboardFragment;
+
+public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
+ implements InputManager.InputDeviceListener {
+
+ private static final String TAG = "NewKeyboardLayoutEnabledLocalesFragment";
+ private static final String PREF_KEY_ENABLED_LOCALES = "enabled_locales_keyboard_layout";
+
+ static final String EXTRA_KEYBOARD_DEVICE_NAME = "extra_keyboard_device_name";
+
+ private InputManager mIm;
+ private InputDeviceIdentifier mInputDeviceIdentifier;
+ private int mInputDeviceId;
+ private Context mContext;
+
+ @Override
+ public void onActivityCreated(final Bundle icicle) {
+ super.onActivityCreated(icicle);
+
+ Bundle arguments = getArguments();
+ final String title = arguments.getString(EXTRA_KEYBOARD_DEVICE_NAME);
+ mInputDeviceIdentifier = arguments.getParcelable(
+ KeyboardLayoutPickerFragment.EXTRA_INPUT_DEVICE_IDENTIFIER);
+ getActivity().setTitle(title);
+ final PreferenceCategory category = findPreference(PREF_KEY_ENABLED_LOCALES);
+
+ // TODO(b/252816846): Need APIs to get the available keyboards from Inputmanager.
+ // For example: InputMethodManager.getEnabledInputMethodLocales()
+ // InputManager.getKeyboardLayoutForLocale()
+ // Hardcode the default value for demo purpose
+ String[] keyboardLanguages = {"English (US)", "German (Germany)", "Spanish (Spain)"};
+ String[] keyboardLayouts = {"English (US)", "German", "Spanish"};
+ for (int i = 0; i < keyboardLanguages.length; i++) {
+ final Preference pref = new Preference(mContext);
+ String key = "keyboard_language_label_" + String.valueOf(i);
+ String keyboardLanguageTitle = keyboardLanguages[i];
+ String keyboardLanguageSummary = keyboardLayouts[i];
+ // TODO: Waiting for new API to use a prefix with special number to setKey
+ pref.setKey(key);
+ pref.setTitle(keyboardLanguageTitle);
+ pref.setSummary(keyboardLanguageSummary);
+ pref.setOnPreferenceClickListener(
+ preference -> {
+ showKeyboardLayoutPicker(
+ keyboardLanguageTitle,
+ keyboardLanguageSummary,
+ mInputDeviceIdentifier);
+ return true;
+ });
+ category.addPreference(pref);
+ }
+ }
+
+ @Override
+ public void onInputDeviceAdded(int deviceId) {
+ // Do nothing.
+ }
+
+ @Override
+ public void onInputDeviceRemoved(int deviceId) {
+ if (mInputDeviceId >= 0 && deviceId == mInputDeviceId) {
+ getActivity().finish();
+ }
+ }
+
+ @Override
+ public void onInputDeviceChanged(int deviceId) {
+ if (mInputDeviceId >= 0 && deviceId == mInputDeviceId) {
+ // TODO(b/252816846): Need APIs to update the available keyboards.
+ }
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = getContext();
+ mIm = mContext.getSystemService(InputManager.class);
+ mInputDeviceId = -1;
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ mIm.registerInputDeviceListener(this, null);
+ final InputDevice inputDevice =
+ mIm.getInputDeviceByDescriptor(mInputDeviceIdentifier.getDescriptor());
+ if (inputDevice == null) {
+ getActivity().finish();
+ return;
+ }
+ mInputDeviceId = inputDevice.getId();
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ mIm.unregisterInputDeviceListener(this);
+ mInputDeviceId = -1;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ // TODO(b/252816846): Need APIs to get the available keyboards from Inputmanager.
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.SETTINGS_KEYBOARDS_ENABLED_LOCALES;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.keyboard_settings_enabled_locales_list;
+ }
+
+ private void showKeyboardLayoutPicker(String language, String layout,
+ InputDeviceIdentifier inputDeviceIdentifier) {
+ Bundle arguments = new Bundle();
+ arguments.putParcelable(KeyboardLayoutPickerFragment.EXTRA_INPUT_DEVICE_IDENTIFIER,
+ inputDeviceIdentifier);
+ arguments.putString(NewKeyboardLayoutPickerFragment.EXTRA_TITLE, language);
+ arguments.putString(NewKeyboardLayoutPickerFragment.EXTRA_KEYBOARD_LAYOUT, layout);
+ new SubSettingLauncher(mContext)
+ .setSourceMetricsCategory(getMetricsCategory())
+ .setDestination(NewKeyboardLayoutPickerFragment.class.getName())
+ .setArguments(arguments)
+ .launch();
+ }
+}
diff --git a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerContent.java b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerContent.java
new file mode 100644
index 00000000000..dc94306b4d6
--- /dev/null
+++ b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerContent.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package com.android.settings.inputmethod;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.hardware.input.InputDeviceIdentifier;
+import android.os.Bundle;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+
+public class NewKeyboardLayoutPickerContent extends DashboardFragment {
+
+ private static final String TAG = "KeyboardLayoutPicker";
+
+ static final String EXTRA_TITLE = "keyboard_layout_picker_title";
+ static final String EXTRA_KEYBOARD_LAYOUT = "keyboard_layout";
+
+ /**
+ * Intent extra: The input device descriptor of the keyboard whose keyboard
+ * layout is to be changed.
+ */
+ public static final String EXTRA_INPUT_DEVICE_IDENTIFIER = "input_device_identifier";
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+
+ Bundle arguments = getArguments();
+ final String title = arguments.getString(EXTRA_TITLE);
+ final String layout = arguments.getString(EXTRA_KEYBOARD_LAYOUT);
+ final InputDeviceIdentifier inputDeviceIdentifier =
+ arguments.getParcelable(EXTRA_INPUT_DEVICE_IDENTIFIER);
+
+ if (inputDeviceIdentifier == null) {
+ getActivity().finish();
+ }
+ getActivity().setTitle(title);
+ use(NewKeyboardLayoutPickerController.class).initialize(this /*parent*/,
+ inputDeviceIdentifier, layout);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ // TODO: add new SettingsEnums SETTINGS_KEYBOARDS_LAYOUT_PICKER_CONTENT
+ return SettingsEnums.SETTINGS_KEYBOARDS_LAYOUT_PICKER;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ protected int getPreferenceScreenResId() {
+ return R.xml.new_keyboard_layout_picker_fragment;
+ }
+}
diff --git a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerController.java b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerController.java
new file mode 100644
index 00000000000..4a598d57469
--- /dev/null
+++ b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerController.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package com.android.settings.inputmethod;
+
+import android.content.Context;
+import android.hardware.input.InputDeviceIdentifier;
+import android.hardware.input.InputManager;
+import android.hardware.input.KeyboardLayout;
+import android.view.InputDevice;
+
+import androidx.fragment.app.Fragment;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+public class NewKeyboardLayoutPickerController extends BasePreferenceController implements
+ InputManager.InputDeviceListener, LifecycleObserver, OnStart, OnStop {
+ private final InputManager mIm;
+ private final Map mPreferenceMap;
+
+ private Fragment mParent;
+ private int mInputDeviceId;
+ private InputDeviceIdentifier mInputDeviceIdentifier;
+ private KeyboardLayout[] mKeyboardLayouts;
+ private PreferenceScreen mScreen;
+ private String mPreviousSelection;
+ private String mLayout;
+
+ public NewKeyboardLayoutPickerController(Context context, String key) {
+ super(context, key);
+ mIm = context.getSystemService(InputManager.class);
+ mInputDeviceId = -1;
+ mPreferenceMap = new HashMap<>();
+ }
+
+ public void initialize(Fragment parent, InputDeviceIdentifier inputDeviceIdentifier,
+ String layout) {
+ mLayout = layout;
+ mParent = parent;
+ mInputDeviceIdentifier = inputDeviceIdentifier;
+ mKeyboardLayouts = mIm.getKeyboardLayoutsForInputDevice(mInputDeviceIdentifier);
+ Arrays.sort(mKeyboardLayouts);
+ }
+
+ @Override
+ public void onStart() {
+ mIm.registerInputDeviceListener(this, null);
+ final InputDevice inputDevice =
+ mIm.getInputDeviceByDescriptor(mInputDeviceIdentifier.getDescriptor());
+ if (inputDevice == null) {
+ mParent.getActivity().finish();
+ return;
+ }
+ mInputDeviceId = inputDevice.getId();
+ }
+
+ @Override
+ public void onStop() {
+ mIm.unregisterInputDeviceListener(this);
+ mInputDeviceId = -1;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mScreen = screen;
+ createPreferenceHierarchy();
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+
+ if (!(preference instanceof KeyboardLayoutPreference)) {
+ return false;
+ }
+
+ final KeyboardLayoutPreference pref = (KeyboardLayoutPreference) preference;
+ // TODO(b/259530132): Need APIs to update the available keyboards for input device.
+ // For example:
+ // inputManager.setCurrentKeyboardLayoutForInputDevice(
+ // InputDevice..., Userid..., ImeSubType ..., String keyboardLayoutDescriptor)
+ if (mPreviousSelection != null && !mPreviousSelection.equals(preference.getKey())) {
+ KeyboardLayoutPreference preSelectedPref = mScreen.findPreference(mPreviousSelection);
+ pref.setCheckMark(true);
+ preSelectedPref.setCheckMark(false);
+ }
+ mPreviousSelection = preference.getKey();
+ return true;
+ }
+
+ @Override
+ public void onInputDeviceAdded(int deviceId) {
+ // Do nothing.
+ }
+
+ @Override
+ public void onInputDeviceRemoved(int deviceId) {
+ if (mInputDeviceId >= 0 && deviceId == mInputDeviceId) {
+ mParent.getActivity().finish();
+ }
+ }
+
+ @Override
+ public void onInputDeviceChanged(int deviceId) {
+ if (mInputDeviceId >= 0 && deviceId == mInputDeviceId) {
+ updateCheckedState();
+ }
+ }
+
+ private void updateCheckedState() {
+ // TODO(b/259530132): Need API to update the keyboard language layout list.
+ }
+
+ private void createPreferenceHierarchy() {
+ for (KeyboardLayout layout : mKeyboardLayouts) {
+ final KeyboardLayoutPreference pref;
+ if (mLayout.equals(layout.getLabel())) {
+ pref = new KeyboardLayoutPreference(mScreen.getContext(), layout.getLabel(), true);
+ mPreviousSelection = layout.getLabel();
+ } else {
+ pref = new KeyboardLayoutPreference(mScreen.getContext(), layout.getLabel(), false);
+ }
+ // TODO: Waiting for new API to use a prefix with special number to setKey
+ pref.setKey(layout.getLabel());
+ mScreen.addPreference(pref);
+ mPreferenceMap.put(pref, layout);
+ }
+ }
+}
diff --git a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerFragment.java b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerFragment.java
new file mode 100644
index 00000000000..c2f41a2f739
--- /dev/null
+++ b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerFragment.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package com.android.settings.inputmethod;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.fragment.app.Fragment;
+
+import com.android.settings.R;
+
+public class NewKeyboardLayoutPickerFragment extends Fragment {
+
+ static final String EXTRA_TITLE = "keyboard_layout_picker_title";
+ static final String EXTRA_KEYBOARD_LAYOUT = "keyboard_layout";
+
+ /**
+ * Intent extra: The input device descriptor of the keyboard whose keyboard
+ * layout is to be changed.
+ */
+ public static final String EXTRA_INPUT_DEVICE_IDENTIFIER = "input_device_identifier";
+
+ private ViewGroup mFragmentView;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ mFragmentView = (ViewGroup) inflater.inflate(
+ R.layout.keyboard_layout_picker, container, false);
+ getActivity().getSupportFragmentManager()
+ .beginTransaction()
+ .replace(R.id.keyboard_layout_title, new NewKeyboardLayoutPickerTitle())
+ .commit();
+
+ NewKeyboardLayoutPickerContent fragment = new NewKeyboardLayoutPickerContent();
+ fragment.setArguments(getArguments());
+ getActivity().getSupportFragmentManager()
+ .beginTransaction()
+ .replace(R.id.keyboard_layouts, fragment)
+ .commit();
+
+ return mFragmentView;
+ }
+}
diff --git a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerTitle.java b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerTitle.java
new file mode 100644
index 00000000000..abcad277e8e
--- /dev/null
+++ b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerTitle.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package com.android.settings.inputmethod;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+
+public class NewKeyboardLayoutPickerTitle extends SettingsPreferenceFragment {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.new_keyboard_layout_picker_title);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ // TODO: add new SettingsEnums SETTINGS_KEYBOARDS_LAYOUT_PICKER_TITLE
+ return SettingsEnums.SETTINGS_KEYBOARDS_LAYOUT_PICKER;
+ }
+
+ public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider(R.xml.new_keyboard_layout_picker_title) {
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return false;
+ }
+ };
+}
diff --git a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java
index d7a208c17f9..38ea840d950 100644
--- a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java
+++ b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java
@@ -33,6 +33,7 @@ import android.os.UserHandle;
import android.provider.SearchIndexableResource;
import android.provider.Settings.Secure;
import android.text.TextUtils;
+import android.util.FeatureFlagUtils;
import android.view.InputDevice;
import androidx.preference.Preference;
@@ -45,6 +46,7 @@ import com.android.internal.util.Preconditions;
import com.android.settings.R;
import com.android.settings.Settings;
import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.core.SubSettingLauncher;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.utils.ThreadUtils;
@@ -52,7 +54,9 @@ import com.android.settingslib.utils.ThreadUtils;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
@SearchIndexable
@@ -60,7 +64,7 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
implements InputManager.InputDeviceListener,
KeyboardLayoutDialogFragment.OnSetupKeyboardLayoutsListener {
- private static final String KEYBOARD_ASSISTANCE_CATEGORY = "keyboard_assistance_category";
+ private static final String KEYBOARD_OPTIONS_CATEGORY = "keyboard_options_category";
private static final String SHOW_VIRTUAL_KEYBOARD_SWITCH = "show_virtual_keyboard_switch";
private static final String KEYBOARD_SHORTCUTS_HELPER = "keyboard_shortcuts_helper";
@@ -74,17 +78,25 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
private SwitchPreference mShowVirtualKeyboardSwitch;
private Intent mIntentWaitingForResult;
+ private boolean mIsNewKeyboardSettings;
+
+ static final String EXTRA_BT_ADDRESS = "extra_bt_address";
+ private String mBluetoothAddress;
@Override
public void onCreatePreferences(Bundle bundle, String s) {
Activity activity = Preconditions.checkNotNull(getActivity());
+ mBluetoothAddress = activity.getIntent().getStringExtra(EXTRA_BT_ADDRESS);
addPreferencesFromResource(R.xml.physical_keyboard_settings);
mIm = Preconditions.checkNotNull(activity.getSystemService(InputManager.class));
mKeyboardAssistanceCategory = Preconditions.checkNotNull(
- (PreferenceCategory) findPreference(KEYBOARD_ASSISTANCE_CATEGORY));
+ (PreferenceCategory) findPreference(KEYBOARD_OPTIONS_CATEGORY));
mShowVirtualKeyboardSwitch = Preconditions.checkNotNull(
(SwitchPreference) mKeyboardAssistanceCategory.findPreference(
SHOW_VIRTUAL_KEYBOARD_SWITCH));
+ mIsNewKeyboardSettings = FeatureFlagUtils.isEnabled(
+ getContext(), FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+ // TODO(b/247080921): Support shortcuts list & modifier keys
}
@Override
@@ -164,17 +176,55 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
preferenceScreen.addPreference(category);
for (HardKeyboardDeviceInfo hardKeyboardDeviceInfo : newHardKeyboards) {
+
+ // if user go into this page from Connected devices entry, we should distinguish the
+ // user-selected keyboard from all enabled keyboards.
+ if (mBluetoothAddress != null
+ && !mBluetoothAddress.equals(hardKeyboardDeviceInfo.mBluetoothAddress)) {
+ continue;
+ }
+
// TODO(yukawa): Consider using com.android.settings.widget.GearPreference
final Preference pref = new Preference(getPrefContext());
pref.setTitle(hardKeyboardDeviceInfo.mDeviceName);
- pref.setSummary(hardKeyboardDeviceInfo.mLayoutLabel);
- pref.setOnPreferenceClickListener(preference -> {
- showKeyboardLayoutDialog(hardKeyboardDeviceInfo.mDeviceIdentifier);
- return true;
- });
+ if (mIsNewKeyboardSettings) {
+ // TODO(b/252816846): Need InputMethodManager to provide the enabled locales.
+ // Hardcode Languages for demo until inputMethodManager provides the latest API.
+ // For example: InputMethodManager.getEnabledInputMethodLocales();
+ String[] keyboardLanguages =
+ {"English (US)", "German (Germany)", "Spanish (Spain)"};
+ String[] keyboardLayouts = {"English (US)", "German", "Spanish"};
+ Map keyboardMap = new HashMap<>();
+ for (int i = 0; i < keyboardLanguages.length; i++) {
+ keyboardMap.put(keyboardLanguages[i], keyboardLayouts[i]);
+ }
+ if (!keyboardMap.isEmpty()) {
+ String summary = keyboardMap.get(keyboardLanguages[0]);
+ StringBuilder result = new StringBuilder(summary);
+ for (int i = 1; i < keyboardLanguages.length; i++) {
+ result.append(", ").append(keyboardMap.get(keyboardLanguages[i]));
+ }
+ pref.setSummary(result.toString());
+ } else {
+ pref.setSummary(hardKeyboardDeviceInfo.mLayoutLabel);
+ }
+ pref.setOnPreferenceClickListener(
+ preference -> {
+ showEnabledLocalesKeyboardLayoutList(
+ hardKeyboardDeviceInfo.mDeviceName,
+ hardKeyboardDeviceInfo.mDeviceIdentifier);
+ return true;
+ });
+ } else {
+ pref.setSummary(hardKeyboardDeviceInfo.mLayoutLabel);
+ pref.setOnPreferenceClickListener(
+ preference -> {
+ showKeyboardLayoutDialog(hardKeyboardDeviceInfo.mDeviceIdentifier);
+ return true;
+ });
+ }
category.addPreference(pref);
}
-
mKeyboardAssistanceCategory.setOrder(1);
preferenceScreen.addPreference(mKeyboardAssistanceCategory);
updateShowVirtualKeyboardSwitch();
@@ -187,6 +237,21 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
fragment.show(getActivity().getSupportFragmentManager(), "keyboardLayout");
}
+ private void showEnabledLocalesKeyboardLayoutList(String keyboardName,
+ InputDeviceIdentifier inputDeviceIdentifier) {
+ // TODO(b/252816846: Need to get enabled locales.
+ Bundle arguments = new Bundle();
+ arguments.putParcelable(KeyboardLayoutPickerFragment.EXTRA_INPUT_DEVICE_IDENTIFIER,
+ inputDeviceIdentifier);
+ arguments.putString(NewKeyboardLayoutEnabledLocalesFragment.EXTRA_KEYBOARD_DEVICE_NAME,
+ keyboardName);
+ new SubSettingLauncher(getContext())
+ .setSourceMetricsCategory(getMetricsCategory())
+ .setDestination(NewKeyboardLayoutEnabledLocalesFragment.class.getName())
+ .setArguments(arguments)
+ .launch();
+ }
+
private void registerShowVirtualKeyboardSettingsObserver() {
unregisterShowVirtualKeyboardSettingsObserver();
getActivity().getContentResolver().registerContentObserver(
@@ -277,7 +342,10 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
continue;
}
keyboards.add(new HardKeyboardDeviceInfo(
- device.getName(), device.getIdentifier(), getLayoutLabel(device, context, im)));
+ device.getName(),
+ device.getIdentifier(),
+ getLayoutLabel(device, context, im),
+ device.getBluetoothAddress()));
}
// We intentionally don't reuse Comparator because Collator may not be thread-safe.
@@ -304,14 +372,18 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
public final InputDeviceIdentifier mDeviceIdentifier;
@NonNull
public final String mLayoutLabel;
+ @Nullable
+ public final String mBluetoothAddress;
public HardKeyboardDeviceInfo(
@Nullable String deviceName,
@NonNull InputDeviceIdentifier deviceIdentifier,
- @NonNull String layoutLabel) {
+ @NonNull String layoutLabel,
+ @Nullable String bluetoothAddress) {
mDeviceName = TextUtils.emptyIfNull(deviceName);
mDeviceIdentifier = deviceIdentifier;
mLayoutLabel = layoutLabel;
+ mBluetoothAddress = bluetoothAddress;
}
@Override
@@ -331,6 +403,9 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
if (!TextUtils.equals(mLayoutLabel, that.mLayoutLabel)) {
return false;
}
+ if (!TextUtils.equals(mBluetoothAddress, that.mBluetoothAddress)) {
+ return false;
+ }
return true;
}