/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.print; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * This class encapsulates information about a document for printing * purposes. This meta-data is used by the platform and print services, * components that interact with printers. For example, this class * contains the number of pages contained in the document it describes and * this number of pages is shown to the user allowing him/her to select * the range to print. Also a print service may optimize the printing * process based on the content type, such as document or photo. *

* Instances of this class are created by the printing application and * passed to the {@link PrintDocumentAdapter.LayoutResultCallback#onLayoutFinished( * PrintDocumentInfo, boolean) PrintDocumentAdapter.LayoutResultCallback.onLayoutFinished( * PrintDocumentInfo, boolean)} callback after successfully laying out the * content which is performed in {@link PrintDocumentAdapter#onLayout(PrintAttributes, * PrintAttributes, android.os.CancellationSignal, PrintDocumentAdapter.LayoutResultCallback, * android.os.Bundle) PrintDocumentAdapter.onLayout(PrintAttributes, * PrintAttributes, android.os.CancellationSignal, * PrintDocumentAdapter.LayoutResultCallback, android.os.Bundle)}. *

*

* An example usage looks like this: *

 *
 * . . .
 *
 * public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
 *         CancellationSignal cancellationSignal, LayoutResultCallback callback,
 *         Bundle metadata) {
 *
 *        // Assume the app defined a LayoutResult class which contains
 *        // the layout result data and that the content is a document.
 *        LayoutResult result = doSomeLayoutWork();
 *
 *        PrintDocumentInfo info = new PrintDocumentInfo
 *                .Builder("printed_file.pdf")
 *                .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
 *                .setPageCount(result.getPageCount())
 *                .build();
 *
 *       callback.onLayoutFinished(info, result.getContentChanged());
 *   }
 *
 *   . . .
 *
 * 
*

