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