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