diff options
Diffstat (limited to 'packages/PrintSpooler/src')
3 files changed, 151 insertions, 101 deletions
diff --git a/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java b/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java index 14a96c9..8b49c0e 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java +++ b/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java @@ -65,10 +65,6 @@ public class NotificationController { } switch (printJob.getState()) { case PrintJobInfo.STATE_QUEUED: { - createQueuingNotificaiton(printJob); - } break; - - case PrintJobInfo.STATE_STARTED: { createPrintingNotificaiton(printJob); } break; @@ -83,22 +79,6 @@ public class NotificationController { } } - private void createQueuingNotificaiton(PrintJobInfo printJob) { - Notification.Builder builder = new Notification.Builder(mContext) - // TODO: Use appropriate icon when assets are ready - .setSmallIcon(android.R.drawable.ic_secure) - .setContentTitle(mContext.getString(R.string.queued_notification_title_template, - printJob.getLabel())) - // TODO: Use appropriate icon when assets are ready - .addAction(android.R.drawable.ic_secure, mContext.getString(R.string.cancel), - createCancelIntent(printJob)) - .setContentText(printJob.getPrinterId().getPrinterName()) - .setWhen(System.currentTimeMillis()) - .setOngoing(true) - .setShowWhen(true); - mNotificationManager.notify(printJob.getId(), builder.build()); - } - private void createPrintingNotificaiton(PrintJobInfo printJob) { Notification.Builder builder = new Notification.Builder(mContext) // TODO: Use appropriate icon when assets are ready diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java index 15c2b2f..00a76b8 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java @@ -17,7 +17,11 @@ package com.android.printspooler; import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.DialogFragment; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; @@ -66,6 +70,7 @@ import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; @@ -137,6 +142,8 @@ public class PrintJobConfigActivity extends Activity { private IBinder mIPrintDocumentAdapter; + private Dialog mGeneratingPrintJobDialog; + @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); @@ -167,17 +174,14 @@ public class PrintJobConfigActivity extends Activity { mController = new PrintController(new RemotePrintDocumentAdapter( IPrintDocumentAdapter.Stub.asInterface(mIPrintDocumentAdapter), mSpooler.generateFileForPrintJob(mPrintJobId))); - } - @Override - protected void onResume() { - super.onResume(); try { mIPrintDocumentAdapter.linkToDeath(mDeathRecipient, 0); } catch (RemoteException re) { finish(); return; } + mController.initialize(); mEditor.initialize(); mPrinterDiscoveryObserver = new PrinterDiscoveryObserver(mEditor, getMainLooper()); @@ -185,27 +189,29 @@ public class PrintJobConfigActivity extends Activity { } @Override - protected void onPause() { + protected void onDestroy() { + // We can safely do the work in here since at this point + // the system is bound to our (spooler) process which + // guarantees that this process will not be killed. mSpooler.stopPrinterDiscovery(); mPrinterDiscoveryObserver.destroy(); mPrinterDiscoveryObserver = null; - if (mController.isCancelled() || mController.isFailed()) { + if (mController.hasStarted()) { + mController.finish(); + } + if (mEditor.isPrintConfirmed() && mController.isFinished()) { + mSpooler.setPrintJobState(mPrintJobId, + PrintJobInfo.STATE_QUEUED, null); + } else { mSpooler.setPrintJobState(mPrintJobId, PrintJobInfo.STATE_CANCELED, null); - } else if (mController.hasStarted()) { - mController.finish(); - if (mEditor.isPrintConfirmed()) { - if (mController.isFinished()) { - mSpooler.setPrintJobState(mPrintJobId, - PrintJobInfo.STATE_QUEUED, null); - } else { - mSpooler.setPrintJobState(mPrintJobId, - PrintJobInfo.STATE_CANCELED, null); - } - } } mIPrintDocumentAdapter.unlinkToDeath(mDeathRecipient, 0); - super.onPause(); + if (mGeneratingPrintJobDialog != null) { + mGeneratingPrintJobDialog.dismiss(); + mGeneratingPrintJobDialog = null; + } + super.onDestroy(); } public boolean onTouchEvent(MotionEvent event) { @@ -243,56 +249,54 @@ public class PrintJobConfigActivity extends Activity { return !mOldPrintAttributes.equals(mCurrPrintAttributes); } + private void showGeneratingPrintJobUi() { + getWindow().getDecorView().setVisibility(View.GONE); + + DialogFragment fragment = new DialogFragment() { + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + return new AlertDialog.Builder(PrintJobConfigActivity.this) + .setTitle(getString(R.string.generating_print_job)) + .setView(PrintJobConfigActivity.this.getLayoutInflater().inflate( + R.layout.generating_print_job_dialog, null)) + .setCancelable(false) + .setPositiveButton(getString(R.string.cancel), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + mEditor.cancel(); + PrintJobConfigActivity.this.finish(); + } + }) + .create(); + } + }; + fragment.show(getFragmentManager(), getString(R.string.generating_print_job)); + } + private class PrintController { private final AtomicInteger mRequestCounter = new AtomicInteger(); private final RemotePrintDocumentAdapter mRemotePrintAdapter; - private final Handler mHandler; + private final Bundle mMetadata; - private int mControllerState = CONTROLLER_STATE_INITIALIZED; + private final ControllerHandler mHandler; - private PageRange[] mRequestedPages; - - private Bundle mMetadata = new Bundle(); + private final LayoutResultCallback mLayoutResultCallback; - private final ILayoutResultCallback mILayoutResultCallback = - new ILayoutResultCallback.Stub() { - @Override - public void onLayoutFinished(PrintDocumentInfo info, boolean changed, int sequence) { - if (mRequestCounter.get() == sequence) { - mHandler.obtainMessage(MyHandler.MSG_ON_LAYOUT_FINISHED, changed ? 1 : 0, - 0, info).sendToTarget(); - } - } - - @Override - public void onLayoutFailed(CharSequence error, int sequence) { - if (mRequestCounter.get() == sequence) { - mHandler.obtainMessage(MyHandler.MSG_ON_LAYOUT_FAILED, error).sendToTarget(); - } - } - }; + private final WriteResultCallback mWriteResultCallback; - private IWriteResultCallback mIWriteResultCallback = new IWriteResultCallback.Stub() { - @Override - public void onWriteFinished(PageRange[] pages, int sequence) { - if (mRequestCounter.get() == sequence) { - mHandler.obtainMessage(MyHandler.MSG_ON_WRITE_FINISHED, pages).sendToTarget(); - } - } + private int mControllerState = CONTROLLER_STATE_INITIALIZED; - @Override - public void onWriteFailed(CharSequence error, int sequence) { - if (mRequestCounter.get() == sequence) { - mHandler.obtainMessage(MyHandler.MSG_ON_WRITE_FAILED, error).sendToTarget(); - } - } - }; + private PageRange[] mRequestedPages; public PrintController(RemotePrintDocumentAdapter adapter) { mRemotePrintAdapter = adapter; - mHandler = new MyHandler(Looper.getMainLooper()); + mMetadata = new Bundle(); + mHandler = new ControllerHandler(getMainLooper()); + mLayoutResultCallback = new LayoutResultCallback(mHandler); + mWriteResultCallback = new WriteResultCallback(mHandler); } public void initialize() { @@ -311,10 +315,6 @@ public class PrintJobConfigActivity extends Activity { return (mControllerState == CONTROLLER_STATE_FINISHED); } - public boolean isFailed() { - return (mControllerState == CONTROLLER_STATE_FAILED); - } - public boolean hasStarted() { return mControllerState >= CONTROLLER_STATE_STARTED; } @@ -338,7 +338,7 @@ public class PrintJobConfigActivity extends Activity { // If the attributes changes, then we do not do a layout but may // have to ask the app to write some pages. Hence, pretend layout // completed and nothing changed, so we handle writing as usual. - handleOnLayoutFinished(mDocument.info, false); + handleOnLayoutFinished(mDocument.info, false, mRequestCounter.get()); } else { mSpooler.setPrintJobAttributesNoPersistence(mPrintJobId, mCurrPrintAttributes); @@ -348,7 +348,7 @@ public class PrintJobConfigActivity extends Activity { mControllerState = CONTROLLER_STATE_LAYOUT_STARTED; mRemotePrintAdapter.layout(mOldPrintAttributes, mCurrPrintAttributes, - mILayoutResultCallback, mMetadata, mRequestCounter.incrementAndGet()); + mLayoutResultCallback, mMetadata, mRequestCounter.incrementAndGet()); mOldPrintAttributes.copyFrom(mCurrPrintAttributes); } @@ -359,7 +359,12 @@ public class PrintJobConfigActivity extends Activity { mRemotePrintAdapter.finish(); } - private void handleOnLayoutFinished(PrintDocumentInfo info, boolean layoutChanged) { + private void handleOnLayoutFinished(PrintDocumentInfo info, + boolean layoutChanged, int sequence) { + if (mRequestCounter.get() != sequence) { + return; + } + if (isCancelled()) { if (mEditor.isDone()) { PrintJobConfigActivity.this.finish(); @@ -421,18 +426,25 @@ public class PrintJobConfigActivity extends Activity { // Request a write of the pages of interest. mControllerState = CONTROLLER_STATE_WRITE_STARTED; - mRemotePrintAdapter.write(mRequestedPages, mIWriteResultCallback, + mRemotePrintAdapter.write(mRequestedPages, mWriteResultCallback, mRequestCounter.incrementAndGet()); } - private void handleOnLayoutFailed(CharSequence error) { + private void handleOnLayoutFailed(CharSequence error, int sequence) { + if (mRequestCounter.get() != sequence) { + return; + } mControllerState = CONTROLLER_STATE_FAILED; // TODO: We need some UI for announcing an error. Log.e(LOG_TAG, "Error during layout: " + error); PrintJobConfigActivity.this.finish(); } - private void handleOnWriteFinished(PageRange[] pages) { + private void handleOnWriteFinished(PageRange[] pages, int sequence) { + if (mRequestCounter.get() != sequence) { + return; + } + if (isCancelled()) { if (mEditor.isDone()) { PrintJobConfigActivity.this.finish(); @@ -490,19 +502,22 @@ public class PrintJobConfigActivity extends Activity { } } - private void handleOnWriteFailed(CharSequence error) { + private void handleOnWriteFailed(CharSequence error, int sequence) { + if (mRequestCounter.get() != sequence) { + return; + } mControllerState = CONTROLLER_STATE_FAILED; Log.e(LOG_TAG, "Error during write: " + error); PrintJobConfigActivity.this.finish(); } - private final class MyHandler extends Handler { + private final class ControllerHandler extends Handler { public static final int MSG_ON_LAYOUT_FINISHED = 1; public static final int MSG_ON_LAYOUT_FAILED = 2; public static final int MSG_ON_WRITE_FINISHED = 3; public static final int MSG_ON_WRITE_FAILED = 4; - public MyHandler(Looper looper) { + public ControllerHandler(Looper looper) { super(looper, null, false); } @@ -512,28 +527,84 @@ public class PrintJobConfigActivity extends Activity { case MSG_ON_LAYOUT_FINISHED: { PrintDocumentInfo info = (PrintDocumentInfo) message.obj; final boolean changed = (message.arg1 == 1); - mController.handleOnLayoutFinished(info, changed); + final int sequence = message.arg2; + handleOnLayoutFinished(info, changed, sequence); } break; case MSG_ON_LAYOUT_FAILED: { CharSequence error = (CharSequence) message.obj; - mController.handleOnLayoutFailed(error); + final int sequence = message.arg1; + handleOnLayoutFailed(error, sequence); } break; case MSG_ON_WRITE_FINISHED: { PageRange[] pages = (PageRange[]) message.obj; - mController.handleOnWriteFinished(pages); + final int sequence = message.arg1; + handleOnWriteFinished(pages, sequence); } break; case MSG_ON_WRITE_FAILED: { CharSequence error = (CharSequence) message.obj; - mController.handleOnWriteFailed(error); + final int sequence = message.arg1; + handleOnWriteFailed(error, sequence); } break; } } } } + private static final class LayoutResultCallback extends ILayoutResultCallback.Stub { + private final WeakReference<PrintController.ControllerHandler> mWeakHandler; + + public LayoutResultCallback(PrintController.ControllerHandler handler) { + mWeakHandler = new WeakReference<PrintController.ControllerHandler>(handler); + } + + @Override + public void onLayoutFinished(PrintDocumentInfo info, boolean changed, int sequence) { + Handler handler = mWeakHandler.get(); + if (handler != null) { + handler.obtainMessage(PrintController.ControllerHandler.MSG_ON_LAYOUT_FINISHED, + changed ? 1 : 0, sequence, info).sendToTarget(); + } + } + + @Override + public void onLayoutFailed(CharSequence error, int sequence) { + Handler handler = mWeakHandler.get(); + if (handler != null) { + handler.obtainMessage(PrintController.ControllerHandler.MSG_ON_LAYOUT_FAILED, + sequence, 0, error).sendToTarget(); + } + } + } + + private static final class WriteResultCallback extends IWriteResultCallback.Stub { + private final WeakReference<PrintController.ControllerHandler> mWeakHandler; + + public WriteResultCallback(PrintController.ControllerHandler handler) { + mWeakHandler = new WeakReference<PrintController.ControllerHandler>(handler); + } + + @Override + public void onWriteFinished(PageRange[] pages, int sequence) { + Handler handler = mWeakHandler.get(); + if (handler != null) { + handler.obtainMessage(PrintController.ControllerHandler.MSG_ON_WRITE_FINISHED, + sequence, 0, pages).sendToTarget(); + } + } + + @Override + public void onWriteFailed(CharSequence error, int sequence) { + Handler handler = mWeakHandler.get(); + if (handler != null) { + handler.obtainMessage(PrintController.ControllerHandler.MSG_ON_WRITE_FAILED, + sequence, 0, error).sendToTarget(); + } + } + } + private final class Editor { private final EditText mCopiesEditText; @@ -837,6 +908,7 @@ public class PrintJobConfigActivity extends Activity { mEditor.confirmPrint(); updateUi(); mController.update(); + showGeneratingPrintJobUi(); } }); diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintSpooler.java b/packages/PrintSpooler/src/com/android/printspooler/PrintSpooler.java index 0bc20a3..00e05bb 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/PrintSpooler.java +++ b/packages/PrintSpooler/src/com/android/printspooler/PrintSpooler.java @@ -177,17 +177,15 @@ public class PrintSpooler { // 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_QUEUED: case PrintJobInfo.STATE_STARTED: { - // We really want to restart this print job. - setPrintJobState(printJob.getId(), PrintJobInfo.STATE_QUEUED, null); + // We have a print job that was queued or started in the past + // but the device battery died or a crash occurred. In this case + // we assume the print job failed and let the user decide whether + // to restart the job or just + setPrintJobState(printJob.getId(), PrintJobInfo.STATE_FAILED, + mService.getString(R.string.no_connection_to_printer)); } break; } } |