Home | History | Annotate | Download | only in settings
      1 /*
      2  * Copyright (C) 2008 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 
     17 package com.android.settings;
     18 
     19 import android.app.AlertDialog;
     20 import android.app.Dialog;
     21 import android.content.Context;
     22 import android.content.DialogInterface;
     23 import android.content.Intent;
     24 import android.content.pm.ApplicationInfo;
     25 import android.content.res.Configuration;
     26 import android.os.Bundle;
     27 import android.os.Environment;
     28 import android.os.SystemProperties;
     29 import android.preference.CheckBoxPreference;
     30 import android.preference.Preference;
     31 import android.preference.PreferenceActivity;
     32 import android.preference.PreferenceGroup;
     33 import android.preference.PreferenceScreen;
     34 import android.provider.Settings;
     35 import android.text.TextUtils;
     36 import android.view.View.OnClickListener;
     37 import android.view.inputmethod.InputMethodInfo;
     38 import android.view.inputmethod.InputMethodManager;
     39 
     40 import java.util.ArrayList;
     41 import java.util.HashSet;
     42 import java.util.List;
     43 
     44 public class LanguageSettings extends PreferenceActivity {
     45 
     46     private static final String KEY_PHONE_LANGUAGE = "phone_language";
     47     private static final String KEY_KEYBOARD_SETTINGS_CATEGORY = "keyboard_settings_category";
     48     private static final String KEY_HARDKEYBOARD_CATEGORY = "hardkeyboard_category";
     49     private boolean mHaveHardKeyboard;
     50 
     51     private List<InputMethodInfo> mInputMethodProperties;
     52     private List<CheckBoxPreference> mCheckboxes;
     53     private Preference mLanguagePref;
     54 
     55     final TextUtils.SimpleStringSplitter mStringColonSplitter
     56             = new TextUtils.SimpleStringSplitter(':');
     57 
     58     private String mLastInputMethodId;
     59     private String mLastTickedInputMethodId;
     60 
     61     static public String getInputMethodIdFromKey(String key) {
     62         return key;
     63     }
     64 
     65     @Override
     66     protected void onCreate(Bundle icicle) {
     67         super.onCreate(icicle);
     68 
     69         addPreferencesFromResource(R.xml.language_settings);
     70 
     71         if (getAssets().getLocales().length == 1) {
     72             getPreferenceScreen().
     73                 removePreference(findPreference(KEY_PHONE_LANGUAGE));
     74         } else {
     75             mLanguagePref = findPreference(KEY_PHONE_LANGUAGE);
     76         }
     77 
     78         Configuration config = getResources().getConfiguration();
     79         if (config.keyboard != Configuration.KEYBOARD_QWERTY) {
     80             getPreferenceScreen().removePreference(
     81                     getPreferenceScreen().findPreference(KEY_HARDKEYBOARD_CATEGORY));
     82         } else {
     83             mHaveHardKeyboard = true;
     84         }
     85         mCheckboxes = new ArrayList<CheckBoxPreference>();
     86         onCreateIMM();
     87     }
     88 
     89     private boolean isSystemIme(InputMethodInfo property) {
     90         return (property.getServiceInfo().applicationInfo.flags
     91                 & ApplicationInfo.FLAG_SYSTEM) != 0;
     92     }
     93 
     94     private void onCreateIMM() {
     95         InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
     96 
     97         mInputMethodProperties = imm.getInputMethodList();
     98 
     99         mLastInputMethodId = Settings.Secure.getString(getContentResolver(),
    100             Settings.Secure.DEFAULT_INPUT_METHOD);
    101 
    102         PreferenceGroup keyboardSettingsCategory = (PreferenceGroup) findPreference(
    103                 KEY_KEYBOARD_SETTINGS_CATEGORY);
    104 
    105         int N = (mInputMethodProperties == null ? 0 : mInputMethodProperties
    106                 .size());
    107         for (int i = 0; i < N; ++i) {
    108             InputMethodInfo property = mInputMethodProperties.get(i);
    109             String prefKey = property.getId();
    110 
    111             CharSequence label = property.loadLabel(getPackageManager());
    112             boolean systemIME = isSystemIme(property);
    113             // Add a check box.
    114             // Don't show the toggle if it's the only keyboard in the system, or it's a system IME.
    115             if (mHaveHardKeyboard || (N > 1 && !systemIME)) {
    116                 CheckBoxPreference chkbxPref = new CheckBoxPreference(this);
    117                 chkbxPref.setKey(prefKey);
    118                 chkbxPref.setTitle(label);
    119                 keyboardSettingsCategory.addPreference(chkbxPref);
    120                 mCheckboxes.add(chkbxPref);
    121             }
    122 
    123             // If setting activity is available, add a setting screen entry.
    124             if (null != property.getSettingsActivity()) {
    125                 PreferenceScreen prefScreen = new PreferenceScreen(this, null);
    126                 String settingsActivity = property.getSettingsActivity();
    127                 if (settingsActivity.lastIndexOf("/") < 0) {
    128                     settingsActivity = property.getPackageName() + "/" + settingsActivity;
    129                 }
    130                 prefScreen.setKey(settingsActivity);
    131                 prefScreen.setTitle(label);
    132                 if (N == 1) {
    133                     prefScreen.setSummary(getString(R.string.onscreen_keyboard_settings_summary));
    134                 } else {
    135                     CharSequence settingsLabel = getResources().getString(
    136                             R.string.input_methods_settings_label_format, label);
    137                     prefScreen.setSummary(settingsLabel);
    138                 }
    139                 keyboardSettingsCategory.addPreference(prefScreen);
    140             }
    141         }
    142     }
    143 
    144     @Override
    145     protected void onResume() {
    146         super.onResume();
    147 
    148         final HashSet<String> enabled = new HashSet<String>();
    149         String enabledStr = Settings.Secure.getString(getContentResolver(),
    150                 Settings.Secure.ENABLED_INPUT_METHODS);
    151         if (enabledStr != null) {
    152             final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
    153             splitter.setString(enabledStr);
    154             while (splitter.hasNext()) {
    155                 enabled.add(splitter.next());
    156             }
    157         }
    158 
    159         // Update the statuses of the Check Boxes.
    160         int N = mInputMethodProperties.size();
    161         for (int i = 0; i < N; ++i) {
    162             final String id = mInputMethodProperties.get(i).getId();
    163             CheckBoxPreference pref = (CheckBoxPreference) findPreference(mInputMethodProperties
    164                     .get(i).getId());
    165             if (pref != null) {
    166                 pref.setChecked(enabled.contains(id));
    167             }
    168         }
    169         mLastTickedInputMethodId = null;
    170 
    171         if (mLanguagePref != null) {
    172             Configuration conf = getResources().getConfiguration();
    173             String locale = conf.locale.getDisplayName(conf.locale);
    174             if (locale != null && locale.length() > 1) {
    175                 locale = Character.toUpperCase(locale.charAt(0)) + locale.substring(1);
    176                 mLanguagePref.setSummary(locale);
    177             }
    178         }
    179     }
    180 
    181     @Override
    182     protected void onPause() {
    183         super.onPause();
    184 
    185         StringBuilder builder = new StringBuilder(256);
    186         StringBuilder disabledSysImes = new StringBuilder(256);
    187 
    188         int firstEnabled = -1;
    189         int N = mInputMethodProperties.size();
    190         for (int i = 0; i < N; ++i) {
    191             final InputMethodInfo property = mInputMethodProperties.get(i);
    192             final String id = property.getId();
    193             CheckBoxPreference pref = (CheckBoxPreference) findPreference(id);
    194             boolean hasIt = id.equals(mLastInputMethodId);
    195             boolean systemIme = isSystemIme(property);
    196             if (((N == 1 || systemIme) && !mHaveHardKeyboard)
    197                     || (pref != null && pref.isChecked())) {
    198                 if (builder.length() > 0) builder.append(':');
    199                 builder.append(id);
    200                 if (firstEnabled < 0) {
    201                     firstEnabled = i;
    202                 }
    203             } else if (hasIt) {
    204                 mLastInputMethodId = mLastTickedInputMethodId;
    205             }
    206             // If it's a disabled system ime, add it to the disabled list so that it
    207             // doesn't get enabled automatically on any changes to the package list
    208             if (pref != null && !pref.isChecked() && systemIme && mHaveHardKeyboard) {
    209                 if (disabledSysImes.length() > 0) disabledSysImes.append(":");
    210                 disabledSysImes.append(id);
    211             }
    212         }
    213 
    214         // If the last input method is unset, set it as the first enabled one.
    215         if (null == mLastInputMethodId || "".equals(mLastInputMethodId)) {
    216             if (firstEnabled >= 0) {
    217                 mLastInputMethodId = mInputMethodProperties.get(firstEnabled).getId();
    218             } else {
    219                 mLastInputMethodId = null;
    220             }
    221         }
    222 
    223         Settings.Secure.putString(getContentResolver(),
    224             Settings.Secure.ENABLED_INPUT_METHODS, builder.toString());
    225         Settings.Secure.putString(getContentResolver(),
    226                 Settings.Secure.DISABLED_SYSTEM_INPUT_METHODS, disabledSysImes.toString());
    227         Settings.Secure.putString(getContentResolver(),
    228             Settings.Secure.DEFAULT_INPUT_METHOD,
    229             mLastInputMethodId != null ? mLastInputMethodId : "");
    230     }
    231 
    232     @Override
    233     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
    234 
    235         // Input Method stuff
    236         if (Utils.isMonkeyRunning()) {
    237             return false;
    238         }
    239 
    240         if (preference instanceof CheckBoxPreference) {
    241             final CheckBoxPreference chkPref = (CheckBoxPreference) preference;
    242             final String id = getInputMethodIdFromKey(chkPref.getKey());
    243             if (chkPref.isChecked()) {
    244                 InputMethodInfo selImi = null;
    245                 final int N = mInputMethodProperties.size();
    246                 for (int i=0; i<N; i++) {
    247                     InputMethodInfo imi = mInputMethodProperties.get(i);
    248                     if (id.equals(imi.getId())) {
    249                         selImi = imi;
    250                         if (isSystemIme(imi)) {
    251                             // This is a built-in IME, so no need to warn.
    252                             mLastTickedInputMethodId = id;
    253                             return super.onPreferenceTreeClick(preferenceScreen, preference);
    254                         }
    255                     }
    256                 }
    257                 chkPref.setChecked(false);
    258                 if (selImi == null) {
    259                     return super.onPreferenceTreeClick(preferenceScreen, preference);
    260                 }
    261                 AlertDialog d = (new AlertDialog.Builder(this))
    262                         .setTitle(android.R.string.dialog_alert_title)
    263                         .setIcon(android.R.drawable.ic_dialog_alert)
    264                         .setMessage(getString(R.string.ime_security_warning,
    265                                 selImi.getServiceInfo().applicationInfo.loadLabel(
    266                                         getPackageManager())))
    267                         .setCancelable(true)
    268                         .setPositiveButton(android.R.string.ok,
    269                                 new DialogInterface.OnClickListener() {
    270                                     public void onClick(DialogInterface dialog, int which) {
    271                                         chkPref.setChecked(true);
    272                                         mLastTickedInputMethodId = id;
    273                                     }
    274 
    275                         })
    276                         .setNegativeButton(android.R.string.cancel,
    277                                 new DialogInterface.OnClickListener() {
    278                                     public void onClick(DialogInterface dialog, int which) {
    279                                     }
    280 
    281                         })
    282                         .create();
    283                 d.show();
    284             } else if (id.equals(mLastTickedInputMethodId)) {
    285                 mLastTickedInputMethodId = null;
    286             }
    287         } else if (preference instanceof PreferenceScreen) {
    288             if (preference.getIntent() == null) {
    289                 PreferenceScreen pref = (PreferenceScreen) preference;
    290                 String activityName = pref.getKey();
    291                 String packageName = activityName.substring(0, activityName
    292                         .lastIndexOf("."));
    293                 int slash = activityName.indexOf("/");
    294                 if (slash > 0) {
    295                     packageName = activityName.substring(0, slash);
    296                     activityName = activityName.substring(slash + 1);
    297                 }
    298                 if (activityName.length() > 0) {
    299                     Intent i = new Intent(Intent.ACTION_MAIN);
    300                     i.setClassName(packageName, activityName);
    301                     startActivity(i);
    302                 }
    303             }
    304         }
    305         return super.onPreferenceTreeClick(preferenceScreen, preference);
    306     }
    307 
    308 }
    309