Check the availability of layouts for showing the input languages in the settings

Bug: 4316889

Change-Id: I746b3ff79c2a6cd4925fca1817d5b209623b5108
diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml
index e0eecfc..2fbf4c2 100644
--- a/java/AndroidManifest.xml
+++ b/java/AndroidManifest.xml
@@ -33,7 +33,7 @@
             </intent-filter>
         </activity>
 
-        <activity android:name="InputLanguageSelection"
+        <activity android:name="com.android.inputmethod.deprecated.languageswitcher.InputLanguageSelection"
                 android:label="@string/language_selection_title">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 9b38139..e88b007 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -91,6 +91,8 @@
         <attr name="verticalGap" format="dimension|fraction" />
         <!-- Popup keyboard layout template -->
         <attr name="popupKeyboardTemplate" format="reference" />
+        <!-- Locale of the keyboard layout -->
+        <attr name="keyboardLocale" format="string" />
     </declare-styleable>
 
     <declare-styleable name="Keyboard_Key">
diff --git a/java/res/xml-ar/kbd_qwerty.xml b/java/res/xml-ar/kbd_qwerty.xml
index 4c6a4f5..5faf603 100644
--- a/java/res/xml-ar/kbd_qwerty.xml
+++ b/java/res/xml-ar/kbd_qwerty.xml
@@ -28,6 +28,7 @@
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
     latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+    latin:keyboardLocale="ar"
 >
     <include
         latin:keyboardLayout="@xml/kbd_ar_rows" />
diff --git a/java/res/xml-cs/kbd_qwerty.xml b/java/res/xml-cs/kbd_qwerty.xml
index 010bdb3..0e6e40d 100644
--- a/java/res/xml-cs/kbd_qwerty.xml
+++ b/java/res/xml-cs/kbd_qwerty.xml
@@ -28,6 +28,7 @@
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
     latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+    latin:keyboardLocale="cs"
 >
     <include
         latin:keyboardLayout="@xml/kbd_qwertz_rows" />
diff --git a/java/res/xml-da/kbd_qwerty.xml b/java/res/xml-da/kbd_qwerty.xml
index 441b7cb..d9847ae 100644
--- a/java/res/xml-da/kbd_qwerty.xml
+++ b/java/res/xml-da/kbd_qwerty.xml
@@ -27,6 +27,7 @@
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
     latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+    latin:keyboardLocale="da"
 >
     <include
         latin:keyboardLayout="@xml/kbd_qwerty_rows_scandinavia" />
diff --git a/java/res/xml-de/kbd_qwerty.xml b/java/res/xml-de/kbd_qwerty.xml
index a23e4fb..6b5c223 100644
--- a/java/res/xml-de/kbd_qwerty.xml
+++ b/java/res/xml-de/kbd_qwerty.xml
@@ -28,6 +28,7 @@
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
     latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+    latin:keyboardLocale="de"
 >
     <include
         latin:keyboardLayout="@xml/kbd_qwertz_rows" />
diff --git a/java/res/xml-fi/kbd_qwerty.xml b/java/res/xml-fi/kbd_qwerty.xml
index b0a7b3e..ea08d67 100644
--- a/java/res/xml-fi/kbd_qwerty.xml
+++ b/java/res/xml-fi/kbd_qwerty.xml
@@ -27,6 +27,7 @@
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
     latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+    latin:keyboardLocale="fi"
 >
     <include
         latin:keyboardLayout="@xml/kbd_qwerty_rows_scandinavia" />
diff --git a/java/res/xml-fr-rCA/kbd_qwerty.xml b/java/res/xml-fr-rCA/kbd_qwerty.xml
index 92d92f0..f9c2969 100644
--- a/java/res/xml-fr-rCA/kbd_qwerty.xml
+++ b/java/res/xml-fr-rCA/kbd_qwerty.xml
@@ -28,6 +28,7 @@
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
     latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+    latin:keyboardLocale="fr_CA"
 >
     <include
         latin:keyboardLayout="@xml/kbd_qwerty_rows" />
