1988323c57bd25a58f05dfa492d9b9c8ab62c5153satok/*
2988323c57bd25a58f05dfa492d9b9c8ab62c5153satok * Copyright (C) 2011 The Android Open Source Project
3988323c57bd25a58f05dfa492d9b9c8ab62c5153satok *
4988323c57bd25a58f05dfa492d9b9c8ab62c5153satok * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5988323c57bd25a58f05dfa492d9b9c8ab62c5153satok * use this file except in compliance with the License. You may obtain a copy of
6988323c57bd25a58f05dfa492d9b9c8ab62c5153satok * the License at
7988323c57bd25a58f05dfa492d9b9c8ab62c5153satok *
8988323c57bd25a58f05dfa492d9b9c8ab62c5153satok * http://www.apache.org/licenses/LICENSE-2.0
9988323c57bd25a58f05dfa492d9b9c8ab62c5153satok *
10988323c57bd25a58f05dfa492d9b9c8ab62c5153satok * Unless required by applicable law or agreed to in writing, software
11988323c57bd25a58f05dfa492d9b9c8ab62c5153satok * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12988323c57bd25a58f05dfa492d9b9c8ab62c5153satok * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13988323c57bd25a58f05dfa492d9b9c8ab62c5153satok * License for the specific language governing permissions and limitations under
14988323c57bd25a58f05dfa492d9b9c8ab62c5153satok * the License.
15988323c57bd25a58f05dfa492d9b9c8ab62c5153satok */
16988323c57bd25a58f05dfa492d9b9c8ab62c5153satok
17988323c57bd25a58f05dfa492d9b9c8ab62c5153satokpackage android.view.textservice;
18988323c57bd25a58f05dfa492d9b9c8ab62c5153satok
1903b2ea1102d9e3e9f189173878706ab04533eea3satokimport org.xmlpull.v1.XmlPullParser;
2003b2ea1102d9e3e9f189173878706ab04533eea3satokimport org.xmlpull.v1.XmlPullParserException;
2103b2ea1102d9e3e9f189173878706ab04533eea3satok
22988323c57bd25a58f05dfa492d9b9c8ab62c5153satokimport android.content.ComponentName;
23988323c57bd25a58f05dfa492d9b9c8ab62c5153satokimport android.content.Context;
24562ab585f9e413d9696ee250e5ec02f95889a157satokimport android.content.pm.PackageManager;
25988323c57bd25a58f05dfa492d9b9c8ab62c5153satokimport android.content.pm.ResolveInfo;
26988323c57bd25a58f05dfa492d9b9c8ab62c5153satokimport android.content.pm.ServiceInfo;
2703b2ea1102d9e3e9f189173878706ab04533eea3satokimport android.content.res.Resources;
2803b2ea1102d9e3e9f189173878706ab04533eea3satokimport android.content.res.TypedArray;
2903b2ea1102d9e3e9f189173878706ab04533eea3satokimport android.content.res.XmlResourceParser;
30562ab585f9e413d9696ee250e5ec02f95889a157satokimport android.graphics.drawable.Drawable;
31988323c57bd25a58f05dfa492d9b9c8ab62c5153satokimport android.os.Parcel;
32988323c57bd25a58f05dfa492d9b9c8ab62c5153satokimport android.os.Parcelable;
3303b2ea1102d9e3e9f189173878706ab04533eea3satokimport android.util.AttributeSet;
3403b2ea1102d9e3e9f189173878706ab04533eea3satokimport android.util.Slog;
3503b2ea1102d9e3e9f189173878706ab04533eea3satokimport android.util.Xml;
3603b2ea1102d9e3e9f189173878706ab04533eea3satok
3703b2ea1102d9e3e9f189173878706ab04533eea3satokimport java.io.IOException;
3803b2ea1102d9e3e9f189173878706ab04533eea3satokimport java.util.ArrayList;
39988323c57bd25a58f05dfa492d9b9c8ab62c5153satok
40988323c57bd25a58f05dfa492d9b9c8ab62c5153satok/**
41f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa * This class is used to specify meta information of a spell checker.
42988323c57bd25a58f05dfa492d9b9c8ab62c5153satok */
43988323c57bd25a58f05dfa492d9b9c8ab62c5153satokpublic final class SpellCheckerInfo implements Parcelable {
4403b2ea1102d9e3e9f189173878706ab04533eea3satok    private static final String TAG = SpellCheckerInfo.class.getSimpleName();
45988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    private final ResolveInfo mService;
46988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    private final String mId;
4703b2ea1102d9e3e9f189173878706ab04533eea3satok    private final int mLabel;
4803b2ea1102d9e3e9f189173878706ab04533eea3satok
4903b2ea1102d9e3e9f189173878706ab04533eea3satok    /**
5003b2ea1102d9e3e9f189173878706ab04533eea3satok     * The spell checker setting activity's name, used by the system settings to
5103b2ea1102d9e3e9f189173878706ab04533eea3satok     * launch the setting activity.
5203b2ea1102d9e3e9f189173878706ab04533eea3satok     */
5303b2ea1102d9e3e9f189173878706ab04533eea3satok    private final String mSettingsActivityName;
5403b2ea1102d9e3e9f189173878706ab04533eea3satok
5503b2ea1102d9e3e9f189173878706ab04533eea3satok    /**
56f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa     * The array of subtypes.
5703b2ea1102d9e3e9f189173878706ab04533eea3satok     */
5803b2ea1102d9e3e9f189173878706ab04533eea3satok    private final ArrayList<SpellCheckerSubtype> mSubtypes = new ArrayList<SpellCheckerSubtype>();
59988323c57bd25a58f05dfa492d9b9c8ab62c5153satok
60988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    /**
61988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     * Constructor.
62988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     * @hide
63988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     */
6403b2ea1102d9e3e9f189173878706ab04533eea3satok    public SpellCheckerInfo(Context context, ResolveInfo service)
6503b2ea1102d9e3e9f189173878706ab04533eea3satok            throws XmlPullParserException, IOException {
66988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        mService = service;
67988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        ServiceInfo si = service.serviceInfo;
68988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        mId = new ComponentName(si.packageName, si.name).flattenToShortString();
6903b2ea1102d9e3e9f189173878706ab04533eea3satok
7003b2ea1102d9e3e9f189173878706ab04533eea3satok        final PackageManager pm = context.getPackageManager();
7103b2ea1102d9e3e9f189173878706ab04533eea3satok        int label = 0;
7203b2ea1102d9e3e9f189173878706ab04533eea3satok        String settingsActivityComponent = null;
7303b2ea1102d9e3e9f189173878706ab04533eea3satok
7403b2ea1102d9e3e9f189173878706ab04533eea3satok        XmlResourceParser parser = null;
7503b2ea1102d9e3e9f189173878706ab04533eea3satok        try {
7603b2ea1102d9e3e9f189173878706ab04533eea3satok            parser = si.loadXmlMetaData(pm, SpellCheckerSession.SERVICE_META_DATA);
7703b2ea1102d9e3e9f189173878706ab04533eea3satok            if (parser == null) {
7803b2ea1102d9e3e9f189173878706ab04533eea3satok                throw new XmlPullParserException("No "
7903b2ea1102d9e3e9f189173878706ab04533eea3satok                        + SpellCheckerSession.SERVICE_META_DATA + " meta-data");
8003b2ea1102d9e3e9f189173878706ab04533eea3satok            }
8103b2ea1102d9e3e9f189173878706ab04533eea3satok
8203b2ea1102d9e3e9f189173878706ab04533eea3satok            final Resources res = pm.getResourcesForApplication(si.applicationInfo);
8303b2ea1102d9e3e9f189173878706ab04533eea3satok            final AttributeSet attrs = Xml.asAttributeSet(parser);
8403b2ea1102d9e3e9f189173878706ab04533eea3satok            int type;
8503b2ea1102d9e3e9f189173878706ab04533eea3satok            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
8603b2ea1102d9e3e9f189173878706ab04533eea3satok                    && type != XmlPullParser.START_TAG) {
8703b2ea1102d9e3e9f189173878706ab04533eea3satok            }
8803b2ea1102d9e3e9f189173878706ab04533eea3satok
8903b2ea1102d9e3e9f189173878706ab04533eea3satok            final String nodeName = parser.getName();
9003b2ea1102d9e3e9f189173878706ab04533eea3satok            if (!"spell-checker".equals(nodeName)) {
9103b2ea1102d9e3e9f189173878706ab04533eea3satok                throw new XmlPullParserException(
9203b2ea1102d9e3e9f189173878706ab04533eea3satok                        "Meta-data does not start with spell-checker tag");
9303b2ea1102d9e3e9f189173878706ab04533eea3satok            }
9403b2ea1102d9e3e9f189173878706ab04533eea3satok
9503b2ea1102d9e3e9f189173878706ab04533eea3satok            TypedArray sa = res.obtainAttributes(attrs,
9603b2ea1102d9e3e9f189173878706ab04533eea3satok                    com.android.internal.R.styleable.SpellChecker);
9703b2ea1102d9e3e9f189173878706ab04533eea3satok            label = sa.getResourceId(com.android.internal.R.styleable.SpellChecker_label, 0);
9803b2ea1102d9e3e9f189173878706ab04533eea3satok            settingsActivityComponent = sa.getString(
9903b2ea1102d9e3e9f189173878706ab04533eea3satok                    com.android.internal.R.styleable.SpellChecker_settingsActivity);
10003b2ea1102d9e3e9f189173878706ab04533eea3satok            sa.recycle();
10103b2ea1102d9e3e9f189173878706ab04533eea3satok
10203b2ea1102d9e3e9f189173878706ab04533eea3satok            final int depth = parser.getDepth();
10303b2ea1102d9e3e9f189173878706ab04533eea3satok            // Parse all subtypes
10403b2ea1102d9e3e9f189173878706ab04533eea3satok            while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
10503b2ea1102d9e3e9f189173878706ab04533eea3satok                    && type != XmlPullParser.END_DOCUMENT) {
10603b2ea1102d9e3e9f189173878706ab04533eea3satok                if (type == XmlPullParser.START_TAG) {
10703b2ea1102d9e3e9f189173878706ab04533eea3satok                    final String subtypeNodeName = parser.getName();
10803b2ea1102d9e3e9f189173878706ab04533eea3satok                    if (!"subtype".equals(subtypeNodeName)) {
10903b2ea1102d9e3e9f189173878706ab04533eea3satok                        throw new XmlPullParserException(
11003b2ea1102d9e3e9f189173878706ab04533eea3satok                                "Meta-data in spell-checker does not start with subtype tag");
11103b2ea1102d9e3e9f189173878706ab04533eea3satok                    }
11203b2ea1102d9e3e9f189173878706ab04533eea3satok                    final TypedArray a = res.obtainAttributes(
11303b2ea1102d9e3e9f189173878706ab04533eea3satok                            attrs, com.android.internal.R.styleable.SpellChecker_Subtype);
11403b2ea1102d9e3e9f189173878706ab04533eea3satok                    SpellCheckerSubtype subtype = new SpellCheckerSubtype(
11503b2ea1102d9e3e9f189173878706ab04533eea3satok                            a.getResourceId(com.android.internal.R.styleable
11603b2ea1102d9e3e9f189173878706ab04533eea3satok                                    .SpellChecker_Subtype_label, 0),
11703b2ea1102d9e3e9f189173878706ab04533eea3satok                            a.getString(com.android.internal.R.styleable
11803b2ea1102d9e3e9f189173878706ab04533eea3satok                                    .SpellChecker_Subtype_subtypeLocale),
11903b2ea1102d9e3e9f189173878706ab04533eea3satok                            a.getString(com.android.internal.R.styleable
12003b2ea1102d9e3e9f189173878706ab04533eea3satok                                    .SpellChecker_Subtype_subtypeExtraValue));
12103b2ea1102d9e3e9f189173878706ab04533eea3satok                    mSubtypes.add(subtype);
12203b2ea1102d9e3e9f189173878706ab04533eea3satok                }
12303b2ea1102d9e3e9f189173878706ab04533eea3satok            }
12403b2ea1102d9e3e9f189173878706ab04533eea3satok        } catch (Exception e) {
12503b2ea1102d9e3e9f189173878706ab04533eea3satok            Slog.e(TAG, "Caught exception: " + e);
12603b2ea1102d9e3e9f189173878706ab04533eea3satok            throw new XmlPullParserException(
12703b2ea1102d9e3e9f189173878706ab04533eea3satok                    "Unable to create context for: " + si.packageName);
12803b2ea1102d9e3e9f189173878706ab04533eea3satok        } finally {
12903b2ea1102d9e3e9f189173878706ab04533eea3satok            if (parser != null) parser.close();
13003b2ea1102d9e3e9f189173878706ab04533eea3satok        }
13103b2ea1102d9e3e9f189173878706ab04533eea3satok        mLabel = label;
13203b2ea1102d9e3e9f189173878706ab04533eea3satok        mSettingsActivityName = settingsActivityComponent;
133988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    }
134988323c57bd25a58f05dfa492d9b9c8ab62c5153satok
135988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    /**
136988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     * Constructor.
137988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     * @hide
138988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     */
139988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    public SpellCheckerInfo(Parcel source) {
14003b2ea1102d9e3e9f189173878706ab04533eea3satok        mLabel = source.readInt();
141988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        mId = source.readString();
14203b2ea1102d9e3e9f189173878706ab04533eea3satok        mSettingsActivityName = source.readString();
143988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        mService = ResolveInfo.CREATOR.createFromParcel(source);
14403b2ea1102d9e3e9f189173878706ab04533eea3satok        source.readTypedList(mSubtypes, SpellCheckerSubtype.CREATOR);
145988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    }
146988323c57bd25a58f05dfa492d9b9c8ab62c5153satok
147988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    /**
148988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     * Return a unique ID for this spell checker.  The ID is generated from
149988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     * the package and class name implementing the method.
150988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     */
151988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    public String getId() {
152988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        return mId;
153988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    }
154988323c57bd25a58f05dfa492d9b9c8ab62c5153satok
155f6710615c6cc1746d1ecc7aebc9afed457dcca41satok    /**
156988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     * Return the component of the service that implements.
157988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     */
158988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    public ComponentName getComponent() {
159988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        return new ComponentName(
160988323c57bd25a58f05dfa492d9b9c8ab62c5153satok                mService.serviceInfo.packageName, mService.serviceInfo.name);
161988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    }
162988323c57bd25a58f05dfa492d9b9c8ab62c5153satok
163988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    /**
16403b2ea1102d9e3e9f189173878706ab04533eea3satok     * Return the .apk package that implements this.
165988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     */
166988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    public String getPackageName() {
167988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        return mService.serviceInfo.packageName;
168988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    }
169988323c57bd25a58f05dfa492d9b9c8ab62c5153satok
170988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    /**
171988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     * Used to package this object into a {@link Parcel}.
172988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     *
173988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     * @param dest The {@link Parcel} to be written.
174988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     * @param flags The flags used for parceling.
175988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     */
176988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    @Override
177988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    public void writeToParcel(Parcel dest, int flags) {
17803b2ea1102d9e3e9f189173878706ab04533eea3satok        dest.writeInt(mLabel);
179988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        dest.writeString(mId);
18003b2ea1102d9e3e9f189173878706ab04533eea3satok        dest.writeString(mSettingsActivityName);
181988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        mService.writeToParcel(dest, flags);
18203b2ea1102d9e3e9f189173878706ab04533eea3satok        dest.writeTypedList(mSubtypes);
183988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    }
184988323c57bd25a58f05dfa492d9b9c8ab62c5153satok
185988323c57bd25a58f05dfa492d9b9c8ab62c5153satok
186988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    /**
187988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     * Used to make this class parcelable.
188988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     */
189988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    public static final Parcelable.Creator<SpellCheckerInfo> CREATOR
190988323c57bd25a58f05dfa492d9b9c8ab62c5153satok            = new Parcelable.Creator<SpellCheckerInfo>() {
191988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        @Override
192988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        public SpellCheckerInfo createFromParcel(Parcel source) {
193988323c57bd25a58f05dfa492d9b9c8ab62c5153satok            return new SpellCheckerInfo(source);
194988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        }
195988323c57bd25a58f05dfa492d9b9c8ab62c5153satok
196988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        @Override
197988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        public SpellCheckerInfo[] newArray(int size) {
198988323c57bd25a58f05dfa492d9b9c8ab62c5153satok            return new SpellCheckerInfo[size];
199988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        }
200988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    };
201988323c57bd25a58f05dfa492d9b9c8ab62c5153satok
202988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    /**
203562ab585f9e413d9696ee250e5ec02f95889a157satok     * Load the user-displayed label for this spell checker.
204562ab585f9e413d9696ee250e5ec02f95889a157satok     *
205562ab585f9e413d9696ee250e5ec02f95889a157satok     * @param pm Supply a PackageManager used to load the spell checker's resources.
206562ab585f9e413d9696ee250e5ec02f95889a157satok     */
207562ab585f9e413d9696ee250e5ec02f95889a157satok    public CharSequence loadLabel(PackageManager pm) {
20803b2ea1102d9e3e9f189173878706ab04533eea3satok        if (mLabel == 0 || pm == null) return "";
20903b2ea1102d9e3e9f189173878706ab04533eea3satok        return pm.getText(getPackageName(), mLabel, mService.serviceInfo.applicationInfo);
210562ab585f9e413d9696ee250e5ec02f95889a157satok    }
211562ab585f9e413d9696ee250e5ec02f95889a157satok
212562ab585f9e413d9696ee250e5ec02f95889a157satok    /**
213562ab585f9e413d9696ee250e5ec02f95889a157satok     * Load the user-displayed icon for this spell checker.
214562ab585f9e413d9696ee250e5ec02f95889a157satok     *
215562ab585f9e413d9696ee250e5ec02f95889a157satok     * @param pm Supply a PackageManager used to load the spell checker's resources.
216562ab585f9e413d9696ee250e5ec02f95889a157satok     */
217562ab585f9e413d9696ee250e5ec02f95889a157satok    public Drawable loadIcon(PackageManager pm) {
218562ab585f9e413d9696ee250e5ec02f95889a157satok        return mService.loadIcon(pm);
219562ab585f9e413d9696ee250e5ec02f95889a157satok    }
220562ab585f9e413d9696ee250e5ec02f95889a157satok
2212388a7ba6218f44400ee78016282cb96c02dfc54satok
2222388a7ba6218f44400ee78016282cb96c02dfc54satok    /**
2232388a7ba6218f44400ee78016282cb96c02dfc54satok     * Return the raw information about the Service implementing this
2242388a7ba6218f44400ee78016282cb96c02dfc54satok     * spell checker.  Do not modify the returned object.
2252388a7ba6218f44400ee78016282cb96c02dfc54satok     */
2262388a7ba6218f44400ee78016282cb96c02dfc54satok    public ServiceInfo getServiceInfo() {
2272388a7ba6218f44400ee78016282cb96c02dfc54satok        return mService.serviceInfo;
2282388a7ba6218f44400ee78016282cb96c02dfc54satok    }
2292388a7ba6218f44400ee78016282cb96c02dfc54satok
230562ab585f9e413d9696ee250e5ec02f95889a157satok    /**
23103b2ea1102d9e3e9f189173878706ab04533eea3satok     * Return the class name of an activity that provides a settings UI.
23203b2ea1102d9e3e9f189173878706ab04533eea3satok     * You can launch this activity be starting it with
23303b2ea1102d9e3e9f189173878706ab04533eea3satok     * an {@link android.content.Intent} whose action is MAIN and with an
23403b2ea1102d9e3e9f189173878706ab04533eea3satok     * explicit {@link android.content.ComponentName}
23503b2ea1102d9e3e9f189173878706ab04533eea3satok     * composed of {@link #getPackageName} and the class name returned here.
23603b2ea1102d9e3e9f189173878706ab04533eea3satok     *
23703b2ea1102d9e3e9f189173878706ab04533eea3satok     * <p>A null will be returned if there is no settings activity.
23803b2ea1102d9e3e9f189173878706ab04533eea3satok     */
23903b2ea1102d9e3e9f189173878706ab04533eea3satok    public String getSettingsActivity() {
24003b2ea1102d9e3e9f189173878706ab04533eea3satok        return mSettingsActivityName;
24103b2ea1102d9e3e9f189173878706ab04533eea3satok    }
24203b2ea1102d9e3e9f189173878706ab04533eea3satok
24303b2ea1102d9e3e9f189173878706ab04533eea3satok    /**
24403b2ea1102d9e3e9f189173878706ab04533eea3satok     * Return the count of the subtypes.
24503b2ea1102d9e3e9f189173878706ab04533eea3satok     */
24603b2ea1102d9e3e9f189173878706ab04533eea3satok    public int getSubtypeCount() {
24703b2ea1102d9e3e9f189173878706ab04533eea3satok        return mSubtypes.size();
24803b2ea1102d9e3e9f189173878706ab04533eea3satok    }
24903b2ea1102d9e3e9f189173878706ab04533eea3satok
25003b2ea1102d9e3e9f189173878706ab04533eea3satok    /**
25103b2ea1102d9e3e9f189173878706ab04533eea3satok     * Return the subtype at the specified index.
25203b2ea1102d9e3e9f189173878706ab04533eea3satok     *
25303b2ea1102d9e3e9f189173878706ab04533eea3satok     * @param index the index of the subtype to return.
25403b2ea1102d9e3e9f189173878706ab04533eea3satok     */
25503b2ea1102d9e3e9f189173878706ab04533eea3satok    public SpellCheckerSubtype getSubtypeAt(int index) {
25603b2ea1102d9e3e9f189173878706ab04533eea3satok        return mSubtypes.get(index);
25703b2ea1102d9e3e9f189173878706ab04533eea3satok    }
25803b2ea1102d9e3e9f189173878706ab04533eea3satok
25903b2ea1102d9e3e9f189173878706ab04533eea3satok    /**
260988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     * Used to make this class parcelable.
261988323c57bd25a58f05dfa492d9b9c8ab62c5153satok     */
262988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    @Override
263988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    public int describeContents() {
264988323c57bd25a58f05dfa492d9b9c8ab62c5153satok        return 0;
265988323c57bd25a58f05dfa492d9b9c8ab62c5153satok    }
266988323c57bd25a58f05dfa492d9b9c8ab62c5153satok}
267