1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of 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, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.printservice; 18 19 import android.content.ComponentName; 20 import android.content.Context; 21 import android.content.pm.PackageManager; 22 import android.content.pm.PackageManager.NameNotFoundException; 23 import android.content.pm.ResolveInfo; 24 import android.content.res.Resources; 25 import android.content.res.TypedArray; 26 import android.content.res.XmlResourceParser; 27 import android.os.Parcel; 28 import android.os.Parcelable; 29 import android.util.AttributeSet; 30 import android.util.Log; 31 import android.util.Xml; 32 33 import org.xmlpull.v1.XmlPullParser; 34 import org.xmlpull.v1.XmlPullParserException; 35 36 import java.io.IOException; 37 38 /** 39 * This class describes a {@link PrintService}. A print service knows 40 * how to communicate with one or more printers over one or more protocols 41 * and exposes printers for use by the applications via the platform print 42 * APIs. 43 * 44 * @see PrintService 45 * @see android.print.PrintManager 46 * 47 * @hide 48 */ 49 public final class PrintServiceInfo implements Parcelable { 50 51 private static final String LOG_TAG = PrintServiceInfo.class.getSimpleName(); 52 53 private static final String TAG_PRINT_SERVICE = "print-service"; 54 55 private final String mId; 56 57 private final ResolveInfo mResolveInfo; 58 59 private final String mSettingsActivityName; 60 61 private final String mAddPrintersActivityName; 62 63 private final String mAdvancedPrintOptionsActivityName; 64 65 /** 66 * Creates a new instance. 67 * 68 * @hide 69 */ PrintServiceInfo(Parcel parcel)70 public PrintServiceInfo(Parcel parcel) { 71 mId = parcel.readString(); 72 mResolveInfo = parcel.readParcelable(null); 73 mSettingsActivityName = parcel.readString(); 74 mAddPrintersActivityName = parcel.readString(); 75 mAdvancedPrintOptionsActivityName = parcel.readString(); 76 } 77 78 /** 79 * Creates a new instance. 80 * 81 * @param resolveInfo The service resolve info. 82 * @param settingsActivityName Optional settings activity name. 83 * @param addPrintersActivityName Optional add printers activity name. 84 * @param advancedPrintOptionsActivityName Optional advanced print options activity. 85 */ PrintServiceInfo(ResolveInfo resolveInfo, String settingsActivityName, String addPrintersActivityName, String advancedPrintOptionsActivityName)86 public PrintServiceInfo(ResolveInfo resolveInfo, String settingsActivityName, 87 String addPrintersActivityName, String advancedPrintOptionsActivityName) { 88 mId = new ComponentName(resolveInfo.serviceInfo.packageName, 89 resolveInfo.serviceInfo.name).flattenToString(); 90 mResolveInfo = resolveInfo; 91 mSettingsActivityName = settingsActivityName; 92 mAddPrintersActivityName = addPrintersActivityName; 93 mAdvancedPrintOptionsActivityName = advancedPrintOptionsActivityName; 94 } 95 96 /** 97 * Creates a new instance. 98 * 99 * @param resolveInfo The service resolve info. 100 * @param context Context for accessing resources. 101 * @throws XmlPullParserException If a XML parsing error occurs. 102 * @throws IOException If a I/O error occurs. 103 */ create(ResolveInfo resolveInfo, Context context)104 public static PrintServiceInfo create(ResolveInfo resolveInfo, Context context) { 105 String settingsActivityName = null; 106 String addPrintersActivityName = null; 107 String advancedPrintOptionsActivityName = null; 108 109 XmlResourceParser parser = null; 110 PackageManager packageManager = context.getPackageManager(); 111 parser = resolveInfo.serviceInfo.loadXmlMetaData(packageManager, 112 PrintService.SERVICE_META_DATA); 113 if (parser != null) { 114 try { 115 int type = 0; 116 while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) { 117 type = parser.next(); 118 } 119 120 String nodeName = parser.getName(); 121 if (!TAG_PRINT_SERVICE.equals(nodeName)) { 122 Log.e(LOG_TAG, "Ignoring meta-data that does not start with " 123 + TAG_PRINT_SERVICE + " tag"); 124 } else { 125 Resources resources = packageManager.getResourcesForApplication( 126 resolveInfo.serviceInfo.applicationInfo); 127 AttributeSet allAttributes = Xml.asAttributeSet(parser); 128 TypedArray attributes = resources.obtainAttributes(allAttributes, 129 com.android.internal.R.styleable.PrintService); 130 131 settingsActivityName = attributes.getString( 132 com.android.internal.R.styleable.PrintService_settingsActivity); 133 134 addPrintersActivityName = attributes.getString( 135 com.android.internal.R.styleable.PrintService_addPrintersActivity); 136 137 advancedPrintOptionsActivityName = attributes.getString(com.android.internal 138 .R.styleable.PrintService_advancedPrintOptionsActivity); 139 140 attributes.recycle(); 141 } 142 } catch (IOException ioe) { 143 Log.w(LOG_TAG, "Error reading meta-data:" + ioe); 144 } catch (XmlPullParserException xppe) { 145 Log.w(LOG_TAG, "Error reading meta-data:" + xppe); 146 } catch (NameNotFoundException e) { 147 Log.e(LOG_TAG, "Unable to load resources for: " 148 + resolveInfo.serviceInfo.packageName); 149 } finally { 150 if (parser != null) { 151 parser.close(); 152 } 153 } 154 } 155 156 return new PrintServiceInfo(resolveInfo, settingsActivityName, 157 addPrintersActivityName, advancedPrintOptionsActivityName); 158 } 159 160 /** 161 * The accessibility service id. 162 * <p> 163 * <strong>Generated by the system.</strong> 164 * </p> 165 * 166 * @return The id. 167 */ getId()168 public String getId() { 169 return mId; 170 } 171 172 /** 173 * The service {@link ResolveInfo}. 174 * 175 * @return The info. 176 */ getResolveInfo()177 public ResolveInfo getResolveInfo() { 178 return mResolveInfo; 179 } 180 181 /** 182 * The settings activity name. 183 * <p> 184 * <strong>Statically set from 185 * {@link PrintService#SERVICE_META_DATA meta-data}.</strong> 186 * </p> 187 * 188 * @return The settings activity name. 189 */ getSettingsActivityName()190 public String getSettingsActivityName() { 191 return mSettingsActivityName; 192 } 193 194 /** 195 * The add printers activity name. 196 * <p> 197 * <strong>Statically set from 198 * {@link PrintService#SERVICE_META_DATA meta-data}.</strong> 199 * </p> 200 * 201 * @return The add printers activity name. 202 */ getAddPrintersActivityName()203 public String getAddPrintersActivityName() { 204 return mAddPrintersActivityName; 205 } 206 207 /** 208 * The advanced print options activity name. 209 * <p> 210 * <strong>Statically set from 211 * {@link PrintService#SERVICE_META_DATA meta-data}.</strong> 212 * </p> 213 * 214 * @return The advanced print options activity name. 215 */ getAdvancedOptionsActivityName()216 public String getAdvancedOptionsActivityName() { 217 return mAdvancedPrintOptionsActivityName; 218 } 219 220 /** 221 * {@inheritDoc} 222 */ describeContents()223 public int describeContents() { 224 return 0; 225 } 226 writeToParcel(Parcel parcel, int flagz)227 public void writeToParcel(Parcel parcel, int flagz) { 228 parcel.writeString(mId); 229 parcel.writeParcelable(mResolveInfo, 0); 230 parcel.writeString(mSettingsActivityName); 231 parcel.writeString(mAddPrintersActivityName); 232 parcel.writeString(mAdvancedPrintOptionsActivityName); 233 } 234 235 @Override hashCode()236 public int hashCode() { 237 return 31 + ((mId == null) ? 0 : mId.hashCode()); 238 } 239 240 @Override equals(Object obj)241 public boolean equals(Object obj) { 242 if (this == obj) { 243 return true; 244 } 245 if (obj == null) { 246 return false; 247 } 248 if (getClass() != obj.getClass()) { 249 return false; 250 } 251 PrintServiceInfo other = (PrintServiceInfo) obj; 252 if (mId == null) { 253 if (other.mId != null) { 254 return false; 255 } 256 } else if (!mId.equals(other.mId)) { 257 return false; 258 } 259 return true; 260 } 261 262 @Override toString()263 public String toString() { 264 StringBuilder builder = new StringBuilder(); 265 builder.append("PrintServiceInfo{"); 266 builder.append("id=").append(mId); 267 builder.append(", resolveInfo=").append(mResolveInfo); 268 builder.append(", settingsActivityName=").append(mSettingsActivityName); 269 builder.append(", addPrintersActivityName=").append(mAddPrintersActivityName); 270 builder.append(", advancedPrintOptionsActivityName=") 271 .append(mAdvancedPrintOptionsActivityName); 272 builder.append("}"); 273 return builder.toString(); 274 } 275 276 public static final Parcelable.Creator<PrintServiceInfo> CREATOR = 277 new Parcelable.Creator<PrintServiceInfo>() { 278 public PrintServiceInfo createFromParcel(Parcel parcel) { 279 return new PrintServiceInfo(parcel); 280 } 281 282 public PrintServiceInfo[] newArray(int size) { 283 return new PrintServiceInfo[size]; 284 } 285 }; 286 } 287