blob: 25f383c09ad1c00ce676945cbc7fd7101cb91353 [file] [log] [blame]
/*
* 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.FloatRange;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringRes;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.service.print.PrintJobInfoProto;
import com.android.internal.util.Preconditions;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
/**
* This class represents the description of a print job. The print job
* state includes properties such as its id, print attributes used for
* generating the content, and so on. Note that the print jobs state may
* change over time and this class represents a snapshot of this state.
*/
public final class PrintJobInfo implements Parcelable {
/** @hide */
@IntDef(prefix = { "STATE_" }, value = {
STATE_CREATED,
STATE_QUEUED,
STATE_STARTED,
STATE_BLOCKED,
STATE_COMPLETED,
STATE_FAILED,
STATE_CANCELED
})
@Retention(RetentionPolicy.SOURCE)
public @interface State {
}
/**
* Constant for matching any print job state.
*
* @hide
*/
public static final int STATE_ANY = -1;
/**
* Constant for matching any print job state.
*
* @hide
*/
public static final int STATE_ANY_VISIBLE_TO_CLIENTS = -2;
/**
* Constant for matching any active print job state.
*
* @hide
*/
public static final int STATE_ANY_ACTIVE = -3;
/**
* Constant for matching any scheduled, i.e. delivered to a print
* service, print job state.
*
* @hide
*/
public static final int STATE_ANY_SCHEDULED = -4;
/**
* Print job state: The print job is being created but not yet
* ready to be printed.
* <p>
* Next valid states: {@link #STATE_QUEUED}
* </p>
*/
public static final int STATE_CREATED = PrintJobInfoProto.STATE_CREATED;
/**
* Print job state: The print jobs is created, it is ready
* to be printed and should be processed.
* <p>
* Next valid states: {@link #STATE_STARTED}, {@link #STATE_FAILED},
* {@link #STATE_CANCELED}
* </p>
*/
public static final int STATE_QUEUED = PrintJobInfoProto.STATE_QUEUED;
/**
* Print job state: The print job is being printed.
* <p>
* Next valid states: {@link #STATE_COMPLETED}, {@link #STATE_FAILED},
* {@link #STATE_CANCELED}, {@link #STATE_BLOCKED}
* </p>
*/
public static final int STATE_STARTED = PrintJobInfoProto.STATE_STARTED;
/**
* Print job state: The print job is blocked.
* <p>
* Next valid states: {@link #STATE_FAILED}, {@link #STATE_CANCELED},
* {@link #STATE_STARTED}
* </p>
*/
public static final int STATE_BLOCKED = PrintJobInfoProto.STATE_BLOCKED;
/**
* Print job state: The print job is successfully printed.
* This is a terminal state.
* <p>
* Next valid states: None
* </p>
*/
public static final int STATE_COMPLETED = PrintJobInfoProto.STATE_COMPLETED;
/**
* Print job state: The print job was printing but printing failed.
* <p>
* Next valid states: {@link #STATE_CANCELED}, {@link #STATE_STARTED}
* </p>
*/
public static final int STATE_FAILED = PrintJobInfoProto.STATE_FAILED;
/**
* Print job state: The print job is canceled.
* This is a terminal state.
* <p>
* Next valid states: None
* </p>
*/
public static final int STATE_CANCELED = PrintJobInfoProto.STATE_CANCELED;
/** The unique print job id. */
private PrintJobId mId;
/** The human readable print job label. */
private String mLabel;
/** The unique id of the printer. */
private PrinterId mPrinterId;
/** The name of the printer - internally used */
private String mPrinterName;
/** The state of the print job. */
private int mState;
/** The id of the app that created the job. */
private int mAppId;
/** Optional tag assigned by a print service.*/
private String mTag;
/** The wall time when the print job was created. */
private long mCreationTime;
/** How many copies to print. */
private int mCopies;
/** The pages to print */
private PageRange[] mPageRanges;
/** The print job attributes size. */
private PrintAttributes mAttributes;
/** Information about the printed document. */
private PrintDocumentInfo mDocumentInfo;
/** The progress made on printing this job or -1 if not set. */
private float mProgress;
/** A short string describing the status of this job. */
private @Nullable CharSequence mStatus;
/** A string resource describing the status of this job. */
private @StringRes int mStatusRes;
private @Nullable CharSequence mStatusResAppPackageName;
/** Advanced printer specific options. */
private Bundle mAdvancedOptions;
/** Whether we are trying to cancel this print job. */
private boolean mCanceling;
/** @hide*/
public PrintJobInfo() {
mProgress = -1;
}
/** @hide */
public PrintJobInfo(PrintJobInfo other) {
mId = other.mId;
mLabel = other.mLabel;
mPrinterId = other.mPrinterId;
mPrinterName = other.mPrinterName;
mState = other.mState;
mAppId = other.mAppId;
mTag = other.mTag;
mCreationTime = other.mCreationTime;
mCopies = other.mCopies;
mPageRanges = other.mPageRanges;
mAttributes = other.mAttributes;
mDocumentInfo = other.mDocumentInfo;
mProgress = other.mProgress;
mStatus = other.mStatus;
mStatusRes = other.mStatusRes;
mStatusResAppPackageName = other.mStatusResAppPackageName;
mCanceling = other.mCanceling;
mAdvancedOptions = other.mAdvancedOptions;
}
private PrintJobInfo(@NonNull Parcel parcel) {
mId = parcel.readParcelable(null);
mLabel = parcel.readString();
mPrinterId = parcel.readParcelable(null);
mPrinterName = parcel.readString();
mState = parcel.readInt();
mAppId = parcel.readInt();
mTag = parcel.readString();
mCreationTime = parcel.readLong();
mCopies = parcel.readInt();
Parcelable[] parcelables = parcel.readParcelableArray(null);
if (parcelables != null) {
mPageRanges = new PageRange[parcelables.length];
for (int i = 0; i < parcelables.length; i++) {
mPageRanges[i] = (PageRange) parcelables[i];
}
}
mAttributes = (PrintAttributes) parcel.readParcelable(null);
mDocumentInfo = (PrintDocumentInfo) parcel.readParcelable(null);
mProgress = parcel.readFloat();
mStatus = parcel.readCharSequence();
mStatusRes = parcel.readInt();
mStatusResAppPackageName = parcel.readCharSequence();
mCanceling = (parcel.readInt() == 1);
mAdvancedOptions = parcel.readBundle();
if (mAdvancedOptions != null) {
Preconditions.checkArgument(!mAdvancedOptions.containsKey(null));
}
}
/**
* Gets the unique print job id.
*
* @return The id.
*/
public @Nullable PrintJobId getId() {
return mId;
}
/**
* Sets the unique print job id.
*
* @param id The job id.
*
* @hide
*/
public void setId(@NonNull PrintJobId id) {
this.mId = id;
}
/**
* Gets the human readable job label.
*
* @return The label.
*/
public @NonNull String getLabel() {
return mLabel;
}
/**
* Sets the human readable job label.
*
* @param label The label.
*
* @hide
*/
public void setLabel(@NonNull String label) {
mLabel = label;
}
/**
* Gets the unique target printer id.
*
* @return The target printer id.
*/
public @Nullable PrinterId getPrinterId() {
return mPrinterId;
}
/**
* Sets the unique target printer id.
*
* @param printerId The target printer id.
*
* @hide
*/
public void setPrinterId(@NonNull PrinterId printerId) {
mPrinterId = printerId;
}
/**
* Gets the name of the target printer.
*
* @return The printer name.
*
* @hide
*/
public @Nullable String getPrinterName() {
return mPrinterName;
}
/**
* Sets the name of the target printer.
*
* @param printerName The printer name.
*
* @hide
*/
public void setPrinterName(@NonNull String printerName) {
mPrinterName = printerName;
}
/**
* Gets the current job state.
*
* @return The job state.
*
* @see #STATE_CREATED
* @see #STATE_QUEUED
* @see #STATE_STARTED
* @see #STATE_COMPLETED
* @see #STATE_BLOCKED
* @see #STATE_FAILED
* @see #STATE_CANCELED
*/
public @State int getState() {
return mState;
}
/**
* Sets the current job state.
*
* @param state The job state.
*
* @hide
*/
public void setState(int state) {
mState = state;
}
/**
* Sets the progress of the print job.
*
* @param progress the progress of the job
*
* @hide
*/
public void setProgress(@FloatRange(from=0.0, to=1.0) float progress) {
Preconditions.checkArgumentInRange(progress, 0, 1, "progress");
mProgress = progress;
}
/**
* Sets the status of the print job.
*
* @param status the status of the job, can be null
*
* @hide
*/
public void setStatus(@Nullable CharSequence status) {
mStatusRes = 0;
mStatusResAppPackageName = null;
mStatus = status;
}
/**
* Sets the status of the print job.
*
* @param status The new status as a string resource
* @param appPackageName App package name the resource belongs to
*
* @hide
*/
public void setStatus(@StringRes int status, @NonNull CharSequence appPackageName) {
mStatus = null;
mStatusRes = status;
mStatusResAppPackageName = appPackageName;
}
/**
* Sets the owning application id.
*
* @return The owning app id.
*
* @hide
*/
public int getAppId() {
return mAppId;
}
/**
* Sets the owning application id.
*
* @param appId The owning app id.
*
* @hide
*/
public void setAppId(int appId) {
mAppId = appId;
}
/**
* Gets the optional tag assigned by a print service.
*
* @return The tag.
*
* @hide
*/
public String getTag() {
return mTag;
}
/**
* Sets the optional tag assigned by a print service.
*
* @param tag The tag.
*
* @hide
*/
public void setTag(String tag) {
mTag = tag;
}
/**
* Gets the wall time in millisecond when this print job was created.
*
* @return The creation time in milliseconds.
*/
public long getCreationTime() {
return mCreationTime;
}
/**
* Sets the wall time in milliseconds when this print job was created.
*
* @param creationTime The creation time in milliseconds.
*
* @hide
*/
public void setCreationTime(long creationTime) {
if (creationTime < 0) {
throw new IllegalArgumentException("creationTime must be non-negative.");
}
mCreationTime = creationTime;
}
/**
* Gets the number of copies.
*
* @return The number of copies or zero if not set.
*/
public @IntRange(from = 0) int getCopies() {
return mCopies;
}
/**
* Sets the number of copies.
*
* @param copyCount The number of copies.
*
* @hide
*/
public void setCopies(int copyCount) {
if (copyCount < 1) {
throw new IllegalArgumentException("Copies must be more than one.");
}
mCopies = copyCount;
}
/**
* Gets the included pages.
*
* @return The included pages or <code>null</code> if not set.
*/
public @Nullable PageRange[] getPages() {
return mPageRanges;
}
/**
* Sets the included pages.
*
* @param pageRanges The included pages.
*
* @hide
*/
public void setPages(PageRange[] pageRanges) {
mPageRanges = pageRanges;
}
/**
* Gets the print job attributes.
*
* @return The attributes.
*/
public @NonNull PrintAttributes getAttributes() {
return mAttributes;
}
/**
* Sets the print job attributes.
*
* @param attributes The attributes.
*
* @hide
*/
public void setAttributes(PrintAttributes attributes) {
mAttributes = attributes;
}
/**
* Gets the info describing the printed document.
*
* @return The document info.
*
* @hide
*/
@UnsupportedAppUsage
public PrintDocumentInfo getDocumentInfo() {
return mDocumentInfo;
}
/**
* Sets the info describing the printed document.
*
* @param info The document info.
*
* @hide
*/
public void setDocumentInfo(PrintDocumentInfo info) {
mDocumentInfo = info;
}
/**
* Gets whether this print is being cancelled.
*
* @return True if the print job is being cancelled.
*
* @hide
*/
public boolean isCancelling() {
return mCanceling;
}
/**
* Sets whether this print is being cancelled.
*
* @param cancelling True if the print job is being cancelled.
*
* @hide
*/
public void setCancelling(boolean cancelling) {
mCanceling = cancelling;
}
/**
* If the print job is actively processed, i.e. the device needs to stay on.
*
* @hide
*/
public boolean shouldStayAwake() {
return mCanceling || mState == STATE_STARTED || mState == STATE_QUEUED;
}
/**
* Gets whether this job has a given advanced (printer specific) print
* option.
*
* @param key The option key.
* @return Whether the option is present.
*/
public boolean hasAdvancedOption(String key) {
return mAdvancedOptions != null && mAdvancedOptions.containsKey(key);
}
/**
* Gets the value of an advanced (printer specific) print option.
*
* @param key The option key.
* @return The option value.
*/
public String getAdvancedStringOption(String key) {
if (mAdvancedOptions != null) {
return mAdvancedOptions.getString(key);
}
return null;
}
/**
* Gets the value of an advanced (printer specific) print option.
*
* @param key The option key.
* @return The option value.
*/
public int getAdvancedIntOption(String key) {
if (mAdvancedOptions != null) {
return mAdvancedOptions.getInt(key);
}
return 0;
}
/**
* Gets the advanced options.
*
* @return The advanced options.
*
* @hide
*/
@UnsupportedAppUsage
public Bundle getAdvancedOptions() {
return mAdvancedOptions;
}
/**
* Sets the advanced options.
*
* @param options The advanced options.
*
* @hide
*/
public void setAdvancedOptions(Bundle options) {
mAdvancedOptions = options;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeParcelable(mId, flags);
parcel.writeString(mLabel);
parcel.writeParcelable(mPrinterId, flags);
parcel.writeString(mPrinterName);
parcel.writeInt(mState);
parcel.writeInt(mAppId);
parcel.writeString(mTag);
parcel.writeLong(mCreationTime);
parcel.writeInt(mCopies);
parcel.writeParcelableArray(mPageRanges, flags);
parcel.writeParcelable(mAttributes, flags);
parcel.writeParcelable(mDocumentInfo, 0);
parcel.writeFloat(mProgress);
parcel.writeCharSequence(mStatus);
parcel.writeInt(mStatusRes);
parcel.writeCharSequence(mStatusResAppPackageName);
parcel.writeInt(mCanceling ? 1 : 0);
parcel.writeBundle(mAdvancedOptions);
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("PrintJobInfo{");
builder.append("label: ").append(mLabel);
builder.append(", id: ").append(mId);
builder.append(", state: ").append(stateToString(mState));
builder.append(", printer: " + mPrinterId);
builder.append(", tag: ").append(mTag);
builder.append(", creationTime: " + mCreationTime);
builder.append(", copies: ").append(mCopies);
builder.append(", attributes: " + (mAttributes != null
? mAttributes.toString() : null));
builder.append(", documentInfo: " + (mDocumentInfo != null
? mDocumentInfo.toString() : null));
builder.append(", cancelling: " + mCanceling);
builder.append(", pages: " + (mPageRanges != null
? Arrays.toString(mPageRanges) : null));
builder.append(", hasAdvancedOptions: " + (mAdvancedOptions != null));
builder.append(", progress: " + mProgress);
builder.append(", status: " + (mStatus != null
? mStatus.toString() : null));
builder.append(", statusRes: " + mStatusRes);
builder.append(", statusResAppPackageName: " + (mStatusResAppPackageName != null
? mStatusResAppPackageName.toString() : null));
builder.append("}");
return builder.toString();
}
/** @hide */
public static String stateToString(int state) {
switch (state) {
case STATE_CREATED: {
return "STATE_CREATED";
}
case STATE_QUEUED: {
return "STATE_QUEUED";
}
case STATE_STARTED: {
return "STATE_STARTED";
}
case STATE_BLOCKED: {
return "STATE_BLOCKED";
}
case STATE_FAILED: {
return "STATE_FAILED";
}
case STATE_COMPLETED: {
return "STATE_COMPLETED";
}
case STATE_CANCELED: {
return "STATE_CANCELED";
}
default: {
return "STATE_UNKNOWN";
}
}
}
/**
* Get the progress that has been made printing this job.
*
* @return the print progress or -1 if not set
* @hide
*/
@TestApi
public float getProgress() {
return mProgress;
}
/**
* Get the status of this job.
*
* @param pm Package manager used to resolve the string
*
* @return the status of this job or null if not set
* @hide
*/
@TestApi
public @Nullable CharSequence getStatus(@NonNull PackageManager pm) {
if (mStatusRes == 0) {
return mStatus;
} else {
try {
return pm.getResourcesForApplication(mStatusResAppPackageName.toString())
.getString(mStatusRes);
} catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
return null;
}
}
}
/**
* Builder for creating a {@link PrintJobInfo}.
*/
public static final class Builder {
private final PrintJobInfo mPrototype;
/**
* Constructor.
*
* @param prototype Prototype to use as a starting point.
* Can be <code>null</code>.
*/
public Builder(@Nullable PrintJobInfo prototype) {
mPrototype = (prototype != null)
? new PrintJobInfo(prototype)
: new PrintJobInfo();
}
/**
* Sets the number of copies.
*
* @param copies The number of copies.
*/
public void setCopies(@IntRange(from = 1) int copies) {
mPrototype.mCopies = copies;
}
/**
* Sets the print job attributes.
*
* @param attributes The attributes.
*/
public void setAttributes(@NonNull PrintAttributes attributes) {
mPrototype.mAttributes = attributes;
}
/**
* Sets the included pages.
*
* @param pages The included pages.
*/
public void setPages(@NonNull PageRange[] pages) {
mPrototype.mPageRanges = pages;
}
/**
* Sets the progress of the print job.
*
* @param progress the progress of the job
* @hide
*/
public void setProgress(@FloatRange(from=0.0, to=1.0) float progress) {
Preconditions.checkArgumentInRange(progress, 0, 1, "progress");
mPrototype.mProgress = progress;
}
/**
* Sets the status of the print job.
*
* @param status the status of the job, can be null
* @hide
*/
public void setStatus(@Nullable CharSequence status) {
mPrototype.mStatus = status;
}
/**
* Puts an advanced (printer specific) option.
*
* @param key The option key.
* @param value The option value.
*/
public void putAdvancedOption(@NonNull String key, @Nullable String value) {
Preconditions.checkNotNull(key, "key cannot be null");
if (mPrototype.mAdvancedOptions == null) {
mPrototype.mAdvancedOptions = new Bundle();
}
mPrototype.mAdvancedOptions.putString(key, value);
}
/**
* Puts an advanced (printer specific) option.
*
* @param key The option key.
* @param value The option value.
*/
public void putAdvancedOption(@NonNull String key, int value) {
if (mPrototype.mAdvancedOptions == null) {
mPrototype.mAdvancedOptions = new Bundle();
}
mPrototype.mAdvancedOptions.putInt(key, value);
}
/**
* Creates a new {@link PrintJobInfo} instance.
*
* @return The new instance.
*/
public @NonNull PrintJobInfo build() {
return mPrototype;
}
}
public static final @android.annotation.NonNull Parcelable.Creator<PrintJobInfo> CREATOR =
new Creator<PrintJobInfo>() {
@Override
public PrintJobInfo createFromParcel(Parcel parcel) {
return new PrintJobInfo(parcel);
}
@Override
public PrintJobInfo[] newArray(int size) {
return new PrintJobInfo[size];
}
};
}