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