PageRenderTime 35ms CodeModel.GetById 10ms app.highlight 20ms RepoModel.GetById 2ms app.codeStats 0ms

/ime/latinime/src/com/googlecode/eyesfree/inputmethod/latin/LatinIMESettings.java

http://eyes-free.googlecode.com/
Java | 352 lines | 269 code | 42 blank | 41 comment | 29 complexity | f0be6b8e8edbf5299c3b8056550fab62 MD5 | raw file
  1/*
  2 * Copyright (C) 2008 The Android Open Source Project
  3 *
  4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5 * use this file except in compliance with the License. You may obtain a copy of
  6 * 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, WITHOUT
 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 13 * License for the specific language governing permissions and limitations under
 14 * the License.
 15 */
 16
 17package com.googlecode.eyesfree.inputmethod.latin;
 18
 19import android.app.AlertDialog;
 20import android.app.Dialog;
 21import android.app.backup.BackupManager;
 22import android.content.DialogInterface;
 23import android.content.Intent;
 24import android.content.SharedPreferences;
 25import android.net.Uri;
 26import android.os.Build;
 27import android.os.Bundle;
 28import android.os.Vibrator;
 29import android.preference.CheckBoxPreference;
 30import android.preference.ListPreference;
 31import android.preference.Preference;
 32import android.preference.Preference.OnPreferenceClickListener;
 33import android.preference.PreferenceActivity;
 34import android.preference.PreferenceGroup;
 35import android.provider.Settings;
 36import android.speech.SpeechRecognizer;
 37import android.text.AutoText;
 38import android.util.Log;
 39
 40import com.googlecode.eyesfree.inputmethod.voice.SettingsUtil;
 41import com.googlecode.eyesfree.inputmethod.voice.VoiceInputLogger;
 42import com.googlecode.eyesfree.utils.PackageManagerUtils;
 43
 44import java.lang.reflect.InvocationTargetException;
 45import java.lang.reflect.Method;
 46import java.util.ArrayList;
 47import java.util.Locale;
 48
 49public class LatinIMESettings extends PreferenceActivity implements
 50        SharedPreferences.OnSharedPreferenceChangeListener, DialogInterface.OnDismissListener {
 51    /** The package that provides the Linear Navigation service. */
 52    public static final String LINEAR_NAVIGATION_PACKAGE =
 53            "com.googlecode.eyesfree.linearnavigation";
 54
 55    /** The URI string for launching the App Market. */
 56    private static final String MARKET_URI = "market://details?id=";
 57
 58    /** Request code for accessibility settings activity. */
 59    private static final int REQUEST_ACCESSIBILITY_SETTINGS = 1;
 60
 61    /** Request code for Market install activity. */
 62    private static final int REQUEST_MARKET_INSTALL = 2;
 63    
 64    /** Preference ordering for Linear Navigation setting. */
 65    private static final int LINEAR_NAVIGATION_ORDER = 7;
 66
 67    private static final String VIBRATE_ON_KEY = "vibrate_on";
 68    private static final String QUICK_FIXES_KEY = "quick_fixes";
 69    private static final String PREDICTION_SETTINGS_KEY = "prediction_settings";
 70    private static final String VOICE_SETTINGS_KEY = "voice_mode";
 71    /* package */static final String PREF_DPAD_KEYS = "dpad_keys";
 72
 73    private static final String TAG = "LatinIMESettings";
 74
 75    // Dialog ids
 76    private static final int VOICE_INPUT_CONFIRM_DIALOG = 0;
 77
 78    private CheckBoxPreference mHapticPreference;
 79    private CheckBoxPreference mQuickFixes;
 80    private ListPreference mVoicePreference;
 81    private boolean mVoiceOn;
 82
 83    private Vibrator mVibrator;
 84    private VoiceInputLogger mLogger;
 85
 86    private boolean mOkClicked = false;
 87    private String mVoiceModeOff;
 88
 89    @Override
 90    protected void onCreate(Bundle icicle) {
 91        super.onCreate(icicle);
 92        addPreferencesFromResource(R.xml.prefs);
 93        mHapticPreference = (CheckBoxPreference) findPreference(VIBRATE_ON_KEY);
 94        mQuickFixes = (CheckBoxPreference) findPreference(QUICK_FIXES_KEY);
 95        mVoicePreference = (ListPreference) findPreference(VOICE_SETTINGS_KEY);
 96        SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
 97        prefs.registerOnSharedPreferenceChangeListener(this);
 98
 99        mVoiceModeOff = getString(R.string.voice_mode_off);
100        mVoiceOn = !(prefs.getString(VOICE_SETTINGS_KEY, mVoiceModeOff).equals(mVoiceModeOff));
101        mLogger = VoiceInputLogger.getLogger(this);
102        mVibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
103
104        updateLinearNavigationPreference();
105        updateHapticPreferenceVisibility();
106    }
107
108    @Override
109    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
110        switch (requestCode) {
111            case REQUEST_ACCESSIBILITY_SETTINGS:
112            case REQUEST_MARKET_INSTALL:
113                updateLinearNavigationPreference();
114                break;
115        }
116        super.onActivityResult(requestCode, resultCode, data);
117    }
118
119    @Override
120    protected void onResume() {
121        super.onResume();
122        int autoTextSize = AutoText.getSize(getListView());
123        if (autoTextSize < 1) {
124            ((PreferenceGroup) findPreference(PREDICTION_SETTINGS_KEY))
125                    .removePreference(mQuickFixes);
126        }
127        if (!LatinIME.VOICE_INSTALLED || !SpeechRecognizer.isRecognitionAvailable(this)) {
128            getPreferenceScreen().removePreference(mVoicePreference);
129        } else {
130            updateVoiceModeSummary();
131        }
132    }
133
134    @Override
135    protected void onDestroy() {
136        getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(
137                this);
138        super.onDestroy();
139    }
140
141    /**
142     * Returns <code>true</code> if this Android build supports
143     * {@link BackupManager}.
144     * 
145     * @return <code>true</code> if this Android build supports
146     *         {@link BackupManager}
147     */
148    private static boolean supportsBackupManager() {
149        return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO);
150    }
151
152    @Override
153    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
154        if (supportsBackupManager()) {
155            (new BackupManager(this)).dataChanged();
156        }
157        // If turning on voice input, show dialog
158        if (key.equals(VOICE_SETTINGS_KEY) && !mVoiceOn) {
159            if (!prefs.getString(VOICE_SETTINGS_KEY, mVoiceModeOff).equals(mVoiceModeOff)) {
160                showVoiceConfirmation();
161            }
162        }
163        mVoiceOn = !(prefs.getString(VOICE_SETTINGS_KEY, mVoiceModeOff).equals(mVoiceModeOff));
164        updateVoiceModeSummary();
165    }
166
167    private void updateHapticPreferenceVisibility() {
168        if (Build.VERSION.SDK_INT < 11) {
169            return;
170        }
171
172        try {
173            Method hasVibrator = mVibrator.getClass().getMethod("hasVibrator");
174            Object result = hasVibrator.invoke(mVibrator);
175            if (result.equals(Boolean.FALSE)) {
176                getPreferenceScreen().removePreference(mHapticPreference);
177            }
178        } catch (SecurityException e) {
179            e.printStackTrace();
180        } catch (NoSuchMethodException e) {
181            e.printStackTrace();
182        } catch (IllegalArgumentException e) {
183            e.printStackTrace();
184        } catch (IllegalAccessException e) {
185            e.printStackTrace();
186        } catch (InvocationTargetException e) {
187            e.printStackTrace();
188        }
189    }
190
191    /**
192     * Disables the "Linear navigation" preference, if applicable.
193     */
194    private void updateLinearNavigationPreference() {
195        final Preference existingPreference = findPreference("linear_navigation");
196        
197        if (existingPreference != null) {
198            getPreferenceScreen().removePreference(existingPreference);
199        }
200
201        final boolean serviceSupported = Build.VERSION.SDK_INT >= 14;
202
203        if (!serviceSupported) {
204            return;
205        }
206
207        final boolean serviceInstalled =
208                PackageManagerUtils.hasPackage(this, LINEAR_NAVIGATION_PACKAGE);
209
210        if (!serviceInstalled) {
211            final Preference installPreference = new Preference(this);
212            installPreference.setKey("linear_navigation");
213            installPreference.setTitle(R.string.linear_navigation);
214            installPreference.setSummary(R.string.linear_navigation_missing);
215            installPreference.setOrder(LINEAR_NAVIGATION_ORDER);
216            installPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
217                @Override
218                public boolean onPreferenceClick(Preference preference) {
219                    final Intent intent =
220                            new Intent(Intent.ACTION_VIEW, Uri.parse(MARKET_URI
221                                    + LINEAR_NAVIGATION_PACKAGE));
222                    startActivityForResult(intent, REQUEST_ACCESSIBILITY_SETTINGS);
223                    return true;
224                }
225            });
226            getPreferenceScreen().addPreference(installPreference);
227            return;
228        }
229
230        final String enabledServices =
231                Settings.Secure.getString(getContentResolver(),
232                        Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
233        final boolean serviceEnabled =
234                (enabledServices != null) && enabledServices.contains(LINEAR_NAVIGATION_PACKAGE);
235
236        if (!serviceEnabled) {
237            final Preference enablePreference = new Preference(this);
238            enablePreference.setKey("linear_navigation");
239            enablePreference.setTitle(R.string.linear_navigation);
240            enablePreference.setSummary(R.string.linear_navigation_disabled);
241            enablePreference.setOrder(LINEAR_NAVIGATION_ORDER);
242            enablePreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
243                @Override
244                public boolean onPreferenceClick(Preference preference) {
245                    final Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
246                    startActivityForResult(intent, REQUEST_ACCESSIBILITY_SETTINGS);
247                    return true;
248                }
249            });
250            getPreferenceScreen().addPreference(enablePreference);
251            return;
252        }
253
254        final CheckBoxPreference defaultPreference = new CheckBoxPreference(this);
255        defaultPreference.setKey("linear_navigation");
256        defaultPreference.setTitle(R.string.linear_navigation);
257        defaultPreference.setSummary(R.string.linear_navigation_summary);
258        defaultPreference.setOrder(LINEAR_NAVIGATION_ORDER);
259        getPreferenceScreen().addPreference(defaultPreference);
260    }
261
262    private void showVoiceConfirmation() {
263        mOkClicked = false;
264        showDialog(VOICE_INPUT_CONFIRM_DIALOG);
265    }
266
267    private void updateVoiceModeSummary() {
268        mVoicePreference.setSummary(getResources()
269                .getStringArray(R.array.voice_input_modes_summary)[mVoicePreference
270                .findIndexOfValue(mVoicePreference.getValue())]);
271    }
272
273    @Override
274    protected Dialog onCreateDialog(int id) {
275        switch (id) {
276            case VOICE_INPUT_CONFIRM_DIALOG:
277                DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
278                    @Override
279                    public void onClick(DialogInterface dialog, int whichButton) {
280                        if (whichButton == DialogInterface.BUTTON_NEGATIVE) {
281                            mVoicePreference.setValue(mVoiceModeOff);
282                            mLogger.settingsWarningDialogCancel();
283                        } else if (whichButton == DialogInterface.BUTTON_POSITIVE) {
284                            mOkClicked = true;
285                            mLogger.settingsWarningDialogOk();
286                        }
287                        updateVoicePreference();
288                    }
289                };
290                AlertDialog.Builder builder =
291                        new AlertDialog.Builder(this).setTitle(R.string.voice_warning_title)
292                                .setPositiveButton(android.R.string.ok, listener)
293                                .setNegativeButton(android.R.string.cancel, listener);
294
295                // Get the current list of supported locales and check the
296                // current locale against
297                // that list, to decide whether to put a warning that voice
298                // input will not work in
299                // the current language as part of the pop-up confirmation
300                // dialog.
301                String supportedLocalesString =
302                        SettingsUtil.getSettingsString(getContentResolver(),
303                                SettingsUtil.LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES,
304                                LatinIME.DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES);
305                ArrayList<String> voiceInputSupportedLocales =
306                        LatinIME.newArrayList(supportedLocalesString.split("\\s+"));
307                boolean localeSupported =
308                        voiceInputSupportedLocales.contains(Locale.getDefault().toString());
309
310                if (localeSupported) {
311                    String message =
312                            getString(R.string.voice_warning_may_not_understand) + "\n\n"
313                                    + getString(R.string.voice_hint_dialog_message);
314                    builder.setMessage(message);
315                } else {
316                    String message =
317                            getString(R.string.voice_warning_locale_not_supported) + "\n\n"
318                                    + getString(R.string.voice_warning_may_not_understand) + "\n\n"
319                                    + getString(R.string.voice_hint_dialog_message);
320                    builder.setMessage(message);
321                }
322
323                AlertDialog dialog = builder.create();
324                dialog.setOnDismissListener(this);
325                mLogger.settingsWarningDialogShown();
326                return dialog;
327            default:
328                Log.e(TAG, "unknown dialog " + id);
329                return null;
330        }
331    }
332
333    @Override
334    public void onDismiss(DialogInterface dialog) {
335        mLogger.settingsWarningDialogDismissed();
336        if (!mOkClicked) {
337            // This assumes that onPreferenceClick gets called first, and this
338            // if the user
339            // agreed after the warning, we set the mOkClicked value to true.
340            mVoicePreference.setValue(mVoiceModeOff);
341        }
342    }
343
344    private void updateVoicePreference() {
345        boolean isChecked = !mVoicePreference.getValue().equals(mVoiceModeOff);
346        if (isChecked) {
347            mLogger.voiceInputSettingEnabled();
348        } else {
349            mLogger.voiceInputSettingDisabled();
350        }
351    }
352}