InputMethodPreference.java revision 88b75f740a1c75040bd7339e5ef9d5abdb50014d
1/* 2 * Copyright (C) 2011 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 com.android.settings.R; 20import com.android.settings.SettingsPreferenceFragment; 21 22import android.app.AlertDialog; 23import android.app.Fragment; 24import android.content.ActivityNotFoundException; 25import android.content.DialogInterface; 26import android.content.Intent; 27import android.content.res.Configuration; 28import android.os.Bundle; 29import android.preference.CheckBoxPreference; 30import android.preference.PreferenceActivity; 31import android.provider.Settings; 32import android.text.TextUtils; 33import android.util.Log; 34import android.view.View; 35import android.view.View.OnClickListener; 36import android.view.View.OnLongClickListener; 37import android.view.inputmethod.InputMethodInfo; 38import android.view.inputmethod.InputMethodManager; 39import android.view.inputmethod.InputMethodSubtype; 40import android.widget.ImageView; 41import android.widget.TextView; 42 43import java.util.Comparator; 44import java.util.List; 45 46public class InputMethodPreference extends CheckBoxPreference 47 implements Comparator<InputMethodPreference> { 48 private static final String TAG = InputMethodPreference.class.getSimpleName(); 49 private static final float DISABLED_ALPHA = 0.4f; 50 private final SettingsPreferenceFragment mFragment; 51 private final InputMethodInfo mImi; 52 private final InputMethodManager mImm; 53 private final Intent mSettingsIntent; 54 private final boolean mIsSystemIme; 55 56 private AlertDialog mDialog = null; 57 private ImageView mInputMethodSettingsButton; 58 private TextView mTitleText; 59 private TextView mSummaryText; 60 private View mInputMethodPref; 61 62 public InputMethodPreference(SettingsPreferenceFragment fragment, Intent settingsIntent, 63 InputMethodManager imm, InputMethodInfo imi, int imiCount) { 64 super(fragment.getActivity(), null, R.style.InputMethodPreferenceStyle); 65 setLayoutResource(R.layout.preference_inputmethod); 66 setWidgetLayoutResource(R.layout.preference_inputmethod_widget); 67 mFragment = fragment; 68 mSettingsIntent = settingsIntent; 69 mImm = imm; 70 mImi = imi; 71 updateSummary(); 72 mIsSystemIme = InputMethodAndSubtypeUtil.isSystemIme(imi); 73 final boolean isAuxIme = InputMethodAndSubtypeUtil.isAuxiliaryIme(imi); 74 if (imiCount <= 1 || (mIsSystemIme && !isAuxIme)) { 75 setEnabled(false); 76 } 77 } 78 79 @Override 80 protected void onBindView(View view) { 81 super.onBindView(view); 82 mInputMethodPref = view.findViewById(R.id.inputmethod_pref); 83 mInputMethodPref.setOnClickListener( 84 new OnClickListener() { 85 @Override 86 public void onClick(View arg0) { 87 if (isChecked()) { 88 setChecked(false); 89 } else { 90 if (mIsSystemIme) { 91 setChecked(true); 92 } else { 93 showSecurityWarnDialog(mImi, InputMethodPreference.this); 94 } 95 } 96 } 97 }); 98 mInputMethodSettingsButton = (ImageView)view.findViewById(R.id.inputmethod_settings); 99 mTitleText = (TextView)view.findViewById(android.R.id.title); 100 101 final boolean hasSubtypes = mImi.getSubtypeCount() > 1; 102 final String imiId = mImi.getId(); 103 mSummaryText = (TextView)view.findViewById(android.R.id.summary); 104 mSummaryText.setOnClickListener(new OnClickListener() { 105 @Override 106 public void onClick(View arg0) { 107 final Bundle bundle = new Bundle(); 108 bundle.putString(Settings.EXTRA_INPUT_METHOD_ID, imiId); 109 startFragment(mFragment, InputMethodAndSubtypeEnabler.class.getName(), 110 0, bundle); 111 } 112 }); 113 if (mSettingsIntent != null) { 114 mInputMethodSettingsButton.setOnClickListener( 115 new OnClickListener() { 116 @Override 117 public void onClick(View arg0) { 118 try { 119 mFragment.startActivity(mSettingsIntent); 120 } catch (ActivityNotFoundException e) { 121 Log.d(TAG, "IME's Settings Activity Not Found: " + e); 122 // If the IME's settings activity does not exist, we can just 123 // do nothing... 124 } 125 } 126 }); 127 } 128 if (hasSubtypes) { 129 final OnLongClickListener listener = new OnLongClickListener() { 130 @Override 131 public boolean onLongClick(View arg0) { 132 final Bundle bundle = new Bundle(); 133 bundle.putString(Settings.EXTRA_INPUT_METHOD_ID, imiId); 134 startFragment(mFragment, InputMethodAndSubtypeEnabler.class.getName(), 135 0, bundle); 136 return true; 137 } 138 }; 139 mInputMethodSettingsButton.setOnLongClickListener(listener); 140 } 141 if (mSettingsIntent == null) { 142 mInputMethodSettingsButton.setVisibility(View.GONE); 143 } else { 144 enableSettingsButton(); 145 } 146 } 147 148 @Override 149 public void setEnabled(boolean enabled) { 150 super.setEnabled(enabled); 151 enableSettingsButton(); 152 } 153 154 private void enableSettingsButton() { 155 final boolean checked = isChecked(); 156 if (mInputMethodSettingsButton != null) { 157 mInputMethodSettingsButton.setEnabled(checked); 158 mInputMethodSettingsButton.setClickable(checked); 159 mInputMethodSettingsButton.setFocusable(checked); 160 if (!checked) { 161 mInputMethodSettingsButton.setAlpha(DISABLED_ALPHA); 162 } 163 } 164 if (mTitleText != null) { 165 mTitleText.setEnabled(true); 166 } 167 if (mSummaryText != null) { 168 mSummaryText.setEnabled(checked); 169 mSummaryText.setClickable(checked); 170 } 171 } 172 173 public static boolean startFragment( 174 Fragment fragment, String fragmentClass, int requestCode, Bundle extras) { 175 if (fragment.getActivity() instanceof PreferenceActivity) { 176 PreferenceActivity preferenceActivity = (PreferenceActivity)fragment.getActivity(); 177 preferenceActivity.startPreferencePanel(fragmentClass, extras, 0, null, fragment, 178 requestCode); 179 return true; 180 } else { 181 Log.w(TAG, "Parent isn't PreferenceActivity, thus there's no way to launch the " 182 + "given Fragment (name: " + fragmentClass + ", requestCode: " + requestCode 183 + ")"); 184 return false; 185 } 186 } 187 188 public String getSummaryString() { 189 final StringBuilder builder = new StringBuilder(); 190 final List<InputMethodSubtype> subtypes = mImm.getEnabledInputMethodSubtypeList(mImi, true); 191 for (InputMethodSubtype subtype : subtypes) { 192 if (builder.length() > 0) { 193 builder.append(", "); 194 } 195 final CharSequence subtypeLabel = subtype.getDisplayName(mFragment.getActivity(), 196 mImi.getPackageName(), mImi.getServiceInfo().applicationInfo); 197 builder.append(subtypeLabel); 198 } 199 return builder.toString(); 200 } 201 202 public void updateSummary() { 203 final String summary = getSummaryString(); 204 if (TextUtils.isEmpty(summary)) { 205 return; 206 } 207 setSummary(summary); 208 } 209 210 @Override 211 public void setChecked(boolean checked) { 212 super.setChecked(checked); 213 saveImeSettings(); 214 } 215 216 private void showSecurityWarnDialog(InputMethodInfo imi, final CheckBoxPreference chkPref) { 217 if (mDialog != null && mDialog.isShowing()) { 218 mDialog.dismiss(); 219 } 220 mDialog = (new AlertDialog.Builder(mFragment.getActivity())) 221 .setTitle(android.R.string.dialog_alert_title) 222 .setIcon(android.R.drawable.ic_dialog_alert) 223 .setCancelable(true) 224 .setPositiveButton(android.R.string.ok, 225 new DialogInterface.OnClickListener() { 226 @Override 227 public void onClick(DialogInterface dialog, int which) { 228 chkPref.setChecked(true); 229 } 230 }) 231 .setNegativeButton(android.R.string.cancel, 232 new DialogInterface.OnClickListener() { 233 @Override 234 public void onClick(DialogInterface dialog, int which) { 235 } 236 }) 237 .create(); 238 mDialog.setMessage(mFragment.getResources().getString(R.string.ime_security_warning, 239 imi.getServiceInfo().applicationInfo.loadLabel( 240 mFragment.getActivity().getPackageManager()))); 241 mDialog.show(); 242 } 243 244 @Override 245 public int compare(InputMethodPreference arg0, InputMethodPreference arg1) { 246 if (arg0.isEnabled() == arg0.isEnabled()) { 247 return arg0.mImi.getId().compareTo(arg1.mImi.getId()); 248 } else { 249 // Prefer system IMEs 250 return arg0.isEnabled() ? 1 : -1; 251 } 252 } 253 254 private void saveImeSettings() { 255 InputMethodAndSubtypeUtil.saveInputMethodSubtypeList( 256 mFragment, mFragment.getActivity().getContentResolver(), mImm.getInputMethodList(), 257 mFragment.getResources().getConfiguration().keyboard 258 == Configuration.KEYBOARD_QWERTY); 259 } 260} 261