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.utils; 18 19 import static com.android.inputmethod.latin.utils.LanguageOnSpacebarUtils.FORMAT_TYPE_FULL_LOCALE; 20 import static com.android.inputmethod.latin.utils.LanguageOnSpacebarUtils.FORMAT_TYPE_LANGUAGE_ONLY; 21 import static com.android.inputmethod.latin.utils.LanguageOnSpacebarUtils.FORMAT_TYPE_NONE; 22 23 import static org.junit.Assert.assertEquals; 24 25 import android.content.Context; 26 import android.view.inputmethod.InputMethodSubtype; 27 28 import androidx.test.InstrumentationRegistry; 29 import androidx.test.filters.SmallTest; 30 import androidx.test.runner.AndroidJUnit4; 31 32 import com.android.inputmethod.latin.RichInputMethodManager; 33 import com.android.inputmethod.latin.RichInputMethodSubtype; 34 import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; 35 import com.android.inputmethod.latin.utils.LanguageOnSpacebarUtils; 36 import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; 37 38 import org.junit.Before; 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 42 import java.util.ArrayList; 43 import java.util.Locale; 44 45 import javax.annotation.Nonnull; 46 47 @SmallTest 48 @RunWith(AndroidJUnit4.class) 49 public class LanguageOnSpacebarUtilsTests { 50 private RichInputMethodManager mRichImm; 51 52 RichInputMethodSubtype EN_US_QWERTY; 53 RichInputMethodSubtype EN_GB_QWERTY; 54 RichInputMethodSubtype FR_AZERTY; 55 RichInputMethodSubtype FR_CA_QWERTY; 56 RichInputMethodSubtype FR_CH_SWISS; 57 RichInputMethodSubtype FR_CH_QWERTY; 58 RichInputMethodSubtype FR_CH_QWERTZ; 59 RichInputMethodSubtype IW_HEBREW; 60 RichInputMethodSubtype ZZ_QWERTY; 61 62 @Before setUp()63 public void setUp() throws Exception { 64 final Context context = InstrumentationRegistry.getTargetContext(); 65 RichInputMethodManager.init(context); 66 mRichImm = RichInputMethodManager.getInstance(); 67 68 EN_US_QWERTY = findSubtypeOf(Locale.US.toString(), "qwerty"); 69 EN_GB_QWERTY = findSubtypeOf(Locale.UK.toString(), "qwerty"); 70 FR_AZERTY = findSubtypeOf(Locale.FRENCH.toString(), "azerty"); 71 FR_CA_QWERTY = findSubtypeOf(Locale.CANADA_FRENCH.toString(), "qwerty"); 72 FR_CH_SWISS = findSubtypeOf("fr_CH", "swiss"); 73 FR_CH_QWERTZ = new RichInputMethodSubtype( 74 AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype("fr_CH", "qwertz")); 75 FR_CH_QWERTY = new RichInputMethodSubtype( 76 AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype("fr_CH", "qwerty")); 77 IW_HEBREW = findSubtypeOf("iw", "hebrew"); 78 ZZ_QWERTY = findSubtypeOf(SubtypeLocaleUtils.NO_LANGUAGE, "qwerty"); 79 } 80 81 @Nonnull findSubtypeOf(final String localeString, final String keyboardLayoutSetName)82 private RichInputMethodSubtype findSubtypeOf(final String localeString, 83 final String keyboardLayoutSetName) { 84 final InputMethodSubtype subtype = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( 85 localeString, keyboardLayoutSetName); 86 if (subtype == null) { 87 throw new RuntimeException("Can't find subtype of " + localeString + " with " 88 + keyboardLayoutSetName); 89 } 90 return new RichInputMethodSubtype(subtype); 91 } 92 enableSubtypes(final RichInputMethodSubtype ... subtypes)93 private static void enableSubtypes(final RichInputMethodSubtype ... subtypes) { 94 final ArrayList<InputMethodSubtype> enabledSubtypes = new ArrayList<>(); 95 for (final RichInputMethodSubtype subtype : subtypes) { 96 enabledSubtypes.add(subtype.getRawSubtype()); 97 } 98 LanguageOnSpacebarUtils.setEnabledSubtypes(enabledSubtypes); 99 } 100 assertFormatType(final RichInputMethodSubtype subtype, final boolean implicitlyEnabledSubtype, final Locale systemLocale, final int expectedFormat)101 private static void assertFormatType(final RichInputMethodSubtype subtype, 102 final boolean implicitlyEnabledSubtype, final Locale systemLocale, 103 final int expectedFormat) { 104 LanguageOnSpacebarUtils.onSubtypeChanged(subtype, implicitlyEnabledSubtype, systemLocale); 105 assertEquals(subtype.getLocale() + " implicitly=" + implicitlyEnabledSubtype 106 + " in " + systemLocale, expectedFormat, 107 LanguageOnSpacebarUtils.getLanguageOnSpacebarFormatType(subtype)); 108 } 109 110 @Test testOneSubtypeImplicitlyEnabled()111 public void testOneSubtypeImplicitlyEnabled() { 112 enableSubtypes(EN_US_QWERTY); 113 assertFormatType(EN_US_QWERTY, true, Locale.US, FORMAT_TYPE_NONE); 114 115 enableSubtypes(EN_GB_QWERTY); 116 assertFormatType(EN_GB_QWERTY, true, Locale.UK, FORMAT_TYPE_NONE); 117 118 enableSubtypes(FR_AZERTY); 119 assertFormatType(FR_AZERTY, true, Locale.FRANCE, FORMAT_TYPE_NONE); 120 121 enableSubtypes(FR_CA_QWERTY); 122 assertFormatType(FR_CA_QWERTY, true, Locale.CANADA_FRENCH, FORMAT_TYPE_NONE); 123 } 124 125 @Test testOneSubtypeExplicitlyEnabled()126 public void testOneSubtypeExplicitlyEnabled() { 127 enableSubtypes(EN_US_QWERTY); 128 assertFormatType(EN_US_QWERTY, false, Locale.UK, FORMAT_TYPE_LANGUAGE_ONLY); 129 assertFormatType(EN_US_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); 130 131 enableSubtypes(EN_GB_QWERTY); 132 assertFormatType(EN_GB_QWERTY, false, Locale.US, FORMAT_TYPE_LANGUAGE_ONLY); 133 assertFormatType(EN_GB_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); 134 135 enableSubtypes(FR_AZERTY); 136 assertFormatType(FR_AZERTY, false, Locale.US, FORMAT_TYPE_LANGUAGE_ONLY); 137 assertFormatType(FR_AZERTY, false, Locale.CANADA_FRENCH, FORMAT_TYPE_LANGUAGE_ONLY); 138 139 enableSubtypes(FR_CA_QWERTY); 140 assertFormatType(FR_CA_QWERTY, false, Locale.US, FORMAT_TYPE_LANGUAGE_ONLY); 141 assertFormatType(FR_CA_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); 142 } 143 144 @Test testOneSubtypeImplicitlyEnabledWithNoLanguageSubtype()145 public void testOneSubtypeImplicitlyEnabledWithNoLanguageSubtype() { 146 final Locale Locale_IW = new Locale("iw"); 147 enableSubtypes(IW_HEBREW, ZZ_QWERTY); 148 // TODO: Should this be FORMAT_TYPE_NONE? 149 assertFormatType(IW_HEBREW, true, Locale_IW, FORMAT_TYPE_LANGUAGE_ONLY); 150 // TODO: Should this be FORMAT_TYPE_NONE? 151 assertFormatType(ZZ_QWERTY, true, Locale_IW, FORMAT_TYPE_FULL_LOCALE); 152 } 153 154 @Test testTwoSubtypesExplicitlyEnabled()155 public void testTwoSubtypesExplicitlyEnabled() { 156 enableSubtypes(EN_US_QWERTY, FR_AZERTY); 157 assertFormatType(EN_US_QWERTY, false, Locale.US, FORMAT_TYPE_LANGUAGE_ONLY); 158 assertFormatType(FR_AZERTY, false, Locale.US, FORMAT_TYPE_LANGUAGE_ONLY); 159 assertFormatType(EN_US_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); 160 assertFormatType(FR_AZERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); 161 assertFormatType(EN_US_QWERTY, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); 162 assertFormatType(FR_AZERTY, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); 163 164 enableSubtypes(EN_US_QWERTY, ZZ_QWERTY); 165 assertFormatType(EN_US_QWERTY, false, Locale.US, FORMAT_TYPE_LANGUAGE_ONLY); 166 assertFormatType(ZZ_QWERTY, false, Locale.US, FORMAT_TYPE_FULL_LOCALE); 167 assertFormatType(EN_US_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); 168 assertFormatType(ZZ_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_FULL_LOCALE); 169 170 } 171 172 @Test testMultiSubtypeWithSameLanuageAndSameLayout()173 public void testMultiSubtypeWithSameLanuageAndSameLayout() { 174 // Explicitly enable en_US, en_GB, fr_FR, and no language keyboards. 175 enableSubtypes(EN_US_QWERTY, EN_GB_QWERTY, FR_CA_QWERTY, ZZ_QWERTY); 176 177 assertFormatType(EN_US_QWERTY, false, Locale.US, FORMAT_TYPE_FULL_LOCALE); 178 assertFormatType(EN_GB_QWERTY, false, Locale.US, FORMAT_TYPE_FULL_LOCALE); 179 assertFormatType(FR_CA_QWERTY, false, Locale.US, FORMAT_TYPE_LANGUAGE_ONLY); 180 assertFormatType(ZZ_QWERTY, false, Locale.US, FORMAT_TYPE_FULL_LOCALE); 181 182 assertFormatType(EN_US_QWERTY, false, Locale.JAPAN, FORMAT_TYPE_FULL_LOCALE); 183 assertFormatType(EN_GB_QWERTY, false, Locale.JAPAN, FORMAT_TYPE_FULL_LOCALE); 184 assertFormatType(FR_CA_QWERTY, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); 185 assertFormatType(ZZ_QWERTY, false, Locale.JAPAN, FORMAT_TYPE_FULL_LOCALE); 186 } 187 188 @Test testMultiSubtypesWithSameLanguageButHaveDifferentLayout()189 public void testMultiSubtypesWithSameLanguageButHaveDifferentLayout() { 190 enableSubtypes(FR_AZERTY, FR_CA_QWERTY, FR_CH_SWISS, FR_CH_QWERTZ); 191 192 assertFormatType(FR_AZERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); 193 assertFormatType(FR_CA_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); 194 assertFormatType(FR_CH_SWISS, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); 195 assertFormatType(FR_CH_QWERTZ, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); 196 197 assertFormatType(FR_AZERTY, false, Locale.CANADA_FRENCH, FORMAT_TYPE_LANGUAGE_ONLY); 198 assertFormatType(FR_CA_QWERTY, false, Locale.CANADA_FRENCH, FORMAT_TYPE_LANGUAGE_ONLY); 199 assertFormatType(FR_CH_SWISS, false, Locale.CANADA_FRENCH, FORMAT_TYPE_LANGUAGE_ONLY); 200 assertFormatType(FR_CH_QWERTZ, false, Locale.CANADA_FRENCH, FORMAT_TYPE_LANGUAGE_ONLY); 201 202 assertFormatType(FR_AZERTY, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); 203 assertFormatType(FR_CA_QWERTY, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); 204 assertFormatType(FR_CH_SWISS, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); 205 assertFormatType(FR_CH_QWERTZ, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); 206 } 207 208 @Test testMultiSubtypesWithSameLanguageAndMayHaveSameLayout()209 public void testMultiSubtypesWithSameLanguageAndMayHaveSameLayout() { 210 enableSubtypes(FR_AZERTY, FR_CA_QWERTY, FR_CH_SWISS, FR_CH_QWERTY, FR_CH_QWERTZ); 211 212 assertFormatType(FR_AZERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); 213 assertFormatType(FR_CA_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_FULL_LOCALE); 214 assertFormatType(FR_CH_SWISS, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); 215 assertFormatType(FR_CH_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_FULL_LOCALE); 216 assertFormatType(FR_CH_QWERTZ, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); 217 218 assertFormatType(FR_AZERTY, false, Locale.CANADA_FRENCH, FORMAT_TYPE_LANGUAGE_ONLY); 219 assertFormatType(FR_CA_QWERTY, false, Locale.CANADA_FRENCH, FORMAT_TYPE_FULL_LOCALE); 220 assertFormatType(FR_CH_SWISS, false, Locale.CANADA_FRENCH, FORMAT_TYPE_LANGUAGE_ONLY); 221 assertFormatType(FR_CH_QWERTY, false, Locale.CANADA_FRENCH, FORMAT_TYPE_FULL_LOCALE); 222 assertFormatType(FR_CH_QWERTZ, false, Locale.CANADA_FRENCH, FORMAT_TYPE_LANGUAGE_ONLY); 223 224 assertFormatType(FR_AZERTY, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); 225 assertFormatType(FR_CA_QWERTY, false, Locale.JAPAN, FORMAT_TYPE_FULL_LOCALE); 226 assertFormatType(FR_CH_SWISS, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); 227 assertFormatType(FR_CH_QWERTY, false, Locale.JAPAN, FORMAT_TYPE_FULL_LOCALE); 228 assertFormatType(FR_CH_QWERTZ, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); 229 } 230 } 231