Merge "Polish the print spooler loading of stored print jobs."
This commit is contained in:
committed by
Android (Google) Code Review
commit
7bb1be4ba9
@ -46,5 +46,4 @@ oneway interface IPrintSpooler {
|
||||
int sequence);
|
||||
void writePrintJobData(in ParcelFileDescriptor fd, int printJobId);
|
||||
void setClient(IPrintSpoolerClient client);
|
||||
void notifyClientForActivteJobs();
|
||||
}
|
||||
|
@ -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<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);
|
||||
// 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<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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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<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 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<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);
|
||||
|
||||
// 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<PrintJobInfo> jobsPerService = activeJobsPerServiceMap.get(service);
|
||||
if (jobsPerService == null) {
|
||||
jobsPerService = new ArrayList<PrintJobInfo>();
|
||||
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<ComponentName, List<PrintJobInfo>> entry
|
||||
: activeJobsPerServiceMap.entrySet()) {
|
||||
ComponentName service = entry.getKey();
|
||||
List<PrintJobInfo> 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<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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
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<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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,19 +228,19 @@ final class RemotePrintService implements DeathRecipient {
|
||||
printerIds).sendToTarget();
|
||||
}
|
||||
|
||||
private void handleReqeustUpdatePritners(final List<PrinterId> printerIds) {
|
||||
private void handleReqeustUpdatePrinters(final List<PrinterId> 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<PrinterId> printerIds = (List<PrinterId>) message.obj;
|
||||
handleReqeustUpdatePritners(printerIds);
|
||||
handleReqeustUpdatePrinters(printerIds);
|
||||
} break;
|
||||
|
||||
case MSG_ON_STOP_PRINTER_DISCOVERY: {
|
||||
|
@ -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();
|
||||
|
@ -166,7 +166,7 @@ final class UserState implements PrintSpoolerCallbacks {
|
||||
return mSpooler;
|
||||
}
|
||||
|
||||
public Map<ComponentName, RemotePrintService> getActiveServices() {
|
||||
public Map<ComponentName, RemotePrintService> getActiveServicesLocked() {
|
||||
synchronized(mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
return mActiveServices;
|
||||
|
Reference in New Issue
Block a user