blob: ddadac105c18dcb601ed1b615e02e570588db777 [file] [log] [blame]
tmfang464da582018-07-04 15:59:21 +08001/*
2 * Copyright (C) 2018 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.settingslib.inputmethod;
18
19import static com.google.common.truth.Truth.assertThat;
20
21import android.content.pm.ApplicationInfo;
22import android.content.pm.ResolveInfo;
23import android.content.pm.ServiceInfo;
24import android.view.inputmethod.InputMethodInfo;
25import android.view.inputmethod.InputMethodSubtype;
26import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
27
28import org.junit.Test;
29import org.junit.runner.RunWith;
30import org.robolectric.RobolectricTestRunner;
31
32import java.util.Arrays;
33import java.util.HashMap;
34import java.util.HashSet;
35
36@RunWith(RobolectricTestRunner.class)
37public class InputMethodAndSubtypeUtilCompatTest {
38
39 private static final HashSet<String> EMPTY_STRING_SET = new HashSet<>();
40
41 private static HashSet<String> asHashSet(String... strings) {
42 HashSet<String> hashSet = new HashSet<>();
43 for (String s : strings) {
44 hashSet.add(s);
45 }
46 return hashSet;
47 }
48
49 @Test
50 public void parseInputMethodsAndSubtypesString_EmptyString() {
51 assertThat(InputMethodAndSubtypeUtilCompat.
52 parseInputMethodsAndSubtypesString("")).isEmpty();
53 assertThat(InputMethodAndSubtypeUtilCompat.
54 parseInputMethodsAndSubtypesString(null)).isEmpty();
55 }
56
57 @Test
58 public void parseInputMethodsAndSubtypesString_SingleImeNoSubtype() {
59 HashMap<String, HashSet<String>> r =
60 InputMethodAndSubtypeUtilCompat.parseInputMethodsAndSubtypesString("ime0");
61 assertThat(r).containsExactly("ime0", EMPTY_STRING_SET);
62 }
63
64 @Test
65 public void parseInputMethodsAndSubtypesString_MultipleImesNoSubtype() {
66 HashMap<String, HashSet<String>> r =
67 InputMethodAndSubtypeUtilCompat.parseInputMethodsAndSubtypesString("ime0:ime1");
68 assertThat(r).containsExactly("ime0", EMPTY_STRING_SET, "ime1", EMPTY_STRING_SET);
69 }
70
71 @Test
72 public void parseInputMethodsAndSubtypesString_SingleImeSingleSubtype() {
73 HashMap<String, HashSet<String>> r =
74 InputMethodAndSubtypeUtilCompat.parseInputMethodsAndSubtypesString("ime0;subtype0");
75 assertThat(r).containsExactly("ime0", asHashSet("subtype0"));
76 }
77
78 @Test
79 public void parseInputMethodsAndSubtypesString_SingleImeDuplicateSameSubtypes() {
80 HashMap<String, HashSet<String>> r =
81 InputMethodAndSubtypeUtilCompat.parseInputMethodsAndSubtypesString(
82 "ime0;subtype0;subtype0");
83 assertThat(r).containsExactly("ime0", asHashSet("subtype0"));
84 }
85
86 @Test
87 public void parseInputMethodsAndSubtypesString_SingleImeMultipleSubtypes() {
88 HashMap<String, HashSet<String>> r =
89 InputMethodAndSubtypeUtilCompat.parseInputMethodsAndSubtypesString(
90 "ime0;subtype0;subtype1");
91 assertThat(r).containsExactly("ime0", asHashSet("subtype0", "subtype1"));
92 }
93
94 @Test
95 public void parseInputMethodsAndSubtypesString_MultiplePairsOfImeSubtype() {
96 assertThat(InputMethodAndSubtypeUtilCompat.parseInputMethodsAndSubtypesString(
97 "ime0;subtype0:ime1;subtype1"))
98 .containsExactly("ime0", asHashSet("subtype0"), "ime1", asHashSet("subtype1"));
99 assertThat(InputMethodAndSubtypeUtilCompat.parseInputMethodsAndSubtypesString(
100 "ime0;subtype0;subtype1:ime1;subtype2"))
101 .containsExactly("ime0", asHashSet("subtype0", "subtype1"),
102 "ime1", asHashSet("subtype2"));
103 assertThat(InputMethodAndSubtypeUtilCompat.parseInputMethodsAndSubtypesString(
104 "ime0;subtype0;subtype1:ime1;subtype1;subtype2"))
105 .containsExactly("ime0", asHashSet("subtype0", "subtype1"),
106 "ime1", asHashSet("subtype1", "subtype2"));
107
108 }
109
110 @Test
111 public void parseInputMethodsAndSubtypesString_MixedImeSubtypePairsAndImeNoSubtype() {
112 HashMap<String, HashSet<String>> r =
113 InputMethodAndSubtypeUtilCompat.parseInputMethodsAndSubtypesString(
114 "ime0;subtype0;subtype1:ime1;subtype1;subtype2:ime2");
115 assertThat(r).containsExactly("ime0", asHashSet("subtype0", "subtype1"),
116 "ime1", asHashSet("subtype1", "subtype2"),
117 "ime2", EMPTY_STRING_SET);
118 }
119
120 @Test
121 public void buildInputMethodsAndSubtypesString_EmptyInput() {
122 HashMap<String, HashSet<String>> map = new HashMap<>();
123 assertThat(map).isEmpty();
124 }
125
126 @Test
127 public void buildInputMethodsAndSubtypesString_SingleIme() {
128 HashMap<String, HashSet<String>> map = new HashMap<>();
129 map.put("ime0", new HashSet<>());
130 String result = InputMethodAndSubtypeUtilCompat.buildInputMethodsAndSubtypesString(map);
131 assertThat(result).isEqualTo("ime0");
132 }
133
134 @Test
135 public void buildInputMethodsAndSubtypesString_SingleImeSingleSubtype() {
136 HashMap<String, HashSet<String>> map = new HashMap<>();
137 map.put("ime0", asHashSet("subtype0"));
138 String result = InputMethodAndSubtypeUtilCompat.buildInputMethodsAndSubtypesString(map);
139 assertThat(result).isEqualTo("ime0;subtype0");
140 }
141
142 @Test
143 public void buildInputMethodsAndSubtypesString_SingleImeMultipleSubtypes() {
144 HashMap<String, HashSet<String>> map = new HashMap<>();
145 map.put("ime0", asHashSet("subtype0", "subtype1"));
146 String result = InputMethodAndSubtypeUtilCompat.buildInputMethodsAndSubtypesString(map);
147
148 // We do not expect what order will be used to concatenate items in
149 // InputMethodAndSubtypeUtil.buildInputMethodsAndSubtypesString() hence accept all possible
150 // permutations here.
151 assertThat(result).matches("ime0;subtype0;subtype1|ime0;subtype1;subtype0");
152 }
153
154 @Test
155 public void buildInputMethodsAndSubtypesString_MultipleImesNoSubtypes() {
156 HashMap<String, HashSet<String>> map = new HashMap<>();
157 map.put("ime0", EMPTY_STRING_SET);
158 map.put("ime1", EMPTY_STRING_SET);
159 String result = InputMethodAndSubtypeUtilCompat.buildInputMethodsAndSubtypesString(map);
160
161 // We do not expect what order will be used to concatenate items in
162 // InputMethodAndSubtypeUtil.buildInputMethodsAndSubtypesString() hence accept all possible
163 // permutations here.
164 assertThat(result).matches("ime0:ime1|ime1:ime0");
165 }
166
167 @Test
168 public void buildInputMethodsAndSubtypesString_MultipleImesWithAndWithoutSubtypes() {
169 HashMap<String, HashSet<String>> map = new HashMap<>();
170 map.put("ime0", asHashSet("subtype0", "subtype1"));
171 map.put("ime1", EMPTY_STRING_SET);
172 String result = InputMethodAndSubtypeUtilCompat.buildInputMethodsAndSubtypesString(map);
173
174 // We do not expect what order will be used to concatenate items in
175 // InputMethodAndSubtypeUtil.buildInputMethodsAndSubtypesString() hence accept all possible
176 // permutations here.
177 assertThat(result).matches("ime0;subtype0;subtype1:ime1|ime0;subtype1;subtype0:ime1"
178 + "|ime1:ime0;subtype0;subtype1|ime1:ime0;subtype1;subtype0");
179 }
180
181 @Test
182 public void buildInputMethodsAndSubtypesString_MultipleImesWithSubtypes() {
183 HashMap<String, HashSet<String>> map = new HashMap<>();
184 map.put("ime0", asHashSet("subtype0", "subtype1"));
185 map.put("ime1", asHashSet("subtype2", "subtype3"));
186 String result = InputMethodAndSubtypeUtilCompat.buildInputMethodsAndSubtypesString(map);
187
188 // We do not expect what order will be used to concatenate items in
189 // InputMethodAndSubtypeUtil.buildInputMethodsAndSubtypesString() hence accept all possible
190 // permutations here.
191 assertThat(result).matches("ime0;subtype0;subtype1:ime1;subtype2;subtype3"
192 + "|ime0;subtype1;subtype0:ime1;subtype2;subtype3"
193 + "|ime0;subtype0;subtype1:ime1;subtype3;subtype2"
194 + "|ime0;subtype1;subtype0:ime1;subtype3;subtype2"
195 + "|ime1;subtype2;subtype3:ime0;subtype0;subtype1"
196 + "|ime2;subtype3;subtype2:ime0;subtype0;subtype1"
197 + "|ime3;subtype2;subtype3:ime0;subtype1;subtype0"
198 + "|ime4;subtype3;subtype2:ime0;subtype1;subtype0");
199 }
200
201 @Test
202 public void isValidSystemNonAuxAsciiCapableIme() {
203 // System IME w/ no subtype
204 assertThat(InputMethodAndSubtypeUtilCompat.isValidSystemNonAuxAsciiCapableIme(
205 createDummyIme(true, false)))
206 .isFalse();
207
208 // System IME w/ non-Aux and non-ASCII-capable "keyboard" subtype
209 assertThat(InputMethodAndSubtypeUtilCompat.isValidSystemNonAuxAsciiCapableIme(
210 createDummyIme(true, false, createDummySubtype("keyboard", false, false))))
211 .isFalse();
212
213 // System IME w/ non-Aux and ASCII-capable "keyboard" subtype
214 assertThat(InputMethodAndSubtypeUtilCompat.isValidSystemNonAuxAsciiCapableIme(
215 createDummyIme(true, false, createDummySubtype("keyboard", false, true))))
216 .isTrue();
217
218 // System IME w/ Aux and ASCII-capable "keyboard" subtype
219 assertThat(InputMethodAndSubtypeUtilCompat.isValidSystemNonAuxAsciiCapableIme(
220 createDummyIme(true, true, createDummySubtype("keyboard", true, true))))
221 .isFalse();
222
223 // System IME w/ non-Aux and ASCII-capable "voice" subtype
224 assertThat(InputMethodAndSubtypeUtilCompat.isValidSystemNonAuxAsciiCapableIme(
225 createDummyIme(true, false, createDummySubtype("voice", false, true))))
226 .isFalse();
227
228 // System IME w/ non-Aux and non-ASCII-capable subtype + Non-Aux and ASCII-capable subtype
229 assertThat(InputMethodAndSubtypeUtilCompat.isValidSystemNonAuxAsciiCapableIme(
230 createDummyIme(true, false,
231 createDummySubtype("keyboard", false, true),
232 createDummySubtype("keyboard", false, false))))
233 .isTrue();
234
235 // Non-system IME w/ non-Aux and ASCII-capable "keyboard" subtype
236 assertThat(InputMethodAndSubtypeUtilCompat.isValidSystemNonAuxAsciiCapableIme(
237 createDummyIme(false, false, createDummySubtype("keyboard", false, true))))
238 .isFalse();
239 }
240
241 private static InputMethodInfo createDummyIme(boolean isSystem, boolean isAuxIme,
242 InputMethodSubtype... subtypes) {
243 final ResolveInfo ri = new ResolveInfo();
244 final ServiceInfo si = new ServiceInfo();
245 final ApplicationInfo ai = new ApplicationInfo();
246 ai.packageName = "com.example.android.dummyime";
247 ai.enabled = true;
248 ai.flags |= (isSystem ? ApplicationInfo.FLAG_SYSTEM : 0);
249 si.applicationInfo = ai;
250 si.enabled = true;
251 si.packageName = "com.example.android.dummyime";
252 si.name = "Dummy IME";
253 si.exported = true;
254 si.nonLocalizedLabel = "Dummy IME";
255 ri.serviceInfo = si;
256 return new InputMethodInfo(ri, isAuxIme, "", Arrays.asList(subtypes), 1, false);
257 }
258
259 private static InputMethodSubtype createDummySubtype(
260 String mode, boolean isAuxiliary, boolean isAsciiCapable) {
261 return new InputMethodSubtypeBuilder()
262 .setSubtypeNameResId(0)
263 .setSubtypeIconResId(0)
264 .setSubtypeLocale("en_US")
265 .setLanguageTag("en-US")
266 .setSubtypeMode(mode)
267 .setIsAuxiliary(isAuxiliary)
268 .setIsAsciiCapable(isAsciiCapable)
269 .build();
270 }
271}