Allow print service to specify progress of print and status

The status has always been there in error cases, it is now also visible
in non-error cases.

If the progress is not set, no progress bar is shown.

Bug: 24135025
Change-Id: Iea23f45d236365433c6f6739597833d236ed6d19
This commit is contained in:
Philip P. Moltmann
2015-11-23 16:12:39 -08:00
parent 032fef9f54
commit b3078c235e
11 changed files with 407 additions and 89 deletions

View File

@@ -28864,6 +28864,8 @@ package android.printservice {
method public boolean isFailed();
method public boolean isQueued();
method public boolean isStarted();
method public void setProgress(float);
method public void setStatus(java.lang.CharSequence);
method public boolean setTag(java.lang.String);
method public boolean start();
}

View File

@@ -30847,6 +30847,8 @@ package android.printservice {
method public boolean isFailed();
method public boolean isQueued();
method public boolean isStarted();
method public void setProgress(float);
method public void setStatus(java.lang.CharSequence);
method public boolean setTag(java.lang.String);
method public boolean start();
}

View File

@@ -28745,7 +28745,9 @@ package android.print {
method public java.lang.String getLabel();
method public android.print.PageRange[] getPages();
method public android.print.PrinterId getPrinterId();
method public float getProgress();
method public int getState();
method public java.lang.CharSequence getStatus();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.print.PrintJobInfo> CREATOR;
field public static final int STATE_BLOCKED = 4; // 0x4
@@ -28864,6 +28866,8 @@ package android.printservice {
method public boolean isFailed();
method public boolean isQueued();
method public boolean isStarted();
method public void setProgress(float);
method public void setStatus(java.lang.CharSequence);
method public boolean setTag(java.lang.String);
method public boolean start();
}

View File

@@ -41,6 +41,23 @@ oneway interface IPrintSpooler {
void createPrintJob(in PrintJobInfo printJob);
void setPrintJobState(in PrintJobId printJobId, int status, String stateReason,
IPrintSpoolerCallbacks callback, int sequence);
/**
* Set the progress of this print job
*
* @param printJobId The print job to update
* @param progress The new progress
*/
void setProgress(in PrintJobId printJobId, in float progress);
/**
* Set the status of this print job
*
* @param printJobId The print job to update
* @param status The new status, can be null
*/
void setStatus(in PrintJobId printJobId, in CharSequence status);
void setPrintJobTag(in PrintJobId printJobId, String tag, IPrintSpoolerCallbacks callback,
int sequence);
void writePrintJobData(in ParcelFileDescriptor fd, in PrintJobId printJobId);

View File

@@ -16,10 +16,15 @@
package android.print;
import android.annotation.FloatRange;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.Preconditions;
import java.util.Arrays;
/**
@@ -149,9 +154,6 @@ public final class PrintJobInfo implements Parcelable {
/** How many copies to print. */
private int mCopies;
/** Reason for the print job being in its current state. */
private String mStateReason;
/** The pages to print */
private PageRange[] mPageRanges;
@@ -161,6 +163,12 @@ public final class PrintJobInfo implements Parcelable {
/** 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 CharSequence mStatus;
/** Advanced printer specific options. */
private Bundle mAdvancedOptions;
@@ -169,7 +177,7 @@ public final class PrintJobInfo implements Parcelable {
/** @hide*/
public PrintJobInfo() {
/* do nothing */
mProgress = -1;
}
/** @hide */
@@ -183,10 +191,11 @@ public final class PrintJobInfo implements Parcelable {
mTag = other.mTag;
mCreationTime = other.mCreationTime;
mCopies = other.mCopies;
mStateReason = other.mStateReason;
mPageRanges = other.mPageRanges;
mAttributes = other.mAttributes;
mDocumentInfo = other.mDocumentInfo;
mProgress = other.mProgress;
mStatus = other.mStatus;
mCanceling = other.mCanceling;
mAdvancedOptions = other.mAdvancedOptions;
}
@@ -201,7 +210,6 @@ public final class PrintJobInfo implements Parcelable {
mTag = parcel.readString();
mCreationTime = parcel.readLong();
mCopies = parcel.readInt();
mStateReason = parcel.readString();
Parcelable[] parcelables = parcel.readParcelableArray(null);
if (parcelables != null) {
mPageRanges = new PageRange[parcelables.length];
@@ -211,6 +219,8 @@ public final class PrintJobInfo implements Parcelable {
}
mAttributes = (PrintAttributes) parcel.readParcelable(null);
mDocumentInfo = (PrintDocumentInfo) parcel.readParcelable(null);
mProgress = parcel.readFloat();
mStatus = parcel.readCharSequence();
mCanceling = (parcel.readInt() == 1);
mAdvancedOptions = parcel.readBundle();
}
@@ -227,7 +237,7 @@ public final class PrintJobInfo implements Parcelable {
/**
* Sets the unique print job id.
*
* @param The job id.
* @param id The job id.
*
* @hide
*/
@@ -265,7 +275,7 @@ public final class PrintJobInfo implements Parcelable {
}
/**
* Sets the unique target pritner id.
* Sets the unique target printer id.
*
* @param printerId The target printer id.
*
@@ -325,6 +335,30 @@ public final class PrintJobInfo implements Parcelable {
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) {
mStatus = status;
}
/**
* Sets the owning application id.
*
@@ -415,30 +449,6 @@ public final class PrintJobInfo implements Parcelable {
mCopies = copyCount;
}
/**
* Gets the reason for the print job being in the current state.
*
* @return The reason, or null if there is no reason or the
* reason is unknown.
*
* @hide
*/
public String getStateReason() {
return mStateReason;
}
/**
* Sets the reason for the print job being in the current state.
*
* @param stateReason The reason, or null if there is no reason
* or the reason is unknown.
*
* @hide
*/
public void setStateReason(String stateReason) {
mStateReason = stateReason;
}
/**
* Gets the included pages.
*
@@ -604,10 +614,11 @@ public final class PrintJobInfo implements Parcelable {
parcel.writeString(mTag);
parcel.writeLong(mCreationTime);
parcel.writeInt(mCopies);
parcel.writeString(mStateReason);
parcel.writeParcelableArray(mPageRanges, flags);
parcel.writeParcelable(mAttributes, flags);
parcel.writeParcelable(mDocumentInfo, 0);
parcel.writeFloat(mProgress);
parcel.writeCharSequence(mStatus);
parcel.writeInt(mCanceling ? 1 : 0);
parcel.writeBundle(mAdvancedOptions);
}
@@ -631,6 +642,9 @@ public final class PrintJobInfo implements Parcelable {
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("}");
return builder.toString();
}
@@ -665,6 +679,28 @@ public final class PrintJobInfo implements Parcelable {
}
}
/**
* 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.
*
* @return the status of this job or null if not set
* @hide
*/
@TestApi
public @Nullable CharSequence getStatus() {
return mStatus;
}
/**
* Builder for creating a {@link PrintJobInfo}.
*/
@@ -710,6 +746,28 @@ public final class PrintJobInfo implements Parcelable {
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.
*

View File

@@ -35,6 +35,22 @@ interface IPrintServiceClient {
boolean setPrintJobTag(in PrintJobId printJobId, String tag);
oneway void writePrintJobData(in ParcelFileDescriptor fd, in PrintJobId printJobId);
/**
* Set the progress of this print job
*
* @param printJobId The print job to update
* @param progress The new progress
*/
void setProgress(in PrintJobId printJobId, in float progress);
/**
* Set the status of this print job
*
* @param printJobId The print job to update
* @param status The new status, can be null
*/
void setStatus(in PrintJobId printJobId, in CharSequence status);
void onPrintersAdded(in ParceledListSlice printers);
void onPrintersRemoved(in ParceledListSlice printerIds);
}

View File

@@ -16,6 +16,10 @@
package android.printservice;
import android.annotation.FloatRange;
import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.RemoteException;
import android.print.PrintJobId;
import android.print.PrintJobInfo;
@@ -41,7 +45,7 @@ public final class PrintJob {
private PrintJobInfo mCachedInfo;
PrintJob(PrintJobInfo jobInfo, IPrintServiceClient client) {
PrintJob(@NonNull PrintJobInfo jobInfo, @NonNull IPrintServiceClient client) {
mCachedInfo = jobInfo;
mPrintServiceClient = client;
mDocument = new PrintDocument(mCachedInfo.getId(), client,
@@ -53,6 +57,7 @@ public final class PrintJob {
*
* @return The id.
*/
@MainThread
public PrintJobId getId() {
PrintService.throwIfNotCalledOnMainThread();
return mCachedInfo.getId();
@@ -68,7 +73,8 @@ public final class PrintJob {
*
* @return The print job info.
*/
public PrintJobInfo getInfo() {
@MainThread
public @NonNull PrintJobInfo getInfo() {
PrintService.throwIfNotCalledOnMainThread();
if (isInImmutableState()) {
return mCachedInfo;
@@ -90,7 +96,8 @@ public final class PrintJob {
*
* @return The document.
*/
public PrintDocument getDocument() {
@MainThread
public @NonNull PrintDocument getDocument() {
PrintService.throwIfNotCalledOnMainThread();
return mDocument;
}
@@ -104,6 +111,7 @@ public final class PrintJob {
* @see #start()
* @see #cancel()
*/
@MainThread
public boolean isQueued() {
PrintService.throwIfNotCalledOnMainThread();
return getInfo().getState() == PrintJobInfo.STATE_QUEUED;
@@ -117,8 +125,9 @@ public final class PrintJob {
*
* @see #complete()
* @see #cancel()
* @see #fail(CharSequence)
* @see #fail(String)
*/
@MainThread
public boolean isStarted() {
PrintService.throwIfNotCalledOnMainThread();
return getInfo().getState() == PrintJobInfo.STATE_STARTED;
@@ -132,8 +141,9 @@ public final class PrintJob {
*
* @see #start()
* @see #cancel()
* @see #fail(CharSequence)
* @see #fail(String)
*/
@MainThread
public boolean isBlocked() {
PrintService.throwIfNotCalledOnMainThread();
return getInfo().getState() == PrintJobInfo.STATE_BLOCKED;
@@ -147,6 +157,7 @@ public final class PrintJob {
*
* @see #complete()
*/
@MainThread
public boolean isCompleted() {
PrintService.throwIfNotCalledOnMainThread();
return getInfo().getState() == PrintJobInfo.STATE_COMPLETED;
@@ -158,8 +169,9 @@ public final class PrintJob {
*
* @return Whether the print job is failed.
*
* @see #fail(CharSequence)
* @see #fail(String)
*/
@MainThread
public boolean isFailed() {
PrintService.throwIfNotCalledOnMainThread();
return getInfo().getState() == PrintJobInfo.STATE_FAILED;
@@ -173,6 +185,7 @@ public final class PrintJob {
*
* @see #cancel()
*/
@MainThread
public boolean isCancelled() {
PrintService.throwIfNotCalledOnMainThread();
return getInfo().getState() == PrintJobInfo.STATE_CANCELED;
@@ -182,12 +195,16 @@ public final class PrintJob {
* Starts the print job. You should call this method if {@link
* #isQueued()} or {@link #isBlocked()} returns true and you started
* resumed printing.
* <p>
* This resets the print status to null. Set the new status by using {@link #setStatus}.
* </p>
*
* @return Whether the job was started.
*
* @see #isQueued()
* @see #isBlocked()
*/
@MainThread
public boolean start() {
PrintService.throwIfNotCalledOnMainThread();
final int state = getInfo().getState();
@@ -205,18 +222,20 @@ public final class PrintJob {
* paper to continue printing. To resume the print job call {@link
* #start()}.
*
* @param reason The human readable, short, and translated reason why the print job is blocked.
* @return Whether the job was blocked.
*
* @see #isStarted()
* @see #isBlocked()
*/
public boolean block(String reason) {
@MainThread
public boolean block(@Nullable 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))) {
&& !TextUtils.equals(info.getStatus(), reason))) {
return setState(PrintJobInfo.STATE_BLOCKED, reason);
}
return false;
@@ -230,6 +249,7 @@ public final class PrintJob {
*
* @see #isStarted()
*/
@MainThread
public boolean complete() {
PrintService.throwIfNotCalledOnMainThread();
if (isStarted()) {
@@ -251,7 +271,8 @@ public final class PrintJob {
* @see #isStarted()
* @see #isBlocked()
*/
public boolean fail(String error) {
@MainThread
public boolean fail(@Nullable String error) {
PrintService.throwIfNotCalledOnMainThread();
if (!isInImmutableState()) {
return setState(PrintJobInfo.STATE_FAILED, error);
@@ -271,6 +292,7 @@ public final class PrintJob {
* @see #isQueued()
* @see #isBlocked()
*/
@MainThread
public boolean cancel() {
PrintService.throwIfNotCalledOnMainThread();
if (!isInImmutableState()) {
@@ -279,6 +301,39 @@ public final class PrintJob {
return false;
}
/**
* Sets the progress of this print job as a fraction of 1.
*
* @param progress The new progress
*/
@MainThread
public void setProgress(@FloatRange(from=0.0, to=1.0) float progress) {
PrintService.throwIfNotCalledOnMainThread();
try {
mPrintServiceClient.setProgress(mCachedInfo.getId(), progress);
} catch (RemoteException re) {
Log.e(LOG_TAG, "Error setting progress for job: " + mCachedInfo.getId(), re);
}
}
/**
* Sets the status of this print job. This should be a human readable, short, and translated
* description of the current state of the print job.
*
* @param status The new status. If null the status will be empty.
*/
@MainThread
public void setStatus(@Nullable CharSequence status) {
PrintService.throwIfNotCalledOnMainThread();
try {
mPrintServiceClient.setStatus(mCachedInfo.getId(), status);
} catch (RemoteException re) {
Log.e(LOG_TAG, "Error setting status for job: " + mCachedInfo.getId(), re);
}
}
/**
* Sets a tag that is valid in the context of a {@link PrintService}
* and is not interpreted by the system. For example, a print service
@@ -288,6 +343,7 @@ public final class PrintJob {
* @param tag The tag.
* @return True if the tag was set, false otherwise.
*/
@MainThread
public boolean setTag(String tag) {
PrintService.throwIfNotCalledOnMainThread();
if (isInImmutableState()) {
@@ -319,6 +375,7 @@ public final class PrintJob {
* @param key The option key.
* @return The option value.
*/
@MainThread
public String getAdvancedStringOption(String key) {
PrintService.throwIfNotCalledOnMainThread();
return getInfo().getAdvancedStringOption(key);
@@ -331,6 +388,7 @@ public final class PrintJob {
* @param key The option key.
* @return Whether the option is present.
*/
@MainThread
public boolean hasAdvancedOption(String key) {
PrintService.throwIfNotCalledOnMainThread();
return getInfo().hasAdvancedOption(key);
@@ -342,6 +400,7 @@ public final class PrintJob {
* @param key The option key.
* @return The option value.
*/
@MainThread
public int getAdvancedIntOption(String key) {
PrintService.throwIfNotCalledOnMainThread();
return getInfo().getAdvancedIntOption(key);
@@ -374,14 +433,14 @@ public final class PrintJob {
|| state == PrintJobInfo.STATE_FAILED;
}
private boolean setState(int state, String error) {
private boolean setState(int state, @Nullable String error) {
try {
if (mPrintServiceClient.setPrintJobState(mCachedInfo.getId(), state, error)) {
// Best effort - update the state of the cached info since
// 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.setStateReason(error);
mCachedInfo.setStatus(error);
return true;
}
} catch (RemoteException re) {

View File

@@ -16,6 +16,8 @@
package com.android.printspooler.model;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Notification;
import android.app.Notification.Action;
import android.app.Notification.InboxStyle;
@@ -129,68 +131,69 @@ final class NotificationController {
mContext.getString(R.string.cancel), createCancelIntent(printJob)).build();
}
private void createPrintingNotification(PrintJobInfo printJob) {
/**
* Create a notification for a print job.
*
* @param printJob the job the notification is for
* @param firstAction the first action shown in the notification
* @param secondAction the second action shown in the notification
*/
private void createNotification(@NonNull PrintJobInfo printJob, @Nullable Action firstAction,
@Nullable Action secondAction) {
Notification.Builder builder = new Notification.Builder(mContext)
.setContentIntent(createContentIntent(printJob.getId()))
.setSmallIcon(computeNotificationIcon(printJob))
.setContentTitle(computeNotificationTitle(printJob))
.addAction(createCancelAction(printJob))
.setContentText(printJob.getPrinterName())
.setWhen(System.currentTimeMillis())
.setOngoing(true)
.setShowWhen(true)
.setColor(mContext.getColor(
com.android.internal.R.color.system_notification_accent_color));
if (firstAction != null) {
builder.addAction(firstAction);
}
if (secondAction != null) {
builder.addAction(secondAction);
}
if (printJob.getState() == PrintJobInfo.STATE_STARTED) {
float progress = printJob.getProgress();
if (progress >= 0) {
builder.setProgress(Integer.MAX_VALUE, (int)(Integer.MAX_VALUE * progress),
false);
}
}
CharSequence status = printJob.getStatus();
if (status != null) {
builder.setContentText(status);
} else {
builder.setContentText(printJob.getPrinterName());
}
mNotificationManager.notify(0, builder.build());
}
private void createPrintingNotification(PrintJobInfo printJob) {
createNotification(printJob, createCancelAction(printJob), null);
}
private void createFailedNotification(PrintJobInfo printJob) {
Action.Builder restartActionBuilder = new Action.Builder(
Icon.createWithResource(mContext, R.drawable.ic_restart),
mContext.getString(R.string.restart), createRestartIntent(printJob.getId()));
Notification.Builder builder = new Notification.Builder(mContext)
.setContentIntent(createContentIntent(printJob.getId()))
.setSmallIcon(computeNotificationIcon(printJob))
.setContentTitle(computeNotificationTitle(printJob))
.addAction(createCancelAction(printJob))
.addAction(restartActionBuilder.build())
.setContentText(printJob.getPrinterName())
.setWhen(System.currentTimeMillis())
.setOngoing(true)
.setShowWhen(true)
.setColor(mContext.getColor(
com.android.internal.R.color.system_notification_accent_color));
mNotificationManager.notify(0, builder.build());
createNotification(printJob, createCancelAction(printJob), restartActionBuilder.build());
}
private void createBlockedNotification(PrintJobInfo printJob) {
Notification.Builder builder = new Notification.Builder(mContext)
.setContentIntent(createContentIntent(printJob.getId()))
.setSmallIcon(computeNotificationIcon(printJob))
.setContentTitle(computeNotificationTitle(printJob))
.addAction(createCancelAction(printJob))
.setContentText(printJob.getPrinterName())
.setWhen(System.currentTimeMillis())
.setOngoing(true)
.setShowWhen(true)
.setColor(mContext.getColor(
com.android.internal.R.color.system_notification_accent_color));
mNotificationManager.notify(0, builder.build());
createNotification(printJob, createCancelAction(printJob), null);
}
private void createCancellingNotification(PrintJobInfo printJob) {
Notification.Builder builder = new Notification.Builder(mContext)
.setContentIntent(createContentIntent(printJob.getId()))
.setSmallIcon(computeNotificationIcon(printJob))
.setContentTitle(computeNotificationTitle(printJob))
.setContentText(printJob.getPrinterName())
.setWhen(System.currentTimeMillis())
.setOngoing(true)
.setShowWhen(true)
.setColor(mContext.getColor(
com.android.internal.R.color.system_notification_accent_color));
mNotificationManager.notify(0, builder.build());
createNotification(printJob, null, null);
}
private void createStackedNotification(List<PrintJobInfo> printJobs) {

View File

@@ -16,6 +16,9 @@
package com.android.printspooler.model;
import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
@@ -497,7 +500,7 @@ public final class PrintSpoolerService extends Service {
success = true;
printJob.setState(state);
printJob.setStateReason(error);
printJob.setStatus(error);
printJob.setCancelling(false);
if (DEBUG_PRINT_JOB_LIFECYCLE) {
@@ -547,6 +550,35 @@ public final class PrintSpoolerService extends Service {
return success;
}
/**
* Set the progress for a print job.
*
* @param printJobId ID of the print job to update
* @param progress the new progress
*/
public void setProgress(@NonNull PrintJobId printJobId,
@FloatRange(from=0.0, to=1.0) float progress) {
synchronized (mLock) {
getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY).setProgress(progress);
mNotificationController.onUpdateNotifications(mPrintJobs);
}
}
/**
* Set the status for a print job.
*
* @param printJobId ID of the print job to update
* @param status the new status
*/
public void setStatus(@NonNull PrintJobId printJobId, @Nullable CharSequence status) {
synchronized (mLock) {
getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY).setStatus(status);
mNotificationController.onUpdateNotifications(mPrintJobs);
}
}
public boolean hasActivePrintJobsLocked() {
final int printJobCount = mPrintJobs.size();
for (int i = 0; i < printJobCount; i++) {
@@ -693,6 +725,8 @@ public final class PrintSpoolerService extends Service {
private static final String ATTR_COPIES = "copies";
private static final String ATTR_PRINTER_NAME = "printerName";
private static final String ATTR_STATE_REASON = "stateReason";
private static final String ATTR_STATUS = "status";
private static final String ATTR_PROGRESS = "progress";
private static final String ATTR_CANCELLING = "cancelling";
private static final String TAG_ADVANCED_OPTIONS = "advancedOptions";
@@ -801,13 +835,19 @@ public final class PrintSpoolerService extends Service {
if (!TextUtils.isEmpty(printerName)) {
serializer.attribute(null, ATTR_PRINTER_NAME, printerName);
}
String stateReason = printJob.getStateReason();
if (!TextUtils.isEmpty(stateReason)) {
serializer.attribute(null, ATTR_STATE_REASON, stateReason);
}
serializer.attribute(null, ATTR_CANCELLING, String.valueOf(
printJob.isCancelling()));
float progress = printJob.getProgress();
if (progress != Float.NaN) {
serializer.attribute(null, ATTR_PROGRESS, String.valueOf(progress));
}
CharSequence status = printJob.getStatus();
if (!TextUtils.isEmpty(status)) {
serializer.attribute(null, ATTR_STATUS, status.toString());
}
PrinterId printerId = printJob.getPrinterId();
if (printerId != null) {
serializer.startTag(null, TAG_PRINTER_ID);
@@ -1025,8 +1065,25 @@ public final class PrintSpoolerService extends Service {
printJob.setCopies(Integer.parseInt(copies));
String printerName = parser.getAttributeValue(null, ATTR_PRINTER_NAME);
printJob.setPrinterName(printerName);
String progressString = parser.getAttributeValue(null, ATTR_PROGRESS);
if (progressString != null) {
float progress = Float.parseFloat(progressString);
if (progress != Float.NaN) {
printJob.setProgress(progress);
}
}
CharSequence status = parser.getAttributeValue(null, ATTR_STATUS);
printJob.setStatus(status);
// stateReason is deprecated, but might be used by old print jobs
String stateReason = parser.getAttributeValue(null, ATTR_STATE_REASON);
printJob.setStateReason(stateReason);
if (stateReason != null) {
printJob.setStatus(stateReason);
}
String cancelling = parser.getAttributeValue(null, ATTR_CANCELLING);
printJob.setCancelling(!TextUtils.isEmpty(cancelling)
? Boolean.parseBoolean(cancelling) : false);
@@ -1323,6 +1380,18 @@ public final class PrintSpoolerService extends Service {
.removeApprovedService(serviceToRemove);
}
@Override
public void setProgress(@NonNull PrintJobId printJobId,
@FloatRange(from=0.0, to=1.0) float progress) throws RemoteException {
PrintSpoolerService.this.setProgress(printJobId, progress);
}
@Override
public void setStatus(@NonNull PrintJobId printJobId,
@Nullable CharSequence status) throws RemoteException {
PrintSpoolerService.this.setStatus(printJobId, status);
}
public PrintSpoolerService getService() {
return PrintSpoolerService.this;
}

View File

@@ -16,6 +16,9 @@
package com.android.server.print;
import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -756,6 +759,33 @@ final class RemotePrintService implements DeathRecipient {
}
}
@Override
public void setProgress(@NonNull PrintJobId printJobId,
@FloatRange(from=0.0, to=1.0) float progress) {
RemotePrintService service = mWeakService.get();
if (service != null) {
final long identity = Binder.clearCallingIdentity();
try {
service.mSpooler.setProgress(printJobId, progress);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}
@Override
public void setStatus(@NonNull PrintJobId printJobId, @Nullable CharSequence status) {
RemotePrintService service = mWeakService.get();
if (service != null) {
final long identity = Binder.clearCallingIdentity();
try {
service.mSpooler.setStatus(printJobId, status);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}
@Override
@SuppressWarnings({"rawtypes", "unchecked"})
public void onPrintersAdded(ParceledListSlice printers) {

View File

@@ -16,6 +16,9 @@
package com.android.server.print;
import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -229,6 +232,61 @@ final class RemotePrintSpooler {
return false;
}
/**
* Set progress of a print job.
*
* @param printJobId The print job to update
* @param progress The new progress
*/
public final void setProgress(@NonNull PrintJobId printJobId,
@FloatRange(from=0.0, to=1.0) float progress) {
throwIfCalledOnMainThread();
synchronized (mLock) {
throwIfDestroyedLocked();
mCanUnbind = false;
}
try {
getRemoteInstanceLazy().setProgress(printJobId, progress);
} catch (RemoteException|TimeoutException re) {
Slog.e(LOG_TAG, "Error setting progress.", re);
} finally {
if (DEBUG) {
Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setProgress()");
}
synchronized (mLock) {
mCanUnbind = true;
mLock.notifyAll();
}
}
}
/**
* Set status of a print job.
*
* @param printJobId The print job to update
* @param status The new status
*/
public final void setStatus(@NonNull PrintJobId printJobId, @Nullable CharSequence status) {
throwIfCalledOnMainThread();
synchronized (mLock) {
throwIfDestroyedLocked();
mCanUnbind = false;
}
try {
getRemoteInstanceLazy().setStatus(printJobId, status);
} catch (RemoteException|TimeoutException re) {
Slog.e(LOG_TAG, "Error setting status.", re);
} finally {
if (DEBUG) {
Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setStatus()");
}
synchronized (mLock) {
mCanUnbind = true;
mLock.notifyAll();
}
}
}
public final boolean setPrintJobTag(PrintJobId printJobId, String tag) {
throwIfCalledOnMainThread();
synchronized (mLock) {