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