If descriptor is null, pass null to LayoutSelectedCallback.onSelected to get default layout preview image. Bug: 396006944 Flag: com.android.settings.keyboard.keyboard_and_touchpad_a11y_new_page_enabled Test: atest packages/apps/Settings/tests/robotests/src/com/android/settings/inputmethod/ Change-Id: I6b454a5f0b95c571cac15258977aab5ee12d4327
247 lines
9.5 KiB
Java
247 lines
9.5 KiB
Java
/*
|
|
* 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.hardware.input.KeyboardLayout;
|
|
import android.hardware.input.KeyboardLayoutSelectionResult;
|
|
import android.os.Bundle;
|
|
import android.view.inputmethod.InputMethodInfo;
|
|
import android.view.inputmethod.InputMethodSubtype;
|
|
|
|
import androidx.annotation.Nullable;
|
|
import androidx.fragment.app.Fragment;
|
|
import androidx.preference.Preference;
|
|
import androidx.preference.PreferenceScreen;
|
|
|
|
import com.android.settings.R;
|
|
import com.android.settings.core.BasePreferenceController;
|
|
import com.android.settings.overlay.FeatureFactory;
|
|
import com.android.settings.widget.TickButtonPreference;
|
|
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
|
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.HashMap;
|
|
import java.util.Map;
|
|
|
|
public class NewKeyboardLayoutPickerController extends BasePreferenceController implements
|
|
InputManager.InputDeviceListener, LifecycleObserver, OnStart, OnStop {
|
|
|
|
private final InputManager mIm;
|
|
private final Map<TickButtonPreference, KeyboardLayout> mPreferenceMap;
|
|
private Fragment mParent;
|
|
private CharSequence mTitle;
|
|
private int mInputDeviceId;
|
|
private int mUserId;
|
|
private InputDeviceIdentifier mInputDeviceIdentifier;
|
|
private InputMethodInfo mInputMethodInfo;
|
|
private InputMethodSubtype mInputMethodSubtype;
|
|
private KeyboardLayout[] mKeyboardLayouts;
|
|
private PreferenceScreen mScreen;
|
|
private String mPreviousSelection;
|
|
private String mFinalSelectedLayoutDescriptor;
|
|
@Nullable private String mSelectedLayoutDescriptor;
|
|
private MetricsFeatureProvider mMetricsFeatureProvider;
|
|
private KeyboardLayoutSelectedCallback mKeyboardLayoutSelectedCallback;
|
|
|
|
public NewKeyboardLayoutPickerController(Context context, String key) {
|
|
super(context, key);
|
|
mIm = context.getSystemService(InputManager.class);
|
|
mInputDeviceId = -1;
|
|
mPreferenceMap = new HashMap<>();
|
|
mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
|
|
}
|
|
|
|
public void initialize(Fragment parent) {
|
|
mParent = parent;
|
|
Bundle arguments = parent.getArguments();
|
|
mTitle = arguments.getCharSequence(InputPeripheralsSettingsUtils.EXTRA_TITLE);
|
|
mUserId = arguments.getInt(InputPeripheralsSettingsUtils.EXTRA_USER_ID);
|
|
mInputDeviceIdentifier =
|
|
arguments.getParcelable(
|
|
InputPeripheralsSettingsUtils.EXTRA_INPUT_DEVICE_IDENTIFIER);
|
|
mInputMethodInfo =
|
|
arguments.getParcelable(InputPeripheralsSettingsUtils.EXTRA_INPUT_METHOD_INFO);
|
|
mInputMethodSubtype =
|
|
arguments.getParcelable(
|
|
InputPeripheralsSettingsUtils.EXTRA_INPUT_METHOD_SUBTYPE);
|
|
mSelectedLayoutDescriptor = getSelectedLayoutDescriptor();
|
|
mFinalSelectedLayoutDescriptor = mSelectedLayoutDescriptor;
|
|
mKeyboardLayouts = mIm.getKeyboardLayoutListForInputDevice(
|
|
mInputDeviceIdentifier, mUserId, mInputMethodInfo, mInputMethodSubtype);
|
|
InputPeripheralsSettingsUtils.sortKeyboardLayoutsByLabel(mKeyboardLayouts);
|
|
parent.getActivity().setTitle(mTitle);
|
|
}
|
|
|
|
@Override
|
|
public void onStart() {
|
|
mIm.registerInputDeviceListener(this, null);
|
|
if (mInputDeviceIdentifier == null
|
|
|| InputPeripheralsSettingsUtils.getInputDevice(mIm, mInputDeviceIdentifier)
|
|
== null) {
|
|
return;
|
|
}
|
|
mInputDeviceId =
|
|
InputPeripheralsSettingsUtils.getInputDevice(mIm,
|
|
mInputDeviceIdentifier).getId();
|
|
}
|
|
|
|
@Override
|
|
public void onStop() {
|
|
if (mSelectedLayoutDescriptor != null
|
|
&& !mSelectedLayoutDescriptor.equals(mFinalSelectedLayoutDescriptor)) {
|
|
String change = "From:"
|
|
+ getLayoutLabel(mSelectedLayoutDescriptor)
|
|
+ ", to:"
|
|
+ getLayoutLabel(mFinalSelectedLayoutDescriptor);
|
|
mMetricsFeatureProvider.action(
|
|
mContext, SettingsEnums.ACTION_PK_LAYOUT_CHANGED, change);
|
|
}
|
|
mIm.unregisterInputDeviceListener(this);
|
|
mInputDeviceId = -1;
|
|
}
|
|
|
|
@Override
|
|
public void displayPreference(PreferenceScreen screen) {
|
|
super.displayPreference(screen);
|
|
mScreen = screen;
|
|
createPreferenceHierarchy();
|
|
}
|
|
|
|
@Override
|
|
public int getAvailabilityStatus() {
|
|
return AVAILABLE;
|
|
}
|
|
|
|
/**
|
|
* Registers {@link KeyboardLayoutSelectedCallback} and get updated.
|
|
*/
|
|
public void registerKeyboardSelectedCallback(KeyboardLayoutSelectedCallback
|
|
keyboardLayoutSelectedCallback) {
|
|
this.mKeyboardLayoutSelectedCallback = keyboardLayoutSelectedCallback;
|
|
}
|
|
|
|
@Override
|
|
public boolean handlePreferenceTreeClick(Preference preference) {
|
|
if (!(preference instanceof TickButtonPreference)) {
|
|
return false;
|
|
}
|
|
|
|
final TickButtonPreference pref = (TickButtonPreference) preference;
|
|
if (mKeyboardLayoutSelectedCallback != null && mPreferenceMap.containsKey(preference)) {
|
|
mKeyboardLayoutSelectedCallback.onSelected(mPreferenceMap.get(preference));
|
|
}
|
|
pref.setSelected(true);
|
|
if (mPreviousSelection != null && !mPreviousSelection.equals(preference.getKey())) {
|
|
TickButtonPreference preSelectedPref = mScreen.findPreference(mPreviousSelection);
|
|
preSelectedPref.setSelected(false);
|
|
}
|
|
setLayout(pref);
|
|
mPreviousSelection = preference.getKey();
|
|
mFinalSelectedLayoutDescriptor = mPreviousSelection;
|
|
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) {
|
|
// Do nothing.
|
|
}
|
|
|
|
private void createPreferenceHierarchy() {
|
|
if (mKeyboardLayouts == null) {
|
|
return;
|
|
}
|
|
for (KeyboardLayout layout : mKeyboardLayouts) {
|
|
final TickButtonPreference pref;
|
|
pref = new TickButtonPreference(mScreen.getContext());
|
|
pref.setTitle(layout.getLabel());
|
|
|
|
if (mSelectedLayoutDescriptor != null && mSelectedLayoutDescriptor.equals(
|
|
layout.getDescriptor())) {
|
|
if (mKeyboardLayoutSelectedCallback != null) {
|
|
mKeyboardLayoutSelectedCallback.onSelected(layout);
|
|
}
|
|
pref.setSelected(true);
|
|
mPreviousSelection = mSelectedLayoutDescriptor;
|
|
}
|
|
pref.setKey(layout.getDescriptor());
|
|
mScreen.addPreference(pref);
|
|
mPreferenceMap.put(pref, layout);
|
|
}
|
|
|
|
if (mSelectedLayoutDescriptor == null && mKeyboardLayoutSelectedCallback != null) {
|
|
// Pass null here since getKeyboardLayoutPreview() accept null layout, which will
|
|
// return default preview image
|
|
mKeyboardLayoutSelectedCallback.onSelected(null);
|
|
}
|
|
}
|
|
|
|
private void setLayout(TickButtonPreference preference) {
|
|
mIm.setKeyboardLayoutForInputDevice(
|
|
mInputDeviceIdentifier,
|
|
mUserId,
|
|
mInputMethodInfo,
|
|
mInputMethodSubtype,
|
|
mPreferenceMap.get(preference).getDescriptor());
|
|
}
|
|
|
|
private String getSelectedLayoutDescriptor() {
|
|
KeyboardLayoutSelectionResult result = InputPeripheralsSettingsUtils.getKeyboardLayout(
|
|
mIm, mUserId, mInputDeviceIdentifier, mInputMethodInfo, mInputMethodSubtype);
|
|
return result.getLayoutDescriptor();
|
|
}
|
|
|
|
private String getLayoutLabel(String descriptor) {
|
|
String label = mContext.getString(R.string.keyboard_default_layout);
|
|
KeyboardLayout[] keyboardLayouts = InputPeripheralsSettingsUtils.getKeyboardLayouts(
|
|
mIm, mUserId, mInputDeviceIdentifier, mInputMethodInfo, mInputMethodSubtype);
|
|
if (descriptor != null) {
|
|
for (KeyboardLayout keyboardLayout : keyboardLayouts) {
|
|
if (keyboardLayout.getDescriptor().equals(descriptor)) {
|
|
label = keyboardLayout.getLabel();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return label;
|
|
}
|
|
|
|
public interface KeyboardLayoutSelectedCallback {
|
|
/**
|
|
* Called when KeyboardLayout been selected.
|
|
*/
|
|
void onSelected(@Nullable KeyboardLayout keyboardLayout);
|
|
}
|
|
}
|