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