summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/java/android/print/IPrintManager.aidl4
-rw-r--r--core/java/android/print/PrintDocumentAdapter.java18
-rw-r--r--core/java/android/print/PrintDocumentInfo.java30
-rw-r--r--core/java/android/print/PrintFileDocumentAdapter.java10
-rw-r--r--core/java/android/print/PrintJobInfo.java62
-rw-r--r--core/java/android/print/PrintManager.java13
-rw-r--r--core/java/android/print/PrinterDiscoverySession.java35
-rw-r--r--core/java/android/print/pdf/PrintedPdfDocument.java5
-rw-r--r--core/java/android/printservice/IPrintService.aidl4
-rw-r--r--core/java/android/printservice/PrintDocument.java11
-rw-r--r--core/java/android/printservice/PrintJob.java71
-rw-r--r--core/java/android/printservice/PrintService.java44
-rw-r--r--core/java/android/printservice/PrinterDiscoverySession.java100
-rw-r--r--core/res/AndroidManifest.xml11
-rw-r--r--core/res/res/values/strings.xml16
-rwxr-xr-xcore/res/res/values/symbols.xml1
16 files changed, 327 insertions, 108 deletions
diff --git a/core/java/android/print/IPrintManager.aidl b/core/java/android/print/IPrintManager.aidl
index 3bfd9a1..fb6bb2e 100644
--- a/core/java/android/print/IPrintManager.aidl
+++ b/core/java/android/print/IPrintManager.aidl
@@ -41,7 +41,9 @@ interface IPrintManager {
void startPrinterDiscovery(in IPrinterDiscoveryObserver observer,
in List<PrinterId> priorityList, int userId);
void stopPrinterDiscovery(in IPrinterDiscoveryObserver observer, int userId);
- void requestPrinterUpdate(in PrinterId printerId, int userId);
+ void validatePrinters(in List<PrinterId> printerIds, int userId);
+ void startPrinterStateTracking(in PrinterId printerId, int userId);
+ void stopPrinterStateTracking(in PrinterId printerId, int userId);
void destroyPrinterDiscoverySession(in IPrinterDiscoveryObserver observer,
int userId);
}
diff --git a/core/java/android/print/PrintDocumentAdapter.java b/core/java/android/print/PrintDocumentAdapter.java
index 8a64e85..33b4aad 100644
--- a/core/java/android/print/PrintDocumentAdapter.java
+++ b/core/java/android/print/PrintDocumentAdapter.java
@@ -18,8 +18,8 @@ package android.print;
import android.os.Bundle;
import android.os.CancellationSignal;
+import android.os.ParcelFileDescriptor;
-import java.io.FileDescriptor;
import java.util.List;
/**
@@ -41,7 +41,7 @@ import java.util.List;
* <li>
* After every call to {@link #onLayout(PrintAttributes, PrintAttributes,
* CancellationSignal, LayoutResultCallback, Bundle)}, you may get a call to
- * {@link #onWrite(PageRange[], FileDescriptor, CancellationSignal, WriteResultCallback)}
+ * {@link #onWrite(PageRange[], ParcelFileDescriptor, CancellationSignal, WriteResultCallback)}
* asking you to write a PDF file with the content for specific pages.
* </li>
* <li>
@@ -64,7 +64,7 @@ import java.util.List;
* PrintAttributes, CancellationSignal, LayoutResultCallback, Bundle)} on
* the UI thread (assuming onStart initializes resources needed for layout).
* This will ensure that the UI does not change while you are laying out the
- * printed content. Then you can handle {@link #onWrite(PageRange[], FileDescriptor,
+ * printed content. Then you can handle {@link #onWrite(PageRange[], ParcelFileDescriptor,
* CancellationSignal, WriteResultCallback)} and {@link #onFinish()} on another
* thread. This will ensure that the UI is frozen for the minimal amount of
* time. Also this assumes that you will generate the printed content in
@@ -150,10 +150,10 @@ public abstract class PrintDocumentAdapter {
* from of a PDF file to the given file descriptor. This method is invoked
* on the main thread.
*<p>
- * After you are done writing, you should <strong>not</strong> close the
- * file descriptor, rather you must invoke: {@link WriteResultCallback
- * #onWriteFinished(List)}, if writing completed successfully; or {@link
- * WriteResultCallback#onWriteFailed(CharSequence)}, if an error occurred.
+ * After you are done writing, you should close the file descriptor and
+ * invoke {@link WriteResultCallback #onWriteFinished(List)}, if writing
+ * completed successfully; or {@link WriteResultCallback#onWriteFailed(
+ * CharSequence)}, if an error occurred.
* </p>
* <p>
* <strong>Note:</strong> If the printed content is large, it is a good
@@ -171,7 +171,7 @@ public abstract class PrintDocumentAdapter {
* @see WriteResultCallback
* @see CancellationSignal
*/
- public abstract void onWrite(PageRange[] pages, FileDescriptor destination,
+ public abstract void onWrite(PageRange[] pages, ParcelFileDescriptor destination,
CancellationSignal cancellationSignal, WriteResultCallback callback);
/**
@@ -185,7 +185,7 @@ public abstract class PrintDocumentAdapter {
/**
* Base class for implementing a callback for the result of {@link
- * PrintDocumentAdapter#onWrite(PageRange[], FileDescriptor, CancellationSignal,
+ * PrintDocumentAdapter#onWrite(PageRange[], ParcelFileDescriptor, CancellationSignal,
* WriteResultCallback)}.
*/
public static abstract class WriteResultCallback {
diff --git a/core/java/android/print/PrintDocumentInfo.java b/core/java/android/print/PrintDocumentInfo.java
index b32961b..f2b91ae 100644
--- a/core/java/android/print/PrintDocumentInfo.java
+++ b/core/java/android/print/PrintDocumentInfo.java
@@ -60,6 +60,7 @@ public final class PrintDocumentInfo implements Parcelable {
private int mColorMode;
private Margins mMargins;
private MediaSize mMediaSize;
+ private long mDataSize;
/**
* Creates a new instance.
@@ -82,6 +83,7 @@ public final class PrintDocumentInfo implements Parcelable {
mColorMode = prototype.mColorMode;
mMargins = prototype.mMargins;
mMediaSize = prototype.mMediaSize;
+ mDataSize = prototype.mDataSize;
}
/**
@@ -98,6 +100,7 @@ public final class PrintDocumentInfo implements Parcelable {
mColorMode = parcel.readInt();
mMargins = Margins.createFromParcel(parcel);
mMediaSize = MediaSize.createFromParcel(parcel);
+ mDataSize = parcel.readLong();
}
/**
@@ -188,6 +191,26 @@ public final class PrintDocumentInfo implements Parcelable {
return mMediaSize;
}
+ /**
+ * Gets the document data size in bytes.
+ *
+ * @return The data size.
+ */
+ public long getDataSize() {
+ return mDataSize;
+ }
+
+ /**
+ * Sets the document data size in bytes.
+ *
+ * @param dataSize The data size.
+ *
+ * @hide
+ */
+ public void setDataSize(long dataSize) {
+ mDataSize = dataSize;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -203,6 +226,7 @@ public final class PrintDocumentInfo implements Parcelable {
parcel.writeInt(mColorMode);
mMargins.writeToParcel(parcel);
mMediaSize.writeToParcel(parcel);
+ parcel.writeLong(mDataSize);
}
@Override
@@ -217,6 +241,8 @@ public final class PrintDocumentInfo implements Parcelable {
result = prime * result + mColorMode;
result = prime * result + (mMargins != null ? mMargins.hashCode() : 0);
result = prime * result + (mMediaSize != null ? mMediaSize.hashCode() : 0);
+ result = prime * result + (int) mDataSize;
+ result = prime * result + (int) mDataSize >> 32;
return result;
}
@@ -264,6 +290,9 @@ public final class PrintDocumentInfo implements Parcelable {
} else if (!mMediaSize.equals(other.mMediaSize)) {
return false;
}
+ if (mDataSize != other.mDataSize) {
+ return false;
+ }
return true;
}
@@ -279,6 +308,7 @@ public final class PrintDocumentInfo implements Parcelable {
builder.append(", colorMode=").append(PrintAttributes.colorModeToString(mColorMode));
builder.append(", margins=").append(mMargins);
builder.append(", mediaSize=").append(mMediaSize);
+ builder.append(", size=").append(mDataSize);
builder.append("}");
return builder.toString();
}
diff --git a/core/java/android/print/PrintFileDocumentAdapter.java b/core/java/android/print/PrintFileDocumentAdapter.java
index dbc8b6f..b905396 100644
--- a/core/java/android/print/PrintFileDocumentAdapter.java
+++ b/core/java/android/print/PrintFileDocumentAdapter.java
@@ -21,6 +21,7 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.CancellationSignal.OnCancelListener;
+import android.os.ParcelFileDescriptor;
import android.util.Log;
import com.android.internal.R;
@@ -28,7 +29,6 @@ import com.android.internal.R;
import libcore.io.IoUtils;
import java.io.File;
-import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -81,7 +81,7 @@ public class PrintFileDocumentAdapter extends PrintDocumentAdapter {
}
@Override
- public void onWrite(PageRange[] pages, FileDescriptor destination,
+ public void onWrite(PageRange[] pages, ParcelFileDescriptor destination,
CancellationSignal cancellationSignal, WriteResultCallback callback) {
mWriteFileAsyncTask = new WriteFileAsyncTask(destination, cancellationSignal, callback);
mWriteFileAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
@@ -90,13 +90,13 @@ public class PrintFileDocumentAdapter extends PrintDocumentAdapter {
private final class WriteFileAsyncTask extends AsyncTask<Void, Void, Void> {
- private final FileDescriptor mDestination;
+ private final ParcelFileDescriptor mDestination;
private final WriteResultCallback mResultCallback;
private final CancellationSignal mCancellationSignal;
- public WriteFileAsyncTask(FileDescriptor destination,
+ public WriteFileAsyncTask(ParcelFileDescriptor destination,
CancellationSignal cancellationSignal, WriteResultCallback callback) {
mDestination = destination;
mResultCallback = callback;
@@ -112,7 +112,7 @@ public class PrintFileDocumentAdapter extends PrintDocumentAdapter {
@Override
protected Void doInBackground(Void... params) {
InputStream in = null;
- OutputStream out = new FileOutputStream(mDestination);
+ OutputStream out = new FileOutputStream(mDestination.getFileDescriptor());
final byte[] buffer = new byte[8192];
try {
in = new FileInputStream(mFile);
diff --git a/core/java/android/print/PrintJobInfo.java b/core/java/android/print/PrintJobInfo.java
index 602f3c1..b919ad6 100644
--- a/core/java/android/print/PrintJobInfo.java
+++ b/core/java/android/print/PrintJobInfo.java
@@ -44,6 +44,13 @@ public final class PrintJobInfo implements Parcelable {
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;
+
+ /**
* Print job state: The print job is being created but not yet
* ready to be printed.
* <p>
@@ -55,7 +62,7 @@ public final class PrintJobInfo implements Parcelable {
public static final int STATE_CREATED = 1;
/**
- * Print job status: The print jobs is created, it is ready
+ * 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},
@@ -65,40 +72,49 @@ public final class PrintJobInfo implements Parcelable {
public static final int STATE_QUEUED = 2;
/**
- * Print job status: The print job is being printed.
+ * Print job state: The print job is being printed.
* <p>
* Next valid states: {@link #STATE_COMPLETED}, {@link #STATE_FAILED},
- * {@link #STATE_CANCELED}
+ * {@link #STATE_CANCELED}, {@link #STATE_BLOCKED}
* </p>
*/
public static final int STATE_STARTED = 3;
/**
- * Print job status: The print job was successfully printed.
+ * 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 = 4;
+
+ /**
+ * Print job state: The print job was successfully printed.
* This is a terminal state.
* <p>
* Next valid states: None
* </p>
*/
- public static final int STATE_COMPLETED = 4;
+ public static final int STATE_COMPLETED = 5;
/**
- * Print job status: The print job was printing but printing failed.
+ * Print job state: The print job was printing but printing failed.
* This is a terminal state.
* <p>
* Next valid states: None
* </p>
*/
- public static final int STATE_FAILED = 5;
+ public static final int STATE_FAILED = 6;
/**
- * Print job status: The print job was canceled.
+ * Print job state: The print job was canceled.
* This is a terminal state.
* <p>
* Next valid states: None
* </p>
*/
- public static final int STATE_CANCELED = 6;
+ public static final int STATE_CANCELED = 7;
/** The unique print job id. */
private int mId;
@@ -127,8 +143,8 @@ public final class PrintJobInfo implements Parcelable {
/** How many copies to print. */
private int mCopies;
- /** Failure reason if this job failed. */
- private String mFailureReason;
+ /** Reason for the print job being in its current state. */
+ private String mStateReason;
/** The pages to print */
private PageRange[] mPageRanges;
@@ -155,7 +171,7 @@ public final class PrintJobInfo implements Parcelable {
mUserId = other.mUserId;
mTag = other.mTag;
mCopies = other.mCopies;
- mFailureReason = other.mFailureReason;
+ mStateReason = other.mStateReason;
mPageRanges = other.mPageRanges;
mAttributes = other.mAttributes;
mDocumentInfo = other.mDocumentInfo;
@@ -171,7 +187,7 @@ public final class PrintJobInfo implements Parcelable {
mUserId = parcel.readInt();
mTag = parcel.readString();
mCopies = parcel.readInt();
- mFailureReason = parcel.readString();
+ mStateReason = parcel.readString();
if (parcel.readInt() == 1) {
Parcelable[] parcelables = parcel.readParcelableArray(null);
mPageRanges = new PageRange[parcelables.length];
@@ -377,25 +393,27 @@ public final class PrintJobInfo implements Parcelable {
}
/**
- * The failure reason if this print job failed.
+ * Gets the reason for the print job being in the current state.
*
- * @return The failure reason.
+ * @return The reason, or null if there is no reason or the
+ * reason is unknown.
*
* @hide
*/
- public String getFailureReason() {
- return mFailureReason;
+ public String getStateReason() {
+ return mStateReason;
}
/**
- * The failure reason if this print job failed.
+ * Sets the reason for the print job being in the current state.
*
- * @param failureReason The failure reason.
+ * @param stateReason The reason, or null if there is no reason
+ * or the reason is unknown.
*
* @hide
*/
- public void setFailureReason(String failureReason) {
- mFailureReason = failureReason;
+ public void setStateReason(String stateReason) {
+ mStateReason = stateReason;
}
/**
@@ -476,7 +494,7 @@ public final class PrintJobInfo implements Parcelable {
parcel.writeInt(mUserId);
parcel.writeString(mTag);
parcel.writeInt(mCopies);
- parcel.writeString(mFailureReason);
+ parcel.writeString(mStateReason);
if (mPageRanges != null) {
parcel.writeInt(1);
parcel.writeParcelableArray(mPageRanges, flags);
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
index d3e35c3..6e32c05 100644
--- a/core/java/android/print/PrintManager.java
+++ b/core/java/android/print/PrintManager.java
@@ -36,7 +36,6 @@ import com.android.internal.os.SomeArgs;
import libcore.io.IoUtils;
import java.io.File;
-import java.io.FileDescriptor;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
@@ -163,7 +162,7 @@ public final class PrintManager {
* @param pdfFile The PDF file to print.
* @param documentInfo Information about the printed document.
* @param attributes The default print job attributes.
- * @return The created print job.
+ * @return The created print job on success or null on failure.
*
* @see PrintJob
*/
@@ -181,7 +180,7 @@ public final class PrintManager {
* @param printJobName A name for the new print job.
* @param documentAdapter An adapter that emits the document to print.
* @param attributes The default print job attributes.
- * @return The created print job.
+ * @return The created print job on success or null on failure.
*
* @see PrintJob
*/
@@ -279,7 +278,7 @@ public final class PrintManager {
}
SomeArgs args = SomeArgs.obtain();
args.arg1 = pages;
- args.arg2 = fd.getFileDescriptor();
+ args.arg2 = fd;
args.arg3 = callback;
args.argi1 = sequence;
mHandler.removeMessages(MyHandler.MSG_WRITE);
@@ -342,7 +341,7 @@ public final class PrintManager {
case MSG_WRITE: {
SomeArgs args = (SomeArgs) message.obj;
PageRange[] pages = (PageRange[]) args.arg1;
- FileDescriptor fd = (FileDescriptor) args.arg2;
+ ParcelFileDescriptor fd = (ParcelFileDescriptor) args.arg2;
IWriteResultCallback callback = (IWriteResultCallback) args.arg3;
final int sequence = args.argi1;
args.recycle();
@@ -428,12 +427,12 @@ public final class PrintManager {
}
private final class MyWriteResultCallback extends WriteResultCallback {
- private FileDescriptor mFd;
+ private ParcelFileDescriptor mFd;
private int mSequence;
private IWriteResultCallback mCallback;
public MyWriteResultCallback(IWriteResultCallback callback,
- FileDescriptor fd, int sequence) {
+ ParcelFileDescriptor fd, int sequence) {
mFd = fd;
mSequence = sequence;
mCallback = callback;
diff --git a/core/java/android/print/PrinterDiscoverySession.java b/core/java/android/print/PrinterDiscoverySession.java
index 8fbdd9c..46f0bef 100644
--- a/core/java/android/print/PrinterDiscoverySession.java
+++ b/core/java/android/print/PrinterDiscoverySession.java
@@ -74,6 +74,7 @@ public final class PrinterDiscoverySession {
public final void startPrinterDisovery(List<PrinterId> priorityList) {
if (isDestroyed()) {
Log.w(LOG_TAG, "Ignoring start printers dsicovery - session destroyed");
+ return;
}
if (!mIsPrinterDiscoveryStarted) {
mIsPrinterDiscoveryStarted = true;
@@ -88,6 +89,7 @@ public final class PrinterDiscoverySession {
public final void stopPrinterDiscovery() {
if (isDestroyed()) {
Log.w(LOG_TAG, "Ignoring stop printers discovery - session destroyed");
+ return;
}
if (mIsPrinterDiscoveryStarted) {
mIsPrinterDiscoveryStarted = false;
@@ -99,14 +101,39 @@ public final class PrinterDiscoverySession {
}
}
- public final void requestPrinterUpdate(PrinterId printerId) {
+ public final void startPrinterStateTracking(PrinterId printerId) {
+ if (isDestroyed()) {
+ Log.w(LOG_TAG, "Ignoring start printer state tracking - session destroyed");
+ return;
+ }
+ try {
+ mPrintManager.startPrinterStateTracking(printerId, mUserId);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error starting printer state tracking", re);
+ }
+ }
+
+ public final void stopPrinterStateTracking(PrinterId printerId) {
if (isDestroyed()) {
- Log.w(LOG_TAG, "Ignoring reqeust printer update - session destroyed");
+ Log.w(LOG_TAG, "Ignoring stop printer state tracking - session destroyed");
+ return;
+ }
+ try {
+ mPrintManager.stopPrinterStateTracking(printerId, mUserId);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error stoping printer state tracking", re);
+ }
+ }
+
+ public final void validatePrinters(List<PrinterId> printerIds) {
+ if (isDestroyed()) {
+ Log.w(LOG_TAG, "Ignoring validate printers - session destroyed");
+ return;
}
try {
- mPrintManager.requestPrinterUpdate(printerId, mUserId);
+ mPrintManager.validatePrinters(printerIds, mUserId);
} catch (RemoteException re) {
- Log.e(LOG_TAG, "Error requesting printer update", re);
+ Log.e(LOG_TAG, "Error validating printers", re);
}
}
diff --git a/core/java/android/print/pdf/PrintedPdfDocument.java b/core/java/android/print/pdf/PrintedPdfDocument.java
index a3be38b..bee17ef 100644
--- a/core/java/android/print/pdf/PrintedPdfDocument.java
+++ b/core/java/android/print/pdf/PrintedPdfDocument.java
@@ -111,7 +111,10 @@ public final class PrintedPdfDocument {
* @see #finishPage(Page)
*/
public Page startPage(int pageNumber) {
- PageInfo pageInfo = new PageInfo.Builder(mPageSize, 0).create();
+ PageInfo pageInfo = new PageInfo
+ .Builder(mPageSize, 0)
+ .setContentSize(mContentSize)
+ .create();
Page page = mDocument.startPage(pageInfo);
return page;
}
diff --git a/core/java/android/printservice/IPrintService.aidl b/core/java/android/printservice/IPrintService.aidl
index 2cee1d8..ee36619 100644
--- a/core/java/android/printservice/IPrintService.aidl
+++ b/core/java/android/printservice/IPrintService.aidl
@@ -33,6 +33,8 @@ oneway interface IPrintService {
void createPrinterDiscoverySession();
void startPrinterDiscovery(in List<PrinterId> priorityList);
void stopPrinterDiscovery();
- void requestPrinterUpdate(in PrinterId printerId);
+ void validatePrinters(in List<PrinterId> printerIds);
+ void startPrinterStateTracking(in PrinterId printerId);
+ void stopPrinterStateTracking(in PrinterId printerId);
void destroyPrinterDiscoverySession();
}
diff --git a/core/java/android/printservice/PrintDocument.java b/core/java/android/printservice/PrintDocument.java
index 7437dc5..8292cfb 100644
--- a/core/java/android/printservice/PrintDocument.java
+++ b/core/java/android/printservice/PrintDocument.java
@@ -21,12 +21,15 @@ import android.os.RemoteException;
import android.print.PrintDocumentInfo;
import android.util.Log;
-import java.io.FileDescriptor;
import java.io.IOException;
/**
* This class represents a printed document from the perspective of a print
* service. It exposes APIs to query the document and obtain its data.
+ * <p>
+ * <strong>Note: </strong> All methods of this class must be executed on the
+ * main application thread.
+ * </p>
*/
public final class PrintDocument {
@@ -51,6 +54,7 @@ public final class PrintDocument {
* @return The document info.
*/
public PrintDocumentInfo getInfo() {
+ PrintService.throwIfNotCalledOnMainThread();
return mInfo;
}
@@ -64,7 +68,8 @@ public final class PrintDocument {
*
* @return A file descriptor for reading the data.
*/
- public FileDescriptor getData() {
+ public ParcelFileDescriptor getData() {
+ PrintService.throwIfNotCalledOnMainThread();
ParcelFileDescriptor source = null;
ParcelFileDescriptor sink = null;
try {
@@ -72,7 +77,7 @@ public final class PrintDocument {
source = fds[0];
sink = fds[1];
mPrintServiceClient.writePrintJobData(sink, mPrintJobId);
- return source.getFileDescriptor();
+ return source;
} catch (IOException ioe) {
Log.e(LOG_TAG, "Error calling getting print job data!", ioe);
} catch (RemoteException re) {
diff --git a/core/java/android/printservice/PrintJob.java b/core/java/android/printservice/PrintJob.java
index d2fbef2..8bae9d6 100644
--- a/core/java/android/printservice/PrintJob.java
+++ b/core/java/android/printservice/PrintJob.java
@@ -18,6 +18,7 @@ package android.printservice;
import android.os.RemoteException;
import android.print.PrintJobInfo;
+import android.text.TextUtils;
import android.util.Log;
/**
@@ -123,6 +124,21 @@ public final class PrintJob {
}
/**
+ * Gets whether this print job is blocked. Such a print job is halted
+ * due to an abnormal condition and can be started or canceled or failed.
+ *
+ * @return Whether the print job is blocked.
+ *
+ * @see #start()
+ * @see #cancel()
+ * @see #fail(CharSequence)
+ */
+ public boolean isBlocked() {
+ PrintService.throwIfNotCalledOnMainThread();
+ return getInfo().getState() == PrintJobInfo.STATE_BLOCKED;
+ }
+
+ /**
* Gets whether this print job is completed. Such a print job
* is successfully printed. This is a final state.
*
@@ -163,21 +179,49 @@ public final class PrintJob {
/**
* Starts the print job. You should call this method if {@link
- * #isQueued()} returns true and you started printing.
+ * #isQueued()} or {@link #isBlocked()} returns true and you started
+ * resumed printing.
*
- * @return Whether the job as started.
+ * @return Whether the job was started.
*
* @see #isQueued()
+ * @see #isBlocked()
*/
public boolean start() {
PrintService.throwIfNotCalledOnMainThread();
- if (isQueued()) {
+ final int state = getInfo().getState();
+ if (state == PrintJobInfo.STATE_QUEUED
+ || state == PrintJobInfo.STATE_BLOCKED) {
return setState(PrintJobInfo.STATE_STARTED, null);
}
return false;
}
/**
+ * Blocks the print job. You should call this method if {@link
+ * #isStarted()} or {@link #isBlocked()} returns true and you need
+ * to block the print job. For example, the user has to add some
+ * paper to continue printing. To resume the print job call {@link
+ * #start()}.
+ *
+ * @return Whether the job was blocked.
+ *
+ * @see #isStarted()
+ * @see #isBlocked()
+ */
+ public boolean block(String reason) {
+ PrintService.throwIfNotCalledOnMainThread();
+ PrintJobInfo info = getInfo();
+ final int state = info.getState();
+ if (state == PrintJobInfo.STATE_STARTED
+ || (state == PrintJobInfo.STATE_BLOCKED
+ && !TextUtils.equals(info.getStateReason(), reason))) {
+ return setState(PrintJobInfo.STATE_BLOCKED, reason);
+ }
+ return false;
+ }
+
+ /**
* Completes the print job. You should call this method if {@link
* #isStarted()} returns true and you are done printing.
*
@@ -195,8 +239,8 @@ public final class PrintJob {
/**
* Fails the print job. You should call this method if {@link
- * #isQueued()} or {@link #isStarted()} returns true you failed
- * while printing.
+ * #isQueued()} or {@link #isStarted()} or {@link #isBlocked()}
+ * returns true you failed while printing.
*
* @param error The human readable, short, and translated reason
* for the failure.
@@ -204,10 +248,11 @@ public final class PrintJob {
*
* @see #isQueued()
* @see #isStarted()
+ * @see #isBlocked()
*/
public boolean fail(String error) {
PrintService.throwIfNotCalledOnMainThread();
- if (isQueued() || isStarted()) {
+ if (!isInImmutableState()) {
return setState(PrintJobInfo.STATE_FAILED, error);
}
return false;
@@ -215,18 +260,19 @@ public final class PrintJob {
/**
* Cancels the print job. You should call this method if {@link
- * #isQueued()} or {@link #isStarted()} returns true and you canceled
- * the print job as a response to a call to {@link
- * PrintService#onRequestCancelPrintJob(PrintJob)}.
+ * #isQueued()} or {@link #isStarted() or #isBlocked()} returns
+ * true and you canceled the print job as a response to a call to
+ * {@link PrintService#onRequestCancelPrintJob(PrintJob)}.
*
* @return Whether the job is canceled.
*
* @see #isStarted()
* @see #isQueued()
+ * @see #isBlocked()
*/
public boolean cancel() {
PrintService.throwIfNotCalledOnMainThread();
- if (isQueued() || isStarted()) {
+ if (!isInImmutableState()) {
return setState(PrintJobInfo.STATE_CANCELED, null);
}
return false;
@@ -277,7 +323,8 @@ public final class PrintJob {
private boolean isInImmutableState() {
final int state = mCachedInfo.getState();
return state == PrintJobInfo.STATE_COMPLETED
- || state == PrintJobInfo.STATE_CANCELED;
+ || state == PrintJobInfo.STATE_CANCELED
+ || state == PrintJobInfo.STATE_FAILED;
}
private boolean setState(int state, String error) {
@@ -287,7 +334,7 @@ public final class PrintJob {
// we may not be able to re-fetch it later if the job gets
// removed from the spooler as a result of the state change.
mCachedInfo.setState(state);
- mCachedInfo.setFailureReason(error);
+ mCachedInfo.setStateReason(error);
return true;
}
} catch (RemoteException re) {
diff --git a/core/java/android/printservice/PrintService.java b/core/java/android/printservice/PrintService.java
index f6c0a9a..96552af 100644
--- a/core/java/android/printservice/PrintService.java
+++ b/core/java/android/printservice/PrintService.java
@@ -314,8 +314,20 @@ public abstract class PrintService extends Service {
}
@Override
- public void requestPrinterUpdate(PrinterId printerId) {
- mHandler.obtainMessage(ServiceHandler.MSG_REQUEST_PRINTER_UPDATE,
+ public void validatePrinters(List<PrinterId> printerIds) {
+ mHandler.obtainMessage(ServiceHandler.MSG_VALIDATE_PRINTERS,
+ printerIds).sendToTarget();
+ }
+
+ @Override
+ public void startPrinterStateTracking(PrinterId printerId) {
+ mHandler.obtainMessage(ServiceHandler.MSG_START_PRINTER_STATE_TRACKING,
+ printerId).sendToTarget();
+ }
+
+ @Override
+ public void stopPrinterStateTracking(PrinterId printerId) {
+ mHandler.obtainMessage(ServiceHandler.MSG_STOP_PRINTER_STATE_TRACKING,
printerId).sendToTarget();
}
@@ -344,10 +356,12 @@ public abstract class PrintService extends Service {
public static final int MSG_DESTROY_PRINTER_DISCOVERY_SESSION = 2;
public static final int MSG_START_PRINTER_DISCOVERY = 3;
public static final int MSG_STOP_PRINTER_DISCOVERY = 4;
- public static final int MSG_REQUEST_PRINTER_UPDATE = 5;
- public static final int MSG_ON_PRINTJOB_QUEUED = 6;
- public static final int MSG_ON_REQUEST_CANCEL_PRINTJOB = 7;
- public static final int MSG_SET_CLEINT = 8;
+ public static final int MSG_VALIDATE_PRINTERS = 5;
+ public static final int MSG_START_PRINTER_STATE_TRACKING = 6;
+ public static final int MSG_STOP_PRINTER_STATE_TRACKING = 7;
+ public static final int MSG_ON_PRINTJOB_QUEUED = 8;
+ public static final int MSG_ON_REQUEST_CANCEL_PRINTJOB = 9;
+ public static final int MSG_SET_CLEINT = 10;
public ServiceHandler(Looper looper) {
super(looper, null, true);
@@ -391,10 +405,24 @@ public abstract class PrintService extends Service {
}
} break;
- case MSG_REQUEST_PRINTER_UPDATE: {
+ case MSG_VALIDATE_PRINTERS: {
+ if (mDiscoverySession != null) {
+ List<PrinterId> printerIds = (List<PrinterId>) message.obj;
+ mDiscoverySession.validatePrinters(printerIds);
+ }
+ } break;
+
+ case MSG_START_PRINTER_STATE_TRACKING: {
+ if (mDiscoverySession != null) {
+ PrinterId printerId = (PrinterId) message.obj;
+ mDiscoverySession.startPrinterStateTracking(printerId);
+ }
+ } break;
+
+ case MSG_STOP_PRINTER_STATE_TRACKING: {
if (mDiscoverySession != null) {
PrinterId printerId = (PrinterId) message.obj;
- mDiscoverySession.requestPrinterUpdate(printerId);
+ mDiscoverySession.stopPrinterStateTracking(printerId);
}
} break;
diff --git a/core/java/android/printservice/PrinterDiscoverySession.java b/core/java/android/printservice/PrinterDiscoverySession.java
index 8b959a6..1f86ecc 100644
--- a/core/java/android/printservice/PrinterDiscoverySession.java
+++ b/core/java/android/printservice/PrinterDiscoverySession.java
@@ -53,15 +53,23 @@ import java.util.List;
* session. Printers are <strong>not</strong> persisted across sessions.
* </p>
* <p>
- * The system will make a call to
- * {@link PrinterDiscoverySession#onRequestPrinterUpdate(PrinterId)} if you
- * need to update a given printer. It is possible that you add a printer without
+ * The system will make a call to {@link #onValidatePrinters(List)} if you
+ * need to update some printers. It is possible that you add a printer without
* specifying its capabilities. This enables you to avoid querying all discovered
* printers for their capabilities, rather querying the capabilities of a printer
* only if necessary. For example, the system will request that you update a printer
- * if it gets selected by the user. If you did not report the printer capabilities
- * when adding it, you must do so after the system requests a printer update.
- * Otherwise, the printer will be ignored.
+ * if it gets selected by the user. When validating printers you do not need to
+ * provide the printers' capabilities but may do so.
+ * </p>
+ * <p>
+ * If the system is interested in being constantly updated for the state of a
+ * printer you will receive a call to {@link #onStartPrinterStateTracking(PrinterId)}
+ * after which you will have to do a best effort to keep the system updated for
+ * changes in the printer state and capabilities. You also <strong>must</strong>
+ * update the printer capabilities if you did not provide them when adding it, or
+ * the printer will be ignored. When the system is no longer interested in getting
+ * updates for a printer you will receive a call to {@link #onStopPrinterStateTracking(
+ * PrinterId)}.
* </p>
* <p>
* <strong>Note: </strong> All callbacks in this class are executed on the main
@@ -115,7 +123,7 @@ public abstract class PrinterDiscoverySession {
* the printer that was added but not removed.
* <p>
* <strong>Note: </strong> Calls to this method after the session is
- * destroyed, i.e. after the {@link #onDestroy()} callback, will be ignored.
+ * destroyed, that is after the {@link #onDestroy()} callback, will be ignored.
* </p>
*
* @return The printers.
@@ -139,7 +147,7 @@ public abstract class PrinterDiscoverySession {
* times during the life of this session. Duplicates will be ignored.
* <p>
* <strong>Note: </strong> Calls to this method after the session is
- * destroyed, i.e. after the {@link #onDestroy()} callback, will be ignored.
+ * destroyed, that is after the {@link #onDestroy()} callback, will be ignored.
* </p>
*
* @param printers The printers to add.
@@ -218,7 +226,7 @@ public abstract class PrinterDiscoverySession {
* call this method multiple times during the lifetime of this session.
* <p>
* <strong>Note: </strong> Calls to this method after the session is
- * destroyed, i.e. after the {@link #onDestroy()} callback, will be ignored.
+ * destroyed, that is after the {@link #onDestroy()} callback, will be ignored.
* </p>
*
* @param printerIds The ids of the removed printers.
@@ -293,7 +301,7 @@ public abstract class PrinterDiscoverySession {
* during the lifetime of this session.
* <p>
* <strong>Note: </strong> Calls to this method after the session is
- * destroyed, i.e. after the {@link #onDestroy()} callback, will be ignored.
+ * destroyed, that is after the {@link #onDestroy()} callback, will be ignored.
* </p>
*
* @param printers The printers to update.
@@ -441,7 +449,9 @@ public abstract class PrinterDiscoverySession {
* <p>
* <strong>Note: </strong>You are also given a list of printers whose availability
* has to be checked first. For example, these printers could be the user's favorite
- * ones, therefore they have to be verified first.
+ * ones, therefore they have to be verified first. You do <strong>not need</strong>
+ * to provide the capabilities of the printers, rather verify whether they exist
+ * similarly to {@link #onValidatePrinters(List)}.
* </p>
*
* @param priorityList The list of printers to validate first. Never null.
@@ -463,9 +473,28 @@ public abstract class PrinterDiscoverySession {
public abstract void onStopPrinterDiscovery();
/**
- * Requests that you update a printer. You are responsible for updating
- * the printer by also reporting its capabilities via calling {@link
- * #updatePrinters(List)}.
+ * Callback asking you to validate that the given printers are valid, that
+ * is they exist. You are responsible for checking whether these printers
+ * exist and for the ones that do exist notify the system via calling
+ * {@link #updatePrinters(List)}.
+ * <p>
+ * <strong>Note: </strong> You are <strong>not required</strong> to provide
+ * the printer capabilities when updating the printers that do exist.
+ * <p>
+ *
+ * @param printerIds The printers to validate.
+ *
+ * @see #updatePrinters(List)
+ * @see PrinterInfo.Builder#setCapabilities(PrinterCapabilitiesInfo)
+ * PrinterInfo.Builder.setCapabilities(PrinterCapabilitiesInfo)
+ */
+ public abstract void onValidatePrinters(List<PrinterId> printerIds);
+
+ /**
+ * Callback asking you to start tracking the state of a printer. Tracking
+ * the state means that you should do a best effort to observe the state
+ * of this printer and notify the system if that state changes via calling
+ * {@link #updatePrinters(List)}.
* <p>
* <strong>Note: </strong> A printer can be initially added without its
* capabilities to avoid polling printers that the user will not select.
@@ -473,18 +502,33 @@ public abstract class PrinterDiscoverySession {
* printer <strong>including</strong> its capabilities. Otherwise, the
* printer will be ignored.
* <p>
- * A scenario when you may be requested to update a printer is if the user
- * selects it and the system has to present print options UI based on the
- * printer's capabilities.
+ * <p>
+ * A scenario when you may be requested to track a printer's state is if
+ * the user selects that printer and the system has to present print
+ * options UI based on the printer's capabilities. In this case the user
+ * should be promptly informed if, for example, the printer becomes
+ * unavailable.
* </p>
*
- * @param printerId The printer id.
+ * @param printerId The printer to start tracking.
*
+ * @see #onStopPrinterStateTracking(PrinterId)
* @see #updatePrinters(List)
* @see PrinterInfo.Builder#setCapabilities(PrinterCapabilitiesInfo)
* PrinterInfo.Builder.setCapabilities(PrinterCapabilitiesInfo)
*/
- public abstract void onRequestPrinterUpdate(PrinterId printerId);
+ public abstract void onStartPrinterStateTracking(PrinterId printerId);
+
+ /**
+ * Callback asking you to stop tracking the state of a printer. The passed
+ * in printer id is the one for which you received a call to {@link
+ * #onStartPrinterStateTracking(PrinterId)}.
+ *
+ * @param printerId The printer to stop tracking.
+ *
+ * @see #onStartPrinterStateTracking(PrinterId)
+ */
+ public abstract void onStopPrinterStateTracking(PrinterId printerId);
/**
* Notifies you that the session is destroyed. After this callback is invoked
@@ -538,9 +582,21 @@ public abstract class PrinterDiscoverySession {
}
}
- void requestPrinterUpdate(PrinterId printerId) {
- if (!mIsDestroyed) {
- onRequestPrinterUpdate(printerId);
+ void validatePrinters(List<PrinterId> printerIds) {
+ if (!mIsDestroyed && mObserver != null) {
+ onValidatePrinters(printerIds);
+ }
+ }
+
+ void startPrinterStateTracking(PrinterId printerId) {
+ if (!mIsDestroyed && mObserver != null) {
+ onStartPrinterStateTracking(printerId);
+ }
+ }
+
+ void stopPrinterStateTracking(PrinterId printerId) {
+ if (!mIsDestroyed && mObserver != null) {
+ onStopPrinterStateTracking(printerId);
}
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index faf6e63..b749aa64 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1915,13 +1915,10 @@
android:description="@string/permdesc_bindNfcService"
android:protectionLevel="signature" />
- <!-- Allows an application to call APIs that give it access to all print jobs
- on the device. Usually an app can access only the print jobts it created.
- This permission is not available to third party applications.
- @hide -->
- <permission android:name="android.permission.ACCESS_ALL_PRINT_JOBS"
- android:label="@string/permlab_accessAllPrintJobs"
- android:description="@string/permdesc_accessAllPrintJobs"
+ <!-- Must be required by the PrintSpooler to ensure that only the system can bind to it. -->
+ <permission android:name="android.permission.BIND_PRINT_SPOOLER_SERVICE"
+ android:label="@string/permlab_bindPrintSpoolerService"
+ android:description="@string/permdesc_bindPrintSpoolerService"
android:protectionLevel="signature" />
<!-- Must be required by a TextService (e.g. SpellCheckerService)
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index ead46c2..4b32e2b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -984,12 +984,13 @@
<string name="permdesc_bindPrintService">Allows the holder to bind to the top-level
interface of a print service. Should never be needed for normal apps.</string>
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_accessAllPrintJobs">access all print jobs</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_accessAllPrintJobs">Allows the holder to access print jobs
- created by another app. Should never be needed for normal apps.</string>
-
+ <!-- Title of an application permission, listed so the user can choose
+ whether they want to allow the application to do this. -->
+ <string name="permlab_bindPrintSpoolerService">bind to a print spooler service</string>
+ <!-- Description of an application permission, listed so the user can
+ choose whether they want to allow the application to do this. -->
+ <string name="permdesc_bindPrintSpoolerService">Allows the holder to bind to the top-level
+ interface of a print spooler service. Should never be needed for normal apps.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_bindNfcService">bind to NFC service</string>
@@ -4292,6 +4293,9 @@
<!-- Write fail reason: couldn't write the printed content. [CHAR LIMIT=none] -->
<string name="write_fail_reason_cannot_write">Error writing content</string>
+ <!-- Print fail reason: unknown. [CHAR LIMIT=25] -->
+ <string name="reason_unknown">unknown</string>
+
<!-- PIN entry dialog label/hint for PIN [CHAR LIMIT=none] -->
<string name="restr_pin_enter_pin">Enter PIN</string>
<!-- PIN entry dialog label/hint for old PIN [CHAR LIMIT=none] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a9c812e..67f25d1 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -868,6 +868,7 @@
<java-symbol type="string" name="mediaSize_na_junior_legal" />
<java-symbol type="string" name="mediaSize_na_ledger" />
<java-symbol type="string" name="mediaSize_na_tabloid" />
+ <java-symbol type="string" name="reason_unknown" />
<java-symbol type="string" name="restr_pin_enter_pin" />
<java-symbol type="string" name="write_fail_reason_cancelled" />
<java-symbol type="string" name="write_fail_reason_cannot_write" />