diff options
Diffstat (limited to 'packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java')
-rw-r--r-- | packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java | 480 |
1 files changed, 56 insertions, 424 deletions
diff --git a/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java index 25bb37c..4006a5a 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java +++ b/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java @@ -17,8 +17,8 @@ package com.android.printspooler; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; -import android.os.ICancellationSignal; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.print.ILayoutResultCallback; @@ -26,11 +26,7 @@ import android.print.IPrintDocumentAdapter; import android.print.IWriteResultCallback; import android.print.PageRange; import android.print.PrintAttributes; -import android.print.PrintDocumentAdapter.LayoutResultCallback; -import android.print.PrintDocumentAdapter.WriteResultCallback; -import android.print.PrintDocumentInfo; import android.util.Log; -import android.util.Slog; import libcore.io.IoUtils; @@ -40,8 +36,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; /** * This class represents a remote print document adapter instance. @@ -49,461 +43,99 @@ import java.util.List; final class RemotePrintDocumentAdapter { private static final String LOG_TAG = "RemotePrintDocumentAdapter"; - private static final boolean DEBUG = true; - - public static final int STATE_INITIALIZED = 0; - public static final int STATE_START_COMPLETED = 1; - public static final int STATE_LAYOUT_STARTED = 2; - public static final int STATE_LAYOUT_COMPLETED = 3; - public static final int STATE_WRITE_STARTED = 4; - public static final int STATE_WRITE_COMPLETED = 5; - public static final int STATE_FINISH_COMPLETED = 6; - public static final int STATE_FAILED = 7; - - private final Object mLock = new Object(); - - private final List<QueuedAsyncTask> mTaskQueue = new ArrayList<QueuedAsyncTask>(); + private static final boolean DEBUG = true && Build.IS_DEBUGGABLE; private final IPrintDocumentAdapter mRemoteInterface; private final File mFile; - private int mState = STATE_INITIALIZED; - public RemotePrintDocumentAdapter(IPrintDocumentAdapter printAdatper, File file) { mRemoteInterface = printAdatper; mFile = file; } - public File getFile() { + public void start() { if (DEBUG) { - Log.i(LOG_TAG, "getFile()"); + Log.i(LOG_TAG, "start()"); } - synchronized (mLock) { - if (mState != STATE_WRITE_COMPLETED - && mState != STATE_FINISH_COMPLETED) { - throw new IllegalStateException("Write not completed"); - } - return mFile; + try { + mRemoteInterface.start(); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error calling start()", re); } } - public void start() { - QueuedAsyncTask task = new QueuedAsyncTask() { - @Override - protected Void doInBackground(Void... params) { - if (DEBUG) { - Log.i(LOG_TAG, "start()"); - } - synchronized (mLock) { - if (mState != STATE_INITIALIZED) { - throw new IllegalStateException("Invalid state: " + mState); - } - } - try { - mRemoteInterface.start(); - synchronized (mLock) { - mState = STATE_START_COMPLETED; - } - } catch (RemoteException re) { - Log.e(LOG_TAG, "Error reading file", re); - } - return null; - } - - @Override - public void cancel() { - /* cannot be cancelled */ - } - }; - synchronized (mLock) { - mTaskQueue.add(task); - } - task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null); - } - public void layout(PrintAttributes oldAttributes, PrintAttributes newAttributes, - LayoutResultCallback callback, Bundle metadata) { - LayoutAsyncTask task = new LayoutAsyncTask(oldAttributes, newAttributes, callback, - metadata); - synchronized (mLock) { - mTaskQueue.add(task); + ILayoutResultCallback callback, Bundle metadata, int sequence) { + if (DEBUG) { + Log.i(LOG_TAG, "layout()"); } - task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null); - } - - public void write(List<PageRange> pages, WriteResultCallback callback) { - WriteAsyncTask task = new WriteAsyncTask(pages, callback); - synchronized (mLock) { - mTaskQueue.add(task); + try { + mRemoteInterface.layout(oldAttributes, newAttributes, callback, metadata, sequence); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error calling layout()", re); } - task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null); } - public void cancel() { - synchronized (mLock) { - final int taskCount = mTaskQueue.size(); - for (int i = taskCount - 1; i >= 0; i--) { - mTaskQueue.remove(i).cancel(); - } + public void write(final PageRange[] pages, final IWriteResultCallback callback, + final int sequence) { + if (DEBUG) { + Log.i(LOG_TAG, "write()"); } - } - - public void finish() { - QueuedAsyncTask task = new QueuedAsyncTask() { + new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { - if (DEBUG) { - Log.i(LOG_TAG, "finish()"); - } - synchronized (mLock) { - if (mState < STATE_START_COMPLETED) { - return null; - } - } + InputStream in = null; + OutputStream out = null; + ParcelFileDescriptor source = null; + ParcelFileDescriptor sink = null; try { - mRemoteInterface.finish(); - synchronized (mLock) { - mState = STATE_FINISH_COMPLETED; - } - } catch (RemoteException re) { - Log.e(LOG_TAG, "Error reading file", re); - mState = STATE_FAILED; - } - return null; - } - - @Override - public void cancel() { - /* cannot be cancelled */ - } - }; - synchronized (mLock) { - mTaskQueue.add(task); - } - task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null); - } - - private abstract class QueuedAsyncTask extends AsyncTask<Void, Void, Void> { - public void cancel() { - super.cancel(true); - } - } - - private final class LayoutAsyncTask extends QueuedAsyncTask { - - private final PrintAttributes mOldAttributes; - - private final PrintAttributes mNewAttributes; - - private final LayoutResultCallback mCallback; - - private final Bundle mMetadata; - - private final ILayoutResultCallback mILayoutResultCallback = - new ILayoutResultCallback.Stub() { - @Override - public void onLayoutStarted(ICancellationSignal cancellationSignal) { - if (DEBUG) { - Log.i(LOG_TAG, "onLayoutStarted()"); - } - synchronized (mLock) { - mCancellationSignal = cancellationSignal; - if (isCancelled()) { - cancelSignalQuietlyLocked(); - } - } - } - - @Override - public void onLayoutFinished(PrintDocumentInfo info, boolean changed) { - if (DEBUG) { - Log.i(LOG_TAG, "onLayoutFinished()"); - } - final boolean cancelled; - synchronized (mLock) { - cancelled = isCancelled(); - mCancellationSignal = null; - mState = STATE_LAYOUT_COMPLETED; - mTaskQueue.remove(this); - mLock.notifyAll(); - } - if (!cancelled) { - mCallback.onLayoutFinished(info, changed); - } - } - - @Override - public void onLayoutFailed(CharSequence error) { - if (DEBUG) { - Log.i(LOG_TAG, "onLayoutFailed()"); - } - final boolean cancelled; - synchronized (mLock) { - cancelled = isCancelled(); - mCancellationSignal = null; - mState = STATE_LAYOUT_COMPLETED; - mTaskQueue.remove(this); - mLock.notifyAll(); - } - if (!cancelled) { - mCallback.onLayoutFailed(error); - } - } - }; + ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); + source = pipe[0]; + sink = pipe[1]; - private ICancellationSignal mCancellationSignal; + in = new FileInputStream(source.getFileDescriptor()); + out = new FileOutputStream(mFile); - public LayoutAsyncTask(PrintAttributes oldAttributes, PrintAttributes newAttributes, - LayoutResultCallback callback, Bundle metadata) { - mOldAttributes = oldAttributes; - mNewAttributes = newAttributes; - mCallback = callback; - mMetadata = metadata; - } + // Async call to initiate the other process writing the data. + mRemoteInterface.write(pages, sink, callback, sequence); - @Override - public void cancel() { - synchronized (mLock) { - throwIfCancelledLocked(); - cancelSignalQuietlyLocked(); - } - super.cancel(); - } + // Close the source. It is now held by the client. + sink.close(); + sink = null; - @Override - protected Void doInBackground(Void... params) { - synchronized (mLock) { - if (DEBUG) { - Log.i(LOG_TAG, "layout()"); - } - if (mState != STATE_START_COMPLETED - && mState != STATE_LAYOUT_COMPLETED - && mState != STATE_WRITE_COMPLETED) { - throw new IllegalStateException("Invalid state: " + mState); - } - mState = STATE_LAYOUT_STARTED; - } - try { - mRemoteInterface.layout(mOldAttributes, mNewAttributes, - mILayoutResultCallback, mMetadata); - synchronized (mLock) { + // Read the data. + final byte[] buffer = new byte[8192]; while (true) { - if (mState == STATE_LAYOUT_COMPLETED) { + final int readByteCount = in.read(buffer); + if (readByteCount < 0) { break; } - try { - mLock.wait(); - } catch (InterruptedException ie) { - /* ignore */ - } + out.write(buffer, 0, readByteCount); } - } - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error calling layout", re); - mState = STATE_FAILED; - mTaskQueue.remove(this); - notifyLayoutFailedQuietly(); - } - return null; - } - - private void cancelSignalQuietlyLocked() { - if (mCancellationSignal != null) { - try { - mCancellationSignal.cancel(); } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error cancelling layout", re); - notifyLayoutFailedQuietly(); + Log.e(LOG_TAG, "Error calling write()", re); + } catch (IOException ioe) { + Log.e(LOG_TAG, "Error calling write()", ioe); + } finally { + IoUtils.closeQuietly(in); + IoUtils.closeQuietly(out); + IoUtils.closeQuietly(sink); + IoUtils.closeQuietly(source); } + return null; } - } - - public void notifyLayoutFailedQuietly() { - try { - mILayoutResultCallback.onLayoutFailed(null); - } catch (RemoteException re) { - /* ignore */ - } - } - - private void throwIfCancelledLocked() { - if (isCancelled()) { - throw new IllegalStateException("Already cancelled"); - } - } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); } - private final class WriteAsyncTask extends QueuedAsyncTask { - - private final List<PageRange> mPages; - - private final WriteResultCallback mCallback; - - private final IWriteResultCallback mIWriteResultCallback = - new IWriteResultCallback.Stub() { - @Override - public void onWriteStarted(ICancellationSignal cancellationSignal) { - if (DEBUG) { - Log.i(LOG_TAG, "onWriteStarted()"); - } - synchronized (mLock) { - mCancellationSignal = cancellationSignal; - if (isCancelled()) { - cancelSignalQuietlyLocked(); - } - } - } - - @Override - public void onWriteFinished(List<PageRange> pages) { - if (DEBUG) { - Log.i(LOG_TAG, "onWriteFinished()"); - } - synchronized (mLock) { - mCancellationSignal = null; - mState = STATE_WRITE_COMPLETED; - mTaskQueue.remove(this); - mLock.notifyAll(); - } - mCallback.onWriteFinished(pages); - } - - @Override - public void onWriteFailed(CharSequence error) { - if (DEBUG) { - Log.i(LOG_TAG, "onWriteFailed()"); - } - synchronized (mLock) { - mCancellationSignal = null; - mState = STATE_WRITE_COMPLETED; - mTaskQueue.remove(this); - mLock.notifyAll(); - } - Slog.e(LOG_TAG, "Error writing print document: " + error); - mCallback.onWriteFailed(error); - } - }; - - private ICancellationSignal mCancellationSignal; - - private Thread mWriteThread; - - public WriteAsyncTask(List<PageRange> pages, WriteResultCallback callback) { - mPages = pages; - mCallback = callback; - } - - @Override - public void cancel() { - synchronized (mLock) { - throwIfCancelledLocked(); - cancelSignalQuietlyLocked(); - mWriteThread.interrupt(); - } - super.cancel(); - } - - @Override - protected Void doInBackground(Void... params) { - if (DEBUG) { - Log.i(LOG_TAG, "write()"); - } - synchronized (mLock) { - if (mState != STATE_LAYOUT_COMPLETED - && mState != STATE_WRITE_COMPLETED) { - throw new IllegalStateException("Invalid state: " + mState); - } - mState = STATE_WRITE_STARTED; - } - InputStream in = null; - OutputStream out = null; - ParcelFileDescriptor source = null; - ParcelFileDescriptor sink = null; - synchronized (mLock) { - mWriteThread = Thread.currentThread(); - } - try { - ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); - source = pipe[0]; - sink = pipe[1]; - - in = new FileInputStream(source.getFileDescriptor()); - out = new FileOutputStream(mFile); - - // Async call to initiate the other process writing the data. - mRemoteInterface.write(mPages, sink, mIWriteResultCallback); - - // Close the source. It is now held by the client. - sink.close(); - sink = null; - - final byte[] buffer = new byte[8192]; - while (true) { - if (Thread.currentThread().isInterrupted()) { - Thread.currentThread().interrupt(); - break; - } - final int readByteCount = in.read(buffer); - if (readByteCount < 0) { - break; - } - out.write(buffer, 0, readByteCount); - } - synchronized (mLock) { - while (true) { - if (mState == STATE_WRITE_COMPLETED) { - break; - } - try { - mLock.wait(); - } catch (InterruptedException ie) { - /* ignore */ - } - } - } - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error writing print document", re); - mState = STATE_FAILED; - mTaskQueue.remove(this); - notifyWriteFailedQuietly(); - } catch (IOException ioe) { - Slog.e(LOG_TAG, "Error writing print document", ioe); - mState = STATE_FAILED; - mTaskQueue.remove(this); - notifyWriteFailedQuietly(); - } finally { - IoUtils.closeQuietly(in); - IoUtils.closeQuietly(out); - IoUtils.closeQuietly(sink); - IoUtils.closeQuietly(source); - } - return null; - } - - private void cancelSignalQuietlyLocked() { - if (mCancellationSignal != null) { - try { - mCancellationSignal.cancel(); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error cancelling layout", re); - notifyWriteFailedQuietly(); - } - } - } - - private void notifyWriteFailedQuietly() { - try { - mIWriteResultCallback.onWriteFailed(null); - } catch (RemoteException re) { - /* ignore */ - } + public void finish() { + if (DEBUG) { + Log.i(LOG_TAG, "finish()"); } - - private void throwIfCancelledLocked() { - if (isCancelled()) { - throw new IllegalStateException("Already cancelled"); - } + try { + mRemoteInterface.finish(); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error calling finish()", re); } } } |