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({
     87             CONTENT_TYPE_UNKNOWN, CONTENT_TYPE_DOCUMENT, CONTENT_TYPE_PHOTO
     88     })
     89     public @interface ContentType {
     90     }
     91     /**
     92      * Content type: unknown.
     93      */
     94     public static final int CONTENT_TYPE_UNKNOWN = -1;
     95 
     96     /**
     97      * Content type: document.
     98      * <p>
     99      * A print service may use normal paper to print the content instead
    100      * of dedicated photo paper. Also it may use a lower quality printing
    101      * process as the content is not as sensitive to print quality variation
    102      * as a photo is.
    103      * </p>
    104      */
    105     public static final int CONTENT_TYPE_DOCUMENT = 0;
    106 
    107     /**
    108      * Content type: photo.
    109      * <p>
    110      * A print service may use dedicated photo paper to print the content
    111      * instead of normal paper. Also it may use a higher quality printing
    112      * process as the content is more sensitive to print quality variation
    113      * than a document.
    114      * </p>
    115      */
    116     public static final int CONTENT_TYPE_PHOTO = 1;
    117 
    118     private @NonNull String mName;
    119     private @IntRange(from = -1) int mPageCount;
    120     private int mContentType;
    121     private long mDataSize;
    122 
    123     /**
    124      * Creates a new instance.
    125      */
    126     private PrintDocumentInfo() {
    127         /* do nothing */
    128     }
    129 
    130     /**
    131      * Creates a new instance.
    132      *
    133      * @param prototype from which to clone.
    134      */
    135     private PrintDocumentInfo(@NonNull PrintDocumentInfo prototype) {
    136         mName = prototype.mName;
    137         mPageCount = prototype.mPageCount;
    138         mContentType = prototype.mContentType;
    139         mDataSize = prototype.mDataSize;
    140     }
    141 
    142     /**
    143      * Creates a new instance.
    144      *
    145      * @param parcel Data from which to initialize.
    146      */
    147     private PrintDocumentInfo(Parcel parcel) {
    148         mName = Preconditions.checkStringNotEmpty(parcel.readString());
    149         mPageCount = parcel.readInt();
    150         Preconditions.checkArgument(mPageCount == PAGE_COUNT_UNKNOWN || mPageCount > 0);
    151         mContentType = parcel.readInt();
    152         mDataSize = Preconditions.checkArgumentNonnegative(parcel.readLong());
    153     }
    154 
    155     /**
    156      * Gets the document name. This name may be shown to
    157      * the user.
    158      *
    159      * @return The document name.
    160      */
    161     public @NonNull String getName() {
    162         return mName;
    163     }
    164 
    165     /**
    166      * Gets the total number of pages.
    167      *
    168      * @return The number of pages.
    169      *
    170      * @see #PAGE_COUNT_UNKNOWN
    171      */
    172     public @IntRange(from = -1) int getPageCount() {
    173         return mPageCount;
    174     }
    175 
    176     /**
    177      * Gets the content type.
    178      *
    179      * @return The content type.
    180      *
    181      * @see #CONTENT_TYPE_UNKNOWN
    182      * @see #CONTENT_TYPE_DOCUMENT
    183      * @see #CONTENT_TYPE_PHOTO
    184      */
    185     public int getContentType() {
    186         return mContentType;
    187     }
    188 
    189     /**
    190      * Gets the document data size in bytes.
    191      *
    192      * @return The data size.
    193      */
    194     public @IntRange(from = 0) long getDataSize() {
    195         return mDataSize;
    196     }
    197 
    198     /**
    199      * Sets the document data size in bytes.
    200      *
    201      * @param dataSize The data size.
    202      *
    203      * @hide
    204      */
    205     public void setDataSize(@IntRange(from = 0) long dataSize) {
    206         mDataSize = dataSize;
    207     }
    208 
    209     @Override
    210     public int describeContents() {
    211         return 0;
    212     }
    213 
    214     @Override
    215     public void writeToParcel(Parcel parcel, int flags) {
    216         parcel.writeString(mName);
    217         parcel.writeInt(mPageCount);
    218         parcel.writeInt(mContentType);
    219         parcel.writeLong(mDataSize);
    220     }
    221 
    222     @Override
    223     public int hashCode() {
    224         final int prime = 31;
    225         int result = 1;
    226         result = prime * result + ((mName != null) ? mName.hashCode() : 0);
    227         result = prime * result + mContentType;
    228         result = prime * result + mPageCount;
    229         result = prime * result + (int) mDataSize;
    230         result = prime * result + (int) (mDataSize >> 32);
    231         return result;
    232     }
    233 
    234     @Override
    235     public boolean equals(Object obj) {
    236         if (this == obj) {
    237             return true;
    238         }
    239         if (obj == null) {
    240             return false;
    241         }
    242         if (getClass() != obj.getClass()) {
    243             return false;
    244         }
    245         PrintDocumentInfo other = (PrintDocumentInfo) obj;
    246         if (!TextUtils.equals(mName, other.mName)) {
    247             return false;
    248         }
    249         if (mContentType != other.mContentType) {
    250             return false;
    251         }
    252         if (mPageCount != other.mPageCount) {
    253             return false;
    254         }
    255         if (mDataSize != other.mDataSize) {
    256             return false;
    257         }
    258         return true;
    259     }
    260 
    261     @Override
    262     public String toString() {
    263         StringBuilder builder = new StringBuilder();
    264         builder.append("PrintDocumentInfo{");
    265         builder.append("name=").append(mName);
    266         builder.append(", pageCount=").append(mPageCount);
    267         builder.append(", contentType=").append(contentTypeToString(mContentType));
    268         builder.append(", dataSize=").append(mDataSize);
    269         builder.append("}");
    270         return builder.toString();
    271     }
    272 
    273     private String contentTypeToString(int contentType) {
    274         switch (contentType) {
    275             case CONTENT_TYPE_DOCUMENT: {
    276                 return "CONTENT_TYPE_DOCUMENT";
    277             }
    278             case CONTENT_TYPE_PHOTO: {
    279                 return "CONTENT_TYPE_PHOTO";
    280             }
    281             default: {
    282                 return "CONTENT_TYPE_UNKNOWN";
    283             }
    284         }
    285     }
    286 
    287     /**
    288      * Builder for creating a {@link PrintDocumentInfo}.
    289      */
    290     public static final class Builder {
    291         private final PrintDocumentInfo mPrototype;
    292 
    293         /**
    294          * Constructor.
    295          *
    296          * <p>
    297          * The values of the relevant properties are initialized with defaults.
    298          * Please refer to the documentation of the individual setters for
    299          * information about the default values.
    300          * </p>
    301          *
    302          * @param name The document name which may be shown to the user and
    303          * is the file name if the content it describes is saved as a PDF.
    304          * Cannot be empty.
    305          */
    306         public Builder(@NonNull String name) {
    307             if (TextUtils.isEmpty(name)) {
    308                 throw new IllegalArgumentException("name cannot be empty");
    309             }
    310             mPrototype = new PrintDocumentInfo();
    311             mPrototype.mName = name;
    312         }
    313 
    314         /**
    315          * Sets the total number of pages.
    316          * <p>
    317          * <strong>Default: </strong> {@link #PAGE_COUNT_UNKNOWN}
    318          * </p>
    319          *
    320          * @param pageCount The number of pages. Must be greater than or equal to zero or
    321          *            {@link PrintDocumentInfo#PAGE_COUNT_UNKNOWN}.
    322          * @return This builder.
    323          */
    324         public @NonNull Builder setPageCount(@IntRange(from = -1) int pageCount) {
    325             if (pageCount < 0 && pageCount != PAGE_COUNT_UNKNOWN) {
    326                 throw new IllegalArgumentException("pageCount"
    327                         + " must be greater than or equal to zero or"
    328                         + " DocumentInfo#PAGE_COUNT_UNKNOWN");
    329             }
    330             mPrototype.mPageCount = pageCount;
    331             return this;
    332         }
    333 
    334         /**
    335          * Sets the content type.
    336          * <p>
    337          * <strong>Default: </strong> {@link #CONTENT_TYPE_UNKNOWN}
    338          * </p>
    339          *
    340          * @param type The content type.
    341          * @return This builder.
    342          * @see #CONTENT_TYPE_UNKNOWN
    343          * @see #CONTENT_TYPE_DOCUMENT
    344          * @see #CONTENT_TYPE_PHOTO
    345          */
    346         public @NonNull Builder setContentType(@ContentType int type) {
    347             mPrototype.mContentType = type;
    348             return this;
    349         }
    350 
    351         /**
    352          * Creates a new {@link PrintDocumentInfo} instance.
    353          *
    354          * @return The new instance.
    355          */
    356         public @NonNull PrintDocumentInfo build() {
    357             // Zero pages is the same as unknown as in this case
    358             // we will have to ask for all pages and look a the
    359             // wiritten PDF file for the page count.
    360             if (mPrototype.mPageCount == 0) {
    361                 mPrototype.mPageCount = PAGE_COUNT_UNKNOWN;
    362             }
    363             return new PrintDocumentInfo(mPrototype);
    364         }
    365     }
    366 
    367     public static final Parcelable.Creator<PrintDocumentInfo> CREATOR =
    368             new Creator<PrintDocumentInfo>() {
    369         @Override
    370         public PrintDocumentInfo createFromParcel(Parcel parcel) {
    371             return new PrintDocumentInfo(parcel);
    372         }
    373 
    374         @Override
    375         public PrintDocumentInfo[] newArray(int size) {
    376             return new PrintDocumentInfo[size];
    377         }
    378     };
    379 }
    380