1766b286187d02b3da6e0142376a4478072f30a16Jeff Brown/* 2766b286187d02b3da6e0142376a4478072f30a16Jeff Brown * Copyright (C) 2012 The Android Open Source Project 3766b286187d02b3da6e0142376a4478072f30a16Jeff Brown * 4766b286187d02b3da6e0142376a4478072f30a16Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 5766b286187d02b3da6e0142376a4478072f30a16Jeff Brown * you may not use this file except in compliance with the License. 6766b286187d02b3da6e0142376a4478072f30a16Jeff Brown * You may obtain a copy of the License at 7766b286187d02b3da6e0142376a4478072f30a16Jeff Brown * 8766b286187d02b3da6e0142376a4478072f30a16Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 9766b286187d02b3da6e0142376a4478072f30a16Jeff Brown * 10766b286187d02b3da6e0142376a4478072f30a16Jeff Brown * Unless required by applicable law or agreed to in writing, software 11766b286187d02b3da6e0142376a4478072f30a16Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 12766b286187d02b3da6e0142376a4478072f30a16Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13766b286187d02b3da6e0142376a4478072f30a16Jeff Brown * See the License for the specific language governing permissions and 14766b286187d02b3da6e0142376a4478072f30a16Jeff Brown * limitations under the License. 15766b286187d02b3da6e0142376a4478072f30a16Jeff Brown */ 16766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 17766b286187d02b3da6e0142376a4478072f30a16Jeff Brownpackage com.android.settings.inputmethod; 18766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 19766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport com.android.settings.R; 20766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport com.android.settings.SettingsPreferenceFragment; 21766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 22766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.content.Context; 23813a54d216010a16d714355c61d606dd3eb589aaRoboErikimport android.hardware.input.InputDeviceIdentifier; 24766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.hardware.input.InputManager; 25766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.hardware.input.InputManager.InputDeviceListener; 26766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.hardware.input.KeyboardLayout; 27766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.os.Bundle; 28766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.preference.CheckBoxPreference; 29766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.preference.Preference; 30766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.preference.PreferenceScreen; 31766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.view.InputDevice; 32766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 33766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport java.util.Arrays; 34766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport java.util.HashMap; 35766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport java.util.Map; 36766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 37766b286187d02b3da6e0142376a4478072f30a16Jeff Brownpublic class KeyboardLayoutPickerFragment extends SettingsPreferenceFragment 38766b286187d02b3da6e0142376a4478072f30a16Jeff Brown implements InputDeviceListener { 39813a54d216010a16d714355c61d606dd3eb589aaRoboErik private InputDeviceIdentifier mInputDeviceIdentifier; 40766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private int mInputDeviceId = -1; 41766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private InputManager mIm; 42766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private KeyboardLayout[] mKeyboardLayouts; 43766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private HashMap<CheckBoxPreference, KeyboardLayout> mPreferenceMap = 44766b286187d02b3da6e0142376a4478072f30a16Jeff Brown new HashMap<CheckBoxPreference, KeyboardLayout>(); 45766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 46766b286187d02b3da6e0142376a4478072f30a16Jeff Brown /** 47766b286187d02b3da6e0142376a4478072f30a16Jeff Brown * Intent extra: The input device descriptor of the keyboard whose keyboard 48766b286187d02b3da6e0142376a4478072f30a16Jeff Brown * layout is to be changed. 49766b286187d02b3da6e0142376a4478072f30a16Jeff Brown */ 50813a54d216010a16d714355c61d606dd3eb589aaRoboErik public static final String EXTRA_INPUT_DEVICE_IDENTIFIER = "input_device_identifier"; 51766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 52766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 53766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onCreate(Bundle icicle) { 54766b286187d02b3da6e0142376a4478072f30a16Jeff Brown super.onCreate(icicle); 55766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 56813a54d216010a16d714355c61d606dd3eb589aaRoboErik mInputDeviceIdentifier = getActivity().getIntent().getParcelableExtra( 57813a54d216010a16d714355c61d606dd3eb589aaRoboErik EXTRA_INPUT_DEVICE_IDENTIFIER); 58813a54d216010a16d714355c61d606dd3eb589aaRoboErik if (mInputDeviceIdentifier == null) { 59766b286187d02b3da6e0142376a4478072f30a16Jeff Brown getActivity().finish(); 60766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 61766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 62766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mIm = (InputManager)getSystemService(Context.INPUT_SERVICE); 63766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mKeyboardLayouts = mIm.getKeyboardLayouts(); 64766b286187d02b3da6e0142376a4478072f30a16Jeff Brown Arrays.sort(mKeyboardLayouts); 65766b286187d02b3da6e0142376a4478072f30a16Jeff Brown setPreferenceScreen(createPreferenceHierarchy()); 66766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 67766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 68766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 69766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onResume() { 70766b286187d02b3da6e0142376a4478072f30a16Jeff Brown super.onResume(); 71766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 72766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mIm.registerInputDeviceListener(this, null); 73766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 74813a54d216010a16d714355c61d606dd3eb589aaRoboErik InputDevice inputDevice = 75813a54d216010a16d714355c61d606dd3eb589aaRoboErik mIm.getInputDeviceByDescriptor(mInputDeviceIdentifier.getDescriptor()); 76766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (inputDevice == null) { 77766b286187d02b3da6e0142376a4478072f30a16Jeff Brown getActivity().finish(); 78766b286187d02b3da6e0142376a4478072f30a16Jeff Brown return; 79766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 80766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mInputDeviceId = inputDevice.getId(); 81766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 82766b286187d02b3da6e0142376a4478072f30a16Jeff Brown updateCheckedState(); 83766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 84766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 85766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 86766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onPause() { 87766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mIm.unregisterInputDeviceListener(this); 88766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mInputDeviceId = -1; 89766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 90766b286187d02b3da6e0142376a4478072f30a16Jeff Brown super.onPause(); 91766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 92766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 93766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 94766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, 95766b286187d02b3da6e0142376a4478072f30a16Jeff Brown Preference preference) { 96766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (preference instanceof CheckBoxPreference) { 97766b286187d02b3da6e0142376a4478072f30a16Jeff Brown CheckBoxPreference checkboxPref = (CheckBoxPreference)preference; 98766b286187d02b3da6e0142376a4478072f30a16Jeff Brown KeyboardLayout layout = mPreferenceMap.get(checkboxPref); 99766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (layout != null) { 100766b286187d02b3da6e0142376a4478072f30a16Jeff Brown boolean checked = checkboxPref.isChecked(); 101766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (checked) { 102813a54d216010a16d714355c61d606dd3eb589aaRoboErik mIm.addKeyboardLayoutForInputDevice(mInputDeviceIdentifier, 103766b286187d02b3da6e0142376a4478072f30a16Jeff Brown layout.getDescriptor()); 104766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } else { 105813a54d216010a16d714355c61d606dd3eb589aaRoboErik mIm.removeKeyboardLayoutForInputDevice(mInputDeviceIdentifier, 106766b286187d02b3da6e0142376a4478072f30a16Jeff Brown layout.getDescriptor()); 107766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 108766b286187d02b3da6e0142376a4478072f30a16Jeff Brown return true; 109766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 110766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 111766b286187d02b3da6e0142376a4478072f30a16Jeff Brown return super.onPreferenceTreeClick(preferenceScreen, preference); 112766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 113766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 114766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 115766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onInputDeviceAdded(int deviceId) { 116766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 117766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 118766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 119766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onInputDeviceChanged(int deviceId) { 120766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (mInputDeviceId >= 0 && deviceId == mInputDeviceId) { 121766b286187d02b3da6e0142376a4478072f30a16Jeff Brown updateCheckedState(); 122766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 123766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 124766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 125766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 126766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onInputDeviceRemoved(int deviceId) { 127766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (mInputDeviceId >= 0 && deviceId == mInputDeviceId) { 128766b286187d02b3da6e0142376a4478072f30a16Jeff Brown getActivity().finish(); 129766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 130766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 131766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 132766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private PreferenceScreen createPreferenceHierarchy() { 133766b286187d02b3da6e0142376a4478072f30a16Jeff Brown PreferenceScreen root = getPreferenceManager().createPreferenceScreen(getActivity()); 134766b286187d02b3da6e0142376a4478072f30a16Jeff Brown Context context = getActivity(); 135766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 136766b286187d02b3da6e0142376a4478072f30a16Jeff Brown for (KeyboardLayout layout : mKeyboardLayouts) { 137766b286187d02b3da6e0142376a4478072f30a16Jeff Brown CheckBoxPreference pref = new CheckBoxPreference(context); 138766b286187d02b3da6e0142376a4478072f30a16Jeff Brown pref.setTitle(layout.getLabel()); 139766b286187d02b3da6e0142376a4478072f30a16Jeff Brown pref.setSummary(layout.getCollection()); 140766b286187d02b3da6e0142376a4478072f30a16Jeff Brown root.addPreference(pref); 141766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mPreferenceMap.put(pref, layout); 142766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 143766b286187d02b3da6e0142376a4478072f30a16Jeff Brown return root; 144766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 145766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 146766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private void updateCheckedState() { 147766b286187d02b3da6e0142376a4478072f30a16Jeff Brown String[] enabledKeyboardLayouts = mIm.getKeyboardLayoutsForInputDevice( 148813a54d216010a16d714355c61d606dd3eb589aaRoboErik mInputDeviceIdentifier); 149766b286187d02b3da6e0142376a4478072f30a16Jeff Brown Arrays.sort(enabledKeyboardLayouts); 150766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 151766b286187d02b3da6e0142376a4478072f30a16Jeff Brown for (Map.Entry<CheckBoxPreference, KeyboardLayout> entry : mPreferenceMap.entrySet()) { 152766b286187d02b3da6e0142376a4478072f30a16Jeff Brown entry.getKey().setChecked(Arrays.binarySearch(enabledKeyboardLayouts, 153766b286187d02b3da6e0142376a4478072f30a16Jeff Brown entry.getValue().getDescriptor()) >= 0); 154766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 155766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 156766b286187d02b3da6e0142376a4478072f30a16Jeff Brown} 157