320 lines
13 KiB
Java
320 lines
13 KiB
Java
/*
|
|
* Copyright (C) 2011 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.android.settings.inputmethod;
|
|
|
|
import com.android.internal.inputmethod.InputMethodUtils;
|
|
import com.android.settings.R;
|
|
import com.android.settings.SettingsActivity;
|
|
import com.android.settings.SettingsPreferenceFragment;
|
|
import com.android.settings.Utils;
|
|
|
|
import android.app.AlertDialog;
|
|
import android.app.Fragment;
|
|
import android.content.ActivityNotFoundException;
|
|
import android.content.Context;
|
|
import android.content.DialogInterface;
|
|
import android.content.Intent;
|
|
import android.content.res.Configuration;
|
|
import android.os.Bundle;
|
|
import android.preference.CheckBoxPreference;
|
|
import android.preference.Preference;
|
|
import android.text.TextUtils;
|
|
import android.util.Log;
|
|
import android.view.View;
|
|
import android.view.View.OnClickListener;
|
|
import android.view.View.OnLongClickListener;
|
|
import android.view.inputmethod.InputMethodInfo;
|
|
import android.view.inputmethod.InputMethodManager;
|
|
import android.view.inputmethod.InputMethodSubtype;
|
|
import android.widget.ImageView;
|
|
import android.widget.TextView;
|
|
import android.widget.Toast;
|
|
|
|
import java.text.Collator;
|
|
import java.util.List;
|
|
|
|
// TODO: Make this non-persistent.
|
|
class InputMethodPreference extends CheckBoxPreference {
|
|
private static final String TAG = InputMethodPreference.class.getSimpleName();
|
|
private final SettingsPreferenceFragment mFragment;
|
|
private final InputMethodInfo mImi;
|
|
private final InputMethodManager mImm;
|
|
private final boolean mIsValidSystemNonAuxAsciiCapableIme;
|
|
private final Intent mSettingsIntent;
|
|
private final boolean mIsSystemIme;
|
|
private final Collator mCollator;
|
|
|
|
private AlertDialog mDialog = null;
|
|
private ImageView mInputMethodSettingsButton;
|
|
private TextView mTitleText;
|
|
private TextView mSummaryText;
|
|
private View mInputMethodPref;
|
|
private OnPreferenceChangeListener mOnImePreferenceChangeListener;
|
|
|
|
private final OnClickListener mPrefOnclickListener = new OnClickListener() {
|
|
@Override
|
|
public void onClick(View arg0) {
|
|
if (!isEnabled()) {
|
|
return;
|
|
}
|
|
if (isChecked()) {
|
|
setChecked(false, true /* save */);
|
|
} else {
|
|
if (mIsSystemIme) {
|
|
setChecked(true, true /* save */);
|
|
} else {
|
|
showSecurityWarnDialog(mImi, InputMethodPreference.this);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
public InputMethodPreference(SettingsPreferenceFragment fragment, Intent settingsIntent,
|
|
InputMethodManager imm, InputMethodInfo imi) {
|
|
super(fragment.getActivity());
|
|
setLayoutResource(R.layout.preference_inputmethod);
|
|
setWidgetLayoutResource(R.layout.preference_inputmethod_widget);
|
|
mFragment = fragment;
|
|
mSettingsIntent = settingsIntent;
|
|
mImm = imm;
|
|
mImi = imi;
|
|
mIsSystemIme = InputMethodUtils.isSystemIme(imi);
|
|
mCollator = Collator.getInstance(fragment.getResources().getConfiguration().locale);
|
|
final Context context = fragment.getActivity();
|
|
mIsValidSystemNonAuxAsciiCapableIme = InputMethodSettingValuesWrapper
|
|
.getInstance(context).isValidSystemNonAuxAsciiCapableIme(imi, context);
|
|
updatePreferenceViews();
|
|
}
|
|
|
|
@Override
|
|
protected void onBindView(View view) {
|
|
super.onBindView(view);
|
|
mInputMethodPref = view.findViewById(R.id.inputmethod_pref);
|
|
mInputMethodPref.setOnClickListener(mPrefOnclickListener);
|
|
mInputMethodSettingsButton = (ImageView)view.findViewById(R.id.inputmethod_settings);
|
|
mTitleText = (TextView)view.findViewById(android.R.id.title);
|
|
mSummaryText = (TextView)view.findViewById(android.R.id.summary);
|
|
final boolean hasSubtypes = mImi.getSubtypeCount() > 1;
|
|
final String imiId = mImi.getId();
|
|
if (hasSubtypes) {
|
|
mInputMethodPref.setOnLongClickListener(new OnLongClickListener() {
|
|
@Override
|
|
public boolean onLongClick(View arg0) {
|
|
final Bundle bundle = new Bundle();
|
|
bundle.putString(android.provider.Settings.EXTRA_INPUT_METHOD_ID, imiId);
|
|
startFragment(mFragment, InputMethodAndSubtypeEnabler.class.getName(),
|
|
0, bundle);
|
|
return true;
|
|
}
|
|
});
|
|
}
|
|
|
|
if (mSettingsIntent != null) {
|
|
mInputMethodSettingsButton.setOnClickListener(
|
|
new OnClickListener() {
|
|
@Override
|
|
public void onClick(View arg0) {
|
|
try {
|
|
mFragment.startActivity(mSettingsIntent);
|
|
} catch (ActivityNotFoundException e) {
|
|
Log.d(TAG, "IME's Settings Activity Not Found: " + e);
|
|
final String msg = mFragment.getString(
|
|
R.string.failed_to_open_app_settings_toast,
|
|
mImi.loadLabel(
|
|
mFragment.getActivity().getPackageManager()));
|
|
Toast.makeText(
|
|
mFragment.getActivity(), msg, Toast.LENGTH_LONG).show();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
if (hasSubtypes) {
|
|
final OnLongClickListener listener = new OnLongClickListener() {
|
|
@Override
|
|
public boolean onLongClick(View arg0) {
|
|
final Bundle bundle = new Bundle();
|
|
bundle.putString(android.provider.Settings.EXTRA_INPUT_METHOD_ID, imiId);
|
|
startFragment(mFragment, InputMethodAndSubtypeEnabler.class.getName(),
|
|
0, bundle);
|
|
return true;
|
|
}
|
|
};
|
|
mInputMethodSettingsButton.setOnLongClickListener(listener);
|
|
}
|
|
if (mSettingsIntent == null) {
|
|
mInputMethodSettingsButton.setVisibility(View.GONE);
|
|
}
|
|
updatePreferenceViews();
|
|
}
|
|
|
|
@Override
|
|
public void setEnabled(boolean enabled) {
|
|
super.setEnabled(enabled);
|
|
updatePreferenceViews();
|
|
}
|
|
|
|
public void updatePreferenceViews() {
|
|
final boolean isAlwaysChecked =
|
|
InputMethodSettingValuesWrapper.getInstance(getContext()).isAlwaysCheckedIme(
|
|
mImi, getContext());
|
|
if (isAlwaysChecked) {
|
|
super.setChecked(true);
|
|
super.setEnabled(false);
|
|
} else {
|
|
super.setEnabled(true);
|
|
}
|
|
final boolean checked = isChecked();
|
|
if (mInputMethodSettingsButton != null) {
|
|
mInputMethodSettingsButton.setEnabled(checked);
|
|
mInputMethodSettingsButton.setClickable(checked);
|
|
mInputMethodSettingsButton.setFocusable(checked);
|
|
if (!checked) {
|
|
mInputMethodSettingsButton.setAlpha(Utils.DISABLED_ALPHA);
|
|
}
|
|
}
|
|
if (mTitleText != null) {
|
|
mTitleText.setEnabled(true);
|
|
}
|
|
if (mSummaryText != null) {
|
|
mSummaryText.setEnabled(checked);
|
|
}
|
|
if (mInputMethodPref != null) {
|
|
mInputMethodPref.setEnabled(true);
|
|
mInputMethodPref.setLongClickable(checked);
|
|
final boolean enabled = isEnabled();
|
|
mInputMethodPref.setOnClickListener(enabled ? mPrefOnclickListener : null);
|
|
if (!enabled) {
|
|
mInputMethodPref.setBackgroundColor(0);
|
|
}
|
|
}
|
|
updateSummary();
|
|
}
|
|
|
|
public static boolean startFragment(
|
|
Fragment fragment, String fragmentClass, int requestCode, Bundle extras) {
|
|
if (fragment.getActivity() instanceof SettingsActivity) {
|
|
SettingsActivity sa = (SettingsActivity) fragment.getActivity();
|
|
sa.startPreferencePanel(fragmentClass, extras, 0, null, fragment, requestCode);
|
|
return true;
|
|
} else {
|
|
Log.w(TAG, "Parent isn't Settings, thus there's no way to launch the "
|
|
+ "given Fragment (name: " + fragmentClass + ", requestCode: " + requestCode
|
|
+ ")");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private String getSummaryString() {
|
|
final StringBuilder builder = new StringBuilder();
|
|
final List<InputMethodSubtype> subtypes = mImm.getEnabledInputMethodSubtypeList(mImi, true);
|
|
for (InputMethodSubtype subtype : subtypes) {
|
|
if (builder.length() > 0) {
|
|
builder.append(", ");
|
|
}
|
|
final CharSequence subtypeLabel = subtype.getDisplayName(mFragment.getActivity(),
|
|
mImi.getPackageName(), mImi.getServiceInfo().applicationInfo);
|
|
builder.append(subtypeLabel);
|
|
}
|
|
return builder.toString();
|
|
}
|
|
|
|
private void updateSummary() {
|
|
final String summary = getSummaryString();
|
|
if (TextUtils.isEmpty(summary)) {
|
|
return;
|
|
}
|
|
setSummary(summary);
|
|
}
|
|
|
|
/**
|
|
* Sets the checkbox state and optionally saves the settings.
|
|
* @param checked whether to check the box
|
|
* @param save whether to save IME settings
|
|
*/
|
|
private void setChecked(boolean checked, boolean save) {
|
|
final boolean wasChecked = isChecked();
|
|
super.setChecked(checked);
|
|
if (save) {
|
|
saveImeSettings();
|
|
if (wasChecked != checked && mOnImePreferenceChangeListener != null) {
|
|
mOnImePreferenceChangeListener.onPreferenceChange(this, checked);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void setOnImePreferenceChangeListener(OnPreferenceChangeListener listener) {
|
|
mOnImePreferenceChangeListener = listener;
|
|
}
|
|
|
|
private void showSecurityWarnDialog(InputMethodInfo imi, final InputMethodPreference chkPref) {
|
|
if (mDialog != null && mDialog.isShowing()) {
|
|
mDialog.dismiss();
|
|
}
|
|
mDialog = (new AlertDialog.Builder(mFragment.getActivity()))
|
|
.setTitle(android.R.string.dialog_alert_title)
|
|
.setCancelable(true)
|
|
.setPositiveButton(android.R.string.ok,
|
|
new DialogInterface.OnClickListener() {
|
|
@Override
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
chkPref.setChecked(true, true);
|
|
}
|
|
})
|
|
.setNegativeButton(android.R.string.cancel,
|
|
new DialogInterface.OnClickListener() {
|
|
@Override
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
}
|
|
})
|
|
.create();
|
|
mDialog.setMessage(mFragment.getResources().getString(R.string.ime_security_warning,
|
|
imi.getServiceInfo().applicationInfo.loadLabel(
|
|
mFragment.getActivity().getPackageManager())));
|
|
mDialog.show();
|
|
}
|
|
|
|
@Override
|
|
public int compareTo(Preference p) {
|
|
if (!(p instanceof InputMethodPreference)) {
|
|
return super.compareTo(p);
|
|
}
|
|
final InputMethodPreference imp = (InputMethodPreference) p;
|
|
final boolean priority0 = mIsSystemIme && mIsValidSystemNonAuxAsciiCapableIme;
|
|
final boolean priority1 = imp.mIsSystemIme && imp.mIsValidSystemNonAuxAsciiCapableIme;
|
|
if (priority0 == priority1) {
|
|
final CharSequence t0 = getTitle();
|
|
final CharSequence t1 = imp.getTitle();
|
|
if (TextUtils.isEmpty(t0)) {
|
|
return 1;
|
|
}
|
|
if (TextUtils.isEmpty(t1)) {
|
|
return -1;
|
|
}
|
|
return mCollator.compare(t0.toString(), t1.toString());
|
|
}
|
|
// Prefer always checked system IMEs
|
|
return priority0 ? -1 : 1;
|
|
}
|
|
|
|
private void saveImeSettings() {
|
|
InputMethodAndSubtypeUtil.saveInputMethodSubtypeList(
|
|
mFragment, mFragment.getActivity().getContentResolver(), mImm.getInputMethodList(),
|
|
mFragment.getResources().getConfiguration().keyboard
|
|
== Configuration.KEYBOARD_QWERTY);
|
|
}
|
|
}
|