1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.settings.inputmethod; 18 19import android.content.Context; 20import android.hardware.input.InputDeviceIdentifier; 21import android.hardware.input.InputManager; 22import android.hardware.input.InputManager.InputDeviceListener; 23import android.hardware.input.KeyboardLayout; 24import android.os.Bundle; 25import android.support.v7.preference.CheckBoxPreference; 26import android.support.v7.preference.Preference; 27import android.support.v7.preference.PreferenceScreen; 28import android.view.InputDevice; 29 30import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 31import com.android.settings.SettingsPreferenceFragment; 32 33import java.util.Arrays; 34import java.util.HashMap; 35import java.util.Map; 36 37public class KeyboardLayoutPickerFragment extends SettingsPreferenceFragment 38 implements InputDeviceListener { 39 private InputDeviceIdentifier mInputDeviceIdentifier; 40 private int mInputDeviceId = -1; 41 private InputManager mIm; 42 private KeyboardLayout[] mKeyboardLayouts; 43 private HashMap<CheckBoxPreference, KeyboardLayout> mPreferenceMap = new HashMap<>(); 44 45 /** 46 * Intent extra: The input device descriptor of the keyboard whose keyboard 47 * layout is to be changed. 48 */ 49 public static final String EXTRA_INPUT_DEVICE_IDENTIFIER = "input_device_identifier"; 50 51 @Override 52 public int getMetricsCategory() { 53 return MetricsEvent.INPUTMETHOD_KEYBOARD; 54 } 55 56 @Override 57 public void onCreate(Bundle icicle) { 58 super.onCreate(icicle); 59 60 mInputDeviceIdentifier = getActivity().getIntent().getParcelableExtra( 61 EXTRA_INPUT_DEVICE_IDENTIFIER); 62 if (mInputDeviceIdentifier == null) { 63 getActivity().finish(); 64 } 65 66 mIm = (InputManager) getSystemService(Context.INPUT_SERVICE); 67 mKeyboardLayouts = mIm.getKeyboardLayoutsForInputDevice(mInputDeviceIdentifier); 68 Arrays.sort(mKeyboardLayouts); 69 setPreferenceScreen(createPreferenceHierarchy()); 70 } 71 72 @Override 73 public void onResume() { 74 super.onResume(); 75 76 mIm.registerInputDeviceListener(this, null); 77 78 InputDevice inputDevice = 79 mIm.getInputDeviceByDescriptor(mInputDeviceIdentifier.getDescriptor()); 80 if (inputDevice == null) { 81 getActivity().finish(); 82 return; 83 } 84 mInputDeviceId = inputDevice.getId(); 85 86 updateCheckedState(); 87 } 88 89 @Override 90 public void onPause() { 91 mIm.unregisterInputDeviceListener(this); 92 mInputDeviceId = -1; 93 94 super.onPause(); 95 } 96 97 @Override 98 public boolean onPreferenceTreeClick(Preference preference) { 99 if (preference instanceof CheckBoxPreference) { 100 CheckBoxPreference checkboxPref = (CheckBoxPreference)preference; 101 KeyboardLayout layout = mPreferenceMap.get(checkboxPref); 102 if (layout != null) { 103 boolean checked = checkboxPref.isChecked(); 104 if (checked) { 105 mIm.addKeyboardLayoutForInputDevice(mInputDeviceIdentifier, 106 layout.getDescriptor()); 107 } else { 108 mIm.removeKeyboardLayoutForInputDevice(mInputDeviceIdentifier, 109 layout.getDescriptor()); 110 } 111 return true; 112 } 113 } 114 return super.onPreferenceTreeClick(preference); 115 } 116 117 @Override 118 public void onInputDeviceAdded(int deviceId) { 119 } 120 121 @Override 122 public void onInputDeviceChanged(int deviceId) { 123 if (mInputDeviceId >= 0 && deviceId == mInputDeviceId) { 124 updateCheckedState(); 125 } 126 } 127 128 @Override 129 public void onInputDeviceRemoved(int deviceId) { 130 if (mInputDeviceId >= 0 && deviceId == mInputDeviceId) { 131 getActivity().finish(); 132 } 133 } 134 135 private PreferenceScreen createPreferenceHierarchy() { 136 PreferenceScreen root = getPreferenceManager().createPreferenceScreen(getActivity()); 137 138 for (KeyboardLayout layout : mKeyboardLayouts) { 139 CheckBoxPreference pref = new CheckBoxPreference(getPrefContext()); 140 pref.setTitle(layout.getLabel()); 141 pref.setSummary(layout.getCollection()); 142 root.addPreference(pref); 143 mPreferenceMap.put(pref, layout); 144 } 145 return root; 146 } 147 148 private void updateCheckedState() { 149 String[] enabledKeyboardLayouts = mIm.getEnabledKeyboardLayoutsForInputDevice( 150 mInputDeviceIdentifier); 151 Arrays.sort(enabledKeyboardLayouts); 152 153 for (Map.Entry<CheckBoxPreference, KeyboardLayout> entry : mPreferenceMap.entrySet()) { 154 entry.getKey().setChecked(Arrays.binarySearch(enabledKeyboardLayouts, 155 entry.getValue().getDescriptor()) >= 0); 156 } 157 } 158} 159