InputMethodInfo.java revision fcedfa01907d8a5f804974a4a3585498e8d6c261
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2007-2008 The Android Open Source Project 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License"); you may not 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * use this file except in compliance with the License. You may obtain a copy of 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the License at 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.apache.org/licenses/LICENSE-2.0 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * License for the specific language governing permissions and limitations under 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the License. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)package android.view.inputmethod; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.xmlpull.v1.XmlPullParser; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import org.xmlpull.v1.XmlPullParserException; 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.ComponentName; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.Context; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.pm.ApplicationInfo; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.pm.PackageManager; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.pm.PackageManager.NameNotFoundException; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.content.pm.ResolveInfo; 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.content.pm.ServiceInfo; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.res.Resources; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.res.Resources.NotFoundException; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.res.TypedArray; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.res.XmlResourceParser; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.graphics.drawable.Drawable; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.os.Parcel; 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import android.os.Parcelable; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.util.AttributeSet; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.util.Printer; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.util.Slog; 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.util.Xml; 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder; 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.view.inputmethod.InputMethodSubtypeArray; 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.io.IOException; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.util.ArrayList; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.util.List; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.util.Map; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This class is used to specify meta information of an input method. 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <p>It should be defined in an XML resource file with an {@code <input-method>} element. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For more information, see the guide to 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <a href="{@docRoot}guide/topics/text/creating-input-method.html"> 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * Creating an Input Method</a>.</p> 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @see InputMethodSubtype 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @attr ref android.R.styleable#InputMethod_settingsActivity 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @attr ref android.R.styleable#InputMethod_isDefault 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @attr ref android.R.styleable#InputMethod_supportsSwitchingToNextInputMethod 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public final class InputMethodInfo implements Parcelable { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static final String TAG = "InputMethodInfo"; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The Service that implements this input method component. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final ResolveInfo mService; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The unique string Id to identify the input method. This is generated 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * from the input method component. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final String mId; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /** 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The input method setting activity's name, used by the system settings to 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * launch the setting activity of this input method. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final String mSettingsActivityName; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * The resource in the input method's .apk that holds a boolean indicating 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * whether it should be considered the default input method for this 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * system. This is a resource ID instead of the final value so that it 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * can change based on the configuration (in particular locale). 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final int mIsDefaultResId; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * An array-like container of the subtypes. 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private final InputMethodSubtypeArray mSubtypes; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private final boolean mIsAuxIme; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /** 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Caveat: mForceDefault must be false for production. This flag is only for test. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private final boolean mForceDefault; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * The flag whether this IME supports ways to switch to a next input method (e.g. globe key.) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private final boolean mSupportsSwitchingToNextInputMethod; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Constructor. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param context The Context in which we are parsing the input method. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param service The ResolveInfo returned from the package manager about 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * this input method's component. 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public InputMethodInfo(Context context, ResolveInfo service) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throws XmlPullParserException, IOException { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this(context, service, null); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Constructor. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param context The Context in which we are parsing the input method. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param service The ResolveInfo returned from the package manager about 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this input method's component. 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param additionalSubtypes additional subtypes being added to this InputMethodInfo 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @hide 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public InputMethodInfo(Context context, ResolveInfo service, 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Map<String, List<InputMethodSubtype>> additionalSubtypesMap) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throws XmlPullParserException, IOException { 131d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mService = service; 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ServiceInfo si = service.serviceInfo; 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) mId = new ComponentName(si.packageName, si.name).flattenToShortString(); 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) boolean isAuxIme = true; 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) boolean supportsSwitchingToNextInputMethod = false; // false as default 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mForceDefault = false; 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PackageManager pm = context.getPackageManager(); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) String settingsActivityComponent = null; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int isDefaultResId = 0; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XmlResourceParser parser = null; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser = si.loadXmlMetaData(pm, InputMethod.SERVICE_META_DATA); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parser == null) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new XmlPullParserException("No " 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + InputMethod.SERVICE_META_DATA + " meta-data"); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Resources res = pm.getResourcesForApplication(si.applicationInfo); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AttributeSet attrs = Xml.asAttributeSet(parser); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int type; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && type != XmlPullParser.START_TAG) { 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) String nodeName = parser.getName(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!"input-method".equals(nodeName)) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new XmlPullParserException( 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "Meta-data does not start with input-method tag"); 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TypedArray sa = res.obtainAttributes(attrs, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) com.android.internal.R.styleable.InputMethod); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settingsActivityComponent = sa.getString( 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) com.android.internal.R.styleable.InputMethod_settingsActivity); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isDefaultResId = sa.getResourceId( 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) com.android.internal.R.styleable.InputMethod_isDefault, 0); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) supportsSwitchingToNextInputMethod = sa.getBoolean( 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) com.android.internal.R.styleable.InputMethod_supportsSwitchingToNextInputMethod, 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) false); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sa.recycle(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final int depth = parser.getDepth(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse all subtypes 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && type != XmlPullParser.END_DOCUMENT) { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == XmlPullParser.START_TAG) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nodeName = parser.getName(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!"subtype".equals(nodeName)) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new XmlPullParserException( 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Meta-data in input-method does not start with subtype tag"); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final TypedArray a = res.obtainAttributes( 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attrs, com.android.internal.R.styleable.InputMethod_Subtype); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final InputMethodSubtype subtype = new InputMethodSubtypeBuilder() 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .setSubtypeNameResId(a.getResourceId(com.android.internal.R.styleable 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .InputMethod_Subtype_label, 0)) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .setSubtypeIconResId(a.getResourceId(com.android.internal.R.styleable 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .InputMethod_Subtype_icon, 0)) 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) .setSubtypeLocale(a.getString(com.android.internal.R.styleable 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .InputMethod_Subtype_imeSubtypeLocale)) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .setSubtypeMode(a.getString(com.android.internal.R.styleable 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .InputMethod_Subtype_imeSubtypeMode)) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .setSubtypeExtraValue(a.getString(com.android.internal.R.styleable 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .InputMethod_Subtype_imeSubtypeExtraValue)) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .setIsAuxiliary(a.getBoolean(com.android.internal.R.styleable 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .InputMethod_Subtype_isAuxiliary, false)) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .setOverridesImplicitlyEnabledSubtype(a.getBoolean( 203ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch com.android.internal.R.styleable 204ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch .InputMethod_Subtype_overridesImplicitlyEnabledSubtype, false)) 205ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch .setSubtypeId(a.getInt(com.android.internal.R.styleable 206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) .InputMethod_Subtype_subtypeId, 0 /* use Arrays.hashCode */)) 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .setIsAsciiCapable(a.getBoolean(com.android.internal.R.styleable 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .InputMethod_Subtype_isAsciiCapable, false)).build(); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!subtype.isAuxiliary()) { 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) isAuxIme = false; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subtypes.add(subtype); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } catch (NameNotFoundException e) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new XmlPullParserException( 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Unable to create context for: " + si.packageName); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } finally { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parser != null) parser.close(); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (subtypes.size() == 0) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isAuxIme = false; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (additionalSubtypesMap != null && additionalSubtypesMap.containsKey(mId)) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final List<InputMethodSubtype> additionalSubtypes = additionalSubtypesMap.get(mId); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final int N = additionalSubtypes.size(); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < N; ++i) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final InputMethodSubtype subtype = additionalSubtypes.get(i); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!subtypes.contains(subtype)) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subtypes.add(subtype); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Slog.w(TAG, "Duplicated subtype definition found: " 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + subtype.getLocale() + ", " + subtype.getMode()); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSubtypes = new InputMethodSubtypeArray(subtypes); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSettingsActivityName = settingsActivityComponent; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mIsDefaultResId = isDefaultResId; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mIsAuxIme = isAuxIme; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSupportsSwitchingToNextInputMethod = supportsSwitchingToNextInputMethod; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InputMethodInfo(Parcel source) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mId = source.readString(); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSettingsActivityName = source.readString(); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mIsDefaultResId = source.readInt(); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mIsAuxIme = source.readInt() == 1; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSupportsSwitchingToNextInputMethod = source.readInt() == 1; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mService = ResolveInfo.CREATOR.createFromParcel(source); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSubtypes = new InputMethodSubtypeArray(source); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mForceDefault = false; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Temporary API for creating a built-in input method for test. 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public InputMethodInfo(String packageName, String className, 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CharSequence label, String settingsActivity) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this(buildDummyResolveInfo(packageName, className, label), false, settingsActivity, null, 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, false /* forceDefault */, true /* supportsSwitchingToNextInputMethod */); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Temporary API for creating a built-in input method for test. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @hide 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public InputMethodInfo(ResolveInfo ri, boolean isAuxIme, 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) String settingsActivity, List<InputMethodSubtype> subtypes, int isDefaultResId, 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) boolean forceDefault) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this(ri, isAuxIme, settingsActivity, subtypes, isDefaultResId, 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forceDefault, true /* supportsSwitchingToNextInputMethod */); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /** 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Temporary API for creating a built-in input method for test. 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @hide 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public InputMethodInfo(ResolveInfo ri, boolean isAuxIme, 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) String settingsActivity, List<InputMethodSubtype> subtypes, int isDefaultResId, 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) boolean forceDefault, boolean supportsSwitchingToNextInputMethod) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final ServiceInfo si = ri.serviceInfo; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mService = ri; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mId = new ComponentName(si.packageName, si.name).flattenToShortString(); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSettingsActivityName = settingsActivity; 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mIsDefaultResId = isDefaultResId; 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mIsAuxIme = isAuxIme; 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mSubtypes = new InputMethodSubtypeArray(subtypes); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mForceDefault = forceDefault; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSupportsSwitchingToNextInputMethod = supportsSwitchingToNextInputMethod; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private static ResolveInfo buildDummyResolveInfo(String packageName, String className, 296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CharSequence label) { 297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ResolveInfo ri = new ResolveInfo(); 298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ServiceInfo si = new ServiceInfo(); 299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ApplicationInfo ai = new ApplicationInfo(); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ai.packageName = packageName; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ai.enabled = true; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) si.applicationInfo = ai; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) si.enabled = true; 304 si.packageName = packageName; 305 si.name = className; 306 si.exported = true; 307 si.nonLocalizedLabel = label; 308 ri.serviceInfo = si; 309 return ri; 310 } 311 312 /** 313 * Return a unique ID for this input method. The ID is generated from 314 * the package and class name implementing the method. 315 */ 316 public String getId() { 317 return mId; 318 } 319 320 /** 321 * Return the .apk package that implements this input method. 322 */ 323 public String getPackageName() { 324 return mService.serviceInfo.packageName; 325 } 326 327 /** 328 * Return the class name of the service component that implements 329 * this input method. 330 */ 331 public String getServiceName() { 332 return mService.serviceInfo.name; 333 } 334 335 /** 336 * Return the raw information about the Service implementing this 337 * input method. Do not modify the returned object. 338 */ 339 public ServiceInfo getServiceInfo() { 340 return mService.serviceInfo; 341 } 342 343 /** 344 * Return the component of the service that implements this input 345 * method. 346 */ 347 public ComponentName getComponent() { 348 return new ComponentName(mService.serviceInfo.packageName, 349 mService.serviceInfo.name); 350 } 351 352 /** 353 * Load the user-displayed label for this input method. 354 * 355 * @param pm Supply a PackageManager used to load the input method's 356 * resources. 357 */ 358 public CharSequence loadLabel(PackageManager pm) { 359 return mService.loadLabel(pm); 360 } 361 362 /** 363 * Load the user-displayed icon for this input method. 364 * 365 * @param pm Supply a PackageManager used to load the input method's 366 * resources. 367 */ 368 public Drawable loadIcon(PackageManager pm) { 369 return mService.loadIcon(pm); 370 } 371 372 /** 373 * Return the class name of an activity that provides a settings UI for 374 * the input method. You can launch this activity be starting it with 375 * an {@link android.content.Intent} whose action is MAIN and with an 376 * explicit {@link android.content.ComponentName} 377 * composed of {@link #getPackageName} and the class name returned here. 378 * 379 * <p>A null will be returned if there is no settings activity associated 380 * with the input method.</p> 381 */ 382 public String getSettingsActivity() { 383 return mSettingsActivityName; 384 } 385 386 /** 387 * Return the count of the subtypes of Input Method. 388 */ 389 public int getSubtypeCount() { 390 return mSubtypes.getCount(); 391 } 392 393 /** 394 * Return the Input Method's subtype at the specified index. 395 * 396 * @param index the index of the subtype to return. 397 */ 398 public InputMethodSubtype getSubtypeAt(int index) { 399 return mSubtypes.get(index); 400 } 401 402 /** 403 * Return the resource identifier of a resource inside of this input 404 * method's .apk that determines whether it should be considered a 405 * default input method for the system. 406 */ 407 public int getIsDefaultResourceId() { 408 return mIsDefaultResId; 409 } 410 411 /** 412 * Return whether or not this ime is a default ime or not. 413 * @hide 414 */ 415 public boolean isDefault(Context context) { 416 if (mForceDefault) { 417 return true; 418 } 419 try { 420 if (getIsDefaultResourceId() == 0) { 421 return false; 422 } 423 final Resources res = context.createPackageContext(getPackageName(), 0).getResources(); 424 return res.getBoolean(getIsDefaultResourceId()); 425 } catch (NameNotFoundException | NotFoundException e) { 426 return false; 427 } 428 } 429 430 public void dump(Printer pw, String prefix) { 431 pw.println(prefix + "mId=" + mId 432 + " mSettingsActivityName=" + mSettingsActivityName); 433 pw.println(prefix + "mIsDefaultResId=0x" 434 + Integer.toHexString(mIsDefaultResId)); 435 pw.println(prefix + "Service:"); 436 mService.dump(pw, prefix + " "); 437 } 438 439 @Override 440 public String toString() { 441 return "InputMethodInfo{" + mId 442 + ", settings: " 443 + mSettingsActivityName + "}"; 444 } 445 446 /** 447 * Used to test whether the given parameter object is an 448 * {@link InputMethodInfo} and its Id is the same to this one. 449 * 450 * @return true if the given parameter object is an 451 * {@link InputMethodInfo} and its Id is the same to this one. 452 */ 453 @Override 454 public boolean equals(Object o) { 455 if (o == this) return true; 456 if (o == null) return false; 457 458 if (!(o instanceof InputMethodInfo)) return false; 459 460 InputMethodInfo obj = (InputMethodInfo) o; 461 return mId.equals(obj.mId); 462 } 463 464 @Override 465 public int hashCode() { 466 return mId.hashCode(); 467 } 468 469 /** 470 * @hide 471 */ 472 public boolean isAuxiliaryIme() { 473 return mIsAuxIme; 474 } 475 476 /** 477 * @return true if this input method supports ways to switch to a next input method. 478 * @hide 479 */ 480 public boolean supportsSwitchingToNextInputMethod() { 481 return mSupportsSwitchingToNextInputMethod; 482 } 483 484 /** 485 * Used to package this object into a {@link Parcel}. 486 * 487 * @param dest The {@link Parcel} to be written. 488 * @param flags The flags used for parceling. 489 */ 490 @Override 491 public void writeToParcel(Parcel dest, int flags) { 492 dest.writeString(mId); 493 dest.writeString(mSettingsActivityName); 494 dest.writeInt(mIsDefaultResId); 495 dest.writeInt(mIsAuxIme ? 1 : 0); 496 dest.writeInt(mSupportsSwitchingToNextInputMethod ? 1 : 0); 497 mService.writeToParcel(dest, flags); 498 mSubtypes.writeToParcel(dest); 499 } 500 501 /** 502 * Used to make this class parcelable. 503 */ 504 public static final Parcelable.Creator<InputMethodInfo> CREATOR 505 = new Parcelable.Creator<InputMethodInfo>() { 506 @Override 507 public InputMethodInfo createFromParcel(Parcel source) { 508 return new InputMethodInfo(source); 509 } 510 511 @Override 512 public InputMethodInfo[] newArray(int size) { 513 return new InputMethodInfo[size]; 514 } 515 }; 516 517 @Override 518 public int describeContents() { 519 return 0; 520 } 521} 522