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