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