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.content.Context;
24import android.content.DialogInterface;
25import android.content.pm.ApplicationInfo;
26import android.content.pm.PackageManager;
27import android.os.Bundle;
28import android.preference.Preference;
29import android.preference.PreferenceScreen;
30import android.util.Log;
31import android.view.textservice.SpellCheckerInfo;
32import android.view.textservice.TextServicesManager;
33
34import java.util.ArrayList;
35
36public class SpellCheckersSettings extends SettingsPreferenceFragment
37        implements Preference.OnPreferenceClickListener {
38    private static final String TAG = SpellCheckersSettings.class.getSimpleName();
39    private static final boolean DBG = false;
40
41    private AlertDialog mDialog = null;
42    private SpellCheckerInfo mCurrentSci;
43    private SpellCheckerInfo[] mEnabledScis;
44    private TextServicesManager mTsm;
45    private final ArrayList<SingleSpellCheckerPreference> mSpellCheckers =
46            new ArrayList<SingleSpellCheckerPreference>();
47
48    @Override
49    public void onCreate(Bundle icicle) {
50        super.onCreate(icicle);
51        mTsm = (TextServicesManager) getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE);
52        addPreferencesFromResource(R.xml.spellchecker_prefs);
53        updateScreen();
54    }
55
56    @Override
57    public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
58        return false;
59    }
60
61    @Override
62    public void onResume() {
63        super.onResume();
64        updateScreen();
65    }
66
67    @Override
68    public void onPause() {
69        super.onPause();
70        saveState();
71    }
72
73    private void saveState() {
74        SpellCheckerUtils.setCurrentSpellChecker(mTsm, mCurrentSci);
75    }
76
77    private void updateScreen() {
78        getPreferenceScreen().removeAll();
79        updateEnabledSpellCheckers();
80    }
81
82    private void updateEnabledSpellCheckers() {
83        final PackageManager pm = getPackageManager();
84        mCurrentSci = SpellCheckerUtils.getCurrentSpellChecker(mTsm);
85        mEnabledScis = SpellCheckerUtils.getEnabledSpellCheckers(mTsm);
86        if (mCurrentSci == null || mEnabledScis == null) {
87            return;
88        }
89        mSpellCheckers.clear();
90        for (int i = 0; i < mEnabledScis.length; ++i) {
91            final SpellCheckerInfo sci = mEnabledScis[i];
92            final SingleSpellCheckerPreference scPref = new SingleSpellCheckerPreference(
93                    this, null, sci, mTsm);
94            mSpellCheckers.add(scPref);
95            scPref.setTitle(sci.loadLabel(pm));
96            scPref.setSelected(mCurrentSci != null && mCurrentSci.getId().equals(sci.getId()));
97            getPreferenceScreen().addPreference(scPref);
98        }
99    }
100
101    @Override
102    public boolean onPreferenceClick(Preference pref) {
103        SingleSpellCheckerPreference targetScp = null;
104        for (SingleSpellCheckerPreference scp : mSpellCheckers) {
105            if (pref.equals(scp)) {
106                targetScp = scp;
107            }
108        }
109        if (targetScp != null) {
110            if (!isSystemApp(targetScp.getSpellCheckerInfo())) {
111                showSecurityWarnDialog(targetScp);
112            } else {
113                changeCurrentSpellChecker(targetScp);
114            }
115        }
116        return true;
117    }
118
119    private void showSecurityWarnDialog(final SingleSpellCheckerPreference scp) {
120        if (mDialog != null && mDialog.isShowing()) {
121            mDialog.dismiss();
122        }
123        mDialog = (new AlertDialog.Builder(getActivity()))
124                .setTitle(android.R.string.dialog_alert_title)
125                .setIconAttribute(android.R.attr.alertDialogIcon)
126                .setCancelable(true)
127                .setPositiveButton(android.R.string.ok,
128                        new DialogInterface.OnClickListener() {
129                    @Override
130                    public void onClick(DialogInterface dialog, int which) {
131                        changeCurrentSpellChecker(scp);
132                    }
133                })
134                .setNegativeButton(android.R.string.cancel,
135                        new DialogInterface.OnClickListener() {
136                    @Override
137                    public void onClick(DialogInterface dialog, int which) {
138                    }
139                })
140                .create();
141        mDialog.setMessage(getResources().getString(R.string.spellchecker_security_warning,
142                scp.getSpellCheckerInfo().getServiceInfo().applicationInfo.loadLabel(
143                        getActivity().getPackageManager())));
144        mDialog.show();
145    }
146
147    private void changeCurrentSpellChecker(SingleSpellCheckerPreference scp) {
148        mTsm.setCurrentSpellChecker(scp.getSpellCheckerInfo());
149        if (DBG) {
150            Log.d(TAG, "Current spell check is "
151                        + SpellCheckerUtils.getCurrentSpellChecker(mTsm).getId());
152        }
153        updateScreen();
154    }
155
156    private static boolean isSystemApp(SpellCheckerInfo sci) {
157        return (sci.getServiceInfo().applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
158    }
159}
160