From 835835ee6f913408ac91678d6056896a2c5b25e3 Mon Sep 17 00:00:00 2001 From: Svetoslav Ganov Date: Sun, 4 Aug 2013 20:17:52 -0700 Subject: Polish the print spooler loading of stored print jobs. 1. The singleton print spooler isntance is created when the print spooler service gets a connection to the system and is destroyed when this connection is removed. Note that if the spooler has work, then the connection to the system will not be removed. When the spooler is created, it reads the stored state and notifies the system which in turn dispatches this to the print services. When the system connects to the spooler and passes it a connection, we schedule a delayed check whether there is work for the spooler. We do not handle this immediately to avoid intermitted spinning on and off of the spooler process if a client makes a sequence of queries while the spooler has really no work. 2. Fixed a bug in the NotificationManagerService where adding a notification and removing it immediately after that does not remove the notification. The code that is adding a notification is run on a handler thread while the code to remove it on the calling thread. This creates a race and erroneous results. Now the removal is also scheduled on the handler. 3. Many small fixes here and there. Change-Id: I6415c253139fa6616393fbe23c659d031a29e1f6 --- core/java/android/print/IPrintSpooler.aidl | 1 - .../printspooler/NotificationController.java | 159 ++++++---- .../printspooler/PrintJobConfigActivity.java | 2 +- .../src/com/android/printspooler/PrintSpooler.java | 350 +++++---------------- .../android/printspooler/PrintSpoolerService.java | 197 +++++++++--- .../android/server/NotificationManagerService.java | 46 +-- .../android/server/print/PrintManagerService.java | 8 +- .../android/server/print/RemotePrintService.java | 8 +- .../android/server/print/RemotePrintSpooler.java | 51 ++- .../java/com/android/server/print/UserState.java | 2 +- 10 files changed, 398 insertions(+), 426 deletions(-) diff --git a/core/java/android/print/IPrintSpooler.aidl b/core/java/android/print/IPrintSpooler.aidl index 428f972..8178180 100644 --- a/core/java/android/print/IPrintSpooler.aidl +++ b/core/java/android/print/IPrintSpooler.aidl @@ -46,5 +46,4 @@ oneway interface IPrintSpooler { int sequence); void writePrintJobData(in ParcelFileDescriptor fd, int printJobId); void setClient(IPrintSpoolerClient client); - void notifyClientForActivteJobs(); } diff --git a/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java b/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java index e4de4b8..14a96c9 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java +++ b/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java @@ -22,7 +22,10 @@ import android.app.PendingIntent; 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; @@ -43,6 +46,8 @@ public class 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"; private final Context mContext; private final NotificationManager mNotificationManager; @@ -53,11 +58,10 @@ public class NotificationController { mContext.getSystemService(Context.NOTIFICATION_SERVICE); } - public void onPrintJobStateChanged(PrintJobInfo printJob, int oldState) { + public void onPrintJobStateChanged(PrintJobInfo printJob) { if (DEBUG) { Log.i(LOG_TAG, "onPrintJobStateChanged() printJobId: " + printJob.getId() - + " oldState: " + PrintJobInfo.stateToString(oldState) - + " newState:" + PrintJobInfo.stateToString(printJob.getState())); + + " state:" + PrintJobInfo.stateToString(printJob.getState())); } switch (printJob.getState()) { case PrintJobInfo.STATE_QUEUED: { @@ -87,10 +91,10 @@ public class NotificationController { printJob.getLabel())) // TODO: Use appropriate icon when assets are ready .addAction(android.R.drawable.ic_secure, mContext.getString(R.string.cancel), - createCancelIntent(printJob.getId())) + createCancelIntent(printJob)) .setContentText(printJob.getPrinterId().getPrinterName()) - .setOngoing(true) .setWhen(System.currentTimeMillis()) + .setOngoing(true) .setShowWhen(true); mNotificationManager.notify(printJob.getId(), builder.build()); } @@ -103,10 +107,10 @@ public class NotificationController { printJob.getLabel())) // TODO: Use appropriate icon when assets are ready .addAction(android.R.drawable.ic_secure, mContext.getString(R.string.cancel), - createCancelIntent(printJob.getId())) + createCancelIntent(printJob)) .setContentText(printJob.getPrinterId().getPrinterName()) - .setOngoing(true) .setWhen(System.currentTimeMillis()) + .setOngoing(true) .setShowWhen(true); mNotificationManager.notify(printJob.getId(), builder.build()); } @@ -119,13 +123,13 @@ public class NotificationController { printJob.getLabel())) // TODO: Use appropriate icon when assets are ready .addAction(android.R.drawable.ic_secure, mContext.getString(R.string.cancel), - createCancelIntent(printJob.getId())) + createCancelIntent(printJob)) // TODO: Use appropriate icon when assets are ready .addAction(android.R.drawable.ic_secure, mContext.getString(R.string.restart), createRestartIntent(printJob.getId())) .setContentText(printJob.getFailureReason()) - .setOngoing(true) .setWhen(System.currentTimeMillis()) + .setOngoing(true) .setShowWhen(true); mNotificationManager.notify(printJob.getId(), builder.build()); } @@ -134,10 +138,12 @@ public class NotificationController { mNotificationManager.cancel(printJobId); } - private PendingIntent createCancelIntent(int printJobId) { + private PendingIntent createCancelIntent(PrintJobInfo printJob) { Intent intent = new Intent(mContext, NotificationBroadcastReceiver.class); - intent.setAction(INTENT_ACTION_CANCEL_PRINTJOB + "_" + String.valueOf(printJobId)); - intent.putExtra(INTENT_EXTRA_PRINTJOB_ID, printJobId); + intent.setAction(INTENT_ACTION_CANCEL_PRINTJOB + "_" + String.valueOf(printJob.getId())); + intent.putExtra(INTENT_EXTRA_PRINTJOB_ID, printJob.getId()); + intent.putExtra(INTENT_EXTRA_PRINTJOB_LABEL, printJob.getLabel()); + intent.putExtra(INTENT_EXTRA_PRINTER_NAME, printJob.getPrinterId().getPrinterName()); return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT); } @@ -156,60 +162,68 @@ public class NotificationController { String action = intent.getAction(); if (action != null && action.startsWith(INTENT_ACTION_CANCEL_PRINTJOB)) { final int printJobId = intent.getExtras().getInt(INTENT_EXTRA_PRINTJOB_ID); - handleCancelPrintJob(context, printJobId); + 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); handleRestartPrintJob(context, printJobId); } } - private void handleCancelPrintJob(final Context context, final int printJobId) { + private void handleCancelPrintJob(final Context context, final int printJobId, + final String printJobLabel, final String printerName) { if (DEBUG) { Log.i(LOG_TAG, "handleCancelPrintJob() printJobId:" + printJobId); } - PrintSpooler printSpooler = PrintSpooler.getInstance(context); - - final PrintJobInfo printJob = printSpooler.getPrintJobInfo(printJobId, - PrintManager.APP_ID_ANY); - - if (printJob == null || printJob.getState() == PrintJobInfo.STATE_CANCELED) { - return; - } - // Put up a notification that we are trying to cancel. NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - Notification.Builder builder = new Notification.Builder(context) // TODO: Use appropriate icon when assets are ready .setSmallIcon(android.R.drawable.ic_secure) .setContentTitle(context.getString( R.string.cancelling_notification_title_template, - printJob.getLabel())) - .setContentText(printJob.getPrinterId().getPrinterName()) - .setOngoing(true) + printJobLabel)) + .setContentText(printerName) .setWhen(System.currentTimeMillis()) + .setOngoing(true) .setShowWhen(true); - - notificationManager.notify(printJob.getId(), builder.build()); - - // We need to request the cancellation to be done by the print - // manager service since it has to communicate with the managing - // print service to request the cancellation. Also we need the - // system service to be bound to the spooler since canceling a - // print job will trigger persistence of current jobs which is - // done on another thread and until it finishes the spooler has - // to be kept around. - IPrintManager printManager = IPrintManager.Stub.asInterface( - ServiceManager.getService(Context.PRINT_SERVICE)); - - try { - printManager.cancelPrintJob(printJobId, PrintManager.APP_ID_ANY, - UserHandle.myUserId()); - } catch (RemoteException re) { - Log.i(LOG_TAG, "Error requestion print job cancellation", re); - } + notificationManager.notify(printJobId, 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 + // service which binding is handled on the main thread. + PowerManager powerManager = (PowerManager) + context.getSystemService(Context.POWER_SERVICE); + final WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, + LOG_TAG); + wakeLock.acquire(); + + new AsyncTask() { + @Override + protected Void doInBackground(Void... params) { + // We need to request the cancellation to be done by the print + // manager service since it has to communicate with the managing + // print service to request the cancellation. Also we need the + // system service to be bound to the spooler since canceling a + // print job will trigger persistence of current jobs which is + // done on another thread and until it finishes the spooler has + // to be kept around. + try { + IPrintManager printManager = IPrintManager.Stub.asInterface( + ServiceManager.getService(Context.PRINT_SERVICE)); + printManager.cancelPrintJob(printJobId, PrintManager.APP_ID_ANY, + UserHandle.myUserId()); + } catch (RemoteException re) { + Log.i(LOG_TAG, "Error requestion print job cancellation", re); + } finally { + wakeLock.release(); + } + return null; + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); } private void handleRestartPrintJob(final Context context, final int printJobId) { @@ -217,29 +231,36 @@ public class NotificationController { Log.i(LOG_TAG, "handleRestartPrintJob() printJobId:" + printJobId); } - PrintSpooler printSpooler = PrintSpooler.getInstance(context); - - PrintJobInfo printJob = printSpooler.getPrintJobInfo(printJobId, - PrintManager.APP_ID_ANY); - - if (printJob == null || printJob.getState() != PrintJobInfo.STATE_FAILED) { - return; - } - - // We need to request the restart to be done by the print manager - // service since the latter must be bound to the spooler because - // restarting a print job will trigger persistence of current jobs - // which is done on another thread and until it finishes the spooler has - // to be kept around. - IPrintManager printManager = IPrintManager.Stub.asInterface( - ServiceManager.getService(Context.PRINT_SERVICE)); - - try { - printManager.restartPrintJob(printJobId, PrintManager.APP_ID_ANY, - UserHandle.myUserId()); - } catch (RemoteException re) { - Log.i(LOG_TAG, "Error requestion print job restart", re); - } + // Call into the print manager service off the main thread since + // the print manager service may end up binding to the print spooler + // service which binding is handled on the main thread. + PowerManager powerManager = (PowerManager) + context.getSystemService(Context.POWER_SERVICE); + final WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, + LOG_TAG); + wakeLock.acquire(); + + new AsyncTask() { + @Override + protected Void doInBackground(Void... params) { + // We need to request the restart to be done by the print manager + // service since the latter must be bound to the spooler because + // restarting a print job will trigger persistence of current jobs + // which is done on another thread and until it finishes the spooler has + // to be kept around. + try { + IPrintManager printManager = IPrintManager.Stub.asInterface( + ServiceManager.getService(Context.PRINT_SERVICE)); + printManager.restartPrintJob(printJobId, PrintManager.APP_ID_ANY, + UserHandle.myUserId()); + } catch (RemoteException re) { + Log.i(LOG_TAG, "Error requestion print job restart", re); + } finally { + wakeLock.release(); + } + return null; + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); } } } diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java index 484c8a9..4a19558 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java @@ -161,7 +161,7 @@ public class PrintJobConfigActivity extends Activity { mCurrPrintAttributes.copyFrom(attributes); } - mSpooler = PrintSpooler.getInstance(this); + mSpooler = PrintSpooler.peekInstance(); mEditor = new Editor(); mDocument = new Document(); mController = new PrintController(new RemotePrintDocumentAdapter( diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintSpooler.java b/packages/PrintSpooler/src/com/android/printspooler/PrintSpooler.java index fabd68f..0bc20a3 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/PrintSpooler.java +++ b/packages/PrintSpooler/src/com/android/printspooler/PrintSpooler.java @@ -19,13 +19,8 @@ package com.android.printspooler; import android.content.ComponentName; import android.content.Context; import android.os.AsyncTask; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; import android.os.ParcelFileDescriptor; -import android.os.RemoteException; import android.print.IPrintClient; -import android.print.IPrintSpoolerClient; import android.print.IPrinterDiscoveryObserver; import android.print.PageRange; import android.print.PrintAttributes; @@ -42,7 +37,6 @@ import android.util.Log; import android.util.Slog; import android.util.Xml; -import com.android.internal.os.SomeArgs; import com.android.internal.util.FastXmlSerializer; import libcore.io.IoUtils; @@ -57,9 +51,7 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; public class PrintSpooler { @@ -87,68 +79,38 @@ public class PrintSpooler { private final NotificationController mNotificationController; - private final Handler mHandler; + private final PrintSpoolerService mService; - private final Context mContext; - - public IPrintSpoolerClient mClient; - - public static PrintSpooler getInstance(Context context) { + public static void destroyInstance() { synchronized (sLock) { - if (sInstance == null) { - sInstance = new PrintSpooler(context); - } - return sInstance; - } - } - - private PrintSpooler(Context context) { - mContext = context; - mPersistanceManager = new PersistenceManager(context); - mNotificationController = new NotificationController(context); - mHandler = new MyHandler(context.getMainLooper()); - } - - public void setCleint(IPrintSpoolerClient client) { - synchronized (mLock) { - mClient = client; - } - } - - public void restorePersistedState() { - synchronized (mLock) { - mPersistanceManager.readStateLocked(); + sInstance = null; } } - public void onReqeustUpdatePrinters(List printers) { - synchronized (mLock) { - SomeArgs args = SomeArgs.obtain(); - args.arg1 = mClient; - args.arg2 = printers; - mHandler.obtainMessage(MyHandler.MSG_ON_REQUEST_UPDATE_PRINTERS, - args).sendToTarget(); + public static void createInstance(PrintSpoolerService service) { + synchronized (sLock) { + sInstance = new PrintSpooler(service); } } - public void startPrinterDiscovery(IPrinterDiscoveryObserver observer) { - synchronized (mLock) { - SomeArgs args = SomeArgs.obtain(); - args.arg1 = mClient; - args.arg2 = observer; - mHandler.obtainMessage(MyHandler.MSG_ON_START_PRINTER_DISCOVERY, - args).sendToTarget(); + public static PrintSpooler peekInstance() { + synchronized (sLock) { + return sInstance; } } - public void stopPrinterDiscovery() { + private PrintSpooler(PrintSpoolerService service) { + mService = service; + mPersistanceManager = new PersistenceManager(service); + mNotificationController = new NotificationController(service); synchronized (mLock) { - mHandler.obtainMessage(MyHandler.MSG_ON_STOP_PRINTER_DISCOVERY, - mClient).sendToTarget(); + mPersistanceManager.readStateLocked(); + handleReadPrintJobsLocked(); } } - public List getPrintJobInfos(ComponentName componentName, int state, int appId) { + public List getPrintJobInfos(ComponentName componentName, + int state, int appId) { List foundPrintJobs = null; synchronized (mLock) { final int printJobCount = mPrintJobs.size(); @@ -207,79 +169,48 @@ public class PrintSpooler { } } - public void notifyClientForActivteJobs() { - IPrintSpoolerClient client = null; - Map> activeJobsPerServiceMap = - new HashMap>(); + private void handleReadPrintJobsLocked() { + final int printJobCount = mPrintJobs.size(); + for (int i = 0; i < printJobCount; i++) { + PrintJobInfo printJob = mPrintJobs.get(i); - synchronized (mLock) { - if (mClient == null) { - throw new IllegalStateException("Client cannot be null."); - } - client = mClient; + // Update the notification. + mNotificationController.onPrintJobStateChanged(printJob); - final int printJobCount = mPrintJobs.size(); - for (int i = 0; i < printJobCount; i++) { - PrintJobInfo printJob = mPrintJobs.get(i); - switch (printJob.getState()) { - case PrintJobInfo.STATE_CREATED: { - /* skip - not ready to be handled by a service */ - } break; + //TODO: Figure out what the right policy for read print jobs is. - case PrintJobInfo.STATE_QUEUED: - case PrintJobInfo.STATE_STARTED: { - ComponentName service = printJob.getPrinterId().getServiceName(); - List jobsPerService = activeJobsPerServiceMap.get(service); - if (jobsPerService == null) { - jobsPerService = new ArrayList(); - activeJobsPerServiceMap.put(service, jobsPerService); - } - jobsPerService.add(printJob); - } break; + switch (printJob.getState()) { + case PrintJobInfo.STATE_QUEUED: { + // Notify that we have a queued job. + mService.onPrintJobQueued(new PrintJobInfo(printJob)); + } break; - default: { - ComponentName service = printJob.getPrinterId().getServiceName(); - if (!activeJobsPerServiceMap.containsKey(service)) { - activeJobsPerServiceMap.put(service, null); - } - } - } + case PrintJobInfo.STATE_STARTED: { + // We really want to restart this print job. + setPrintJobState(printJob.getId(), PrintJobInfo.STATE_QUEUED, null); + } break; } } + } - boolean allPrintJobsHandled = true; - - for (Map.Entry> entry - : activeJobsPerServiceMap.entrySet()) { - ComponentName service = entry.getKey(); - List printJobs = entry.getValue(); - - if (printJobs != null) { - allPrintJobsHandled = false; - final int printJobCount = printJobs.size(); - for (int i = 0; i < printJobCount; i++) { - PrintJobInfo printJob = printJobs.get(i); - if (printJob.getState() == PrintJobInfo.STATE_QUEUED) { - SomeArgs args = SomeArgs.obtain(); - args.arg1 = client; - args.arg2 = new PrintJobInfo(printJob); - mHandler.obtainMessage(MyHandler.MSG_ON_PRINT_JOB_QUEUED, - args).sendToTarget(); - } - } - } else { - SomeArgs args = SomeArgs.obtain(); - args.arg1 = client; - args.arg2 = service; - mHandler.obtainMessage(MyHandler.MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED, - args).sendToTarget(); + public void checkAllPrintJobsHandled() { + synchronized (mLock) { + if (!hasActivePrintJobsLocked()) { + notifyOnAllPrintJobsHandled(); } } + } - if (allPrintJobsHandled) { - mHandler.obtainMessage(MyHandler.MSG_ON_ALL_PRINT_JOBS_HANDLED, - client).sendToTarget(); - } + public void startPrinterDiscovery(IPrinterDiscoveryObserver observer) { + mService.startPrinterDiscovery(observer); + } + + public void stopPrinterDiscovery() { + mService.stopPrinterDiscovery(); + } + + public void onReqeustUpdatePrinters(List printerIds) { + mService.onReqeustUpdatePrinters(printerIds); } private int generatePrintJobIdLocked() { @@ -341,7 +272,7 @@ public class PrintSpooler { } public File generateFileForPrintJob(int printJobId) { - return new File(mContext.getFilesDir(), "print_job_" + return new File(mService.getFilesDir(), "print_job_" + printJobId + "." + PRINT_FILE_EXTENSION); } @@ -365,88 +296,67 @@ public class PrintSpooler { boolean success = false; synchronized (mLock) { - if (mClient == null) { - throw new IllegalStateException("Client cannot be null."); - } - PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); if (printJob != null) { success = true; - final int oldState = printJob.getState(); printJob.setState(state); printJob.setFailureReason(error); - mNotificationController.onPrintJobStateChanged(printJob, oldState); + mNotificationController.onPrintJobStateChanged(printJob); if (DEBUG_PRINT_JOB_LIFECYCLE) { Slog.i(LOG_TAG, "[STATE CHANGED] " + printJob); } - // TODO: Update notifications. switch (state) { case PrintJobInfo.STATE_COMPLETED: - case PrintJobInfo.STATE_CANCELED: { + case PrintJobInfo.STATE_CANCELED: removePrintJobLocked(printJob); - - // No printer means creation of a print job was cancelled, - // therefore the state of the spooler did not change and no - // notifications are needed. We also do not need to persist - // the state. + // $fall-through$ + case PrintJobInfo.STATE_FAILED: { PrinterId printerId = printJob.getPrinterId(); - if (printerId == null) { - return true; - } - - ComponentName service = printerId.getServiceName(); - if (!hasActivePrintJobsForServiceLocked(service)) { - SomeArgs args = SomeArgs.obtain(); - args.arg1 = mClient; - args.arg2 = service; - mHandler.obtainMessage( - MyHandler.MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED, - args).sendToTarget(); - } - - if (!hasActivePrintJobsLocked()) { - mHandler.obtainMessage(MyHandler.MSG_ON_ALL_PRINT_JOBS_HANDLED, - mClient).sendToTarget(); + if (printerId != null) { + ComponentName service = printerId.getServiceName(); + if (!hasActivePrintJobsForServiceLocked(service)) { + mService.onAllPrintJobsForServiceHandled(service); + } } } break; case PrintJobInfo.STATE_QUEUED: { - SomeArgs args = SomeArgs.obtain(); - args.arg1 = mClient; - args.arg2 = new PrintJobInfo(printJob); - mHandler.obtainMessage(MyHandler.MSG_ON_PRINT_JOB_QUEUED, - args).sendToTarget(); + mService.onPrintJobQueued(new PrintJobInfo(printJob)); } break; } if (shouldPersistPrintJob(printJob)) { mPersistanceManager.writeStateLocked(); } + + if (!hasActivePrintJobsLocked()) { + notifyOnAllPrintJobsHandled(); + } } } return success; } - private boolean hasActivePrintJobsLocked() { + public boolean hasActivePrintJobsLocked() { final int printJobCount = mPrintJobs.size(); for (int i = 0; i < printJobCount; i++) { PrintJobInfo printJob = mPrintJobs.get(i); - if (!isActiveState(printJob.getState())) { + if (isActiveState(printJob.getState())) { return true; } } return false; } - private boolean hasActivePrintJobsForServiceLocked(ComponentName service) { + public boolean hasActivePrintJobsForServiceLocked(ComponentName service) { final int printJobCount = mPrintJobs.size(); for (int i = 0; i < printJobCount; i++) { PrintJobInfo printJob = mPrintJobs.get(i); - if (!isActiveState(printJob.getState()) + if (isActiveState(printJob.getState()) && printJob.getPrinterId().getServiceName().equals(service)) { return true; } @@ -455,9 +365,9 @@ public class PrintSpooler { } private static boolean isActiveState(int printJobState) { - return printJobState != PrintJobInfo.STATE_CREATED - || printJobState != PrintJobInfo.STATE_QUEUED - || printJobState != PrintJobInfo.STATE_STARTED; + return printJobState == PrintJobInfo.STATE_CREATED + || printJobState == PrintJobInfo.STATE_QUEUED + || printJobState == PrintJobInfo.STATE_STARTED; } public boolean setPrintJobTag(int printJobId, String tag) { @@ -531,6 +441,20 @@ public class PrintSpooler { return printJob.getState() >= PrintJobInfo.STATE_QUEUED; } + private void notifyOnAllPrintJobsHandled() { + // This has to run on the tread that is persisting the current state + // since this call may result in the system unbinding from the spooler + // and as a result the spooler process may get killed before the write + // completes. + new AsyncTask() { + @Override + protected Void doInBackground(Void... params) { + mService.onAllPrintJobsHandled(); + return null; + } + }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null); + } + private final class PersistenceManager { private static final String PERSIST_FILE_NAME = "print_spooler_state.xml"; @@ -1056,108 +980,4 @@ public class PrintSpooler { return true; } } - - private final class MyHandler extends Handler { - public static final int MSG_ON_START_PRINTER_DISCOVERY = 1; - public static final int MSG_ON_STOP_PRINTER_DISCOVERY = 2; - public static final int MSG_ON_PRINT_JOB_QUEUED = 3; - public static final int MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED = 4; - public static final int MSG_ON_ALL_PRINT_JOBS_HANDLED = 5; - public static final int MSG_ON_REQUEST_UPDATE_PRINTERS = 6; - - public MyHandler(Looper looper) { - super(looper, null, false); - } - - @Override - @SuppressWarnings("unchecked") - public void handleMessage(Message message) { - switch (message.what) { - case MSG_ON_START_PRINTER_DISCOVERY: { - SomeArgs args = (SomeArgs) message.obj; - IPrintSpoolerClient client = (IPrintSpoolerClient) args.arg1; - IPrinterDiscoveryObserver observer = (IPrinterDiscoveryObserver) args.arg2; - args.recycle(); - if (client != null) { - try { - client.onStartPrinterDiscovery(observer); - } catch (RemoteException re) { - Log.e(LOG_TAG, "Error notifying start printer discovery.", re); - } - } - } break; - - case MSG_ON_STOP_PRINTER_DISCOVERY: { - IPrintSpoolerClient client = (IPrintSpoolerClient) message.obj; - if (client != null) { - try { - client.onStopPrinterDiscovery(); - } catch (RemoteException re) { - Log.e(LOG_TAG, "Error notifying stop printer discovery.", re); - } - } - } break; - - case MSG_ON_PRINT_JOB_QUEUED: { - SomeArgs args = (SomeArgs) message.obj; - IPrintSpoolerClient client = (IPrintSpoolerClient) args.arg1; - PrintJobInfo printJob = (PrintJobInfo) args.arg2; - args.recycle(); - if (client != null) { - try { - client.onPrintJobQueued(printJob); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error notify for a queued print job.", re); - } - } - } break; - - case MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED: { - SomeArgs args = (SomeArgs) message.obj; - IPrintSpoolerClient client = (IPrintSpoolerClient) args.arg1; - ComponentName service = (ComponentName) args.arg2; - args.recycle(); - if (client != null) { - try { - client.onAllPrintJobsForServiceHandled(service); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error notify for all print jobs per service" - + " handled.", re); - } - } - } break; - - case MSG_ON_ALL_PRINT_JOBS_HANDLED: { - final IPrintSpoolerClient client = (IPrintSpoolerClient) message.obj; - // This has to run on the tread that is persisting the current state - // since this call may result in the system unbinding from the spooler - // and as a result the spooler process may get killed before the write - // completes. - new AsyncTask() { - @Override - protected Void doInBackground(Void... params) { - try { - client.onAllPrintJobsHandled(); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error notify for all print job handled.", re); - } - return null; - } - }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null); - } break; - - case MSG_ON_REQUEST_UPDATE_PRINTERS: { - SomeArgs args = (SomeArgs) message.obj; - IPrintSpoolerClient client = (IPrintSpoolerClient) args.arg1; - List printerIds = (List) args.arg2; - args.recycle(); - try { - client.onRequestUpdatePrinters(printerIds); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error requesting to update pritners.", re); - } - } break; - } - } - } } diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java index 58853f7..e5153e7 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java +++ b/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java @@ -16,8 +16,6 @@ package com.android.printspooler; -import java.util.List; - import android.app.PendingIntent; import android.app.Service; import android.content.ComponentName; @@ -29,44 +27,48 @@ import android.os.Looper; import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.RemoteException; -import android.print.IPrintDocumentAdapter; import android.print.IPrintClient; -import android.print.IPrintSpoolerClient; +import android.print.IPrintDocumentAdapter; import android.print.IPrintSpooler; import android.print.IPrintSpoolerCallbacks; +import android.print.IPrintSpoolerClient; +import android.print.IPrinterDiscoveryObserver; import android.print.PrintAttributes; import android.print.PrintJobInfo; +import android.print.PrinterId; +import android.util.Log; import android.util.Slog; import com.android.internal.os.SomeArgs; +import java.util.List; + /** * Service for exposing some of the {@link PrintSpooler} functionality to * another process. */ public final class PrintSpoolerService extends Service { + private static final long CHECK_ALL_PRINTJOBS_HANDLED_DELAY = 5000; + private static final String LOG_TAG = "PrintSpoolerService"; private Intent mStartPrintJobConfigActivityIntent; - private PrintSpooler mSpooler; + private IPrintSpoolerClient mClient; - private Handler mHanlder; + private Handler mHandler; @Override public void onCreate() { super.onCreate(); mStartPrintJobConfigActivityIntent = new Intent(PrintSpoolerService.this, PrintJobConfigActivity.class); - mSpooler = PrintSpooler.getInstance(this); - mHanlder = new MyHandler(getMainLooper()); + mHandler = new MyHandler(getMainLooper()); } @Override public IBinder onBind(Intent intent) { - mSpooler.restorePersistedState(); - return new IPrintSpooler.Stub() { @Override public void getPrintJobInfos(IPrintSpoolerCallbacks callback, @@ -74,7 +76,8 @@ public final class PrintSpoolerService extends Service { throws RemoteException { List printJobs = null; try { - printJobs = mSpooler.getPrintJobInfos(componentName, state, appId); + printJobs = PrintSpooler.peekInstance().getPrintJobInfos( + componentName, state, appId); } finally { callback.onGetPrintJobInfosResult(printJobs, sequence); } @@ -85,7 +88,7 @@ public final class PrintSpoolerService extends Service { int appId, int sequence) throws RemoteException { PrintJobInfo printJob = null; try { - printJob = mSpooler.getPrintJobInfo(printJobId, appId); + printJob = PrintSpooler.peekInstance().getPrintJobInfo(printJobId, appId); } finally { callback.onGetPrintJobInfoResult(printJob, sequence); } @@ -99,7 +102,7 @@ public final class PrintSpoolerService extends Service { throws RemoteException { PrintJobInfo printJob = null; try { - printJob = mSpooler.createPrintJob(printJobName, client, + printJob = PrintSpooler.peekInstance().createPrintJob(printJobName, client, attributes, appId); if (printJob != null) { Intent intent = mStartPrintJobConfigActivityIntent; @@ -116,7 +119,8 @@ public final class PrintSpoolerService extends Service { SomeArgs args = SomeArgs.obtain(); args.arg1 = client; args.arg2 = sender; - mHanlder.obtainMessage(0, args).sendToTarget(); + mHandler.obtainMessage(MyHandler.MSG_START_PRINT_JOB_CONFIG_ACTIVITY, + args).sendToTarget(); } } finally { callback.onCreatePrintJobResult(printJob, sequence); @@ -128,7 +132,8 @@ public final class PrintSpoolerService extends Service { IPrintSpoolerCallbacks callback, int sequece) throws RemoteException { boolean success = false; try { - success = mSpooler.setPrintJobState(printJobId, state, error); + success = PrintSpooler.peekInstance().setPrintJobState( + printJobId, state, error); } finally { callback.onSetPrintJobStateResult(success, sequece); } @@ -136,11 +141,10 @@ public final class PrintSpoolerService extends Service { @Override public void setPrintJobTag(int printJobId, String tag, - IPrintSpoolerCallbacks callback, int sequece) - throws RemoteException { + IPrintSpoolerCallbacks callback, int sequece) throws RemoteException { boolean success = false; try { - success = mSpooler.setPrintJobTag(printJobId, tag); + success = PrintSpooler.peekInstance().setPrintJobTag(printJobId, tag); } finally { callback.onSetPrintJobTagResult(success, sequece); } @@ -148,37 +152,158 @@ public final class PrintSpoolerService extends Service { @Override public void writePrintJobData(ParcelFileDescriptor fd, int printJobId) { - mSpooler.writePrintJobData(fd, printJobId); - } - - @Override - public void setClient(IPrintSpoolerClient client) { - mSpooler.setCleint(client); + PrintSpooler.peekInstance().writePrintJobData(fd, printJobId); } @Override - public void notifyClientForActivteJobs() { - mSpooler.notifyClientForActivteJobs(); + public void setClient(IPrintSpoolerClient client) { + mHandler.obtainMessage(MyHandler.MSG_SET_CLIENT, client).sendToTarget(); } }; } - private static final class MyHandler extends Handler { + public void onPrintJobQueued(PrintJobInfo printJob) { + mHandler.obtainMessage(MyHandler.MSG_ON_PRINT_JOB_QUEUED, + printJob).sendToTarget(); + } + + public void onReqeustUpdatePrinters(List printers) { + mHandler.obtainMessage(MyHandler.MSG_ON_REQUEST_UPDATE_PRINTERS, + printers).sendToTarget(); + } + + public void startPrinterDiscovery(IPrinterDiscoveryObserver observer) { + mHandler.obtainMessage(MyHandler.MSG_ON_START_PRINTER_DISCOVERY, + observer).sendToTarget(); + } + + public void stopPrinterDiscovery() { + mHandler.sendEmptyMessage(MyHandler.MSG_ON_STOP_PRINTER_DISCOVERY); + } + + public void onAllPrintJobsForServiceHandled(ComponentName service) { + mHandler.obtainMessage(MyHandler.MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED, + service).sendToTarget(); + } + + public void onAllPrintJobsHandled() { + mHandler.sendEmptyMessage(MyHandler.MSG_ON_ALL_PRINT_JOBS_HANDLED); + } + + private final class MyHandler extends Handler { + public static final int MSG_SET_CLIENT = 1; + public static final int MSG_START_PRINT_JOB_CONFIG_ACTIVITY = 2; + public static final int MSG_ON_START_PRINTER_DISCOVERY = 3; + public static final int MSG_ON_STOP_PRINTER_DISCOVERY = 4; + public static final int MSG_ON_PRINT_JOB_QUEUED = 5; + public static final int MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED = 6; + public static final int MSG_ON_ALL_PRINT_JOBS_HANDLED = 7; + public static final int MSG_ON_REQUEST_UPDATE_PRINTERS = 8; + public static final int MSG_CHECK_ALL_PRINTJOBS_HANDLED = 9; public MyHandler(Looper looper) { - super(looper, null, true); + super(looper, null, false); } @Override + @SuppressWarnings("unchecked") public void handleMessage(Message message) { - SomeArgs args = (SomeArgs) message.obj; - IPrintClient client = (IPrintClient) args.arg1; - IntentSender sender = (IntentSender) args.arg2; - args.recycle(); - try { - client.startPrintJobConfigActivity(sender); - } catch (RemoteException re) { - Slog.i(LOG_TAG, "Error starting print job config activity!", re); + switch (message.what) { + case MSG_SET_CLIENT: { + mClient = (IPrintSpoolerClient) message.obj; + if (mClient != null) { + PrintSpooler.createInstance(PrintSpoolerService.this); + mHandler.sendEmptyMessageDelayed( + MyHandler.MSG_CHECK_ALL_PRINTJOBS_HANDLED, + CHECK_ALL_PRINTJOBS_HANDLED_DELAY); + } else { + PrintSpooler.destroyInstance(); + } + } break; + + case MSG_START_PRINT_JOB_CONFIG_ACTIVITY: { + SomeArgs args = (SomeArgs) message.obj; + IPrintClient client = (IPrintClient) args.arg1; + IntentSender sender = (IntentSender) args.arg2; + args.recycle(); + try { + client.startPrintJobConfigActivity(sender); + } catch (RemoteException re) { + Slog.i(LOG_TAG, "Error starting print job config activity!", re); + } + } break; + + case MSG_ON_START_PRINTER_DISCOVERY: { + IPrinterDiscoveryObserver observer = (IPrinterDiscoveryObserver) message.obj; + if (mClient != null) { + try { + mClient.onStartPrinterDiscovery(observer); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error notifying start printer discovery.", re); + } + } + } break; + + case MSG_ON_STOP_PRINTER_DISCOVERY: { + if (mClient != null) { + try { + mClient.onStopPrinterDiscovery(); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error notifying stop printer discovery.", re); + } + } + } break; + + case MSG_ON_PRINT_JOB_QUEUED: { + PrintJobInfo printJob = (PrintJobInfo) message.obj; + if (mClient != null) { + try { + mClient.onPrintJobQueued(printJob); + } catch (RemoteException re) { + Slog.e(LOG_TAG, "Error notify for a queued print job.", re); + } + } + } break; + + case MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED: { + ComponentName service = (ComponentName) message.obj; + if (mClient != null) { + try { + mClient.onAllPrintJobsForServiceHandled(service); + } catch (RemoteException re) { + Slog.e(LOG_TAG, "Error notify for all print jobs per service" + + " handled.", re); + } + } + } break; + + case MSG_ON_ALL_PRINT_JOBS_HANDLED: { + if (mClient != null) { + try { + mClient.onAllPrintJobsHandled(); + } catch (RemoteException re) { + Slog.e(LOG_TAG, "Error notify for all print job handled.", re); + } + } + } break; + + case MSG_ON_REQUEST_UPDATE_PRINTERS: { + List printerIds = (List) message.obj; + if (mClient != null) { + try { + mClient.onRequestUpdatePrinters(printerIds); + } catch (RemoteException re) { + Slog.e(LOG_TAG, "Error requesting to update pritners.", re); + } + } + } break; + + case MSG_CHECK_ALL_PRINTJOBS_HANDLED: { + PrintSpooler spooler = PrintSpooler.peekInstance(); + if (spooler != null) { + spooler.checkAllPrintJobsHandled(); + } + } break; } } } diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java index 1e8a5899..b881934 100644 --- a/services/java/com/android/server/NotificationManagerService.java +++ b/services/java/com/android/server/NotificationManagerService.java @@ -2047,29 +2047,39 @@ public class NotificationManagerService extends INotificationManager.Stub * Cancels a notification ONLY if it has all of the {@code mustHaveFlags} * and none of the {@code mustNotHaveFlags}. */ - private void cancelNotification(String pkg, String tag, int id, int mustHaveFlags, - int mustNotHaveFlags, boolean sendDelete, int userId) { - EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, tag, userId, - mustHaveFlags, mustNotHaveFlags); + private void cancelNotification(final String pkg, final String tag, final int id, + final int mustHaveFlags, final int mustNotHaveFlags, final boolean sendDelete, + final int userId) { + // In enqueueNotificationInternal notifications are added by scheduling the + // work on the worker handler. Hence, we also schedule the cancel on this + // handler to avoid a scenario where an add notification call followed by a + // remove notification call ends up in not removing the notification. + mHandler.post(new Runnable() { + @Override + public void run() { + EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, tag, userId, + mustHaveFlags, mustNotHaveFlags); - synchronized (mNotificationList) { - int index = indexOfNotificationLocked(pkg, tag, id, userId); - if (index >= 0) { - NotificationRecord r = mNotificationList.get(index); + synchronized (mNotificationList) { + int index = indexOfNotificationLocked(pkg, tag, id, userId); + if (index >= 0) { + NotificationRecord r = mNotificationList.get(index); - if ((r.getNotification().flags & mustHaveFlags) != mustHaveFlags) { - return; - } - if ((r.getNotification().flags & mustNotHaveFlags) != 0) { - return; - } + if ((r.getNotification().flags & mustHaveFlags) != mustHaveFlags) { + return; + } + if ((r.getNotification().flags & mustNotHaveFlags) != 0) { + return; + } - mNotificationList.remove(index); + mNotificationList.remove(index); - cancelNotificationLocked(r, sendDelete); - updateLightsLocked(); + cancelNotificationLocked(r, sendDelete); + updateLightsLocked(); + } + } } - } + }); } /** diff --git a/services/java/com/android/server/print/PrintManagerService.java b/services/java/com/android/server/print/PrintManagerService.java index 41399d8..8ee2fea 100644 --- a/services/java/com/android/server/print/PrintManagerService.java +++ b/services/java/com/android/server/print/PrintManagerService.java @@ -68,7 +68,7 @@ public final class PrintManagerService extends IPrintManager.Stub { synchronized (mLock) { UserState userState = getCurrentUserStateLocked(); userState.updateIfNeededLocked(); - userState.getSpoolerLocked().notifyClientForActivteJobs(); + userState.getSpoolerLocked().start(); } } }); @@ -144,7 +144,7 @@ public final class PrintManagerService extends IPrintManager.Stub { } final long identity = Binder.clearCallingIdentity(); try { - PrintJobInfo printJobInfo = getPrintJobInfo(printJobId, resolvedAppId, resolvedUserId); + PrintJobInfo printJobInfo = spooler.getPrintJobInfo(printJobId, resolvedAppId); if (printJobInfo == null) { return; } @@ -152,7 +152,7 @@ public final class PrintManagerService extends IPrintManager.Stub { ComponentName printServiceName = printJobInfo.getPrinterId().getServiceName(); RemotePrintService printService = null; synchronized (mLock) { - printService = userState.getActiveServices().get(printServiceName); + printService = userState.getActiveServicesLocked().get(printServiceName); } if (printService == null) { return; @@ -328,7 +328,7 @@ public final class PrintManagerService extends IPrintManager.Stub { mCurrentUserId = newUserId; UserState userState = getCurrentUserStateLocked(); userState.updateIfNeededLocked(); - userState.getSpoolerLocked().notifyClientForActivteJobs(); + userState.getSpoolerLocked().start(); } } diff --git a/services/java/com/android/server/print/RemotePrintService.java b/services/java/com/android/server/print/RemotePrintService.java index 5aa9952..28a7362 100644 --- a/services/java/com/android/server/print/RemotePrintService.java +++ b/services/java/com/android/server/print/RemotePrintService.java @@ -228,19 +228,19 @@ final class RemotePrintService implements DeathRecipient { printerIds).sendToTarget(); } - private void handleReqeustUpdatePritners(final List printerIds) { + private void handleReqeustUpdatePrinters(final List printerIds) { throwIfDestroyed(); if (!isBound()) { ensureBound(); mPendingCommands.add(new Runnable() { @Override public void run() { - handleReqeustUpdatePritners(printerIds); + handleReqeustUpdatePrinters(printerIds); } }); } else { if (DEBUG) { - Slog.i(LOG_TAG, "[user: " + mUserId + "] handleReqeustUpdatePritners()"); + Slog.i(LOG_TAG, "[user: " + mUserId + "] handleReqeustUpdatePrinters()"); } try { mPrintService.onRequestUpdatePrinters(printerIds); @@ -367,7 +367,7 @@ final class RemotePrintService implements DeathRecipient { case MSG_ON_REQUEST_UPDATE_PRINTERS: { List printerIds = (List) message.obj; - handleReqeustUpdatePritners(printerIds); + handleReqeustUpdatePrinters(printerIds); } break; case MSG_ON_STOP_PRINTER_DISCOVERY: { diff --git a/services/java/com/android/server/print/RemotePrintSpooler.java b/services/java/com/android/server/print/RemotePrintSpooler.java index 4e561bb..3a96a5b 100644 --- a/services/java/com/android/server/print/RemotePrintSpooler.java +++ b/services/java/com/android/server/print/RemotePrintSpooler.java @@ -116,9 +116,6 @@ final class RemotePrintSpooler { throwIfDestroyedLocked(); mCanUnbind = false; } - if (DEBUG) { - Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfos()"); - } try { return mGetPrintJobInfosCaller.getPrintJobInfos(getRemoteInstanceLazy(), componentName, state, appId); @@ -127,6 +124,9 @@ final class RemotePrintSpooler { } catch (TimeoutException te) { Slog.e(LOG_TAG, "Error getting print jobs.", te); } finally { + if (DEBUG) { + Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfos()"); + } synchronized (mLock) { mCanUnbind = true; mLock.notifyAll(); @@ -142,9 +142,6 @@ final class RemotePrintSpooler { throwIfDestroyedLocked(); mCanUnbind = false; } - if (DEBUG) { - Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] createPrintJob()"); - } try { return mCreatePrintJobCaller.createPrintJob(getRemoteInstanceLazy(), printJobName, client, documentAdapter, attributes, appId); @@ -153,6 +150,9 @@ final class RemotePrintSpooler { } catch (TimeoutException te) { Slog.e(LOG_TAG, "Error creating print job.", te); } finally { + if (DEBUG) { + Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] createPrintJob()"); + } synchronized (mLock) { mCanUnbind = true; mLock.notifyAll(); @@ -167,9 +167,6 @@ final class RemotePrintSpooler { throwIfDestroyedLocked(); mCanUnbind = false; } - if (DEBUG) { - Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] writePrintJobData()"); - } try { getRemoteInstanceLazy().writePrintJobData(fd, printJobId); } catch (RemoteException re) { @@ -177,6 +174,9 @@ final class RemotePrintSpooler { } catch (TimeoutException te) { Slog.e(LOG_TAG, "Error writing print job data.", te); } finally { + if (DEBUG) { + Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] writePrintJobData()"); + } // We passed the file descriptor across and now the other // side is responsible to close it, so close the local copy. IoUtils.closeQuietly(fd); @@ -193,9 +193,6 @@ final class RemotePrintSpooler { throwIfDestroyedLocked(); mCanUnbind = false; } - if (DEBUG) { - Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfo()"); - } try { return mGetPrintJobInfoCaller.getPrintJobInfo(getRemoteInstanceLazy(), printJobId, appId); @@ -204,6 +201,9 @@ final class RemotePrintSpooler { } catch (TimeoutException te) { Slog.e(LOG_TAG, "Error getting print job info.", te); } finally { + if (DEBUG) { + Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfo()"); + } synchronized (mLock) { mCanUnbind = true; mLock.notifyAll(); @@ -218,9 +218,6 @@ final class RemotePrintSpooler { throwIfDestroyedLocked(); mCanUnbind = false; } - if (DEBUG) { - Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobState()"); - } try { return mSetPrintJobStatusCaller.setPrintJobState(getRemoteInstanceLazy(), printJobId, state, error); @@ -229,6 +226,9 @@ final class RemotePrintSpooler { } catch (TimeoutException te) { Slog.e(LOG_TAG, "Error setting print job state.", te); } finally { + if (DEBUG) { + Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobState()"); + } synchronized (mLock) { mCanUnbind = true; mLock.notifyAll(); @@ -243,9 +243,6 @@ final class RemotePrintSpooler { throwIfDestroyedLocked(); mCanUnbind = false; } - if (DEBUG) { - Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobTag()"); - } try { return mSetPrintJobTagCaller.setPrintJobTag(getRemoteInstanceLazy(), printJobId, tag); @@ -254,6 +251,9 @@ final class RemotePrintSpooler { } catch (TimeoutException te) { Slog.e(LOG_TAG, "Error setting print job tag.", te); } finally { + if (DEBUG) { + Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobTag()"); + } synchronized (mLock) { mCanUnbind = true; mLock.notifyAll(); @@ -262,23 +262,20 @@ final class RemotePrintSpooler { return false; } - public final void notifyClientForActivteJobs() { + public final void start() { throwIfCalledOnMainThread(); synchronized (mLock) { throwIfDestroyedLocked(); mCanUnbind = false; } - if (DEBUG) { - Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() - + "] notifyClientForActivteJobs()"); - } try { - getRemoteInstanceLazy().notifyClientForActivteJobs(); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error asking for active print job notification.", re); + getRemoteInstanceLazy(); } catch (TimeoutException te) { - Slog.e(LOG_TAG, "Error asking for active print job notification.", te); + Slog.e(LOG_TAG, "Error starting the spooler.", te); } finally { + if (DEBUG) { + Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] start()"); + } synchronized (mLock) { mCanUnbind = true; mLock.notifyAll(); diff --git a/services/java/com/android/server/print/UserState.java b/services/java/com/android/server/print/UserState.java index c4fe124..00cc2ff 100644 --- a/services/java/com/android/server/print/UserState.java +++ b/services/java/com/android/server/print/UserState.java @@ -166,7 +166,7 @@ final class UserState implements PrintSpoolerCallbacks { return mSpooler; } - public Map getActiveServices() { + public Map getActiveServicesLocked() { synchronized(mLock) { throwIfDestroyedLocked(); return mActiveServices; -- cgit v1.1