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; }