diff options
author | Svetoslav <svetoslavganov@google.com> | 2013-09-16 17:53:51 -0700 |
---|---|---|
committer | Svetoslav <svetoslavganov@google.com> | 2013-09-16 17:55:14 -0700 |
commit | 2fbd2a7f070f246ddafd9de94efa9a98861e9136 (patch) | |
tree | 2a918b4226106a2350277ae8fa73a9e2ce79d697 /packages/PrintSpooler/src | |
parent | 3fb53d8238c0ccec275237cf4f4962f2a00eab7e (diff) | |
download | frameworks_base-2fbd2a7f070f246ddafd9de94efa9a98861e9136.zip frameworks_base-2fbd2a7f070f246ddafd9de94efa9a98861e9136.tar.gz frameworks_base-2fbd2a7f070f246ddafd9de94efa9a98861e9136.tar.bz2 |
App UI freezes when printing. API clean up.
1. The UI of a printing app was freezing a little when calling the print
method since the print manager service was waiting for it to bind to the
print spooler which generated the print job id (and the initial print
job info really). Now the print manager service is responsible for job
id generation and does not not wait for the print spooler to spin. Hence,
the app UI is not blocked at all. Note that the print manager initiates
the binding to the spooler and as soon as it completes the spooler shows
the print UI which is hosted in its process. It is not possible to show
the print UI before the system is bound to the spooler since during this
binding the system passes a callback to the spooler so the latter can
talk to the system.
2. Changed the print job id to be an opaque class allowing us to vary the
way we generate print job ids in the future.
3. The queued print job state was hidden but the print job returned by the
print method of the print manager is in that state. Now now hidden.
4. We were incorrecly removing print job infos if they are completed or
cancelled. Doing that is problematic since the print job returned by
the print method allows the app to query for the job info after the
job has been say completed. Hence, an app can initiate printing and
get a print job whose state is "created" and hold onto it until after
the job is completed, now if the app asks for the print job info it
will get an info in "created" state even though the job is "completed"
since the spooler was not retaining the completed jobs. Now the spooler
removes the PDF files for the completed and cancelled print jobs but
keeps around the infos (also persisting them to disc) so it can answer
questions about them. On first boot or switch to a user we purge the
persisted print jobs in completed/cancelled state since they
are obsolete - no app can have a handle to them.
5. Removed the print method that takes a file since we have a public
PrintDocumentAdapter implementation for printing files. Once can
instantiate a PrintFileDocumentAdapter and pass it to the print
method. This class also allows overriding of the finish method to
know when the data is spooled and deleted the file if desired, etc.
6. Replaced the wrong code to slice a large list of parcelables to
use ParceledListSlice class.
bug:10748093
Change-Id: I1ebeeb47576e88fce550851cdd3e401fcede6e2b
Diffstat (limited to 'packages/PrintSpooler/src')
3 files changed, 146 insertions, 124 deletions
diff --git a/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java b/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java index 43a751c..829fb06 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java +++ b/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java @@ -23,13 +23,13 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.AsyncTask; -import android.os.Build; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; import android.print.IPrintManager; +import android.print.PrintJobId; import android.print.PrintJobInfo; import android.print.PrintManager; import android.text.TextUtils; @@ -40,12 +40,13 @@ import android.util.Log; * based on print job state transitions. */ public class NotificationController { - public static final boolean DEBUG = true && Build.IS_DEBUGGABLE; + public static final boolean DEBUG = false; public static final String LOG_TAG = "NotificationController"; private static final String INTENT_ACTION_CANCEL_PRINTJOB = "INTENT_ACTION_CANCEL_PRINTJOB"; private static final String INTENT_ACTION_RESTART_PRINTJOB = "INTENT_ACTION_RESTART_PRINTJOB"; + private static final String INTENT_EXTRA_PRINTJOB_ID = "INTENT_EXTRA_PRINTJOB_ID"; private static final String INTENT_EXTRA_PRINTJOB_LABEL = "INTENT_EXTRA_PRINTJOB_LABEL"; private static final String INTENT_EXTRA_PRINTER_NAME = "INTENT_EXTRA_PRINTER_NAME"; @@ -61,8 +62,9 @@ public class NotificationController { public void onPrintJobStateChanged(PrintJobInfo printJob) { if (DEBUG) { - Log.i(LOG_TAG, "onPrintJobStateChanged() printJobId: " + printJob.getId() - + " state:" + PrintJobInfo.stateToString(printJob.getState())); + Log.i(LOG_TAG, "onPrintJobStateChanged() printJobId: " + + printJob.getId().flattenToString() + " state:" + + PrintJobInfo.stateToString(printJob.getState())); } switch (printJob.getState()) { case PrintJobInfo.STATE_QUEUED: @@ -96,7 +98,7 @@ public class NotificationController { .setWhen(System.currentTimeMillis()) .setOngoing(true) .setShowWhen(true); - mNotificationManager.notify(printJob.getId(), builder.build()); + mNotificationManager.notify(printJob.getId().flattenToString(), 0, builder.build()); } private void createFailedNotification(PrintJobInfo printJob) { @@ -115,7 +117,7 @@ public class NotificationController { .setWhen(System.currentTimeMillis()) .setOngoing(true) .setShowWhen(true); - mNotificationManager.notify(printJob.getId(), builder.build()); + mNotificationManager.notify(printJob.getId().flattenToString(), 0, builder.build()); } private void createBlockedNotification(PrintJobInfo printJob) { @@ -132,25 +134,25 @@ public class NotificationController { .setWhen(System.currentTimeMillis()) .setOngoing(true) .setShowWhen(true); - mNotificationManager.notify(printJob.getId(), builder.build()); + mNotificationManager.notify(printJob.getId().flattenToString(), 0, builder.build()); } - private void removeNotification(int printJobId) { - mNotificationManager.cancel(printJobId); + private void removeNotification(PrintJobId printJobId) { + mNotificationManager.cancel(printJobId.flattenToString(), 0); } private PendingIntent createCancelIntent(PrintJobInfo printJob) { Intent intent = new Intent(mContext, NotificationBroadcastReceiver.class); - intent.setAction(INTENT_ACTION_CANCEL_PRINTJOB + "_" + String.valueOf(printJob.getId())); + intent.setAction(INTENT_ACTION_CANCEL_PRINTJOB + "_" + printJob.getId().flattenToString()); intent.putExtra(INTENT_EXTRA_PRINTJOB_ID, printJob.getId()); intent.putExtra(INTENT_EXTRA_PRINTJOB_LABEL, printJob.getLabel()); intent.putExtra(INTENT_EXTRA_PRINTER_NAME, printJob.getPrinterName()); return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT); } - private PendingIntent createRestartIntent(int printJobId) { + private PendingIntent createRestartIntent(PrintJobId printJobId) { Intent intent = new Intent(mContext, NotificationBroadcastReceiver.class); - intent.setAction(INTENT_ACTION_RESTART_PRINTJOB + "_" + String.valueOf(printJobId)); + intent.setAction(INTENT_ACTION_RESTART_PRINTJOB + "_" + printJobId.flattenToString()); intent.putExtra(INTENT_EXTRA_PRINTJOB_ID, printJobId); return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT); } @@ -162,17 +164,17 @@ public class NotificationController { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action != null && action.startsWith(INTENT_ACTION_CANCEL_PRINTJOB)) { - final int printJobId = intent.getExtras().getInt(INTENT_EXTRA_PRINTJOB_ID); + PrintJobId printJobId = intent.getExtras().getParcelable(INTENT_EXTRA_PRINTJOB_ID); String printJobLabel = intent.getExtras().getString(INTENT_EXTRA_PRINTJOB_LABEL); String printerName = intent.getExtras().getString(INTENT_EXTRA_PRINTER_NAME); handleCancelPrintJob(context, printJobId, printJobLabel, printerName); } else if (action != null && action.startsWith(INTENT_ACTION_RESTART_PRINTJOB)) { - final int printJobId = intent.getExtras().getInt(INTENT_EXTRA_PRINTJOB_ID); + PrintJobId printJobId = intent.getExtras().getParcelable(INTENT_EXTRA_PRINTJOB_ID); handleRestartPrintJob(context, printJobId); } } - private void handleCancelPrintJob(final Context context, final int printJobId, + private void handleCancelPrintJob(final Context context, final PrintJobId printJobId, final String printJobLabel, final String printerName) { if (DEBUG) { Log.i(LOG_TAG, "handleCancelPrintJob() printJobId:" + printJobId); @@ -190,7 +192,7 @@ public class NotificationController { .setWhen(System.currentTimeMillis()) .setOngoing(true) .setShowWhen(true); - notificationManager.notify(printJobId, builder.build()); + notificationManager.notify(printJobId.flattenToString(), 0, builder.build()); // Call into the print manager service off the main thread since // the print manager service may end up binding to the print spooler @@ -226,7 +228,7 @@ public class NotificationController { }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); } - private void handleRestartPrintJob(final Context context, final int printJobId) { + private void handleRestartPrintJob(final Context context, final PrintJobId printJobId) { if (DEBUG) { Log.i(LOG_TAG, "handleRestartPrintJob() printJobId:" + printJobId); } diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java index 14f60f1..4333aea 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java @@ -47,6 +47,7 @@ import android.print.PrintAttributes.MediaSize; import android.print.PrintAttributes.Resolution; import android.print.PrintDocumentAdapter; import android.print.PrintDocumentInfo; +import android.print.PrintJobId; import android.print.PrintJobInfo; import android.print.PrintManager; import android.print.PrinterCapabilitiesInfo; @@ -104,8 +105,7 @@ public class PrintJobConfigActivity extends Activity { private static final boolean DEBUG = true && Build.IS_DEBUGGABLE; public static final String EXTRA_PRINT_DOCUMENT_ADAPTER = "printDocumentAdapter"; - public static final String EXTRA_PRINT_ATTRIBUTES = "printAttributes"; - public static final String EXTRA_PRINT_JOB_ID = "printJobId"; + public static final String EXTRA_PRINT_JOB = "printJob"; public static final String INTENT_EXTRA_PRINTER_ID = "INTENT_EXTRA_PRINTER_ID"; @@ -163,7 +163,7 @@ public class PrintJobConfigActivity extends Activity { private Document mDocument; private PrintController mController; - private int mPrintJobId; + private PrintJobId mPrintJobId; private IBinder mIPrintDocumentAdapter; @@ -175,17 +175,18 @@ public class PrintJobConfigActivity extends Activity { Bundle extras = getIntent().getExtras(); - mPrintJobId = extras.getInt(EXTRA_PRINT_JOB_ID, -1); - if (mPrintJobId < 0) { - throw new IllegalArgumentException("Invalid print job id: " + mPrintJobId); + PrintJobInfo printJob = extras.getParcelable(EXTRA_PRINT_JOB); + if (printJob == null) { + throw new IllegalArgumentException("printJob cannot be null"); } + mPrintJobId = printJob.getId(); mIPrintDocumentAdapter = extras.getBinder(EXTRA_PRINT_DOCUMENT_ADAPTER); if (mIPrintDocumentAdapter == null) { throw new IllegalArgumentException("PrintDocumentAdapter cannot be null"); } - PrintAttributes attributes = getIntent().getParcelableExtra(EXTRA_PRINT_ATTRIBUTES); + PrintAttributes attributes = printJob.getAttributes(); if (attributes != null) { mCurrPrintAttributes.copyFrom(attributes); } diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java index 8580fcd..a6353f7 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java +++ b/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java @@ -37,6 +37,7 @@ import android.print.PrintAttributes.Margins; import android.print.PrintAttributes.MediaSize; import android.print.PrintAttributes.Resolution; import android.print.PrintDocumentInfo; +import android.print.PrintJobId; import android.print.PrintJobInfo; import android.print.PrintManager; import android.print.PrinterId; @@ -51,6 +52,8 @@ import com.android.internal.os.HandlerCaller; import com.android.internal.os.SomeArgs; import com.android.internal.util.FastXmlSerializer; +import libcore.io.IoUtils; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; @@ -63,8 +66,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import libcore.io.IoUtils; - /** * Service for exposing some of the {@link PrintSpooler} functionality to * another process. @@ -73,7 +74,7 @@ public final class PrintSpoolerService extends Service { private static final String LOG_TAG = "PrintSpoolerService"; - private static final boolean DEBUG_PRINT_JOB_LIFECYCLE = false; + private static final boolean DEBUG_PRINT_JOB_LIFECYCLE = true; private static final boolean DEBUG_PERSISTENCE = false; @@ -91,10 +92,6 @@ public final class PrintSpoolerService extends Service { private static PrintSpoolerService sInstance; - private static int sPrintJobIdCounter; - - private Intent mStartPrintJobConfigActivityIntent; - private IPrintSpoolerClient mClient; private HandlerCaller mHandlerCaller; @@ -112,8 +109,6 @@ public final class PrintSpoolerService extends Service { @Override public void onCreate() { super.onCreate(); - mStartPrintJobConfigActivityIntent = new Intent(PrintSpoolerService.this, - PrintJobConfigActivity.class); mHandlerCaller = new HandlerCaller(this, getMainLooper(), new HandlerCallerCallback(), false); @@ -147,7 +142,7 @@ public final class PrintSpoolerService extends Service { } @Override - public void getPrintJobInfo(int printJobId, IPrintSpoolerCallbacks callback, + public void getPrintJobInfo(PrintJobId printJobId, IPrintSpoolerCallbacks callback, int appId, int sequence) throws RemoteException { PrintJobInfo printJob = null; try { @@ -159,38 +154,28 @@ public final class PrintSpoolerService extends Service { @SuppressWarnings("deprecation") @Override - public void createPrintJob(String printJobName, IPrintClient client, - IPrintDocumentAdapter printAdapter, PrintAttributes attributes, - IPrintSpoolerCallbacks callback, int appId, int sequence) - throws RemoteException { - PrintJobInfo printJob = null; - try { - printJob = PrintSpoolerService.this.createPrintJob( - printJobName, client, attributes, appId); - if (printJob != null) { - Intent intent = mStartPrintJobConfigActivityIntent; - intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_DOCUMENT_ADAPTER, - printAdapter.asBinder()); - intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_JOB_ID, - printJob.getId()); - intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_ATTRIBUTES, attributes); - - IntentSender sender = PendingIntent.getActivity( - PrintSpoolerService.this, 0, intent, PendingIntent.FLAG_ONE_SHOT - | PendingIntent.FLAG_CANCEL_CURRENT).getIntentSender(); - - Message message = mHandlerCaller.obtainMessageOO( - HandlerCallerCallback.MSG_START_PRINT_JOB_CONFIG_ACTIVITY, - client, sender); - mHandlerCaller.executeOrSendMessage(message); - } - } finally { - callback.onCreatePrintJobResult(printJob, sequence); - } + public void createPrintJob(PrintJobInfo printJob, IPrintClient client, + IPrintDocumentAdapter printAdapter) throws RemoteException { + PrintSpoolerService.this.createPrintJob(printJob); + + Intent intent = new Intent(printJob.getId().flattenToString()); + intent.setClass(PrintSpoolerService.this, PrintJobConfigActivity.class); + intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_DOCUMENT_ADAPTER, + printAdapter.asBinder()); + intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_JOB, printJob); + + IntentSender sender = PendingIntent.getActivity( + PrintSpoolerService.this, 0, intent, PendingIntent.FLAG_ONE_SHOT + | PendingIntent.FLAG_CANCEL_CURRENT).getIntentSender(); + + Message message = mHandlerCaller.obtainMessageOO( + HandlerCallerCallback.MSG_START_PRINT_JOB_CONFIG_ACTIVITY, + client, sender); + mHandlerCaller.executeOrSendMessage(message); } @Override - public void setPrintJobState(int printJobId, int state, String error, + public void setPrintJobState(PrintJobId printJobId, int state, String error, IPrintSpoolerCallbacks callback, int sequece) throws RemoteException { boolean success = false; try { @@ -202,7 +187,7 @@ public final class PrintSpoolerService extends Service { } @Override - public void setPrintJobTag(int printJobId, String tag, + public void setPrintJobTag(PrintJobId printJobId, String tag, IPrintSpoolerCallbacks callback, int sequece) throws RemoteException { boolean success = false; try { @@ -213,7 +198,7 @@ public final class PrintSpoolerService extends Service { } @Override - public void writePrintJobData(ParcelFileDescriptor fd, int printJobId) { + public void writePrintJobData(ParcelFileDescriptor fd, PrintJobId printJobId) { PrintSpoolerService.this.writePrintJobData(fd, printJobId); } @@ -223,6 +208,16 @@ public final class PrintSpoolerService extends Service { HandlerCallerCallback.MSG_SET_CLIENT, client); mHandlerCaller.executeOrSendMessage(message); } + + @Override + public void removeObsoletePrintJobs() { + PrintSpoolerService.this.removeObsoletePrintJobs(); + } + + @Override + public void forgetPrintJobs(List<PrintJobId> printJobIds) { + PrintSpoolerService.this.forgetPrintJobs(printJobIds); + } }; } @@ -351,15 +346,16 @@ public final class PrintSpoolerService extends Service { private boolean isStateVisibleToUser(int state) { return (isActiveState(state) && (state == PrintJobInfo.STATE_FAILED - || state == PrintJobInfo.STATE_COMPLETED|| state == PrintJobInfo.STATE_CANCELED)); + || state == PrintJobInfo.STATE_COMPLETED || state == PrintJobInfo.STATE_CANCELED + || state == PrintJobInfo.STATE_BLOCKED)); } - public PrintJobInfo getPrintJobInfo(int printJobId, int appId) { + public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId) { synchronized (mLock) { final int printJobCount = mPrintJobs.size(); for (int i = 0; i < printJobCount; i++) { PrintJobInfo printJob = mPrintJobs.get(i); - if (printJob.getId() == printJobId + if (printJob.getId().equals(printJobId) && (appId == PrintManager.APP_ID_ANY || appId == printJob.getAppId())) { return printJob; @@ -369,20 +365,9 @@ public final class PrintSpoolerService extends Service { } } - public PrintJobInfo createPrintJob(String label, IPrintClient client, - PrintAttributes attributes, int appId) { + public void createPrintJob(PrintJobInfo printJob) { synchronized (mLock) { - final int printJobId = generatePrintJobIdLocked(); - PrintJobInfo printJob = new PrintJobInfo(); - printJob.setId(printJobId); - printJob.setAppId(appId); - printJob.setLabel(label); - printJob.setAttributes(attributes); - printJob.setState(PrintJobInfo.STATE_CREATED); - addPrintJobLocked(printJob); - - return printJob; } } @@ -404,8 +389,7 @@ public final class PrintSpoolerService extends Service { // decide whether to restart the job or just cancel it. setPrintJobState(printJob.getId(), PrintJobInfo.STATE_FAILED, getString(R.string.no_connection_to_printer)); - } - break; + } break; } } } @@ -418,26 +402,7 @@ public final class PrintSpoolerService extends Service { } } - private int generatePrintJobIdLocked() { - int printJobId = sPrintJobIdCounter++; - while (isDuplicatePrintJobId(printJobId)) { - printJobId = sPrintJobIdCounter++; - } - return printJobId; - } - - private boolean isDuplicatePrintJobId(int printJobId) { - final int printJobCount = mPrintJobs.size(); - for (int j = 0; j < printJobCount; j++) { - PrintJobInfo printJob = mPrintJobs.get(j); - if (printJob.getId() == printJobId) { - return true; - } - } - return false; - } - - public void writePrintJobData(final ParcelFileDescriptor fd, final int printJobId) { + public void writePrintJobData(final ParcelFileDescriptor fd, final PrintJobId printJobId) { final PrintJobInfo printJob; synchronized (mLock) { printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); @@ -476,9 +441,9 @@ public final class PrintSpoolerService extends Service { }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); } - public File generateFileForPrintJob(int printJobId) { + public File generateFileForPrintJob(PrintJobId printJobId) { return new File(getFilesDir(), "print_job_" - + printJobId + "." + PRINT_FILE_EXTENSION); + + printJobId.flattenToString() + "." + PRINT_FILE_EXTENSION); } private void addPrintJobLocked(PrintJobInfo printJob) { @@ -488,16 +453,59 @@ public final class PrintSpoolerService extends Service { } } - private void removePrintJobLocked(PrintJobInfo printJob) { - if (mPrintJobs.remove(printJob)) { - generateFileForPrintJob(printJob.getId()).delete(); + private void forgetPrintJobs(List<PrintJobId> printJobIds) { + synchronized (mLock) { + boolean printJobsRemoved = false; + final int removedPrintJobCount = printJobIds.size(); + for (int i = 0; i < removedPrintJobCount; i++) { + PrintJobId removedPrintJobId = printJobIds.get(i); + final int printJobCount = mPrintJobs.size(); + for (int j = printJobCount - 1; j >= 0; j--) { + PrintJobInfo printJob = mPrintJobs.get(j); + if (removedPrintJobId.equals(printJob.getId())) { + mPrintJobs.remove(j); + printJobsRemoved = true; + if (DEBUG_PRINT_JOB_LIFECYCLE) { + Slog.i(LOG_TAG, "[FORGOT] " + printJob.getId().flattenToString()); + } + removePrintJobFileLocked(printJob.getId()); + } + } + } + if (printJobsRemoved) { + mPersistanceManager.writeStateLocked(); + } + } + } + + private void removeObsoletePrintJobs() { + synchronized (mLock) { + final int printJobCount = mPrintJobs.size(); + for (int i = printJobCount - 1; i >= 0; i--) { + PrintJobInfo printJob = mPrintJobs.get(i); + if (isObsoleteState(printJob.getState())) { + mPrintJobs.remove(i); + if (DEBUG_PRINT_JOB_LIFECYCLE) { + Slog.i(LOG_TAG, "[REMOVE] " + printJob.getId().flattenToString()); + } + removePrintJobFileLocked(printJob.getId()); + } + } + mPersistanceManager.writeStateLocked(); + } + } + + private void removePrintJobFileLocked(PrintJobId printJobId) { + File file = generateFileForPrintJob(printJobId); + if (file.exists()) { + file.delete(); if (DEBUG_PRINT_JOB_LIFECYCLE) { - Slog.i(LOG_TAG, "[REMOVE] " + printJob); + Slog.i(LOG_TAG, "[REMOVE FILE FOR] " + printJobId.flattenToString()); } } } - public boolean setPrintJobState(int printJobId, int state, String error) { + public boolean setPrintJobState(PrintJobId printJobId, int state, String error) { boolean success = false; synchronized (mLock) { @@ -516,7 +524,11 @@ public final class PrintSpoolerService extends Service { switch (state) { case PrintJobInfo.STATE_COMPLETED: case PrintJobInfo.STATE_CANCELED: - removePrintJobLocked(printJob); + // Just remove the file but keep the print job info since + // the app that created it may be holding onto the PrintJob + // instance and query it for its most recent state. We will + // remove the info for this job when told so by the system. + removePrintJobFileLocked(printJob.getId()); // $fall-through$ case PrintJobInfo.STATE_FAILED: { @@ -570,6 +582,11 @@ public final class PrintSpoolerService extends Service { return false; } + private boolean isObsoleteState(int printJobState) { + return (isTeminalState(printJobState) + || printJobState == PrintJobInfo.STATE_QUEUED); + } + private boolean isActiveState(int printJobState) { return printJobState == PrintJobInfo.STATE_CREATED || printJobState == PrintJobInfo.STATE_QUEUED @@ -577,7 +594,12 @@ public final class PrintSpoolerService extends Service { || printJobState == PrintJobInfo.STATE_BLOCKED; } - public boolean setPrintJobTag(int printJobId, String tag) { + private boolean isTeminalState(int printJobState) { + return printJobState == PrintJobInfo.STATE_COMPLETED + || printJobState == PrintJobInfo.STATE_CANCELED; + } + + public boolean setPrintJobTag(PrintJobId printJobId, String tag) { synchronized (mLock) { PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); if (printJob != null) { @@ -599,7 +621,7 @@ public final class PrintSpoolerService extends Service { return false; } - public void setPrintJobCopiesNoPersistence(int printJobId, int copies) { + public void setPrintJobCopiesNoPersistence(PrintJobId printJobId, int copies) { synchronized (mLock) { PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); if (printJob != null) { @@ -608,7 +630,8 @@ public final class PrintSpoolerService extends Service { } } - public void setPrintJobPrintDocumentInfoNoPersistence(int printJobId, PrintDocumentInfo info) { + public void setPrintJobPrintDocumentInfoNoPersistence(PrintJobId printJobId, + PrintDocumentInfo info) { synchronized (mLock) { PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); if (printJob != null) { @@ -617,7 +640,8 @@ public final class PrintSpoolerService extends Service { } } - public void setPrintJobAttributesNoPersistence(int printJobId, PrintAttributes attributes) { + public void setPrintJobAttributesNoPersistence(PrintJobId printJobId, + PrintAttributes attributes) { synchronized (mLock) { PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); if (printJob != null) { @@ -626,7 +650,7 @@ public final class PrintSpoolerService extends Service { } } - public void setPrintJobPrinterNoPersistence(int printJobId, PrinterInfo printer) { + public void setPrintJobPrinterNoPersistence(PrintJobId printJobId, PrinterInfo printer) { synchronized (mLock) { PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); if (printJob != null) { @@ -636,7 +660,7 @@ public final class PrintSpoolerService extends Service { } } - public void setPrintJobPagesNoPersistence(int printJobId, PageRange[] pages) { + public void setPrintJobPagesNoPersistence(PrintJobId printJobId, PageRange[] pages) { synchronized (mLock) { PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); if (printJob != null) { @@ -759,15 +783,9 @@ public final class PrintSpoolerService extends Service { for (int j = 0; j < printJobCount; j++) { PrintJobInfo printJob = printJobs.get(j); - final int state = printJob.getState(); - if (state < PrintJobInfo.STATE_QUEUED - || state > PrintJobInfo.STATE_CANCELED) { - continue; - } - serializer.startTag(null, TAG_JOB); - serializer.attribute(null, ATTR_ID, String.valueOf(printJob.getId())); + serializer.attribute(null, ATTR_ID, printJob.getId().flattenToString()); serializer.attribute(null, ATTR_LABEL, printJob.getLabel().toString()); serializer.attribute(null, ATTR_STATE, String.valueOf(printJob.getState())); serializer.attribute(null, ATTR_APP_ID, String.valueOf(printJob.getAppId())); @@ -948,7 +966,8 @@ public final class PrintSpoolerService extends Service { PrintJobInfo printJob = new PrintJobInfo(); - final int printJobId = Integer.parseInt(parser.getAttributeValue(null, ATTR_ID)); + PrintJobId printJobId = PrintJobId.unflattenFromString( + parser.getAttributeValue(null, ATTR_ID)); printJob.setId(printJobId); String label = parser.getAttributeValue(null, ATTR_LABEL); printJob.setLabel(label); |