292 lines
10 KiB
Java
292 lines
10 KiB
Java
/*
|
|
* 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 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.PrintWriterPrinter;
|
|
import android.util.Slog;
|
|
import android.util.Xml;
|
|
|
|
import org.xmlpull.v1.XmlPullParser;
|
|
import org.xmlpull.v1.XmlPullParserException;
|
|
|
|
import java.io.IOException;
|
|
import java.io.PrintWriter;
|
|
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<>();
|
|
|
|
/**
|
|
* 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_languageTag),
|
|
a.getString(com.android.internal.R.styleable
|
|
.SpellChecker_Subtype_subtypeExtraValue),
|
|
a.getInt(com.android.internal.R.styleable
|
|
.SpellChecker_Subtype_subtypeId, 0));
|
|
a.recycle();
|
|
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 @android.annotation.NonNull 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;
|
|
}
|
|
|
|
/**
|
|
* @hide
|
|
*/
|
|
public void dump(final PrintWriter pw, final String prefix) {
|
|
pw.println(prefix + "mId=" + mId);
|
|
pw.println(prefix + "mSettingsActivityName=" + mSettingsActivityName);
|
|
pw.println(prefix + "Service:");
|
|
mService.dump(new PrintWriterPrinter(pw), prefix + " ");
|
|
final int N = getSubtypeCount();
|
|
for (int i = 0; i < N; i++) {
|
|
final SpellCheckerSubtype st = getSubtypeAt(i);
|
|
pw.println(prefix + " " + "Subtype #" + i + ":");
|
|
pw.println(prefix + " " + "locale=" + st.getLocale()
|
|
+ " languageTag=" + st.getLanguageTag());
|
|
pw.println(prefix + " " + "extraValue=" + st.getExtraValue());
|
|
}
|
|
}
|
|
}
|