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.print;
18 
19 import android.os.Parcel;
20 import android.os.Parcelable;
21 import android.text.TextUtils;
22 
23 /**
24  * This class encapsulates information about a document for printing
25  * purposes. This meta-data is used by the platform and print services,
26  * components that interact with printers. For example, this class
27  * contains the number of pages contained in the document it describes and
28  * this number of pages is shown to the user allowing him/her to select
29  * the range to print. Also a print service may optimize the printing
30  * process based on the content type, such as document or photo.
31  * <p>
32  * Instances of this class are created by the printing application and
33  * passed to the {@link PrintDocumentAdapter.LayoutResultCallback#onLayoutFinished(
34  * PrintDocumentInfo, boolean) PrintDocumentAdapter.LayoutResultCallback.onLayoutFinished(
35  * PrintDocumentInfo, boolean)} callback after successfully laying out the
36  * content which is performed in {@link PrintDocumentAdapter#onLayout(PrintAttributes,
37  * PrintAttributes, android.os.CancellationSignal, PrintDocumentAdapter.LayoutResultCallback,
38  * android.os.Bundle) PrintDocumentAdapter.onLayout(PrintAttributes,
39  * PrintAttributes, android.os.CancellationSignal,
40  * PrintDocumentAdapter.LayoutResultCallback, android.os.Bundle)}.
41  * </p>
42  * <p>
43  * An example usage looks like this:
44  * <pre>
45  *
46  * . . .
47  *
48  * public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
49  *         CancellationSignal cancellationSignal, LayoutResultCallback callback,
50  *         Bundle metadata) {
51  *
52  *        // Assume the app defined a LayoutResult class which contains
53  *        // the layout result data and that the content is a document.
54  *        LayoutResult result = doSomeLayoutWork();
55  *
56  *        PrintDocumentInfo info = new PrintDocumentInfo
57  *                .Builder("printed_file.pdf")
58  *                .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
59  *                .setPageCount(result.getPageCount())
60  *                .build();
61  *
62  *       callback.onLayoutFinished(info, result.getContentChanged());
63  *   }
64  *
65  *   . . .
66  *
67  * </pre>
68  * </p>
69  */
70 public final class PrintDocumentInfo implements Parcelable {
71 
72     /**
73      * Constant for unknown page count.
74      */
75     public static final int PAGE_COUNT_UNKNOWN = -1;
76 
77     /**
78      * Content type: unknown.
79      */
80     public static final int CONTENT_TYPE_UNKNOWN = -1;
81 
82     /**
83      * Content type: document.
84      * <p>
85      * A print service may use normal paper to print the content instead
86      * of dedicated photo paper. Also it may use a lower quality printing
87      * process as the content is not as sensitive to print quality variation
88      * as a photo is.
89      * </p>
90      */
91     public static final int CONTENT_TYPE_DOCUMENT = 0;
92 
93     /**
94      * Content type: photo.
95      * <p>
96      * A print service may use dedicated photo paper to print the content
97      * instead of normal paper. Also it may use a higher quality printing
98      * process as the content is more sensitive to print quality variation
99      * than a document.
100      * </p>
101      */
102     public static final int CONTENT_TYPE_PHOTO = 1;
103 
104     private String mName;
105     private int mPageCount;
106     private int mContentType;
107     private long mDataSize;
108 
109     /**
110      * Creates a new instance.
111      */
PrintDocumentInfo()112     private PrintDocumentInfo() {
113         /* do nothing */
114     }
115 
116     /**
117      * Creates a new instance.
118      *
119      * @param Prototype from which to clone.
120      */
PrintDocumentInfo(PrintDocumentInfo prototype)121     private PrintDocumentInfo(PrintDocumentInfo prototype) {
122         mName = prototype.mName;
123         mPageCount = prototype.mPageCount;
124         mContentType = prototype.mContentType;
125         mDataSize = prototype.mDataSize;
126     }
127 
128     /**
129      * Creates a new instance.
130      *
131      * @param parcel Data from which to initialize.
132      */
PrintDocumentInfo(Parcel parcel)133     private PrintDocumentInfo(Parcel parcel) {
134         mName = parcel.readString();
135         mPageCount = parcel.readInt();
136         mContentType = parcel.readInt();
137         mDataSize = parcel.readLong();
138     }
139 
140     /**
141      * Gets the document name. This name may be shown to
142      * the user.
143      *
144      * @return The document name.
145      */
getName()146     public String getName() {
147         return mName;
148     }
149 
150     /**
151      * Gets the total number of pages.
152      *
153      * @return The number of pages.
154      *
155      * @see #PAGE_COUNT_UNKNOWN
156      */
getPageCount()157     public int getPageCount() {
158         return mPageCount;
159     }
160 
161     /**
162      * Gets the content type.
163      *
164      * @return The content type.
165      *
166      * @see #CONTENT_TYPE_UNKNOWN
167      * @see #CONTENT_TYPE_DOCUMENT
168      * @see #CONTENT_TYPE_PHOTO
169      */
getContentType()170     public int getContentType() {
171         return mContentType;
172     }
173 
174     /**
175      * Gets the document data size in bytes.
176      *
177      * @return The data size.
178      */
getDataSize()179     public long getDataSize() {
180         return mDataSize;
181     }
182 
183     /**
184      * Sets the document data size in bytes.
185      *
186      * @param dataSize The data size.
187      *
188      * @hide
189      */
setDataSize(long dataSize)190     public void setDataSize(long dataSize) {
191         mDataSize = dataSize;
192     }
193 
194     @Override
describeContents()195     public int describeContents() {
196         return 0;
197     }
198 
199     @Override
writeToParcel(Parcel parcel, int flags)200     public void writeToParcel(Parcel parcel, int flags) {
201         parcel.writeString(mName);
202         parcel.writeInt(mPageCount);
203         parcel.writeInt(mContentType);
204         parcel.writeLong(mDataSize);
205     }
206 
207     @Override
hashCode()208     public int hashCode() {
209         final int prime = 31;
210         int result = 1;
211         result = prime * result + ((mName != null) ? mName.hashCode() : 0);
212         result = prime * result + mContentType;
213         result = prime * result + mPageCount;
214         result = prime * result + (int) mDataSize;
215         result = prime * result + (int) (mDataSize >> 32);
216         return result;
217     }
218 
219     @Override
equals(Object obj)220     public boolean equals(Object obj) {
221         if (this == obj) {
222             return true;
223         }
224         if (obj == null) {
225             return false;
226         }
227         if (getClass() != obj.getClass()) {
228             return false;
229         }
230         PrintDocumentInfo other = (PrintDocumentInfo) obj;
231         if (!TextUtils.equals(mName, other.mName)) {
232             return false;
233         }
234         if (mContentType != other.mContentType) {
235             return false;
236         }
237         if (mPageCount != other.mPageCount) {
238             return false;
239         }
240         if (mDataSize != other.mDataSize) {
241             return false;
242         }
243         return true;
244     }
245 
246     @Override
toString()247     public String toString() {
248         StringBuilder builder = new StringBuilder();
249         builder.append("PrintDocumentInfo{");
250         builder.append("name=").append(mName);
251         builder.append(", pageCount=").append(mPageCount);
252         builder.append(", contentType=").append(contentTyepToString(mContentType));
253         builder.append(", dataSize=").append(mDataSize);
254         builder.append("}");
255         return builder.toString();
256     }
257 
contentTyepToString(int contentType)258     private String contentTyepToString(int contentType) {
259         switch (contentType) {
260             case CONTENT_TYPE_DOCUMENT: {
261                 return "CONTENT_TYPE_DOCUMENT";
262             }
263             case CONTENT_TYPE_PHOTO: {
264                 return "CONTENT_TYPE_PHOTO";
265             }
266             default: {
267                 return "CONTENT_TYPE_UNKNOWN";
268             }
269         }
270     }
271 
272     /**
273      * Builder for creating a {@link PrintDocumentInfo}.
274      */
275     public static final class Builder {
276         private final PrintDocumentInfo mPrototype;
277 
278         /**
279          * Constructor.
280          *
281          * <p>
282          * The values of the relevant properties are initialized with defaults.
283          * Please refer to the documentation of the individual setters for
284          * information about the default values.
285          * </p>
286          *
287          * @param name The document name which may be shown to the user and
288          * is the file name if the content it describes is saved as a PDF.
289          * Cannot be empty.
290          */
Builder(String name)291         public Builder(String name) {
292             if (TextUtils.isEmpty(name)) {
293                 throw new IllegalArgumentException("name cannot be empty");
294             }
295             mPrototype = new PrintDocumentInfo();
296             mPrototype.mName = name;
297         }
298 
299         /**
300          * Sets the total number of pages.
301          * <p>
302          * <strong>Default: </strong> {@link #PAGE_COUNT_UNKNOWN}
303          * </p>
304          *
305          * @param pageCount The number of pages. Must be greater than
306          * or equal to zero or {@link PrintDocumentInfo#PAGE_COUNT_UNKNOWN}.
307          */
setPageCount(int pageCount)308         public Builder setPageCount(int pageCount) {
309             if (pageCount < 0 && pageCount != PAGE_COUNT_UNKNOWN) {
310                 throw new IllegalArgumentException("pageCount"
311                         + " must be greater than or equal to zero or"
312                         + " DocumentInfo#PAGE_COUNT_UNKNOWN");
313             }
314             mPrototype.mPageCount = pageCount;
315             return this;
316         }
317 
318         /**
319          * Sets the content type.
320          * <p>
321          * <strong>Default: </strong> {@link #CONTENT_TYPE_UNKNOWN}
322          * </p>
323          *
324          * @param type The content type.
325          *
326          * @see #CONTENT_TYPE_UNKNOWN
327          * @see #CONTENT_TYPE_DOCUMENT
328          * @see #CONTENT_TYPE_PHOTO
329          */
setContentType(int type)330         public Builder setContentType(int type) {
331             mPrototype.mContentType = type;
332             return this;
333         }
334 
335         /**
336          * Creates a new {@link PrintDocumentInfo} instance.
337          *
338          * @return The new instance.
339          */
build()340         public PrintDocumentInfo build() {
341             // Zero pages is the same as unknown as in this case
342             // we will have to ask for all pages and look a the
343             // wiritten PDF file for the page count.
344             if (mPrototype.mPageCount == 0) {
345                 mPrototype.mPageCount = PAGE_COUNT_UNKNOWN;
346             }
347             return new PrintDocumentInfo(mPrototype);
348         }
349     }
350 
351     public static final Parcelable.Creator<PrintDocumentInfo> CREATOR =
352             new Creator<PrintDocumentInfo>() {
353         @Override
354         public PrintDocumentInfo createFromParcel(Parcel parcel) {
355             return new PrintDocumentInfo(parcel);
356         }
357 
358         @Override
359         public PrintDocumentInfo[] newArray(int size) {
360             return new PrintDocumentInfo[size];
361         }
362     };
363 }
364