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 android.app.Activity; 2039b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.app.AlertDialog; 21766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.app.Dialog; 22766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.app.DialogFragment; 23766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.app.LoaderManager.LoaderCallbacks; 24766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.content.AsyncTaskLoader; 25766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.content.Context; 26766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.content.DialogInterface; 27766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.content.Intent; 28766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.content.Loader; 29813a54d216010a16d714355c61d606dd3eb589aaRoboErikimport android.hardware.input.InputDeviceIdentifier; 30766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.hardware.input.InputManager; 31766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.hardware.input.InputManager.InputDeviceListener; 3239b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.hardware.input.KeyboardLayout; 33766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.os.Bundle; 34766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.view.InputDevice; 35766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.view.LayoutInflater; 36766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.view.View; 37766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.view.ViewGroup; 38766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.widget.ArrayAdapter; 39766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.widget.CheckedTextView; 40766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.widget.RadioButton; 41766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport android.widget.TextView; 42766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 43265d3c2a0c36251bf8a9f571d7239b6dd404d942Tamas Berghammerimport com.android.internal.logging.nano.MetricsProto; 4439b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.settings.R; 451e516287bd0c910f83d2ead28bf67e26dfbead86Fan Zhangimport com.android.settings.core.instrumentation.InstrumentedDialogFragment; 4639b467482d1bf256a111c757e9b7621c6f523271Jason Monk 47766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport java.util.ArrayList; 48766b286187d02b3da6e0142376a4478072f30a16Jeff Brownimport java.util.Collections; 49766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 501e516287bd0c910f83d2ead28bf67e26dfbead86Fan Zhangpublic class KeyboardLayoutDialogFragment extends InstrumentedDialogFragment 51766b286187d02b3da6e0142376a4478072f30a16Jeff Brown implements InputDeviceListener, LoaderCallbacks<KeyboardLayoutDialogFragment.Keyboards> { 52813a54d216010a16d714355c61d606dd3eb589aaRoboErik private static final String KEY_INPUT_DEVICE_IDENTIFIER = "inputDeviceIdentifier"; 53766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 54813a54d216010a16d714355c61d606dd3eb589aaRoboErik private InputDeviceIdentifier mInputDeviceIdentifier; 55766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private int mInputDeviceId = -1; 56766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private InputManager mIm; 57766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private KeyboardLayoutAdapter mAdapter; 5817b631988451613393c4656900c1821e23d8434aMichael Wright private boolean mHasShownLayoutSelectionScreen; 59766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 60766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public KeyboardLayoutDialogFragment() { 61766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 62766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 63813a54d216010a16d714355c61d606dd3eb589aaRoboErik public KeyboardLayoutDialogFragment(InputDeviceIdentifier inputDeviceIdentifier) { 64813a54d216010a16d714355c61d606dd3eb589aaRoboErik mInputDeviceIdentifier = inputDeviceIdentifier; 65766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 66766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 671e516287bd0c910f83d2ead28bf67e26dfbead86Fan Zhang 681e516287bd0c910f83d2ead28bf67e26dfbead86Fan Zhang @Override 691e516287bd0c910f83d2ead28bf67e26dfbead86Fan Zhang public int getMetricsCategory() { 701e516287bd0c910f83d2ead28bf67e26dfbead86Fan Zhang return MetricsProto.MetricsEvent.DIALOG_KEYBOARD_LAYOUT; 711e516287bd0c910f83d2ead28bf67e26dfbead86Fan Zhang } 721e516287bd0c910f83d2ead28bf67e26dfbead86Fan Zhang 73766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 74766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onAttach(Activity activity) { 75766b286187d02b3da6e0142376a4478072f30a16Jeff Brown super.onAttach(activity); 76766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 77766b286187d02b3da6e0142376a4478072f30a16Jeff Brown Context context = activity.getBaseContext(); 78766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mIm = (InputManager)context.getSystemService(Context.INPUT_SERVICE); 79766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mAdapter = new KeyboardLayoutAdapter(context); 80766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 81766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 82766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 83766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onCreate(Bundle savedInstanceState) { 84766b286187d02b3da6e0142376a4478072f30a16Jeff Brown super.onCreate(savedInstanceState); 85766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 86766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (savedInstanceState != null) { 87813a54d216010a16d714355c61d606dd3eb589aaRoboErik mInputDeviceIdentifier = savedInstanceState.getParcelable(KEY_INPUT_DEVICE_IDENTIFIER); 88766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 89766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 90766b286187d02b3da6e0142376a4478072f30a16Jeff Brown getLoaderManager().initLoader(0, null, this); 91766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 92766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 93766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 94766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onSaveInstanceState(Bundle outState) { 95766b286187d02b3da6e0142376a4478072f30a16Jeff Brown super.onSaveInstanceState(outState); 96813a54d216010a16d714355c61d606dd3eb589aaRoboErik outState.putParcelable(KEY_INPUT_DEVICE_IDENTIFIER, mInputDeviceIdentifier); 97766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 98766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 99766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 100766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public Dialog onCreateDialog(Bundle savedInstanceState) { 101766b286187d02b3da6e0142376a4478072f30a16Jeff Brown Context context = getActivity(); 102766b286187d02b3da6e0142376a4478072f30a16Jeff Brown LayoutInflater inflater = LayoutInflater.from(context); 103766b286187d02b3da6e0142376a4478072f30a16Jeff Brown AlertDialog.Builder builder = new AlertDialog.Builder(context) 104766b286187d02b3da6e0142376a4478072f30a16Jeff Brown .setTitle(R.string.keyboard_layout_dialog_title) 105766b286187d02b3da6e0142376a4478072f30a16Jeff Brown .setPositiveButton(R.string.keyboard_layout_dialog_setup_button, 106766b286187d02b3da6e0142376a4478072f30a16Jeff Brown new DialogInterface.OnClickListener() { 107766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 108766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onClick(DialogInterface dialog, int which) { 109766b286187d02b3da6e0142376a4478072f30a16Jeff Brown onSetupLayoutsButtonClicked(); 110766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 111766b286187d02b3da6e0142376a4478072f30a16Jeff Brown }) 112766b286187d02b3da6e0142376a4478072f30a16Jeff Brown .setSingleChoiceItems(mAdapter, -1, 113766b286187d02b3da6e0142376a4478072f30a16Jeff Brown new DialogInterface.OnClickListener() { 114766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 115766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onClick(DialogInterface dialog, int which) { 116766b286187d02b3da6e0142376a4478072f30a16Jeff Brown onKeyboardLayoutClicked(which); 117766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 118766b286187d02b3da6e0142376a4478072f30a16Jeff Brown }) 119766b286187d02b3da6e0142376a4478072f30a16Jeff Brown .setView(inflater.inflate(R.layout.keyboard_layout_dialog_switch_hint, null)); 120766b286187d02b3da6e0142376a4478072f30a16Jeff Brown updateSwitchHintVisibility(); 121766b286187d02b3da6e0142376a4478072f30a16Jeff Brown return builder.create(); 122766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 123766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 124766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 125766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onResume() { 126766b286187d02b3da6e0142376a4478072f30a16Jeff Brown super.onResume(); 127766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 128766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mIm.registerInputDeviceListener(this, null); 129766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 130813a54d216010a16d714355c61d606dd3eb589aaRoboErik InputDevice inputDevice = 131813a54d216010a16d714355c61d606dd3eb589aaRoboErik mIm.getInputDeviceByDescriptor(mInputDeviceIdentifier.getDescriptor()); 132766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (inputDevice == null) { 133766b286187d02b3da6e0142376a4478072f30a16Jeff Brown dismiss(); 134766b286187d02b3da6e0142376a4478072f30a16Jeff Brown return; 135766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 136766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mInputDeviceId = inputDevice.getId(); 137766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 138766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 139766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 140766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onPause() { 141766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mIm.unregisterInputDeviceListener(this); 142766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mInputDeviceId = -1; 143766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 144766b286187d02b3da6e0142376a4478072f30a16Jeff Brown super.onPause(); 145766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 146766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 147766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 148766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onCancel(DialogInterface dialog) { 149766b286187d02b3da6e0142376a4478072f30a16Jeff Brown super.onCancel(dialog); 150766b286187d02b3da6e0142376a4478072f30a16Jeff Brown dismiss(); 151766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 152766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 153766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private void onSetupLayoutsButtonClicked() { 154766b286187d02b3da6e0142376a4478072f30a16Jeff Brown ((OnSetupKeyboardLayoutsListener)getTargetFragment()).onSetupKeyboardLayouts( 155813a54d216010a16d714355c61d606dd3eb589aaRoboErik mInputDeviceIdentifier); 156766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 157766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 158766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 159766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onActivityResult(int requestCode, int resultCode, Intent data) { 160766b286187d02b3da6e0142376a4478072f30a16Jeff Brown super.onActivityResult(requestCode, resultCode, data); 161766b286187d02b3da6e0142376a4478072f30a16Jeff Brown show(getActivity().getFragmentManager(), "layout"); 162766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 163766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 164766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private void onKeyboardLayoutClicked(int which) { 165766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (which >= 0 && which < mAdapter.getCount()) { 166766b286187d02b3da6e0142376a4478072f30a16Jeff Brown KeyboardLayout keyboardLayout = mAdapter.getItem(which); 167766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (keyboardLayout != null) { 168813a54d216010a16d714355c61d606dd3eb589aaRoboErik mIm.setCurrentKeyboardLayoutForInputDevice(mInputDeviceIdentifier, 169766b286187d02b3da6e0142376a4478072f30a16Jeff Brown keyboardLayout.getDescriptor()); 170766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 171766b286187d02b3da6e0142376a4478072f30a16Jeff Brown dismiss(); 172766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 173766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 174766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 175766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 176766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public Loader<Keyboards> onCreateLoader(int id, Bundle args) { 177813a54d216010a16d714355c61d606dd3eb589aaRoboErik return new KeyboardLayoutLoader(getActivity().getBaseContext(), mInputDeviceIdentifier); 178766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 179766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 180766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 181766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onLoadFinished(Loader<Keyboards> loader, Keyboards data) { 182766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mAdapter.clear(); 183766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mAdapter.addAll(data.keyboardLayouts); 184766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mAdapter.setCheckedItem(data.current); 185766b286187d02b3da6e0142376a4478072f30a16Jeff Brown AlertDialog dialog = (AlertDialog)getDialog(); 186766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (dialog != null) { 187766b286187d02b3da6e0142376a4478072f30a16Jeff Brown dialog.getListView().setItemChecked(data.current, true); 188766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 189766b286187d02b3da6e0142376a4478072f30a16Jeff Brown updateSwitchHintVisibility(); 19017b631988451613393c4656900c1821e23d8434aMichael Wright showSetupKeyboardLayoutsIfNecessary(); 191766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 192766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 193766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 194766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onLoaderReset(Loader<Keyboards> loader) { 195766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mAdapter.clear(); 196766b286187d02b3da6e0142376a4478072f30a16Jeff Brown updateSwitchHintVisibility(); 197766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 198766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 199766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 200766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onInputDeviceAdded(int deviceId) { 201766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 202766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 203766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 204766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onInputDeviceChanged(int deviceId) { 205766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (mInputDeviceId >= 0 && deviceId == mInputDeviceId) { 206766b286187d02b3da6e0142376a4478072f30a16Jeff Brown getLoaderManager().restartLoader(0, null, this); 207766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 208766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 209766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 210766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 211766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void onInputDeviceRemoved(int deviceId) { 212766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (mInputDeviceId >= 0 && deviceId == mInputDeviceId) { 213766b286187d02b3da6e0142376a4478072f30a16Jeff Brown dismiss(); 214766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 215766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 216766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 217766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private void updateSwitchHintVisibility() { 218766b286187d02b3da6e0142376a4478072f30a16Jeff Brown AlertDialog dialog = (AlertDialog)getDialog(); 219766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (dialog != null) { 220766b286187d02b3da6e0142376a4478072f30a16Jeff Brown View customPanel = dialog.findViewById(com.android.internal.R.id.customPanel); 221766b286187d02b3da6e0142376a4478072f30a16Jeff Brown customPanel.setVisibility(mAdapter.getCount() > 1 ? View.VISIBLE : View.GONE); 222766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 223766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 224766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 22517b631988451613393c4656900c1821e23d8434aMichael Wright private void showSetupKeyboardLayoutsIfNecessary() { 22617b631988451613393c4656900c1821e23d8434aMichael Wright AlertDialog dialog = (AlertDialog)getDialog(); 22717b631988451613393c4656900c1821e23d8434aMichael Wright if (dialog != null 22817b631988451613393c4656900c1821e23d8434aMichael Wright && mAdapter.getCount() == 1 && mAdapter.getItem(0) == null 22917b631988451613393c4656900c1821e23d8434aMichael Wright && !mHasShownLayoutSelectionScreen) { 23017b631988451613393c4656900c1821e23d8434aMichael Wright mHasShownLayoutSelectionScreen = true; 23117b631988451613393c4656900c1821e23d8434aMichael Wright ((OnSetupKeyboardLayoutsListener)getTargetFragment()).onSetupKeyboardLayouts( 23217b631988451613393c4656900c1821e23d8434aMichael Wright mInputDeviceIdentifier); 23317b631988451613393c4656900c1821e23d8434aMichael Wright } 23417b631988451613393c4656900c1821e23d8434aMichael Wright } 23517b631988451613393c4656900c1821e23d8434aMichael Wright 236766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private static final class KeyboardLayoutAdapter extends ArrayAdapter<KeyboardLayout> { 237766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private final LayoutInflater mInflater; 238766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private int mCheckedItem = -1; 239766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 240766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public KeyboardLayoutAdapter(Context context) { 241766b286187d02b3da6e0142376a4478072f30a16Jeff Brown super(context, com.android.internal.R.layout.simple_list_item_2_single_choice); 242766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 243766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 244766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 245766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public void setCheckedItem(int position) { 246766b286187d02b3da6e0142376a4478072f30a16Jeff Brown mCheckedItem = position; 247766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 248766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 249766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 250766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public View getView(int position, View convertView, ViewGroup parent) { 251766b286187d02b3da6e0142376a4478072f30a16Jeff Brown KeyboardLayout item = getItem(position); 252766b286187d02b3da6e0142376a4478072f30a16Jeff Brown String label, collection; 253766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (item != null) { 254766b286187d02b3da6e0142376a4478072f30a16Jeff Brown label = item.getLabel(); 255766b286187d02b3da6e0142376a4478072f30a16Jeff Brown collection = item.getCollection(); 256766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } else { 257766b286187d02b3da6e0142376a4478072f30a16Jeff Brown label = getContext().getString(R.string.keyboard_layout_default_label); 258766b286187d02b3da6e0142376a4478072f30a16Jeff Brown collection = ""; 259766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 260766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 261766b286187d02b3da6e0142376a4478072f30a16Jeff Brown boolean checked = (position == mCheckedItem); 262766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (collection.isEmpty()) { 263766b286187d02b3da6e0142376a4478072f30a16Jeff Brown return inflateOneLine(convertView, parent, label, checked); 264766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } else { 265766b286187d02b3da6e0142376a4478072f30a16Jeff Brown return inflateTwoLine(convertView, parent, label, collection, checked); 266766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 267766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 268766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 269766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private View inflateOneLine(View convertView, ViewGroup parent, 270766b286187d02b3da6e0142376a4478072f30a16Jeff Brown String label, boolean checked) { 271766b286187d02b3da6e0142376a4478072f30a16Jeff Brown View view = convertView; 272766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (view == null || isTwoLine(view)) { 273766b286187d02b3da6e0142376a4478072f30a16Jeff Brown view = mInflater.inflate( 274766b286187d02b3da6e0142376a4478072f30a16Jeff Brown com.android.internal.R.layout.simple_list_item_single_choice, 275766b286187d02b3da6e0142376a4478072f30a16Jeff Brown parent, false); 276766b286187d02b3da6e0142376a4478072f30a16Jeff Brown setTwoLine(view, false); 277766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 278766b286187d02b3da6e0142376a4478072f30a16Jeff Brown CheckedTextView headline = (CheckedTextView) view.findViewById(android.R.id.text1); 279766b286187d02b3da6e0142376a4478072f30a16Jeff Brown headline.setText(label); 280766b286187d02b3da6e0142376a4478072f30a16Jeff Brown headline.setChecked(checked); 281766b286187d02b3da6e0142376a4478072f30a16Jeff Brown return view; 282766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 283766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 284766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private View inflateTwoLine(View convertView, ViewGroup parent, 285766b286187d02b3da6e0142376a4478072f30a16Jeff Brown String label, String collection, boolean checked) { 286766b286187d02b3da6e0142376a4478072f30a16Jeff Brown View view = convertView; 287766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (view == null || !isTwoLine(view)) { 288766b286187d02b3da6e0142376a4478072f30a16Jeff Brown view = mInflater.inflate( 289766b286187d02b3da6e0142376a4478072f30a16Jeff Brown com.android.internal.R.layout.simple_list_item_2_single_choice, 290766b286187d02b3da6e0142376a4478072f30a16Jeff Brown parent, false); 291766b286187d02b3da6e0142376a4478072f30a16Jeff Brown setTwoLine(view, true); 292766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 293766b286187d02b3da6e0142376a4478072f30a16Jeff Brown TextView headline = (TextView) view.findViewById(android.R.id.text1); 294766b286187d02b3da6e0142376a4478072f30a16Jeff Brown TextView subText = (TextView) view.findViewById(android.R.id.text2); 295766b286187d02b3da6e0142376a4478072f30a16Jeff Brown RadioButton radioButton = 296766b286187d02b3da6e0142376a4478072f30a16Jeff Brown (RadioButton)view.findViewById(com.android.internal.R.id.radio); 297766b286187d02b3da6e0142376a4478072f30a16Jeff Brown headline.setText(label); 298766b286187d02b3da6e0142376a4478072f30a16Jeff Brown subText.setText(collection); 299766b286187d02b3da6e0142376a4478072f30a16Jeff Brown radioButton.setChecked(checked); 300766b286187d02b3da6e0142376a4478072f30a16Jeff Brown return view; 301766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 302766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 303766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private static boolean isTwoLine(View view) { 304766b286187d02b3da6e0142376a4478072f30a16Jeff Brown return view.getTag() == Boolean.TRUE; 305766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 306766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 307766b286187d02b3da6e0142376a4478072f30a16Jeff Brown private static void setTwoLine(View view, boolean twoLine) { 308766b286187d02b3da6e0142376a4478072f30a16Jeff Brown view.setTag(Boolean.valueOf(twoLine)); 309766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 310766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 311766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 3125f0b59babfbfe483855b294098613f8d0fc2f9b4Abodunrinwa Toki private static final class KeyboardLayoutLoader extends AsyncTaskLoader<Keyboards> { 313813a54d216010a16d714355c61d606dd3eb589aaRoboErik private final InputDeviceIdentifier mInputDeviceIdentifier; 314766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 315813a54d216010a16d714355c61d606dd3eb589aaRoboErik public KeyboardLayoutLoader(Context context, InputDeviceIdentifier inputDeviceIdentifier) { 316766b286187d02b3da6e0142376a4478072f30a16Jeff Brown super(context); 317813a54d216010a16d714355c61d606dd3eb589aaRoboErik mInputDeviceIdentifier = inputDeviceIdentifier; 318766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 319766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 320766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 321766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public Keyboards loadInBackground() { 322766b286187d02b3da6e0142376a4478072f30a16Jeff Brown Keyboards keyboards = new Keyboards(); 323766b286187d02b3da6e0142376a4478072f30a16Jeff Brown InputManager im = (InputManager)getContext().getSystemService(Context.INPUT_SERVICE); 32417b631988451613393c4656900c1821e23d8434aMichael Wright String[] keyboardLayoutDescriptors = im.getEnabledKeyboardLayoutsForInputDevice( 325813a54d216010a16d714355c61d606dd3eb589aaRoboErik mInputDeviceIdentifier); 326766b286187d02b3da6e0142376a4478072f30a16Jeff Brown for (String keyboardLayoutDescriptor : keyboardLayoutDescriptors) { 327766b286187d02b3da6e0142376a4478072f30a16Jeff Brown KeyboardLayout keyboardLayout = im.getKeyboardLayout(keyboardLayoutDescriptor); 328766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (keyboardLayout != null) { 329766b286187d02b3da6e0142376a4478072f30a16Jeff Brown keyboards.keyboardLayouts.add(keyboardLayout); 330766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 331766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 332766b286187d02b3da6e0142376a4478072f30a16Jeff Brown Collections.sort(keyboards.keyboardLayouts); 333766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 334766b286187d02b3da6e0142376a4478072f30a16Jeff Brown String currentKeyboardLayoutDescriptor = 335813a54d216010a16d714355c61d606dd3eb589aaRoboErik im.getCurrentKeyboardLayoutForInputDevice(mInputDeviceIdentifier); 336766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (currentKeyboardLayoutDescriptor != null) { 337766b286187d02b3da6e0142376a4478072f30a16Jeff Brown final int numKeyboardLayouts = keyboards.keyboardLayouts.size(); 338766b286187d02b3da6e0142376a4478072f30a16Jeff Brown for (int i = 0; i < numKeyboardLayouts; i++) { 339766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (keyboards.keyboardLayouts.get(i).getDescriptor().equals( 340766b286187d02b3da6e0142376a4478072f30a16Jeff Brown currentKeyboardLayoutDescriptor)) { 341766b286187d02b3da6e0142376a4478072f30a16Jeff Brown keyboards.current = i; 342766b286187d02b3da6e0142376a4478072f30a16Jeff Brown break; 343766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 344766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 345766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 346766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 347766b286187d02b3da6e0142376a4478072f30a16Jeff Brown if (keyboards.keyboardLayouts.isEmpty()) { 348766b286187d02b3da6e0142376a4478072f30a16Jeff Brown keyboards.keyboardLayouts.add(null); // default layout 349766b286187d02b3da6e0142376a4478072f30a16Jeff Brown keyboards.current = 0; 350766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 351766b286187d02b3da6e0142376a4478072f30a16Jeff Brown return keyboards; 352766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 353766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 354766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 355766b286187d02b3da6e0142376a4478072f30a16Jeff Brown protected void onStartLoading() { 356766b286187d02b3da6e0142376a4478072f30a16Jeff Brown super.onStartLoading(); 357766b286187d02b3da6e0142376a4478072f30a16Jeff Brown forceLoad(); 358766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 359766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 360766b286187d02b3da6e0142376a4478072f30a16Jeff Brown @Override 361766b286187d02b3da6e0142376a4478072f30a16Jeff Brown protected void onStopLoading() { 362766b286187d02b3da6e0142376a4478072f30a16Jeff Brown super.onStopLoading(); 363766b286187d02b3da6e0142376a4478072f30a16Jeff Brown cancelLoad(); 364766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 365766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 366766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 367766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public static final class Keyboards { 368766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public final ArrayList<KeyboardLayout> keyboardLayouts = new ArrayList<KeyboardLayout>(); 369766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public int current = -1; 370766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 371766b286187d02b3da6e0142376a4478072f30a16Jeff Brown 372766b286187d02b3da6e0142376a4478072f30a16Jeff Brown public interface OnSetupKeyboardLayoutsListener { 373813a54d216010a16d714355c61d606dd3eb589aaRoboErik public void onSetupKeyboardLayouts(InputDeviceIdentifier mInputDeviceIdentifier); 374766b286187d02b3da6e0142376a4478072f30a16Jeff Brown } 37517b631988451613393c4656900c1821e23d8434aMichael Wright} 376