diff --git a/java/res/xml-fr-rCH/kbd_qwerty.xml b/java/res/xml-fr-rCH/kbd_qwerty.xml
index a23e4fb..e47cfd9 100644
--- a/java/res/xml-fr-rCH/kbd_qwerty.xml
+++ b/java/res/xml-fr-rCH/kbd_qwerty.xml
@@ -28,6 +28,7 @@
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
     latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+    latin:keyboardLocale="fr_CH"
 >
     <include
         latin:keyboardLayout="@xml/kbd_qwertz_rows" />
diff --git a/java/res/xml-fr/kbd_qwerty.xml b/java/res/xml-fr/kbd_qwerty.xml
index 2d0b42b..e4b73bf 100644
--- a/java/res/xml-fr/kbd_qwerty.xml
+++ b/java/res/xml-fr/kbd_qwerty.xml
@@ -28,6 +28,7 @@
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
     latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+    latin:keyboardLocale="fr"
 >
     <include
         latin:keyboardLayout="@xml/kbd_azerty_rows" />
diff --git a/java/res/xml-hu/kbd_qwerty.xml b/java/res/xml-hu/kbd_qwerty.xml
index 010bdb3..db729cf 100644
--- a/java/res/xml-hu/kbd_qwerty.xml
+++ b/java/res/xml-hu/kbd_qwerty.xml
@@ -28,6 +28,7 @@
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
     latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+    latin:keyboardLocale="hu"
 >
     <include
         latin:keyboardLayout="@xml/kbd_qwertz_rows" />
diff --git a/java/res/xml-iw/kbd_qwerty.xml b/java/res/xml-iw/kbd_qwerty.xml
index 72826d4..4cd565b 100644
--- a/java/res/xml-iw/kbd_qwerty.xml
+++ b/java/res/xml-iw/kbd_qwerty.xml
@@ -28,6 +28,7 @@
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
     latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+    latin:keyboardLocale="iw"
 >
     <include
         latin:keyboardLayout="@xml/kbd_iw_rows" />
diff --git a/java/res/xml-nb/kbd_qwerty.xml b/java/res/xml-nb/kbd_qwerty.xml
index 441b7cb..7b20ca2 100644
--- a/java/res/xml-nb/kbd_qwerty.xml
+++ b/java/res/xml-nb/kbd_qwerty.xml
@@ -27,6 +27,7 @@
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
     latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+    latin:keyboardLocale="nb"
 >
     <include
         latin:keyboardLayout="@xml/kbd_qwerty_rows_scandinavia" />
diff --git a/java/res/xml-ru/kbd_qwerty.xml b/java/res/xml-ru/kbd_qwerty.xml
index 0eb3115..065cf3a 100644
--- a/java/res/xml-ru/kbd_qwerty.xml
+++ b/java/res/xml-ru/kbd_qwerty.xml
@@ -27,6 +27,7 @@
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
     latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+    latin:keyboardLocale="ru"
 >
     <include
         latin:keyboardLayout="@xml/kbd_ru_rows" />
diff --git a/java/res/xml-sr/kbd_qwerty.xml b/java/res/xml-sr/kbd_qwerty.xml
index 3995e4e..9782cd5 100644
--- a/java/res/xml-sr/kbd_qwerty.xml
+++ b/java/res/xml-sr/kbd_qwerty.xml
@@ -27,6 +27,7 @@
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
     latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+    latin:keyboardLocale="sr"
 >
     <include
         latin:keyboardLayout="@xml/kbd_sr_rows" />
diff --git a/java/res/xml-sv/kbd_qwerty.xml b/java/res/xml-sv/kbd_qwerty.xml
index 72bdc33..3ff1679 100644
--- a/java/res/xml-sv/kbd_qwerty.xml
+++ b/java/res/xml-sv/kbd_qwerty.xml
@@ -27,6 +27,7 @@
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
     latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+    latin:keyboardLocale="sv"
 >
     <include
         latin:keyboardLayout="@xml/kbd_qwerty_rows_scandinavia" />
