InputMethodInfo.java revision f013e1afd1e68af5e3b868c26a653bbfb39538f8
1/* 2 * Copyright (C) 2007-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17package android.view.inputmethod; 18 19import org.xmlpull.v1.XmlPullParser; 20import org.xmlpull.v1.XmlPullParserException; 21 22import android.content.ComponentName; 23import android.content.Context; 24import android.content.pm.ApplicationInfo; 25import android.content.pm.PackageManager; 26import android.content.pm.ResolveInfo; 27import android.content.pm.ServiceInfo; 28import android.content.res.TypedArray; 29import android.content.res.XmlResourceParser; 30import android.graphics.drawable.Drawable; 31import android.os.Parcel; 32import android.os.Parcelable; 33import android.util.AttributeSet; 34import android.util.Printer; 35import android.util.Xml; 36 37import java.io.IOException; 38 39/** 40 * This class is used to specify meta information of an input method. 41 */ 42public final class InputMethodInfo implements Parcelable { 43 static final String TAG = "InputMethodMetaInfo"; 44 45 /** 46 * The Service that implements this input method component. 47 */ 48 final ResolveInfo mService; 49 50 /** 51 * The unique string Id to identify the input method. This is generated 52 * from the input method component. 53 */ 54 final String mId; 55 56 /** 57 * The input method setting activity's name, used by the system settings to 58 * launch the setting activity of this input method. 59 */ 60 final String mSettingsActivityName; 61 62 /** 63 * The resource in the input method's .apk that holds a boolean indicating 64 * whether it should be considered the default input method for this 65 * system. This is a resource ID instead of the final value so that it 66 * can change based on the configuration (in particular locale). 67 */ 68 final int mIsDefaultResId; 69 70 /** 71 * Constructor. 72 * 73 * @param context The Context in which we are parsing the input method. 74 * @param service The ResolveInfo returned from the package manager about 75 * this input method's component. 76 */ 77 public InputMethodInfo(Context context, ResolveInfo service) 78 throws XmlPullParserException, IOException { 79 mService = service; 80 ServiceInfo si = service.serviceInfo; 81 mId = new ComponentName(si.packageName, si.name).flattenToShortString(); 82 83 PackageManager pm = context.getPackageManager(); 84 String settingsActivityComponent = null; 85 int isDefaultResId = 0; 86 87 XmlResourceParser parser = null; 88 try { 89 parser = si.loadXmlMetaData(pm, InputMethod.SERVICE_META_DATA); 90 if (parser == null) { 91 throw new XmlPullParserException("No " 92 + InputMethod.SERVICE_META_DATA + " meta-data"); 93 } 94 95 AttributeSet attrs = Xml.asAttributeSet(parser); 96 97 int type; 98 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 99 && type != XmlPullParser.START_TAG) { 100 } 101 102 String nodeName = parser.getName(); 103 if (!"input-method".equals(nodeName)) { 104 throw new XmlPullParserException( 105 "Meta-data does not start with input-method tag"); 106 } 107 108 TypedArray sa = context.getResources().obtainAttributes(attrs, 109 com.android.internal.R.styleable.InputMethod); 110 settingsActivityComponent = sa.getString( 111 com.android.internal.R.styleable.InputMethod_settingsActivity); 112 isDefaultResId = sa.getResourceId( 113 com.android.internal.R.styleable.InputMethod_isDefault, 0); 114 sa.recycle(); 115 } finally { 116 if (parser != null) parser.close(); 117 } 118 119 mSettingsActivityName = settingsActivityComponent; 120 mIsDefaultResId = isDefaultResId; 121 } 122 123 InputMethodInfo(Parcel source) { 124 mId = source.readString(); 125 mSettingsActivityName = source.readString(); 126 mIsDefaultResId = source.readInt(); 127 mService = ResolveInfo.CREATOR.createFromParcel(source); 128 } 129 130 /** 131 * Temporary API for creating a built-in input method. 132 */ 133 public InputMethodInfo(String packageName, String className, 134 CharSequence label, String settingsActivity) { 135 ResolveInfo ri = new ResolveInfo(); 136 ServiceInfo si = new ServiceInfo(); 137 ApplicationInfo ai = new ApplicationInfo(); 138 ai.packageName = packageName; 139 ai.enabled = true; 140 si.applicationInfo = ai; 141 si.enabled = true; 142 si.packageName = packageName; 143 si.name = className; 144 si.exported = true; 145 si.nonLocalizedLabel = label; 146 ri.serviceInfo = si; 147 mService = ri; 148 mId = new ComponentName(si.packageName, si.name).flattenToShortString(); 149 mSettingsActivityName = settingsActivity; 150 mIsDefaultResId = 0; 151 } 152 153 /** 154 * Return a unique ID for this input method. The ID is generated from 155 * the package and class name implementing the method. 156 */ 157 public String getId() { 158 return mId; 159 } 160 161 /** 162 * Return the .apk package that implements this input method. 163 */ 164 public String getPackageName() { 165 return mService.serviceInfo.packageName; 166 } 167 168 /** 169 * Return the class name of the service component that implements 170 * this input method. 171 */ 172 public String getServiceName() { 173 return mService.serviceInfo.name; 174 } 175 176 /** 177 * Return the component of the service that implements this input 178 * method. 179 */ 180 public ComponentName getComponent() { 181 return new ComponentName(mService.serviceInfo.packageName, 182 mService.serviceInfo.name); 183 } 184 185 /** 186 * Load the user-displayed label for this input method. 187 * 188 * @param pm Supply a PackageManager used to load the input method's 189 * resources. 190 */ 191 public CharSequence loadLabel(PackageManager pm) { 192 return mService.loadLabel(pm); 193 } 194 195 /** 196 * Load the user-displayed icon for this input method. 197 * 198 * @param pm Supply a PackageManager used to load the input method's 199 * resources. 200 */ 201 public Drawable loadIcon(PackageManager pm) { 202 return mService.loadIcon(pm); 203 } 204 205 /** 206 * Return the class name of an activity that provides a settings UI for 207 * the input method. You can launch this activity be starting it with 208 * an {@link android.content.Intent} whose action is MAIN and with an 209 * explicit {@link android.content.ComponentName} 210 * composed of {@link #getPackageName} and the class name returned here. 211 * 212 * <p>A null will be returned if there is no settings activity associated 213 * with the input method. 214 */ 215 public String getSettingsActivity() { 216 return mSettingsActivityName; 217 } 218 219 /** 220 * Return the resource identifier of a resource inside of this input 221 * method's .apk that determines whether it should be considered a 222 * default input method for the system. 223 */ 224 public int getIsDefaultResourceId() { 225 return mIsDefaultResId; 226 } 227 228 /** 229 * Returns true if this input method is one of the components that is 230 * built in to the system. 231 */ 232 public boolean isBuiltin() { 233 return mService.serviceInfo.packageName.equals( 234 InputMethodManager.BUILDIN_INPUTMETHOD_PACKAGE); 235 } 236 237 public void dump(Printer pw, String prefix) { 238 pw.println(prefix + "mId=" + mId 239 + " mSettingsActivityName=" + mSettingsActivityName); 240 pw.println(prefix + "mIsDefaultResId=0x" 241 + Integer.toHexString(mIsDefaultResId)); 242 pw.println(prefix + "Service:"); 243 mService.dump(pw, prefix + " "); 244 } 245 246 @Override 247 public String toString() { 248 return "InputMethodMetaInfo{" + mId 249 + ", settings: " 250 + mSettingsActivityName + "}"; 251 } 252 253 /** 254 * Used to test whether the given parameter object is an 255 * {@link InputMethodInfo} and its Id is the same to this one. 256 * 257 * @return true if the given parameter object is an 258 * {@link InputMethodInfo} and its Id is the same to this one. 259 */ 260 @Override 261 public boolean equals(Object o) { 262 if (o == this) return true; 263 if (o == null) return false; 264 265 if (!(o instanceof InputMethodInfo)) return false; 266 267 InputMethodInfo obj = (InputMethodInfo) o; 268 return mId.equals(obj.mId); 269 } 270 271 /** 272 * Used to package this object into a {@link Parcel}. 273 * 274 * @param dest The {@link Parcel} to be written. 275 * @param flags The flags used for parceling. 276 */ 277 public void writeToParcel(Parcel dest, int flags) { 278 dest.writeString(mId); 279 dest.writeString(mSettingsActivityName); 280 dest.writeInt(mIsDefaultResId); 281 mService.writeToParcel(dest, flags); 282 } 283 284 /** 285 * Used to make this class parcelable. 286 */ 287 public static final Parcelable.Creator<InputMethodInfo> CREATOR = new Parcelable.Creator<InputMethodInfo>() { 288 public InputMethodInfo createFromParcel(Parcel source) { 289 return new InputMethodInfo(source); 290 } 291 292 public InputMethodInfo[] newArray(int size) { 293 return new InputMethodInfo[size]; 294 } 295 }; 296 297 public int describeContents() { 298 return 0; 299 } 300} 301