diff --git a/core/java/android/print/IPrintSpooler.aidl b/core/java/android/print/IPrintSpooler.aidl index 428f9722ec648..81781801d0db9 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 e4de4b85273bf..14a96c946182e 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(printJobId, builder.build()); - notificationManager.notify(printJob.getId(), 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(); - // 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); - } + 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); + // 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(); - 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); - } + 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 484c8a96f3d1e..4a19558336102 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 fabd68f9683b8..0bc20a3f2f2c3 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) { + sInstance = null; + } + } + + public static void createInstance(PrintSpoolerService service) { + synchronized (sLock) { + sInstance = new PrintSpooler(service); + } + } + + public static PrintSpooler peekInstance() { 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() { + private PrintSpooler(PrintSpoolerService service) { + mService = service; + mPersistanceManager = new PersistenceManager(service); + mNotificationController = new NotificationController(service); synchronized (mLock) { mPersistanceManager.readStateLocked(); + handleReadPrintJobsLocked(); } } - 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 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 void stopPrinterDiscovery() { - synchronized (mLock) { - mHandler.obtainMessage(MyHandler.MSG_ON_STOP_PRINTER_DISCOVERY, - mClient).sendToTarget(); - } - } - - 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); + // Update the notification. + mNotificationController.onPrintJobStateChanged(printJob); + + //TODO: Figure out what the right policy for read print jobs is. + + switch (printJob.getState()) { + case PrintJobInfo.STATE_QUEUED: { + // Notify that we have a queued job. + mService.onPrintJobQueued(new PrintJobInfo(printJob)); + } break; + + case PrintJobInfo.STATE_STARTED: { + // We really want to restart this print job. + setPrintJobState(printJob.getId(), PrintJobInfo.STATE_QUEUED, null); + } break; + } + } + } + + public void checkAllPrintJobsHandled() { synchronized (mLock) { - if (mClient == null) { - throw new IllegalStateException("Client cannot be null."); - } - client = mClient; - - 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; - - 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; - - default: { - ComponentName service = printJob.getPrinterId().getServiceName(); - if (!activeJobsPerServiceMap.containsKey(service)) { - activeJobsPerServiceMap.put(service, null); - } - } - } + if (!hasActivePrintJobsLocked()) { + notifyOnAllPrintJobsHandled(); } } + } - boolean allPrintJobsHandled = true; + public void startPrinterDiscovery(IPrinterDiscoveryObserver observer) { + mService.startPrinterDiscovery(observer); + } - for (Map.Entry> entry - : activeJobsPerServiceMap.entrySet()) { - ComponentName service = entry.getKey(); - List printJobs = entry.getValue(); + public void stopPrinterDiscovery() { + mService.stopPrinterDiscovery(); + } - 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(); - } - } - - if (allPrintJobsHandled) { - mHandler.obtainMessage(MyHandler.MSG_ON_ALL_PRINT_JOBS_HANDLED, - client).sendToTarget(); - } + 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 58853f79867e3..e5153e759263a 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); + PrintSpooler.peekInstance().writePrintJobData(fd, printJobId); } @Override - public void setClient(IPrintSpoolerClient client) { - mSpooler.setCleint(client); - } - - @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 1e8a589992d1c..b881934879d61 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 & mustHaveFlags) != mustHaveFlags) { + return; + } + if ((r.getNotification().flags & mustNotHaveFlags) != 0) { + return; + } + + mNotificationList.remove(index); + + cancelNotificationLocked(r, sendDelete); + updateLightsLocked(); + } } - if ((r.getNotification().flags & mustNotHaveFlags) != 0) { - return; - } - - mNotificationList.remove(index); - - 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 41399d874d38d..8ee2fea27a13b 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 5aa9952bd5365..28a7362bc6cd0 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 4e561bb2b42f2..3a96a5bc74f22 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 c4fe124adbfee..00cc2ffca0e0e 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;