diff --git a/java/res/xml-xlarge/kbd_qwerty.xml b/java/res/xml-xlarge/kbd_qwerty.xml
deleted file mode 100644
index 1c8d51f..0000000
--- a/java/res/xml-xlarge/kbd_qwerty.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2010, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<Keyboard
-    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
-    latin:rowHeight="25%p"
-    latin:horizontalGap="@dimen/key_horizontal_gap"
-    latin:verticalGap="@dimen/key_bottom_gap"
-    latin:popupKeyboardTemplate="@xml/kbd_popup_template"
-    latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
->
-    <include
-        latin:keyboardLayout="@xml/kbd_qwerty_rows" />
-</Keyboard>
diff --git a/java/res/xml/kbd_qwerty.xml b/java/res/xml/kbd_qwerty.xml
index 92d92f0..6bf6b78 100644
--- a/java/res/xml/kbd_qwerty.xml
+++ b/java/res/xml/kbd_qwerty.xml
@@ -28,6 +28,7 @@
     latin:verticalGap="@dimen/key_bottom_gap"
     latin:popupKeyboardTemplate="@xml/kbd_popup_template"
     latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+    latin:keyboardLocale="en"
 >
     <include
         latin:keyboardLayout="@xml/kbd_qwerty_rows" />
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index cbfc3c3..fb7b0ea 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -64,6 +64,13 @@
             android:key="subtype_settings"
             android:title="@string/language_selection_title"
             android:summary="@string/language_selection_summary" />
+        <PreferenceScreen
+            android:key="language_selection"
+            android:title="@string/language_selection_title"
+            android:summary="@string/language_selection_summary">
+            <intent
+                    android:action="com.android.inputmethod.latin.INPUT_LANGUAGE_SELECTION"/>
+        </PreferenceScreen>
     </PreferenceCategory>
     <PreferenceCategory
         android:title="@string/prediction_category"
