/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.printservice; import android.annotation.NonNull; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; import android.util.Xml; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; /** * This class describes a {@link PrintService}. A print service knows * how to communicate with one or more printers over one or more protocols * and exposes printers for use by the applications via the platform print * APIs. * * @see PrintService * @see android.print.PrintManager * * @hide */ public final class PrintServiceInfo implements Parcelable { private static final String LOG_TAG = PrintServiceInfo.class.getSimpleName(); private static final String TAG_PRINT_SERVICE = "print-service"; private final String mId; private boolean mIsEnabled; private final ResolveInfo mResolveInfo; private final String mSettingsActivityName; private final String mAddPrintersActivityName; private final String mAdvancedPrintOptionsActivityName; /** * Creates a new instance. * * @hide */ public PrintServiceInfo(Parcel parcel) { mId = parcel.readString(); mIsEnabled = parcel.readByte() != 0; mResolveInfo = parcel.readParcelable(null); mSettingsActivityName = parcel.readString(); mAddPrintersActivityName = parcel.readString(); mAdvancedPrintOptionsActivityName = parcel.readString(); } /** * Creates a new instance. * * @param resolveInfo The service resolve info. * @param settingsActivityName Optional settings activity name. * @param addPrintersActivityName Optional add printers activity name. * @param advancedPrintOptionsActivityName Optional advanced print options activity. */ public PrintServiceInfo(ResolveInfo resolveInfo, String settingsActivityName, String addPrintersActivityName, String advancedPrintOptionsActivityName) { mId = new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name).flattenToString(); mResolveInfo = resolveInfo; mSettingsActivityName = settingsActivityName; mAddPrintersActivityName = addPrintersActivityName; mAdvancedPrintOptionsActivityName = advancedPrintOptionsActivityName; } /** * Return the component name for this print service. * * @return The component name for this print service. */ public @NonNull ComponentName getComponentName() { return new ComponentName(mResolveInfo.serviceInfo.packageName, mResolveInfo.serviceInfo.name); } /** * Creates a new instance. * * @param resolveInfo The service resolve info. * @param context Context for accessing resources. * @return The created instance. */ public static PrintServiceInfo create(ResolveInfo resolveInfo, Context context) { String settingsActivityName = null; String addPrintersActivityName = null; String advancedPrintOptionsActivityName = null; XmlResourceParser parser = null; PackageManager packageManager = context.getPackageManager(); parser = resolveInfo.serviceInfo.loadXmlMetaData(packageManager, PrintService.SERVICE_META_DATA); if (parser != null) { try { int type = 0; while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) { type = parser.next(); } String nodeName = parser.getName(); if (!TAG_PRINT_SERVICE.equals(nodeName)) { Log.e(LOG_TAG, "Ignoring meta-data that does not start with " + TAG_PRINT_SERVICE + " tag"); } else { Resources resources = packageManager.getResourcesForApplication( resolveInfo.serviceInfo.applicationInfo); AttributeSet allAttributes = Xml.asAttributeSet(parser); TypedArray attributes = resources.obtainAttributes(allAttributes, com.android.internal.R.styleable.PrintService); settingsActivityName = attributes.getString( com.android.internal.R.styleable.PrintService_settingsActivity); addPrintersActivityName = attributes.getString( com.android.internal.R.styleable.PrintService_addPrintersActivity); advancedPrintOptionsActivityName = attributes.getString(com.android.internal .R.styleable.PrintService_advancedPrintOptionsActivity); attributes.recycle(); } } catch (IOException ioe) { Log.w(LOG_TAG, "Error reading meta-data:" + ioe); } catch (XmlPullParserException xppe) { Log.w(LOG_TAG, "Error reading meta-data:" + xppe); } catch (NameNotFoundException e) { Log.e(LOG_TAG, "Unable to load resources for: " + resolveInfo.serviceInfo.packageName); } finally { if (parser != null) { parser.close(); } } } return new PrintServiceInfo(resolveInfo, settingsActivityName, addPrintersActivityName, advancedPrintOptionsActivityName); } /** * The accessibility service id. * <p> * <strong>Generated by the system.</strong> * </p> * * @return The id. */ public String getId() { return mId; } /** * If the service was enabled when it was read from the system. * * @return The id. */ public boolean isEnabled() { return mIsEnabled; } /** * Mark a service as enabled or not * * @param isEnabled If the service should be marked as enabled. */ public void setIsEnabled(boolean isEnabled) { mIsEnabled = isEnabled; } /** * The service {@link ResolveInfo}. * * @return The info. */ public ResolveInfo getResolveInfo() { return mResolveInfo; } /** * The settings activity name. * <p> * <strong>Statically set from * {@link PrintService#SERVICE_META_DATA meta-data}.</strong> * </p> * * @return The settings activity name. */ public String getSettingsActivityName() { return mSettingsActivityName; } /** * The add printers activity name. * <p> * <strong>Statically set from * {@link PrintService#SERVICE_META_DATA meta-data}.</strong> * </p> * * @return The add printers activity name. */ public String getAddPrintersActivityName() { return mAddPrintersActivityName; } /** * The advanced print options activity name. * <p> * <strong>Statically set from * {@link PrintService#SERVICE_META_DATA meta-data}.</strong> * </p> * * @return The advanced print options activity name. */ public String getAdvancedOptionsActivityName() { return mAdvancedPrintOptionsActivityName; } /** * {@inheritDoc} */ @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int flagz) { parcel.writeString(mId); parcel.writeByte((byte)(mIsEnabled ? 1 : 0)); parcel.writeParcelable(mResolveInfo, 0); parcel.writeString(mSettingsActivityName); parcel.writeString(mAddPrintersActivityName); parcel.writeString(mAdvancedPrintOptionsActivityName); } @Override public int hashCode() { return 31 + ((mId == null) ? 0 : mId.hashCode()); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } PrintServiceInfo other = (PrintServiceInfo) obj; if (mId == null) { if (other.mId != null) { return false; } } else if (!mId.equals(other.mId)) { return false; } return true; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("PrintServiceInfo{"); builder.append("id=").append(mId); builder.append("isEnabled=").append(mIsEnabled); builder.append(", resolveInfo=").append(mResolveInfo); builder.append(", settingsActivityName=").append(mSettingsActivityName); builder.append(", addPrintersActivityName=").append(mAddPrintersActivityName); builder.append(", advancedPrintOptionsActivityName=") .append(mAdvancedPrintOptionsActivityName); builder.append("}"); return builder.toString(); } public static final Parcelable.Creator<PrintServiceInfo> CREATOR = new Parcelable.Creator<PrintServiceInfo>() { @Override public PrintServiceInfo createFromParcel(Parcel parcel) { return new PrintServiceInfo(parcel); } @Override public PrintServiceInfo[] newArray(int size) { return new PrintServiceInfo[size]; } }; }