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 17 package com.android.inputmethod.latin; 18 19 import android.content.Context; 20 import android.content.res.Resources; 21 import android.test.AndroidTestCase; 22 import android.test.suitebuilder.annotation.SmallTest; 23 import android.view.inputmethod.InputMethodInfo; 24 import android.view.inputmethod.InputMethodSubtype; 25 26 import com.android.inputmethod.latin.R; 27 import com.android.inputmethod.latin.RichInputMethodManager; 28 import com.android.inputmethod.latin.RichInputMethodSubtype; 29 import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; 30 import com.android.inputmethod.latin.utils.RunInLocale; 31 import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; 32 33 import java.util.ArrayList; 34 import java.util.Locale; 35 36 @SmallTest 37 public class RichInputMethodSubtypeTests extends AndroidTestCase { 38 // All input method subtypes of LatinIME. 39 private final ArrayList<RichInputMethodSubtype> mSubtypesList = new ArrayList<>(); 40 41 private RichInputMethodManager mRichImm; 42 private Resources mRes; 43 private InputMethodSubtype mSavedAddtionalSubtypes[]; 44 45 RichInputMethodSubtype EN_US; 46 RichInputMethodSubtype EN_GB; 47 RichInputMethodSubtype ES_US; 48 RichInputMethodSubtype FR; 49 RichInputMethodSubtype FR_CA; 50 RichInputMethodSubtype FR_CH; 51 RichInputMethodSubtype DE; 52 RichInputMethodSubtype DE_CH; 53 RichInputMethodSubtype HI; 54 RichInputMethodSubtype SR; 55 RichInputMethodSubtype ZZ; 56 RichInputMethodSubtype DE_QWERTY; 57 RichInputMethodSubtype FR_QWERTZ; 58 RichInputMethodSubtype EN_US_AZERTY; 59 RichInputMethodSubtype EN_UK_DVORAK; 60 RichInputMethodSubtype ES_US_COLEMAK; 61 RichInputMethodSubtype ZZ_AZERTY; 62 RichInputMethodSubtype ZZ_PC; 63 64 // These are preliminary subtypes and may not exist. 65 RichInputMethodSubtype HI_LATN; // Hinglish 66 RichInputMethodSubtype SR_LATN; // Serbian Latin 67 RichInputMethodSubtype HI_LATN_DVORAK; 68 RichInputMethodSubtype SR_LATN_QWERTY; 69 70 @Override 71 protected void setUp() throws Exception { 72 super.setUp(); 73 final Context context = getContext(); 74 mRes = context.getResources(); 75 RichInputMethodManager.init(context); 76 mRichImm = RichInputMethodManager.getInstance(); 77 78 // Save and reset additional subtypes 79 mSavedAddtionalSubtypes = mRichImm.getAdditionalSubtypes(); 80 final InputMethodSubtype[] predefinedAddtionalSubtypes = 81 AdditionalSubtypeUtils.createAdditionalSubtypesArray( 82 AdditionalSubtypeUtils.createPrefSubtypes( 83 mRes.getStringArray(R.array.predefined_subtypes))); 84 mRichImm.setAdditionalInputMethodSubtypes(predefinedAddtionalSubtypes); 85 86 final InputMethodInfo imi = mRichImm.getInputMethodInfoOfThisIme(); 87 final int subtypeCount = imi.getSubtypeCount(); 88 for (int index = 0; index < subtypeCount; index++) { 89 final InputMethodSubtype subtype = imi.getSubtypeAt(index); 90 mSubtypesList.add(new RichInputMethodSubtype(subtype)); 91 } 92 93 EN_US = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( 94 Locale.US.toString(), "qwerty")); 95 EN_GB = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( 96 Locale.UK.toString(), "qwerty")); 97 ES_US = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( 98 "es_US", "spanish")); 99 FR = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( 100 Locale.FRENCH.toString(), "azerty")); 101 FR_CA = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( 102 Locale.CANADA_FRENCH.toString(), "qwerty")); 103 FR_CH = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( 104 "fr_CH", "swiss")); 105 DE = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( 106 Locale.GERMAN.toString(), "qwertz")); 107 DE_CH = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( 108 "de_CH", "swiss")); 109 HI = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( 110 "hi", "hindi")); 111 SR = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( 112 "sr", "south_slavic")); 113 ZZ = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( 114 SubtypeLocaleUtils.NO_LANGUAGE, "qwerty")); 115 DE_QWERTY = new RichInputMethodSubtype( 116 AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( 117 Locale.GERMAN.toString(), "qwerty")); 118 FR_QWERTZ = new RichInputMethodSubtype( 119 AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( 120 Locale.FRENCH.toString(), "qwertz")); 121 EN_US_AZERTY = new RichInputMethodSubtype( 122 AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( 123 Locale.US.toString(), "azerty")); 124 EN_UK_DVORAK = new RichInputMethodSubtype( 125 AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( 126 Locale.UK.toString(), "dvorak")); 127 ES_US_COLEMAK = new RichInputMethodSubtype( 128 AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( 129 "es_US", "colemak")); 130 ZZ_AZERTY = new RichInputMethodSubtype( 131 AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( 132 SubtypeLocaleUtils.NO_LANGUAGE, "azerty")); 133 ZZ_PC = new RichInputMethodSubtype( 134 AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( 135 SubtypeLocaleUtils.NO_LANGUAGE, "pcqwerty")); 136 137 final InputMethodSubtype hiLatn = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( 138 "hi_ZZ", "qwerty"); 139 if (hiLatn != null) { 140 HI_LATN = new RichInputMethodSubtype(hiLatn); 141 HI_LATN_DVORAK = new RichInputMethodSubtype( 142 AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( 143 "hi_ZZ", "dvorak")); 144 } 145 final InputMethodSubtype srLatn = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( 146 "sr_ZZ", "serbian_qwertz"); 147 if (srLatn != null) { 148 SR_LATN = new RichInputMethodSubtype(srLatn); 149 SR_LATN_QWERTY = new RichInputMethodSubtype( 150 AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( 151 "sr_ZZ", "qwerty")); 152 } 153 } 154 155 @Override 156 protected void tearDown() throws Exception { 157 // Restore additional subtypes. 158 mRichImm.setAdditionalInputMethodSubtypes(mSavedAddtionalSubtypes); 159 super.tearDown(); 160 } 161 162 public void testAllFullDisplayNameForSpacebar() { 163 for (final RichInputMethodSubtype subtype : mSubtypesList) { 164 final String subtypeName = SubtypeLocaleUtils 165 .getSubtypeDisplayNameInSystemLocale(subtype.getRawSubtype()); 166 final String spacebarText = subtype.getFullDisplayName(); 167 final String languageName = SubtypeLocaleUtils 168 .getSubtypeLocaleDisplayName(subtype.getLocale().toString()); 169 if (subtype.isNoLanguage()) { 170 assertFalse(subtypeName, spacebarText.contains(languageName)); 171 } else { 172 assertTrue(subtypeName, spacebarText.contains(languageName)); 173 } 174 } 175 } 176 177 public void testAllMiddleDisplayNameForSpacebar() { 178 for (final RichInputMethodSubtype subtype : mSubtypesList) { 179 final String subtypeName = SubtypeLocaleUtils 180 .getSubtypeDisplayNameInSystemLocale(subtype.getRawSubtype()); 181 final Locale locale = subtype.getLocale(); 182 final Locale displayLocale = SubtypeLocaleUtils.getDisplayLocaleOfSubtypeLocale( 183 locale.toString()); 184 if (Locale.ROOT.equals(displayLocale)) { 185 // Skip test because the language part of this locale string doesn't represent 186 // the locale to be displayed on the spacebar (for example Hinglish). 187 continue; 188 } 189 final String spacebarText = subtype.getMiddleDisplayName(); 190 if (subtype.isNoLanguage()) { 191 assertEquals(subtypeName, SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName( 192 subtype.getRawSubtype()), spacebarText); 193 } else { 194 assertEquals(subtypeName, 195 SubtypeLocaleUtils.getSubtypeLanguageDisplayName(locale.toString()), 196 spacebarText); 197 } 198 } 199 } 200 201 // InputMethodSubtype's display name for spacebar text in its locale. 202 // isAdditionalSubtype (T=true, F=false) 203 // locale layout | Middle Full 204 // ------ -------------- - --------- ---------------------- 205 // en_US qwerty F English English (US) exception 206 // en_GB qwerty F English English (UK) exception 207 // es_US spanish F Espaol Espaol (EE.UU.) exception 208 // fr azerty F Franais Franais 209 // fr_CA qwerty F Franais Franais (Canada) 210 // fr_CH swiss F Franais Franais (Suisse) 211 // de qwertz F Deutsch Deutsch 212 // de_CH swiss F Deutsch Deutsch (Schweiz) 213 // hi hindi F 214 // hi_ZZ qwerty F Hinglish Hinglish exception 215 // sr south_slavic F 216 // sr_ZZ serbian_qwertz F Srpski Srpski exception 217 // zz qwerty F QWERTY QWERTY 218 // fr qwertz T Franais Franais 219 // de qwerty T Deutsch Deutsch 220 // en_US azerty T English English (US) 221 // en_GB dvorak T English English (UK) 222 // hi_ZZ dvorak T Hinglish Hinglish exception 223 // sr_ZZ qwerty T Srpski Srpski exception 224 // zz azerty T AZERTY AZERTY 225 226 private final RunInLocale<Void> testsPredefinedSubtypesForSpacebar = new RunInLocale<Void>() { 227 @Override 228 protected Void job(final Resources res) { 229 assertEquals("en_US", "English (US)", EN_US.getFullDisplayName()); 230 assertEquals("en_GB", "English (UK)", EN_GB.getFullDisplayName()); 231 assertEquals("es_US", "Espaol (EE.UU.)", ES_US.getFullDisplayName()); 232 assertEquals("fr", "Franais", FR.getFullDisplayName()); 233 assertEquals("fr_CA", "Franais (Canada)", FR_CA.getFullDisplayName()); 234 assertEquals("fr_CH", "Franais (Suisse)", FR_CH.getFullDisplayName()); 235 assertEquals("de", "Deutsch", DE.getFullDisplayName()); 236 assertEquals("de_CH", "Deutsch (Schweiz)", DE_CH.getFullDisplayName()); 237 assertEquals("hi", "", HI.getFullDisplayName()); 238 assertEquals("sr", "", SR.getFullDisplayName()); 239 assertEquals("zz", "QWERTY", ZZ.getFullDisplayName()); 240 241 assertEquals("en_US", "English", EN_US.getMiddleDisplayName()); 242 assertEquals("en_GB", "English", EN_GB.getMiddleDisplayName()); 243 assertEquals("es_US", "Espaol", ES_US.getMiddleDisplayName()); 244 assertEquals("fr", "Franais", FR.getMiddleDisplayName()); 245 assertEquals("fr_CA", "Franais", FR_CA.getMiddleDisplayName()); 246 assertEquals("fr_CH", "Franais", FR_CH.getMiddleDisplayName()); 247 assertEquals("de", "Deutsch", DE.getMiddleDisplayName()); 248 assertEquals("de_CH", "Deutsch", DE_CH.getMiddleDisplayName()); 249 assertEquals("zz", "QWERTY", ZZ.getMiddleDisplayName()); 250 251 // These are preliminary subtypes and may not exist. 252 if (HI_LATN != null) { 253 assertEquals("hi_ZZ", "Hinglish", HI_LATN.getFullDisplayName()); 254 assertEquals("hi_ZZ", "Hinglish", HI_LATN.getMiddleDisplayName()); 255 } 256 if (SR_LATN != null) { 257 assertEquals("sr_ZZ", "Srpski", SR_LATN.getFullDisplayName()); 258 assertEquals("sr_ZZ", "Srpski", SR_LATN.getMiddleDisplayName()); 259 } 260 return null; 261 } 262 }; 263 264 private final RunInLocale<Void> testsAdditionalSubtypesForSpacebar = new RunInLocale<Void>() { 265 @Override 266 protected Void job(final Resources res) { 267 assertEquals("fr qwertz", "Franais", FR_QWERTZ.getFullDisplayName()); 268 assertEquals("de qwerty", "Deutsch", DE_QWERTY.getFullDisplayName()); 269 assertEquals("en_US azerty", "English (US)", EN_US_AZERTY.getFullDisplayName()); 270 assertEquals("en_UK dvorak", "English (UK)", EN_UK_DVORAK.getFullDisplayName()); 271 assertEquals("es_US colemak", "Espaol (EE.UU.)", ES_US_COLEMAK.getFullDisplayName()); 272 assertEquals("zz azerty", "AZERTY", ZZ_AZERTY.getFullDisplayName()); 273 assertEquals("zz pc", "PC", ZZ_PC.getFullDisplayName()); 274 275 assertEquals("fr qwertz", "Franais", FR_QWERTZ.getMiddleDisplayName()); 276 assertEquals("de qwerty", "Deutsch", DE_QWERTY.getMiddleDisplayName()); 277 assertEquals("en_US azerty", "English", EN_US_AZERTY.getMiddleDisplayName()); 278 assertEquals("en_UK dvorak", "English", EN_UK_DVORAK.getMiddleDisplayName()); 279 assertEquals("es_US colemak", "Espaol", ES_US_COLEMAK.getMiddleDisplayName()); 280 assertEquals("zz azerty", "AZERTY", ZZ_AZERTY.getMiddleDisplayName()); 281 assertEquals("zz pc", "PC", ZZ_PC.getMiddleDisplayName()); 282 283 // These are preliminary subtypes and may not exist. 284 if (HI_LATN_DVORAK != null) { 285 assertEquals("hi_ZZ dvorak", "Hinglish", HI_LATN_DVORAK.getFullDisplayName()); 286 assertEquals("hi_ZZ dvorak", "Hinglish", HI_LATN_DVORAK.getMiddleDisplayName()); 287 } 288 if (SR_LATN_QWERTY != null) { 289 assertEquals("sr_ZZ qwerty", "Srpski", SR_LATN_QWERTY.getFullDisplayName()); 290 assertEquals("sr_ZZ qwerty", "Srpski", SR_LATN_QWERTY.getMiddleDisplayName()); 291 } 292 return null; 293 } 294 }; 295 296 public void testPredefinedSubtypesForSpacebarInEnglish() { 297 testsPredefinedSubtypesForSpacebar.runInLocale(mRes, Locale.ENGLISH); 298 } 299 300 public void testAdditionalSubtypeForSpacebarInEnglish() { 301 testsAdditionalSubtypesForSpacebar.runInLocale(mRes, Locale.ENGLISH); 302 } 303 304 public void testPredefinedSubtypesForSpacebarInFrench() { 305 testsPredefinedSubtypesForSpacebar.runInLocale(mRes, Locale.FRENCH); 306 } 307 308 public void testAdditionalSubtypeForSpacebarInFrench() { 309 testsAdditionalSubtypesForSpacebar.runInLocale(mRes, Locale.FRENCH); 310 } 311 312 public void testRichInputMethodSubtypeForNullInputMethodSubtype() { 313 RichInputMethodSubtype subtype = RichInputMethodSubtype.getRichInputMethodSubtype(null); 314 assertNotNull(subtype); 315 assertEquals("zz", subtype.getRawSubtype().getLocale()); 316 assertEquals("keyboard", subtype.getRawSubtype().getMode()); 317 } 318 } 319