SubtypeSwitcher.java revision 3b776b78924610da2874f3ac555ed5d91a550843
1/*
2 * Copyright (C) 2010 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;
18
19import com.android.inputmethod.voice.SettingsUtil;
20
21import android.content.SharedPreferences;
22import android.content.res.Configuration;
23import android.content.res.Resources;
24import android.inputmethodservice.InputMethodService;
25import android.preference.PreferenceManager;
26import android.text.TextUtils;
27import android.view.inputmethod.InputMethodSubtype;
28
29import java.util.Arrays;
30import java.util.List;
31import java.util.Locale;
32
33public class SubtypeSwitcher {
34    // This flag indicates if we support language switching by swipe on space bar.
35    // We may or may not draw the current language on space bar regardless of this flag.
36    public static final boolean USE_SPACEBAR_LANGUAGE_SWITCHER = true;
37    private static final String TAG = "SubtypeSwitcher";
38    private static final SubtypeSwitcher sInstance = new SubtypeSwitcher();
39    private InputMethodService mService;
40    private Resources mResources;
41    private Locale mSystemLocale;
42
43    public static SubtypeSwitcher getInstance() {
44        return sInstance;
45    }
46
47    public static void init(LatinIME service) {
48        sInstance.mService = service;
49        sInstance.mResources = service.getResources();
50        sInstance.mSystemLocale = sInstance.mResources.getConfiguration().locale;
51        if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
52            sInstance.initLanguageSwitcher(service);
53        }
54    }
55
56    private SubtypeSwitcher() {
57    }
58
59    public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) {
60    }
61
62    //////////////////////////////////
63    // Language Switching functions //
64    //////////////////////////////////
65
66    public int getEnabledKeyboardLocaleCount() {
67        if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
68            return mLanguageSwitcher.getLocaleCount();
69        }
70        // TODO: Implement for no legacy mode
71        return 0;
72    }
73
74    // TODO: Cache the value
75    public boolean needsToDisplayLanguage() {
76     // TODO: Takes care of two-char locale such as "en" in addition to "en_US"
77        return !(getEnabledKeyboardLocaleCount() == 1 && getSystemLocale().getLanguage(
78                ).equalsIgnoreCase(getInputLocale().getLanguage()));
79    }
80
81    public Locale getInputLocale() {
82        if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
83            return mLanguageSwitcher.getInputLocale();
84        }
85        // TODO: Implement for no legacy mode
86        return null;
87    }
88
89    public String getInputLanguage() {
90        String inputLanguage = null;
91        if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
92            inputLanguage = mLanguageSwitcher.getInputLanguage();
93        }
94        // Should return system locale if there is no Language available.
95        if (inputLanguage == null) {
96            inputLanguage = getSystemLocale().getLanguage();
97        }
98        return inputLanguage;
99    }
100
101    public String[] getEnabledLanguages() {
102        if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
103            return mLanguageSwitcher.getEnabledLanguages();
104        }
105        // TODO: Implement for no legacy mode
106        return null;
107    }
108
109    public Locale getSystemLocale() {
110        return mSystemLocale;
111    }
112
113    // TODO: Cache the value for faster processing.
114    public boolean isSystemLocaleSameAsInputLocale() {
115        // TODO: Takes care of two-char locale such as "en" in addition to "en_US"
116        return getSystemLocale().getLanguage().equalsIgnoreCase(
117                getInputLanguage().substring(0, 2));
118    }
119
120    public void onConfigurationChanged(Configuration conf) {
121        if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
122            // If the system locale changes and is different from the saved
123            // locale (mSystemLocale), then reload the input locale list from the
124            // latin ime settings (shared prefs) and reset the input locale
125            // to the first one.
126            final Locale systemLocale = conf.locale;
127            if (!TextUtils.equals(systemLocale.toString(), mSystemLocale.toString())) {
128                mSystemLocale = systemLocale;
129                mLanguageSwitcher.loadLocales(
130                        PreferenceManager.getDefaultSharedPreferences(mService));
131                mLanguageSwitcher.setSystemLocale(systemLocale);
132                toggleLanguage(true, true);
133            }
134            return;
135        }
136    }
137
138    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
139        if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
140            mLanguageSwitcher.loadLocales(sharedPreferences);
141            return;
142        }
143    }
144
145    public Locale changeSystemLocale(Locale newLocale) {
146        Configuration conf = mResources.getConfiguration();
147        Locale oldLocale = conf.locale;
148        conf.locale = newLocale;
149        mResources.updateConfiguration(conf, mResources.getDisplayMetrics());
150        return oldLocale;
151    }
152
153    ////////////////////////////////////////////
154    // Legacy Language Switch support //
155    ////////////////////////////////////////////
156    private LanguageSwitcher mLanguageSwitcher;
157
158    public static String getLanguageName(Locale locale) {
159        return toTitleCase(locale.getDisplayLanguage(locale));
160    }
161
162    public static String getShortLanguageName(Locale locale) {
163        return toTitleCase(locale.getLanguage());
164    }
165
166    private static String toTitleCase(String s) {
167        if (s.length() == 0) {
168            return s;
169        }
170        return Character.toUpperCase(s.charAt(0)) + s.substring(1);
171    }
172
173    public String getInputLanguageName() {
174        return getLanguageName(getInputLocale());
175    }
176
177    public String getNextInputLanguageName() {
178        if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
179            return getLanguageName(mLanguageSwitcher.getNextInputLocale());
180        }
181        return "";
182    }
183
184    public String getPreviousInputLanguageName() {
185        if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
186            return getLanguageName(mLanguageSwitcher.getPrevInputLocale());
187        }
188        return "";
189    }
190
191    // TODO: This can be an array of String
192    // A list of locales which are supported by default for voice input, unless we get a
193    // different list from Gservices.
194    private static final String DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES =
195            "en " +
196            "en_US " +
197            "en_GB " +
198            "en_AU " +
199            "en_CA " +
200            "en_IE " +
201            "en_IN " +
202            "en_NZ " +
203            "en_SG " +
204            "en_ZA ";
205
206    public boolean isVoiceSupported(String locale) {
207        // Get the current list of supported locales and check the current locale against that
208        // list. We cache this value so as not to check it every time the user starts a voice
209        // input. Because this method is called by onStartInputView, this should mean that as
210        // long as the locale doesn't change while the user is keeping the IME open, the
211        // value should never be stale.
212        String supportedLocalesString = SettingsUtil.getSettingsString(
213                mService.getContentResolver(),
214                SettingsUtil.LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES,
215                DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES);
216        List<String> voiceInputSupportedLocales = Arrays.asList(
217                supportedLocalesString.split("\\s+"));
218        return voiceInputSupportedLocales.contains(locale);
219    }
220
221    public void loadSettings(SharedPreferences prefs) {
222        if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
223            mLanguageSwitcher.loadLocales(prefs);
224        }
225    }
226
227    public void toggleLanguage(boolean reset, boolean next) {
228        if (reset) {
229            mLanguageSwitcher.reset();
230        } else {
231            if (next) {
232                mLanguageSwitcher.next();
233            } else {
234                mLanguageSwitcher.prev();
235            }
236        }
237        mLanguageSwitcher.persist();
238    }
239
240    private void initLanguageSwitcher(LatinIME service) {
241        final Configuration conf = service.getResources().getConfiguration();
242        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(service);
243        mLanguageSwitcher = new LanguageSwitcher(service);
244        mLanguageSwitcher.loadLocales(prefs);
245        mLanguageSwitcher.setSystemLocale(conf.locale);
246    }
247}