InputMethodPreference.java revision 1c2b175d7ab8da48a12191c4930bd4ed451a9952
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 mSummaryText = (TextView)view.findViewById(android.R.id.summary); 101 if (mSettingsIntent != null) { 102 mInputMethodSettingsButton.setOnClickListener( 103 new OnClickListener() { 104 @Override 105 public void onClick(View arg0) { 106 try { 107 mFragment.startActivity(mSettingsIntent); 108 } catch (ActivityNotFoundException e) { 109 Log.d(TAG, "IME's Settings Activity Not Found: " + e); 110 // If the IME's settings activity does not exist, we can just 111 // do nothing... 112 } 113 } 114 }); 115 } 116 final boolean hasSubtypes = mImi.getSubtypeCount() > 1; 117 final String imiId = mImi.getId(); 118 if (hasSubtypes) { 119 final OnLongClickListener listener = new OnLongClickListener() { 120 @Override 121 public boolean onLongClick(View arg0) { 122 final Bundle bundle = new Bundle(); 123 bundle.putString(Settings.EXTRA_INPUT_METHOD_ID, imiId); 124 startFragment(mFragment, InputMethodAndSubtypeEnabler.class.getName(), 125 0, bundle); 126 return true; 127 } 128 }; 129 mInputMethodSettingsButton.setOnLongClickListener(listener); 130 } 131 if (mSettingsIntent == null) { 132 mInputMethodSettingsButton.setVisibility(View.GONE); 133 } else { 134 enableSettingsButton(); 135 } 136 } 137 138 @Override 139 public void setEnabled(boolean enabled) { 140 super.setEnabled(enabled); 141 enableSettingsButton(); 142 } 143 144 private void enableSettingsButton() { 145 if (mInputMethodSettingsButton != null) { 146 final boolean checked = isChecked(); 147 mInputMethodSettingsButton.setEnabled(checked); 148 mInputMethodSettingsButton.setClickable(checked); 149 mInputMethodSettingsButton.setFocusable(checked); 150 if (!checked) { 151 mInputMethodSettingsButton.setAlpha(DISABLED_ALPHA); 152 } 153 } 154 if (mTitleText != null) { 155 mTitleText.setEnabled(true); 156 } 157 if (mSummaryText != null) { 158 mSummaryText.setEnabled(true); 159 } 160 } 161 162 public static boolean startFragment( 163 Fragment fragment, String fragmentClass, int requestCode, Bundle extras) { 164 if (fragment.getActivity() instanceof PreferenceActivity) { 165 PreferenceActivity preferenceActivity = (PreferenceActivity)fragment.getActivity(); 166 preferenceActivity.startPreferencePanel(fragmentClass, extras, 0, null, fragment, 167 requestCode); 168 return true; 169 } else { 170 Log.w(TAG, "Parent isn't PreferenceActivity, thus there's no way to launch the " 171 + "given Fragment (name: " + fragmentClass + ", requestCode: " + requestCode 172 + ")"); 173 return false; 174 } 175 } 176 177 public String getSummaryString() { 178 final StringBuilder builder = new StringBuilder(); 179 final List<InputMethodSubtype> subtypes = mImm.getEnabledInputMethodSubtypeList(mImi, true); 180 for (InputMethodSubtype subtype : subtypes) { 181 if (builder.length() > 0) { 182 builder.append(", "); 183 } 184 final CharSequence subtypeLabel = subtype.getDisplayName(mFragment.getActivity(), 185 mImi.getPackageName(), mImi.getServiceInfo().applicationInfo); 186 builder.append(subtypeLabel); 187 } 188 return builder.toString(); 189 } 190 191 public void updateSummary() { 192 final String summary = getSummaryString(); 193 if (TextUtils.isEmpty(summary)) { 194 return; 195 } 196 setSummary(summary); 197 } 198 199 @Override 200 public void setChecked(boolean checked) { 201 super.setChecked(checked); 202 saveImeSettings(); 203 } 204 205 private void showSecurityWarnDialog(InputMethodInfo imi, final CheckBoxPreference chkPref) { 206 if (mDialog != null && mDialog.isShowing()) { 207 mDialog.dismiss(); 208 } 209 mDialog = (new AlertDialog.Builder(mFragment.getActivity())) 210 .setTitle(android.R.string.dialog_alert_title) 211 .setIcon(android.R.drawable.ic_dialog_alert) 212 .setCancelable(true) 213 .setPositiveButton(android.R.string.ok, 214 new DialogInterface.OnClickListener() { 215 @Override 216 public void onClick(DialogInterface dialog, int which) { 217 chkPref.setChecked(true); 218 } 219 }) 220 .setNegativeButton(android.R.string.cancel, 221 new DialogInterface.OnClickListener() { 222 @Override 223 public void onClick(DialogInterface dialog, int which) { 224 } 225 }) 226 .create(); 227 mDialog.setMessage(mFragment.getResources().getString(R.string.ime_security_warning, 228 imi.getServiceInfo().applicationInfo.loadLabel( 229 mFragment.getActivity().getPackageManager()))); 230 mDialog.show(); 231 } 232 233 @Override 234 public int compare(InputMethodPreference arg0, InputMethodPreference arg1) { 235 if (arg0.isEnabled() == arg0.isEnabled()) { 236 return arg0.mImi.getId().compareTo(arg1.mImi.getId()); 237 } else { 238 // Prefer system IMEs 239 return arg0.isEnabled() ? 1 : -1; 240 } 241 } 242 243 private void saveImeSettings() { 244 InputMethodAndSubtypeUtil.saveInputMethodSubtypeList( 245 mFragment, mFragment.getActivity().getContentResolver(), mImm.getInputMethodList(), 246 mFragment.getResources().getConfiguration().keyboard 247 == Configuration.KEYBOARD_QWERTY); 248 } 249} 250