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