summaryrefslogtreecommitdiffstats
path: root/packages/PrintSpooler/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/PrintSpooler/src')
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/NotificationController.java159
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java2
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/PrintSpooler.java350
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java197
4 files changed, 337 insertions, 371 deletions
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<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
+ // 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<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));
+ 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<PrinterId> 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<PrintJobInfo> getPrintJobInfos(ComponentName componentName, int state, int appId) {
+ public List<PrintJobInfo> getPrintJobInfos(ComponentName componentName,
+ int state, int appId) {
List<PrintJobInfo> foundPrintJobs = null;
synchronized (mLock) {
final int printJobCount = mPrintJobs.size();
@@ -207,79 +169,48 @@ public class PrintSpooler {
}
}
- public void notifyClientForActivteJobs() {
- IPrintSpoolerClient client = null;
- Map<ComponentName, List<PrintJobInfo>> activeJobsPerServiceMap =
- new HashMap<ComponentName, List<PrintJobInfo>>();
+ 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<PrintJobInfo> jobsPerService = activeJobsPerServiceMap.get(service);
- if (jobsPerService == null) {
- jobsPerService = new ArrayList<PrintJobInfo>();
- 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<ComponentName, List<PrintJobInfo>> entry
- : activeJobsPerServiceMap.entrySet()) {
- ComponentName service = entry.getKey();
- List<PrintJobInfo> 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<PrinterId> 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<Void, Void, Void>() {
+ @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<Void, Void, Void>() {
- @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<PrinterId> printerIds = (List<PrinterId>) 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<PrintJobInfo> 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<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();
+ }
+
+ 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<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;
}
}
}