*/ public final class PrintDocumentInfo implements Parcelable { /** * Constant for unknown page count. */ public static final int PAGE_COUNT_UNKNOWN = -1; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef({ CONTENT_TYPE_UNKNOWN, CONTENT_TYPE_DOCUMENT, CONTENT_TYPE_PHOTO }) public @interface ContentType { } /** * Content type: unknown. */ public static final int CONTENT_TYPE_UNKNOWN = -1; /** * Content type: document. *

* A print service may use normal paper to print the content instead * of dedicated photo paper. Also it may use a lower quality printing * process as the content is not as sensitive to print quality variation * as a photo is. *

*/ public static final int CONTENT_TYPE_DOCUMENT = 0; /** * Content type: photo. *

* A print service may use dedicated photo paper to print the content * instead of normal paper. Also it may use a higher quality printing * process as the content is more sensitive to print quality variation * than a document. *

*/ public static final int CONTENT_TYPE_PHOTO = 1; private @NonNull String mName; private @IntRange(from = -1) int mPageCount; private int mContentType; private long mDataSize; /** * Creates a new instance. */ private PrintDocumentInfo() { /* do nothing */ } /** * Creates a new instance. * * @param prototype from which to clone. */ private PrintDocumentInfo(@NonNull PrintDocumentInfo prototype) { mName = prototype.mName; mPageCount = prototype.mPageCount; mContentType = prototype.mContentType; mDataSize = prototype.mDataSize; } /** * Creates a new instance. * * @param parcel Data from which to initialize. */ private PrintDocumentInfo(Parcel parcel) { mName = Preconditions.checkStringNotEmpty(parcel.readString()); mPageCount = parcel.readInt(); Preconditions.checkArgument(mPageCount == PAGE_COUNT_UNKNOWN || mPageCount > 0); mContentType = parcel.readInt(); mDataSize = Preconditions.checkArgumentNonnegative(parcel.readLong()); } /** * Gets the document name. This name may be shown to * the user. * * @return The document name. */ public @NonNull String getName() { return mName; } /** * Gets the total number of pages. * * @return The number of pages. * * @see #PAGE_COUNT_UNKNOWN */ public @IntRange(from = -1) int getPageCount() { return mPageCount; } /** * Gets the content type. * * @return The content type. * * @see #CONTENT_TYPE_UNKNOWN * @see #CONTENT_TYPE_DOCUMENT * @see #CONTENT_TYPE_PHOTO */ public int getContentType() { return mContentType; } /** * Gets the document data size in bytes. * * @return The data size. */ public @IntRange(from = 0) long getDataSize() { return mDataSize; } /** * Sets the document data size in bytes. * * @param dataSize The data size. * * @hide */ public void setDataSize(@IntRange(from = 0) long dataSize) { mDataSize = dataSize; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int flags) { parcel.writeString(mName); parcel.writeInt(mPageCount); parcel.writeInt(mContentType); parcel.writeLong(mDataSize); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((mName != null) ? mName.hashCode() : 0); result = prime * result + mContentType; result = prime * result + mPageCount; result = prime * result + (int) mDataSize; result = prime * result + (int) (mDataSize >> 32); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } PrintDocumentInfo other = (PrintDocumentInfo) obj; if (!TextUtils.equals(mName, other.mName)) { return false; } if (mContentType != other.mContentType) { return false; } if (mPageCount != other.mPageCount) { return false; } if (mDataSize != other.mDataSize) { return false; } return true; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("PrintDocumentInfo{"); builder.append("name=").append(mName); builder.append(", pageCount=").append(mPageCount); builder.append(", contentType=").append(contentTypeToString(mContentType)); builder.append(", dataSize=").append(mDataSize); builder.append("}"); return builder.toString(); } private String contentTypeToString(int contentType) { switch (contentType) { case CONTENT_TYPE_DOCUMENT: { return "CONTENT_TYPE_DOCUMENT"; } case CONTENT_TYPE_PHOTO: { return "CONTENT_TYPE_PHOTO"; } default: { return "CONTENT_TYPE_UNKNOWN"; } } } /** * Builder for creating a {@link PrintDocumentInfo}. */ public static final class Builder { private final PrintDocumentInfo mPrototype; /** * Constructor. * *

* The values of the relevant properties are initialized with defaults. * Please refer to the documentation of the individual setters for * information about the default values. *

* * @param name The document name which may be shown to the user and * is the file name if the content it describes is saved as a PDF. * Cannot be empty. */ public Builder(@NonNull String name) { if (TextUtils.isEmpty(name)) { throw new IllegalArgumentException("name cannot be empty"); } mPrototype = new PrintDocumentInfo(); mPrototype.mName = name; } /** * Sets the total number of pages. *

* Default: {@link #PAGE_COUNT_UNKNOWN} *

* * @param pageCount The number of pages. Must be greater than or equal to zero or * {@link PrintDocumentInfo#PAGE_COUNT_UNKNOWN}. * @return This builder. */ public @NonNull Builder setPageCount(@IntRange(from = -1) int pageCount) { if (pageCount < 0 && pageCount != PAGE_COUNT_UNKNOWN) { throw new IllegalArgumentException("pageCount" + " must be greater than or equal to zero or" + " DocumentInfo#PAGE_COUNT_UNKNOWN"); } mPrototype.mPageCount = pageCount; return this; } /** * Sets the content type. *

* Default: {@link #CONTENT_TYPE_UNKNOWN} *

* * @param type The content type. * @return This builder. * @see #CONTENT_TYPE_UNKNOWN * @see #CONTENT_TYPE_DOCUMENT * @see #CONTENT_TYPE_PHOTO */ public @NonNull Builder setContentType(@ContentType int type) { mPrototype.mContentType = type; return this; } /** * Creates a new {@link PrintDocumentInfo} instance. * * @return The new instance. */ public @NonNull PrintDocumentInfo build() { // Zero pages is the same as unknown as in this case // we will have to ask for all pages and look a the // wiritten PDF file for the page count. if (mPrototype.mPageCount == 0) { mPrototype.mPageCount = PAGE_COUNT_UNKNOWN; } return new PrintDocumentInfo(mPrototype); } } public static final Parcelable.Creator CREATOR = new Creator() { @Override public PrintDocumentInfo createFromParcel(Parcel parcel) { return new PrintDocumentInfo(parcel); } @Override public PrintDocumentInfo[] newArray(int size) { return new PrintDocumentInfo[size]; } }; }