diff --git a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
similarity index 81%
rename from java/src/com/android/inputmethod/latin/InputLanguageSelection.java
rename to java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
index 40ab28c..9ad64f8 100644
--- a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java
+++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
@@ -1,12 +1,12 @@
 /*
  * Copyright (C) 2008-2009 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -14,7 +14,18 @@
  * the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.deprecated.languageswitcher;
+
+import com.android.inputmethod.keyboard.KeyboardParser;
+import com.android.inputmethod.latin.BinaryDictionary;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.Settings;
+import com.android.inputmethod.latin.SharedPreferencesCompat;
+import com.android.inputmethod.latin.SubtypeSwitcher;
+import com.android.inputmethod.latin.Suggest;
+import com.android.inputmethod.latin.Utils;
+
+import org.xmlpull.v1.XmlPullParserException;
 
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
@@ -27,6 +38,7 @@
 import android.preference.PreferenceManager;
 import android.text.TextUtils;
 
+import java.io.IOException;
 import java.text.Collator;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -37,9 +49,6 @@
     private SharedPreferences mPrefs;
     private String mSelectedLanguages;
     private ArrayList<Loc> mAvailableLanguages = new ArrayList<Loc>();
-    private static final String[] BLACKLIST_LANGUAGES = {
-        "ko", "ja", "zh", "el", "zz"
-    };
 
     private static class Loc implements Comparable<Object> {
         private static Collator sCollator = Collator.getInstance();
@@ -78,8 +87,11 @@
         mAvailableLanguages = getUniqueLocales();
         PreferenceGroup parent = getPreferenceScreen();
         for (int i = 0; i < mAvailableLanguages.size(); i++) {
-            CheckBoxPreference pref = new CheckBoxPreference(this);
             Locale locale = mAvailableLanguages.get(i).mLocale;
+            if (!hasDictionary(locale) && !hasLayout(locale)) {
+                continue;
+            }
+            CheckBoxPreference pref = new CheckBoxPreference(this);
             pref.setTitle(SubtypeSwitcher.getFullDisplayName(locale, true));
             boolean checked = isLocaleIn(locale, languageList);
             pref.setChecked(checked);
@@ -120,6 +132,32 @@
         return haveDictionary;
     }
 
+    private boolean hasLayout(Locale locale) {
+        if (locale == null) return false;
+        final Resources res = getResources();
+        final Configuration conf = res.getConfiguration();
+        final Locale saveLocale = conf.locale;
+        conf.locale = locale;
+        res.updateConfiguration(conf, res.getDisplayMetrics());
+
+        try {
+            final String countryCode = locale.getLanguage();
+            final String layoutCountryCode = KeyboardParser.parseKeyboardLocale(
+                    this, R.xml.kbd_qwerty);
+            if (!TextUtils.isEmpty(countryCode) && !TextUtils.isEmpty(layoutCountryCode)) {
+                return countryCode.subSequence(0, 2).equals(layoutCountryCode.substring(0, 2));
+            }
+            return false;
+        } catch (XmlPullParserException e) {
+            return false;
+        } catch (IOException e) {
+            return false;
+        } finally {
+            conf.locale = saveLocale;
+            res.updateConfiguration(conf, res.getDisplayMetrics());
+        }
+    }
+
     private String get5Code(Locale locale) {
         String country = locale.getCountry();
         return locale.getLanguage()
@@ -173,7 +211,7 @@
             Locale l = new Locale(language, country);
 
             // Exclude languages that are not relevant to LatinIME
-            if (arrayContains(BLACKLIST_LANGUAGES, language) || TextUtils.isEmpty(language)) {
+            if (TextUtils.isEmpty(language)) {
                 continue;
             }
 
@@ -207,11 +245,4 @@
         }
         return uniqueLocales;
     }
-
-    private boolean arrayContains(String[] array, String value) {
-        for (int i = 0; i < array.length; i++) {
-            if (array[i].equalsIgnoreCase(value)) return true;
-        }
-        return false;
-    }
 }
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
index 9c556c3..69ae788 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
@@ -22,6 +22,7 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
+import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
@@ -163,6 +164,27 @@
         }
     }
 
+    public static String parseKeyboardLocale(
+            Context context, int resId) throws XmlPullParserException, IOException {
+        final Resources res = context.getResources();
+        final XmlResourceParser parser = res.getXml(resId);
+        if (parser == null) return "";
+        int event;
+        while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
+            if (event == XmlPullParser.START_TAG) {
+                final String tag = parser.getName();
+                if (TAG_KEYBOARD.equals(tag)) {
+                    final TypedArray keyboardAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
+                            R.styleable.Keyboard);
+                    return keyboardAttr.getString(R.styleable.Keyboard_keyboardLocale);
+                } else {
+                    throw new IllegalStartTag(parser, TAG_KEYBOARD);
+                }
+            }
+        }
+        return "";
+    }
+
     private void parseKeyboardAttributes(XmlResourceParser parser) {
         final Keyboard keyboard = mKeyboard;
         final TypedArray keyboardAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 8f7278e..1725ee7 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -18,6 +18,7 @@
 
 import com.android.inputmethod.compat.CompatUtils;
 import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
+import com.android.inputmethod.compat.InputMethodServiceCompatWrapper;
 import com.android.inputmethod.deprecated.VoiceProxy;
 import com.android.inputmethod.compat.VibratorCompatWrapper;
 
@@ -67,6 +68,7 @@
     public static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold";
     public static final String PREF_BIGRAM_SUGGESTIONS = "bigram_suggestion";
     public static final String PREF_DEBUG_SETTINGS = "debug_settings";
+    public static final String PREF_LANGUAGE_SELECTION = "language_selection";
 
     public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
 
@@ -183,6 +185,10 @@
         if (!showUsabilityModeStudyOption) {
             getPreferenceScreen().removePreference(findPreference(PREF_USABILITY_STUDY_MODE));
         }
+
+        if (InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) {
+            generalSettings.removePreference(findPreference(PREF_LANGUAGE_SELECTION));
+        }
     }
 
     @Override
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index cd7f71c..f372062 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -75,7 +75,7 @@
     public static final String DICT_KEY_USER_BIGRAM = "user_bigram";
     public static final String DICT_KEY_WHITELIST ="whitelist";
 
-    static final int LARGE_DICTIONARY_THRESHOLD = 200 * 1000;
+    public static final int LARGE_DICTIONARY_THRESHOLD = 200 * 1000;
 
     private static final boolean DBG = LatinImeLogger.sDBG;