1/*
2 * Copyright (C) 2014 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.inputmethod.latin.settings;
18
19import android.Manifest;
20import android.app.Activity;
21import android.content.Context;
22import android.content.Intent;
23import android.content.SharedPreferences;
24import android.content.pm.PackageManager;
25import android.content.pm.ResolveInfo;
26import android.os.Build;
27import android.os.Bundle;
28import android.preference.Preference;
29import android.preference.SwitchPreference;
30import android.text.TextUtils;
31
32import com.android.inputmethod.dictionarypack.DictionarySettingsActivity;
33import com.android.inputmethod.latin.R;
34import com.android.inputmethod.latin.permissions.PermissionsManager;
35import com.android.inputmethod.latin.permissions.PermissionsUtil;
36import com.android.inputmethod.latin.userdictionary.UserDictionaryList;
37import com.android.inputmethod.latin.userdictionary.UserDictionarySettings;
38
39import java.util.TreeSet;
40
41/**
42 * "Text correction" settings sub screen.
43 *
44 * This settings sub screen handles the following text correction preferences.
45 * - Personal dictionary
46 * - Add-on dictionaries
47 * - Block offensive words
48 * - Auto-correction
49 * - Show correction suggestions
50 * - Personalized suggestions
51 * - Suggest Contact names
52 * - Next-word suggestions
53 */
54public final class CorrectionSettingsFragment extends SubScreenFragment
55    implements SharedPreferences.OnSharedPreferenceChangeListener,
56            PermissionsManager.PermissionsResultCallback {
57
58    private static final boolean DBG_USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS = false;
59    private static final boolean USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS =
60            DBG_USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS
61            || Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2;
62
63    private SwitchPreference mUseContactsPreference;
64
65    @Override
66    public void onCreate(final Bundle icicle) {
67        super.onCreate(icicle);
68        addPreferencesFromResource(R.xml.prefs_screen_correction);
69
70        final Context context = getActivity();
71        final PackageManager pm = context.getPackageManager();
72
73        final Preference dictionaryLink = findPreference(Settings.PREF_CONFIGURE_DICTIONARIES_KEY);
74        final Intent intent = dictionaryLink.getIntent();
75        intent.setClassName(context.getPackageName(), DictionarySettingsActivity.class.getName());
76        final int number = pm.queryIntentActivities(intent, 0).size();
77        if (0 >= number) {
78            removePreference(Settings.PREF_CONFIGURE_DICTIONARIES_KEY);
79        }
80
81        final Preference editPersonalDictionary =
82                findPreference(Settings.PREF_EDIT_PERSONAL_DICTIONARY);
83        final Intent editPersonalDictionaryIntent = editPersonalDictionary.getIntent();
84        final ResolveInfo ri = USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS ? null
85                : pm.resolveActivity(
86                        editPersonalDictionaryIntent, PackageManager.MATCH_DEFAULT_ONLY);
87        if (ri == null) {
88            overwriteUserDictionaryPreference(editPersonalDictionary);
89        }
90
91        mUseContactsPreference = (SwitchPreference) findPreference(Settings.PREF_KEY_USE_CONTACTS_DICT);
92        turnOffUseContactsIfNoPermission();
93    }
94
95    private void overwriteUserDictionaryPreference(final Preference userDictionaryPreference) {
96        final Activity activity = getActivity();
97        final TreeSet<String> localeList = UserDictionaryList.getUserDictionaryLocalesSet(activity);
98        if (null == localeList) {
99            // The locale list is null if and only if the user dictionary service is
100            // not present or disabled. In this case we need to remove the preference.
101            getPreferenceScreen().removePreference(userDictionaryPreference);
102        } else if (localeList.size() <= 1) {
103            userDictionaryPreference.setFragment(UserDictionarySettings.class.getName());
104            // If the size of localeList is 0, we don't set the locale parameter in the
105            // extras. This will be interpreted by the UserDictionarySettings class as
106            // meaning "the current locale".
107            // Note that with the current code for UserDictionaryList#getUserDictionaryLocalesSet()
108            // the locale list always has at least one element, since it always includes the current
109            // locale explicitly. @see UserDictionaryList.getUserDictionaryLocalesSet().
110            if (localeList.size() == 1) {
111                final String locale = (String)localeList.toArray()[0];
112                userDictionaryPreference.getExtras().putString("locale", locale);
113            }
114        } else {
115            userDictionaryPreference.setFragment(UserDictionaryList.class.getName());
116        }
117    }
118
119    @Override
120    public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
121        if (!TextUtils.equals(key, Settings.PREF_KEY_USE_CONTACTS_DICT)) {
122            return;
123        }
124        if (!sharedPreferences.getBoolean(key, false)) {
125            // don't care if the preference is turned off.
126            return;
127        }
128
129        // Check for permissions.
130        if (PermissionsUtil.checkAllPermissionsGranted(
131                getActivity() /* context */, Manifest.permission.READ_CONTACTS)) {
132            return; // all permissions granted, no need to request permissions.
133        }
134
135        PermissionsManager.get(getActivity() /* context */).requestPermissions(
136                this /* PermissionsResultCallback */,
137                getActivity() /* activity */,
138                Manifest.permission.READ_CONTACTS);
139    }
140
141    @Override
142    public void onRequestPermissionsResult(boolean allGranted) {
143        turnOffUseContactsIfNoPermission();
144    }
145
146    private void turnOffUseContactsIfNoPermission() {
147        if (!PermissionsUtil.checkAllPermissionsGranted(
148                getActivity(), Manifest.permission.READ_CONTACTS)) {
149            mUseContactsPreference.setChecked(false);
150        }
151    }
152}
153