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