| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| |
| package android.view.textservice; |
| |
| import org.xmlpull.v1.XmlPullParser; |
| import org.xmlpull.v1.XmlPullParserException; |
| |
| import android.content.ComponentName; |
| import android.content.Context; |
| import android.content.pm.PackageManager; |
| import android.content.pm.ResolveInfo; |
| import android.content.pm.ServiceInfo; |
| import android.content.res.Resources; |
| import android.content.res.TypedArray; |
| import android.content.res.XmlResourceParser; |
| import android.graphics.drawable.Drawable; |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| import android.util.AttributeSet; |
| import android.util.Slog; |
| import android.util.Xml; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| |
| /** |
| * This class is used to specify meta information of a spell checker. |
| */ |
| public final class SpellCheckerInfo implements Parcelable { |
| private static final String TAG = SpellCheckerInfo.class.getSimpleName(); |
| private final ResolveInfo mService; |
| private final String mId; |
| private final int mLabel; |
| |
| /** |
| * The spell checker setting activity's name, used by the system settings to |
| * launch the setting activity. |
| */ |
| private final String mSettingsActivityName; |
| |
| /** |
| * The array of subtypes. |
| */ |
| private final ArrayList<SpellCheckerSubtype> mSubtypes = new ArrayList<SpellCheckerSubtype>(); |
| |
| /** |
| * Constructor. |
| * @hide |
| */ |
| public SpellCheckerInfo(Context context, ResolveInfo service) |
| throws XmlPullParserException, IOException { |
| mService = service; |
| ServiceInfo si = service.serviceInfo; |
| mId = new ComponentName(si.packageName, si.name).flattenToShortString(); |
| |
| final PackageManager pm = context.getPackageManager(); |
| int label = 0; |
| String settingsActivityComponent = null; |
| |
| XmlResourceParser parser = null; |
| try { |
| parser = si.loadXmlMetaData(pm, SpellCheckerSession.SERVICE_META_DATA); |
| if (parser == null) { |
| throw new XmlPullParserException("No " |
| + SpellCheckerSession.SERVICE_META_DATA + " meta-data"); |
| } |
| |
| final Resources res = pm.getResourcesForApplication(si.applicationInfo); |
| final AttributeSet attrs = Xml.asAttributeSet(parser); |
| int type; |
| while ((type=parser.next()) != XmlPullParser.END_DOCUMENT |
| && type != XmlPullParser.START_TAG) { |
| } |
| |
| final String nodeName = parser.getName(); |
| if (!"spell-checker".equals(nodeName)) { |
| throw new XmlPullParserException( |
| "Meta-data does not start with spell-checker tag"); |
| } |
| |
| TypedArray sa = res.obtainAttributes(attrs, |
| com.android.internal.R.styleable.SpellChecker); |
| label = sa.getResourceId(com.android.internal.R.styleable.SpellChecker_label, 0); |
| settingsActivityComponent = sa.getString( |
| com.android.internal.R.styleable.SpellChecker_settingsActivity); |
| sa.recycle(); |
| |
| final int depth = parser.getDepth(); |
| // Parse all subtypes |
| while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) |
| && type != XmlPullParser.END_DOCUMENT) { |
| if (type == XmlPullParser.START_TAG) { |
| final String subtypeNodeName = parser.getName(); |
| if (!"subtype".equals(subtypeNodeName)) { |
| throw new XmlPullParserException( |
| "Meta-data in spell-checker does not start with subtype tag"); |
| } |
| final TypedArray a = res.obtainAttributes( |
| attrs, com.android.internal.R.styleable.SpellChecker_Subtype); |
| SpellCheckerSubtype subtype = new SpellCheckerSubtype( |
| a.getResourceId(com.android.internal.R.styleable |
| .SpellChecker_Subtype_label, 0), |
| a.getString(com.android.internal.R.styleable |
| .SpellChecker_Subtype_subtypeLocale), |
| a.getString(com.android.internal.R.styleable |
| .SpellChecker_Subtype_subtypeExtraValue)); |
| mSubtypes.add(subtype); |
| } |
| } |
| } catch (Exception e) { |
| Slog.e(TAG, "Caught exception: " + e); |
| throw new XmlPullParserException( |
| "Unable to create context for: " + si.packageName); |
| } finally { |
| if (parser != null) parser.close(); |
| } |
| mLabel = label; |
| mSettingsActivityName = settingsActivityComponent; |
| } |
| |
| /** |
| * Constructor. |
| * @hide |
| */ |
| public SpellCheckerInfo(Parcel source) { |
| mLabel = source.readInt(); |
| mId = source.readString(); |
| mSettingsActivityName = source.readString(); |
| mService = ResolveInfo.CREATOR.createFromParcel(source); |
| source.readTypedList(mSubtypes, SpellCheckerSubtype.CREATOR); |
| } |
| |
| /** |
| * Return a unique ID for this spell checker. The ID is generated from |
| * the package and class name implementing the method. |
| */ |
| public String getId() { |
| return mId; |
| } |
| |
| |
| /** |
| * Return the component of the service that implements. |
| */ |
| public ComponentName getComponent() { |
| return new ComponentName( |
| mService.serviceInfo.packageName, mService.serviceInfo.name); |
| } |
| |
| /** |
| * Return the .apk package that implements this. |
| */ |
| public String getPackageName() { |
| return mService.serviceInfo.packageName; |
| } |
| |
| /** |
| * Used to package this object into a {@link Parcel}. |
| * |
| * @param dest The {@link Parcel} to be written. |
| * @param flags The flags used for parceling. |
| */ |
| @Override |
| public void writeToParcel(Parcel dest, int flags) { |
| dest.writeInt(mLabel); |
| dest.writeString(mId); |
| dest.writeString(mSettingsActivityName); |
| mService.writeToParcel(dest, flags); |
| dest.writeTypedList(mSubtypes); |
| } |
| |
| |
| /** |
| * Used to make this class parcelable. |
| */ |
| public static final Parcelable.Creator<SpellCheckerInfo> CREATOR |
| = new Parcelable.Creator<SpellCheckerInfo>() { |
| @Override |
| public SpellCheckerInfo createFromParcel(Parcel source) { |
| return new SpellCheckerInfo(source); |
| } |
| |
| @Override |
| public SpellCheckerInfo[] newArray(int size) { |
| return new SpellCheckerInfo[size]; |
| } |
| }; |
| |
| /** |
| * Load the user-displayed label for this spell checker. |
| * |
| * @param pm Supply a PackageManager used to load the spell checker's resources. |
| */ |
| public CharSequence loadLabel(PackageManager pm) { |
| if (mLabel == 0 || pm == null) return ""; |
| return pm.getText(getPackageName(), mLabel, mService.serviceInfo.applicationInfo); |
| } |
| |
| /** |
| * Load the user-displayed icon for this spell checker. |
| * |
| * @param pm Supply a PackageManager used to load the spell checker's resources. |
| */ |
| public Drawable loadIcon(PackageManager pm) { |
| return mService.loadIcon(pm); |
| } |
| |
| |
| /** |
| * Return the raw information about the Service implementing this |
| * spell checker. Do not modify the returned object. |
| */ |
| public ServiceInfo getServiceInfo() { |
| return mService.serviceInfo; |
| } |
| |
| /** |
| * Return the class name of an activity that provides a settings UI. |
| * You can launch this activity be starting it with |
| * an {@link android.content.Intent} whose action is MAIN and with an |
| * explicit {@link android.content.ComponentName} |
| * composed of {@link #getPackageName} and the class name returned here. |
| * |
| * <p>A null will be returned if there is no settings activity. |
| */ |
| public String getSettingsActivity() { |
| return mSettingsActivityName; |
| } |
| |
| /** |
| * Return the count of the subtypes. |
| */ |
| public int getSubtypeCount() { |
| return mSubtypes.size(); |
| } |
| |
| /** |
| * Return the subtype at the specified index. |
| * |
| * @param index the index of the subtype to return. |
| */ |
| public SpellCheckerSubtype getSubtypeAt(int index) { |
| return mSubtypes.get(index); |
| } |
| |
| /** |
| * Used to make this class parcelable. |
| */ |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| } |