• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 android.view.inputmethod.cts;
18 
19 import android.content.ComponentName;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.pm.ApplicationInfo;
23 import android.content.pm.PackageManager;
24 import android.content.pm.ResolveInfo;
25 import android.content.pm.ServiceInfo;
26 import android.content.res.Resources;
27 import android.os.Parcel;
28 import android.test.AndroidTestCase;
29 import android.util.Printer;
30 import android.view.inputmethod.InputMethod;
31 import android.view.inputmethod.InputMethodInfo;
32 import android.view.inputmethod.InputMethodManager;
33 import android.view.inputmethod.InputMethodSubtype;
34 
35 import org.xmlpull.v1.XmlPullParserException;
36 
37 import java.io.IOException;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.List;
41 
42 public class InputMethodInfoTest extends AndroidTestCase {
43     private InputMethodInfo mInputMethodInfo;
44     private String mPackageName;
45     private String mClassName;
46     private CharSequence mLabel;
47     private String mSettingsActivity;
48 
49     private int mSubtypeNameResId;
50     private int mSubtypeIconResId;
51     private String mSubtypeLocale;
52     private String mSubtypeMode;
53     private String mSubtypeExtraValue_key;
54     private String mSubtypeExtraValue_value;
55     private String mSubtypeExtraValue;
56     private boolean mSubtypeIsAuxiliary;
57     private boolean mSubtypeOverridesImplicitlyEnabledSubtype;
58     private int mSubtypeId;
59     private InputMethodSubtype mInputMethodSubtype;
60 
61     @Override
setUp()62     protected void setUp() throws Exception {
63         super.setUp();
64         mPackageName = mContext.getPackageName();
65         mClassName = InputMethodSettingsActivityStub.class.getName();
66         mLabel = "test";
67         mSettingsActivity = "android.view.inputmethod.cts.InputMethodSettingsActivityStub";
68         mInputMethodInfo = new InputMethodInfo(mPackageName, mClassName, mLabel, mSettingsActivity);
69 
70         mSubtypeNameResId = 0;
71         mSubtypeIconResId = 0;
72         mSubtypeLocale = "en_US";
73         mSubtypeMode = "keyboard";
74         mSubtypeExtraValue_key = "key1";
75         mSubtypeExtraValue_value = "value1";
76         mSubtypeExtraValue = "tag," + mSubtypeExtraValue_key + "=" + mSubtypeExtraValue_value;
77         mSubtypeIsAuxiliary = false;
78         mSubtypeOverridesImplicitlyEnabledSubtype = false;
79         mSubtypeId = 99;
80         mInputMethodSubtype = new InputMethodSubtype(mSubtypeNameResId, mSubtypeIconResId,
81                 mSubtypeLocale, mSubtypeMode, mSubtypeExtraValue, mSubtypeIsAuxiliary,
82                 mSubtypeOverridesImplicitlyEnabledSubtype, mSubtypeId);
83     }
84 
testInputMethodInfoProperties()85     public void testInputMethodInfoProperties() throws XmlPullParserException, IOException {
86         assertEquals(0, mInputMethodInfo.describeContents());
87         assertNotNull(mInputMethodInfo.toString());
88 
89         assertInfo(mInputMethodInfo);
90         assertEquals(0, mInputMethodInfo.getIsDefaultResourceId());
91 
92         Intent intent = new Intent(InputMethod.SERVICE_INTERFACE);
93         intent.setClass(mContext, InputMethodSettingsActivityStub.class);
94         PackageManager pm = mContext.getPackageManager();
95         List<ResolveInfo> ris = pm.queryIntentServices(intent, PackageManager.GET_META_DATA);
96         for (int i = 0; i < ris.size(); i++) {
97             ResolveInfo resolveInfo = ris.get(i);
98             mInputMethodInfo = new InputMethodInfo(mContext, resolveInfo);
99             assertService(resolveInfo.serviceInfo, mInputMethodInfo.getServiceInfo());
100             assertInfo(mInputMethodInfo);
101         }
102     }
103 
testInputMethodSubtypeProperties()104     public void testInputMethodSubtypeProperties() {
105         // TODO: Test InputMethodSubtype.getDisplayName()
106         assertEquals(mSubtypeNameResId, mInputMethodSubtype.getNameResId());
107         assertEquals(mSubtypeIconResId, mInputMethodSubtype.getIconResId());
108         assertEquals(mSubtypeLocale, mInputMethodSubtype.getLocale());
109         assertEquals(mSubtypeMode, mInputMethodSubtype.getMode());
110         assertEquals(mSubtypeExtraValue, mInputMethodSubtype.getExtraValue());
111         assertTrue(mInputMethodSubtype.containsExtraValueKey(mSubtypeExtraValue_key));
112         assertEquals(mSubtypeExtraValue_value,
113                 mInputMethodSubtype.getExtraValueOf(mSubtypeExtraValue_key));
114         assertEquals(mSubtypeIsAuxiliary, mInputMethodSubtype.isAuxiliary());
115         assertEquals(mSubtypeOverridesImplicitlyEnabledSubtype,
116                 mInputMethodSubtype.overridesImplicitlyEnabledSubtype());
117         assertEquals(mSubtypeId, mInputMethodSubtype.hashCode());
118     }
119 
assertService(ServiceInfo expected, ServiceInfo actual)120     private void assertService(ServiceInfo expected, ServiceInfo actual) {
121         assertEquals(expected.getIconResource(), actual.getIconResource());
122         assertEquals(expected.labelRes, actual.labelRes);
123         assertEquals(expected.nonLocalizedLabel, actual.nonLocalizedLabel);
124         assertEquals(expected.icon, actual.icon);
125         assertEquals(expected.permission, actual.permission);
126     }
127 
assertInfo(InputMethodInfo info)128     private void assertInfo(InputMethodInfo info) {
129         assertEquals(mPackageName, info.getPackageName());
130         assertEquals(mSettingsActivity, info.getSettingsActivity());
131         ComponentName component = info.getComponent();
132         assertEquals(mClassName, component.getClassName());
133         String expectedId = component.flattenToShortString();
134         assertEquals(expectedId, info.getId());
135         assertEquals(mClassName, info.getServiceName());
136     }
137 
testDump()138     public void testDump() {
139         MockPrinter printer = new MockPrinter();
140         String prefix = "test";
141         mInputMethodInfo.dump(printer, prefix);
142     }
143 
testLoadIcon()144     public void testLoadIcon() {
145         PackageManager pm = mContext.getPackageManager();
146         assertNotNull(mInputMethodInfo.loadIcon(pm));
147     }
148 
testEquals()149     public void testEquals() {
150         InputMethodInfo inputMethodInfo = new InputMethodInfo(mPackageName, mClassName, mLabel,
151                 mSettingsActivity);
152         assertTrue(inputMethodInfo.equals(mInputMethodInfo));
153     }
154 
testLoadLabel()155     public void testLoadLabel() {
156         CharSequence expected = "test";
157         PackageManager pm = mContext.getPackageManager();
158         assertEquals(expected.toString(), mInputMethodInfo.loadLabel(pm).toString());
159     }
160 
testInputMethodInfoWriteToParcel()161     public void testInputMethodInfoWriteToParcel() {
162         final Parcel p = Parcel.obtain();
163         mInputMethodInfo.writeToParcel(p, 0);
164         p.setDataPosition(0);
165         final InputMethodInfo imi = InputMethodInfo.CREATOR.createFromParcel(p);
166         p.recycle();
167 
168         assertEquals(mInputMethodInfo.getPackageName(), imi.getPackageName());
169         assertEquals(mInputMethodInfo.getServiceName(), imi.getServiceName());
170         assertEquals(mInputMethodInfo.getSettingsActivity(), imi.getSettingsActivity());
171         assertEquals(mInputMethodInfo.getId(), imi.getId());
172         assertEquals(mInputMethodInfo.getIsDefaultResourceId(), imi.getIsDefaultResourceId());
173         assertService(mInputMethodInfo.getServiceInfo(), imi.getServiceInfo());
174     }
175 
testInputMethodSubtypeWriteToParcel()176     public void testInputMethodSubtypeWriteToParcel() {
177         final Parcel p = Parcel.obtain();
178         mInputMethodSubtype.writeToParcel(p, 0);
179         p.setDataPosition(0);
180         final InputMethodSubtype subtype = InputMethodSubtype.CREATOR.createFromParcel(p);
181         p.recycle();
182 
183         assertEquals(mInputMethodSubtype.containsExtraValueKey(mSubtypeExtraValue_key),
184                 subtype.containsExtraValueKey(mSubtypeExtraValue_key));
185         assertEquals(mInputMethodSubtype.getExtraValue(), subtype.getExtraValue());
186         assertEquals(mInputMethodSubtype.getExtraValueOf(mSubtypeExtraValue_key),
187                 subtype.getExtraValueOf(mSubtypeExtraValue_key));
188         assertEquals(mInputMethodSubtype.getIconResId(), subtype.getIconResId());
189         assertEquals(mInputMethodSubtype.getLocale(), subtype.getLocale());
190         assertEquals(mInputMethodSubtype.getMode(), subtype.getMode());
191         assertEquals(mInputMethodSubtype.getNameResId(), subtype.getNameResId());
192         assertEquals(mInputMethodSubtype.hashCode(), subtype.hashCode());
193         assertEquals(mInputMethodSubtype.isAuxiliary(), subtype.isAuxiliary());
194         assertEquals(mInputMethodSubtype.overridesImplicitlyEnabledSubtype(),
195                 subtype.overridesImplicitlyEnabledSubtype());
196     }
197 
testInputMethodSubtypesOfSystemImes()198     public void testInputMethodSubtypesOfSystemImes() {
199         if (!getContext().getPackageManager().hasSystemFeature(
200                 PackageManager.FEATURE_INPUT_METHODS)) {
201             return;
202         }
203 
204         final InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
205         final List<InputMethodInfo> imis = imm.getInputMethodList();
206         final ArrayList<String> localeList = new ArrayList<>(Arrays.asList(
207                 Resources.getSystem().getAssets().getLocales()));
208         boolean foundEnabledSystemImeSubtypeWithValidLanguage = false;
209         for (InputMethodInfo imi : imis) {
210             if ((imi.getServiceInfo().applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
211                 continue;
212             }
213             final int subtypeCount = imi.getSubtypeCount();
214             // System IME must have one subtype at least.
215             assertTrue(subtypeCount > 0);
216             if (foundEnabledSystemImeSubtypeWithValidLanguage) {
217                 continue;
218             }
219             final List<InputMethodSubtype> enabledSubtypes =
220                     imm.getEnabledInputMethodSubtypeList(imi, true);
221             SUBTYPE_LOOP:
222             for (InputMethodSubtype subtype : enabledSubtypes) {
223                 final String subtypeLocale = subtype.getLocale();
224                 if (subtypeLocale.length() < 2) {
225                     continue;
226                 }
227                 // TODO: Detect language more strictly.
228                 final String subtypeLanguage = subtypeLocale.substring(0, 2);
229                 for (final String locale : localeList) {
230                     if (locale.startsWith(subtypeLanguage)) {
231                         foundEnabledSystemImeSubtypeWithValidLanguage = true;
232                         break SUBTYPE_LOOP;
233                     }
234                 }
235             }
236         }
237         assertTrue(foundEnabledSystemImeSubtypeWithValidLanguage);
238     }
239 
testAtLeastOneEncryptionAwareInputMethodIsAvailable()240     public void testAtLeastOneEncryptionAwareInputMethodIsAvailable() {
241         if (!getContext().getPackageManager().hasSystemFeature(
242                 PackageManager.FEATURE_INPUT_METHODS)) {
243             return;
244         }
245 
246         final InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
247         final List<InputMethodInfo> imis = imm.getInputMethodList();
248         boolean hasEncryptionAwareInputMethod = false;
249         for (final InputMethodInfo imi : imis) {
250             final ServiceInfo serviceInfo = imi.getServiceInfo();
251             if (serviceInfo == null) {
252                 continue;
253             }
254             if ((serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) !=
255                     ApplicationInfo.FLAG_SYSTEM) {
256                 continue;
257             }
258             if (serviceInfo.encryptionAware) {
259                 hasEncryptionAwareInputMethod = true;
260                 break;
261             }
262         }
263         assertTrue(hasEncryptionAwareInputMethod);
264     }
265 
266     class MockPrinter implements Printer {
267         @Override
println(String x)268         public void println(String x) {
269         }
270     }
271 }
272