blob: 4e985914c03e326e9caa2cede439583e9b0350d8 [file] [log] [blame]
/*
* Copyright (C) 2007-2008 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.inputmethod;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
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.Printer;
import android.util.Xml;
import java.io.IOException;
/**
* This class is used to specify meta information of an input method.
*/
public final class InputMethodInfo implements Parcelable {
static final String TAG = "InputMethodMetaInfo";
/**
* The Service that implements this input method component.
*/
final ResolveInfo mService;
/**
* The unique string Id to identify the input method. This is generated
* from the input method component.
*/
final String mId;
/**
* The input method setting activity's name, used by the system settings to
* launch the setting activity of this input method.
*/
final String mSettingsActivityName;
/**
* The resource in the input method's .apk that holds a boolean indicating
* whether it should be considered the default input method for this
* system. This is a resource ID instead of the final value so that it
* can change based on the configuration (in particular locale).
*/
final int mIsDefaultResId;
/**
* Constructor.
*
* @param context The Context in which we are parsing the input method.
* @param service The ResolveInfo returned from the package manager about
* this input method's component.
*/
public InputMethodInfo(Context context, ResolveInfo service)
throws XmlPullParserException, IOException {
mService = service;
ServiceInfo si = service.serviceInfo;
mId = new ComponentName(si.packageName, si.name).flattenToShortString();
PackageManager pm = context.getPackageManager();
String settingsActivityComponent = null;
int isDefaultResId = 0;
XmlResourceParser parser = null;
try {
parser = si.loadXmlMetaData(pm, InputMethod.SERVICE_META_DATA);
if (parser == null) {
throw new XmlPullParserException("No "
+ InputMethod.SERVICE_META_DATA + " meta-data");
}
AttributeSet attrs = Xml.asAttributeSet(parser);
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& type != XmlPullParser.START_TAG) {
}
String nodeName = parser.getName();
if (!"input-method".equals(nodeName)) {
throw new XmlPullParserException(
"Meta-data does not start with input-method tag");
}
TypedArray sa = context.getResources().obtainAttributes(attrs,
com.android.internal.R.styleable.InputMethod);
settingsActivityComponent = sa.getString(
com.android.internal.R.styleable.InputMethod_settingsActivity);
isDefaultResId = sa.getResourceId(
com.android.internal.R.styleable.InputMethod_isDefault, 0);
sa.recycle();
} finally {
if (parser != null) parser.close();
}
mSettingsActivityName = settingsActivityComponent;
mIsDefaultResId = isDefaultResId;
}
InputMethodInfo(Parcel source) {
mId = source.readString();
mSettingsActivityName = source.readString();
mIsDefaultResId = source.readInt();
mService = ResolveInfo.CREATOR.createFromParcel(source);
}
/**
* Temporary API for creating a built-in input method.
*/
public InputMethodInfo(String packageName, String className,
CharSequence label, String settingsActivity) {
ResolveInfo ri = new ResolveInfo();
ServiceInfo si = new ServiceInfo();
ApplicationInfo ai = new ApplicationInfo();
ai.packageName = packageName;
ai.enabled = true;
si.applicationInfo = ai;
si.enabled = true;
si.packageName = packageName;
si.name = className;
si.exported = true;
si.nonLocalizedLabel = label;
ri.serviceInfo = si;
mService = ri;
mId = new ComponentName(si.packageName, si.name).flattenToShortString();
mSettingsActivityName = settingsActivity;
mIsDefaultResId = 0;
}
/**
* Return a unique ID for this input method. The ID is generated from
* the package and class name implementing the method.
*/
public String getId() {
return mId;
}
/**
* Return the .apk package that implements this input method.
*/
public String getPackageName() {
return mService.serviceInfo.packageName;
}
/**
* Return the class name of the service component that implements
* this input method.
*/
public String getServiceName() {
return mService.serviceInfo.name;
}
/**
* Return the component of the service that implements this input
* method.
*/
public ComponentName getComponent() {
return new ComponentName(mService.serviceInfo.packageName,
mService.serviceInfo.name);
}
/**
* Load the user-displayed label for this input method.
*
* @param pm Supply a PackageManager used to load the input method's
* resources.
*/
public CharSequence loadLabel(PackageManager pm) {
return mService.loadLabel(pm);
}
/**
* Load the user-displayed icon for this input method.
*
* @param pm Supply a PackageManager used to load the input method's
* resources.
*/
public Drawable loadIcon(PackageManager pm) {
return mService.loadIcon(pm);
}
/**
* Return the class name of an activity that provides a settings UI for
* the input method. 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 associated
* with the input method.
*/
public String getSettingsActivity() {
return mSettingsActivityName;
}
/**
* Return the resource identifier of a resource inside of this input
* method's .apk that determines whether it should be considered a
* default input method for the system.
*/
public int getIsDefaultResourceId() {
return mIsDefaultResId;
}
public void dump(Printer pw, String prefix) {
pw.println(prefix + "mId=" + mId
+ " mSettingsActivityName=" + mSettingsActivityName);
pw.println(prefix + "mIsDefaultResId=0x"
+ Integer.toHexString(mIsDefaultResId));
pw.println(prefix + "Service:");
mService.dump(pw, prefix + " ");
}
@Override
public String toString() {
return "InputMethodMetaInfo{" + mId
+ ", settings: "
+ mSettingsActivityName + "}";
}
/**
* Used to test whether the given parameter object is an
* {@link InputMethodInfo} and its Id is the same to this one.
*
* @return true if the given parameter object is an
* {@link InputMethodInfo} and its Id is the same to this one.
*/
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof InputMethodInfo)) return false;
InputMethodInfo obj = (InputMethodInfo) o;
return mId.equals(obj.mId);
}
/**
* Used to package this object into a {@link Parcel}.
*
* @param dest The {@link Parcel} to be written.
* @param flags The flags used for parceling.
*/
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mId);
dest.writeString(mSettingsActivityName);
dest.writeInt(mIsDefaultResId);
mService.writeToParcel(dest, flags);
}
/**
* Used to make this class parcelable.
*/
public static final Parcelable.Creator<InputMethodInfo> CREATOR = new Parcelable.Creator<InputMethodInfo>() {
public InputMethodInfo createFromParcel(Parcel source) {
return new InputMethodInfo(source);
}
public InputMethodInfo[] newArray(int size) {
return new InputMethodInfo[size];
}
};
public int describeContents() {
return 0;
}
}