Loading core/java/android/print/IPrintSpooler.aidl +0 −1 Original line number Diff line number Diff line Loading @@ -46,5 +46,4 @@ oneway interface IPrintSpooler { int sequence); void writePrintJobData(in ParcelFileDescriptor fd, int printJobId); void setClient(IPrintSpoolerClient client); void notifyClientForActivteJobs(); } packages/PrintSpooler/src/com/android/printspooler/NotificationController.java +90 −69 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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: { Loading Loading @@ -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()); } Loading @@ -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()); } Loading @@ -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()); } Loading @@ -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); } Loading @@ -156,44 +162,48 @@ 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()); 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<Void, Void, Void>() { @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 Loading @@ -201,15 +211,19 @@ public class NotificationController { // 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)); try { 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) { Loading @@ -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; } // 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<Void, Void, Void>() { @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)); try { 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); } } } packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java +1 −1 Original line number Diff line number Diff line Loading @@ -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( Loading packages/PrintSpooler/src/com/android/printspooler/PrintSpooler.java +85 −265 File changed.Preview size limit exceeded, changes collapsed. Show changes packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java +161 −36 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package com.android.printspooler; import java.util.List; import android.app.PendingIntent; import android.app.Service; import android.content.ComponentName; Loading @@ -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, Loading @@ -74,7 +76,8 @@ public final class PrintSpoolerService extends Service { throws RemoteException { List<PrintJobInfo> printJobs = null; try { printJobs = mSpooler.getPrintJobInfos(componentName, state, appId); printJobs = PrintSpooler.peekInstance().getPrintJobInfos( componentName, state, appId); } finally { callback.onGetPrintJobInfosResult(printJobs, sequence); } Loading @@ -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); } Loading @@ -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; Loading @@ -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); Loading @@ -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); } Loading @@ -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); } Loading @@ -148,29 +152,76 @@ 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); mHandler.obtainMessage(MyHandler.MSG_SET_CLIENT, client).sendToTarget(); } }; } @Override public void notifyClientForActivteJobs() { mSpooler.notifyClientForActivteJobs(); public void onPrintJobQueued(PrintJobInfo printJob) { mHandler.obtainMessage(MyHandler.MSG_ON_PRINT_JOB_QUEUED, printJob).sendToTarget(); } }; public void onReqeustUpdatePrinters(List<PrinterId> 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(); } private static final class MyHandler extends Handler { 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) { 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; Loading @@ -180,6 +231,80 @@ public final class PrintSpoolerService extends Service { } 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<PrinterId> printerIds = (List<PrinterId>) 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; } } } } Loading
core/java/android/print/IPrintSpooler.aidl +0 −1 Original line number Diff line number Diff line Loading @@ -46,5 +46,4 @@ oneway interface IPrintSpooler { int sequence); void writePrintJobData(in ParcelFileDescriptor fd, int printJobId); void setClient(IPrintSpoolerClient client); void notifyClientForActivteJobs(); }
packages/PrintSpooler/src/com/android/printspooler/NotificationController.java +90 −69 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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: { Loading Loading @@ -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()); } Loading @@ -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()); } Loading @@ -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()); } Loading @@ -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); } Loading @@ -156,44 +162,48 @@ 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()); 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<Void, Void, Void>() { @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 Loading @@ -201,15 +211,19 @@ public class NotificationController { // 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)); try { 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) { Loading @@ -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; } // 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<Void, Void, Void>() { @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)); try { 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); } } }
packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java +1 −1 Original line number Diff line number Diff line Loading @@ -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( Loading
packages/PrintSpooler/src/com/android/printspooler/PrintSpooler.java +85 −265 File changed.Preview size limit exceeded, changes collapsed. Show changes
packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java +161 −36 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package com.android.printspooler; import java.util.List; import android.app.PendingIntent; import android.app.Service; import android.content.ComponentName; Loading @@ -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, Loading @@ -74,7 +76,8 @@ public final class PrintSpoolerService extends Service { throws RemoteException { List<PrintJobInfo> printJobs = null; try { printJobs = mSpooler.getPrintJobInfos(componentName, state, appId); printJobs = PrintSpooler.peekInstance().getPrintJobInfos( componentName, state, appId); } finally { callback.onGetPrintJobInfosResult(printJobs, sequence); } Loading @@ -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); } Loading @@ -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; Loading @@ -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); Loading @@ -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); } Loading @@ -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); } Loading @@ -148,29 +152,76 @@ 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); mHandler.obtainMessage(MyHandler.MSG_SET_CLIENT, client).sendToTarget(); } }; } @Override public void notifyClientForActivteJobs() { mSpooler.notifyClientForActivteJobs(); public void onPrintJobQueued(PrintJobInfo printJob) { mHandler.obtainMessage(MyHandler.MSG_ON_PRINT_JOB_QUEUED, printJob).sendToTarget(); } }; public void onReqeustUpdatePrinters(List<PrinterId> 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(); } private static final class MyHandler extends Handler { 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) { 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; Loading @@ -180,6 +231,80 @@ public final class PrintSpoolerService extends Service { } 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<PrinterId> printerIds = (List<PrinterId>) 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; } } } }