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.annotation.NonNull; 20 import android.annotation.SystemApi; 21 import android.content.ComponentName; 22 import android.content.Context; 23 import android.content.pm.PackageManager; 24 import android.content.pm.PackageManager.NameNotFoundException; 25 import android.content.pm.ResolveInfo; 26 import android.content.res.Resources; 27 import android.content.res.TypedArray; 28 import android.content.res.XmlResourceParser; 29 import android.os.Parcel; 30 import android.os.Parcelable; 31 import android.util.AttributeSet; 32 import android.util.Log; 33 import android.util.Xml; 34 35 import org.xmlpull.v1.XmlPullParser; 36 import org.xmlpull.v1.XmlPullParserException; 37 38 import java.io.IOException; 39 40 /** 41 * This class describes a {@link PrintService}. A print service knows 42 * how to communicate with one or more printers over one or more protocols 43 * and exposes printers for use by the applications via the platform print 44 * APIs. 45 * 46 * @see PrintService 47 * @see android.print.PrintManager 48 * 49 * @hide 50 */ 51 @SystemApi 52 public final class PrintServiceInfo implements Parcelable { 53 54 private static final String LOG_TAG = PrintServiceInfo.class.getSimpleName(); 55 56 private static final String TAG_PRINT_SERVICE = "print-service"; 57 58 private final String mId; 59 60 private boolean mIsEnabled; 61 62 private final ResolveInfo mResolveInfo; 63 64 private final String mSettingsActivityName; 65 66 private final String mAddPrintersActivityName; 67 68 private final String mAdvancedPrintOptionsActivityName; 69 70 /** 71 * Creates a new instance. 72 * 73 * @hide 74 */ PrintServiceInfo(Parcel parcel)75 public PrintServiceInfo(Parcel parcel) { 76 mId = parcel.readString(); 77 mIsEnabled = parcel.readByte() != 0; 78 mResolveInfo = parcel.readParcelable(null); 79 mSettingsActivityName = parcel.readString(); 80 mAddPrintersActivityName = parcel.readString(); 81 mAdvancedPrintOptionsActivityName = parcel.readString(); 82 } 83 84 /** 85 * Creates a new instance. 86 * 87 * @param resolveInfo The service resolve info. 88 * @param settingsActivityName Optional settings activity name. 89 * @param addPrintersActivityName Optional add printers activity name. 90 * @param advancedPrintOptionsActivityName Optional advanced print options activity. 91 * 92 * @hide 93 */ PrintServiceInfo(ResolveInfo resolveInfo, String settingsActivityName, String addPrintersActivityName, String advancedPrintOptionsActivityName)94 public PrintServiceInfo(ResolveInfo resolveInfo, String settingsActivityName, 95 String addPrintersActivityName, String advancedPrintOptionsActivityName) { 96 mId = new ComponentName(resolveInfo.serviceInfo.packageName, 97 resolveInfo.serviceInfo.name).flattenToString(); 98 mResolveInfo = resolveInfo; 99 mSettingsActivityName = settingsActivityName; 100 mAddPrintersActivityName = addPrintersActivityName; 101 mAdvancedPrintOptionsActivityName = advancedPrintOptionsActivityName; 102 } 103 104 /** 105 * Return the component name for this print service. 106 * 107 * @return The component name for this print service. 108 */ getComponentName()109 public @NonNull ComponentName getComponentName() { 110 return new ComponentName(mResolveInfo.serviceInfo.packageName, 111 mResolveInfo.serviceInfo.name); 112 } 113 114 /** 115 * Creates a new instance. 116 * 117 * @param context Context for accessing resources. 118 * @param resolveInfo The service resolve info. 119 * @return The created instance. 120 * 121 * @hide 122 */ create(Context context, ResolveInfo resolveInfo)123 public static PrintServiceInfo create(Context context, ResolveInfo resolveInfo) { 124 String settingsActivityName = null; 125 String addPrintersActivityName = null; 126 String advancedPrintOptionsActivityName = null; 127 128 XmlResourceParser parser = null; 129 PackageManager packageManager = context.getPackageManager(); 130 parser = resolveInfo.serviceInfo.loadXmlMetaData(packageManager, 131 PrintService.SERVICE_META_DATA); 132 if (parser != null) { 133 try { 134 int type = 0; 135 while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) { 136 type = parser.next(); 137 } 138 139 String nodeName = parser.getName(); 140 if (!TAG_PRINT_SERVICE.equals(nodeName)) { 141 Log.e(LOG_TAG, "Ignoring meta-data that does not start with " 142 + TAG_PRINT_SERVICE + " tag"); 143 } else { 144 Resources resources = packageManager.getResourcesForApplication( 145 resolveInfo.serviceInfo.applicationInfo); 146 AttributeSet allAttributes = Xml.asAttributeSet(parser); 147 TypedArray attributes = resources.obtainAttributes(allAttributes, 148 com.android.internal.R.styleable.PrintService); 149 150 settingsActivityName = attributes.getString( 151 com.android.internal.R.styleable.PrintService_settingsActivity); 152 153 addPrintersActivityName = attributes.getString( 154 com.android.internal.R.styleable.PrintService_addPrintersActivity); 155 156 advancedPrintOptionsActivityName = attributes.getString(com.android.internal 157 .R.styleable.PrintService_advancedPrintOptionsActivity); 158 159 attributes.recycle(); 160 } 161 } catch (IOException ioe) { 162 Log.w(LOG_TAG, "Error reading meta-data:" + ioe); 163 } catch (XmlPullParserException xppe) { 164 Log.w(LOG_TAG, "Error reading meta-data:" + xppe); 165 } catch (NameNotFoundException e) { 166 Log.e(LOG_TAG, "Unable to load resources for: " 167 + resolveInfo.serviceInfo.packageName); 168 } finally { 169 if (parser != null) { 170 parser.close(); 171 } 172 } 173 } 174 175 return new PrintServiceInfo(resolveInfo, settingsActivityName, 176 addPrintersActivityName, advancedPrintOptionsActivityName); 177 } 178 179 /** 180 * The accessibility service id. 181 * <p> 182 * <strong>Generated by the system.</strong> 183 * </p> 184 * 185 * @return The id. 186 * 187 * @hide 188 */ getId()189 public String getId() { 190 return mId; 191 } 192 193 /** 194 * If the service was enabled when it was read from the system. 195 * 196 * @return The id. 197 * 198 * @hide 199 */ isEnabled()200 public boolean isEnabled() { 201 return mIsEnabled; 202 } 203 204 /** 205 * Mark a service as enabled or not 206 * 207 * @param isEnabled If the service should be marked as enabled. 208 * 209 * @hide 210 */ setIsEnabled(boolean isEnabled)211 public void setIsEnabled(boolean isEnabled) { 212 mIsEnabled = isEnabled; 213 } 214 215 /** 216 * The service {@link ResolveInfo}. 217 * 218 * @return The info. 219 * 220 * @hide 221 */ getResolveInfo()222 public ResolveInfo getResolveInfo() { 223 return mResolveInfo; 224 } 225 226 /** 227 * The settings activity name. 228 * <p> 229 * <strong>Statically set from 230 * {@link PrintService#SERVICE_META_DATA meta-data}.</strong> 231 * </p> 232 * 233 * @return The settings activity name. 234 * 235 * @hide 236 */ getSettingsActivityName()237 public String getSettingsActivityName() { 238 return mSettingsActivityName; 239 } 240 241 /** 242 * The add printers activity name. 243 * <p> 244 * <strong>Statically set from 245 * {@link PrintService#SERVICE_META_DATA meta-data}.</strong> 246 * </p> 247 * 248 * @return The add printers activity name. 249 * 250 * @hide 251 */ getAddPrintersActivityName()252 public String getAddPrintersActivityName() { 253 return mAddPrintersActivityName; 254 } 255 256 /** 257 * The advanced print options activity name. 258 * <p> 259 * <strong>Statically set from 260 * {@link PrintService#SERVICE_META_DATA meta-data}.</strong> 261 * </p> 262 * 263 * @return The advanced print options activity name. 264 * 265 * @hide 266 */ getAdvancedOptionsActivityName()267 public String getAdvancedOptionsActivityName() { 268 return mAdvancedPrintOptionsActivityName; 269 } 270 271 /** 272 * {@inheritDoc} 273 */ 274 @Override describeContents()275 public int describeContents() { 276 return 0; 277 } 278 279 @Override writeToParcel(Parcel parcel, int flagz)280 public void writeToParcel(Parcel parcel, int flagz) { 281 parcel.writeString(mId); 282 parcel.writeByte((byte)(mIsEnabled ? 1 : 0)); 283 parcel.writeParcelable(mResolveInfo, 0); 284 parcel.writeString(mSettingsActivityName); 285 parcel.writeString(mAddPrintersActivityName); 286 parcel.writeString(mAdvancedPrintOptionsActivityName); 287 } 288 289 @Override hashCode()290 public int hashCode() { 291 return 31 + ((mId == null) ? 0 : mId.hashCode()); 292 } 293 294 @Override equals(Object obj)295 public boolean equals(Object obj) { 296 if (this == obj) { 297 return true; 298 } 299 if (obj == null) { 300 return false; 301 } 302 if (getClass() != obj.getClass()) { 303 return false; 304 } 305 PrintServiceInfo other = (PrintServiceInfo) obj; 306 if (mId == null) { 307 if (other.mId != null) { 308 return false; 309 } 310 } else if (!mId.equals(other.mId)) { 311 return false; 312 } 313 return true; 314 } 315 316 @Override toString()317 public String toString() { 318 StringBuilder builder = new StringBuilder(); 319 builder.append("PrintServiceInfo{"); 320 builder.append("id=").append(mId); 321 builder.append("isEnabled=").append(mIsEnabled); 322 builder.append(", resolveInfo=").append(mResolveInfo); 323 builder.append(", settingsActivityName=").append(mSettingsActivityName); 324 builder.append(", addPrintersActivityName=").append(mAddPrintersActivityName); 325 builder.append(", advancedPrintOptionsActivityName=") 326 .append(mAdvancedPrintOptionsActivityName); 327 builder.append("}"); 328 return builder.toString(); 329 } 330 331 public static final Parcelable.Creator<PrintServiceInfo> CREATOR = 332 new Parcelable.Creator<PrintServiceInfo>() { 333 @Override 334 public PrintServiceInfo createFromParcel(Parcel parcel) { 335 return new PrintServiceInfo(parcel); 336 } 337 338 @Override 339 public PrintServiceInfo[] newArray(int size) { 340 return new PrintServiceInfo[size]; 341 } 342 }; 343 } 344