am b02b14b2: am ef4a6f86: Merge "Do not do a layout and write while a cancellation is in progress." into klp-dev

* commit 'b02b14b21e46c531ae726094413f036ae36c56f9':
  Do not do a layout and write while a cancellation is in progress.
This commit is contained in:
Svetoslav Ganov
2013-10-08 09:39:08 -07:00
committed by Android Git Automerger

View File

@@ -57,6 +57,8 @@ public final class PrintManager {
private static final String LOG_TAG = "PrintManager"; private static final String LOG_TAG = "PrintManager";
private static final boolean DEBUG = false;
/** @hide */ /** @hide */
public static final int APP_ID_ANY = -2; public static final int APP_ID_ANY = -2;
@@ -350,6 +352,16 @@ public final class PrintManager {
private Handler mHandler; // Strong reference OK - cleared in finish() private Handler mHandler; // Strong reference OK - cleared in finish()
private LayoutSpec mLastLayoutSpec;
private WriteSpec mLastWriteSpec;
private boolean mStartReqeusted;
private boolean mStarted;
private boolean mFinishRequested;
private boolean mFinished;
public PrintDocumentAdapterDelegate(PrintDocumentAdapter documentAdapter, Looper looper) { public PrintDocumentAdapterDelegate(PrintDocumentAdapter documentAdapter, Looper looper) {
mDocumentAdapter = documentAdapter; mDocumentAdapter = documentAdapter;
mHandler = new MyHandler(looper); mHandler = new MyHandler(looper);
@@ -357,47 +369,102 @@ public final class PrintManager {
@Override @Override
public void start() { public void start() {
mHandler.sendEmptyMessage(MyHandler.MSG_START); synchronized (mLock) {
// Started or finished - nothing to do.
if (mStartReqeusted || mFinishRequested) {
return;
}
mStartReqeusted = true;
doPendingWorkLocked();
}
} }
@Override @Override
public void layout(PrintAttributes oldAttributes, PrintAttributes newAttributes, public void layout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
ILayoutResultCallback callback, Bundle metadata, int sequence) { ILayoutResultCallback callback, Bundle metadata, int sequence) {
synchronized (mLock) { synchronized (mLock) {
if (mLayoutOrWriteCancellation != null) { // Start not called or finish called - nothing to do.
mLayoutOrWriteCancellation.cancel(); if (!mStartReqeusted || mFinishRequested) {
return;
} }
// Layout cancels write and overrides layout.
if (mLastWriteSpec != null) {
IoUtils.closeQuietly(mLastWriteSpec.fd);
mLastWriteSpec = null;
}
mLastLayoutSpec = new LayoutSpec();
mLastLayoutSpec.callback = callback;
mLastLayoutSpec.oldAttributes = oldAttributes;
mLastLayoutSpec.newAttributes = newAttributes;
mLastLayoutSpec.metadata = metadata;
mLastLayoutSpec.sequence = sequence;
// Cancel the previous cancellable operation.When the
// cancellation completes we will do the pending work.
if (cancelPreviousCancellableOperationLocked()) {
return;
}
doPendingWorkLocked();
} }
SomeArgs args = SomeArgs.obtain();
args.arg1 = oldAttributes;
args.arg2 = newAttributes;
args.arg3 = callback;
args.arg4 = metadata;
args.argi1 = sequence;
mHandler.removeMessages(MyHandler.MSG_LAYOUT);
mHandler.obtainMessage(MyHandler.MSG_LAYOUT, args).sendToTarget();
} }
@Override @Override
public void write(PageRange[] pages, ParcelFileDescriptor fd, public void write(PageRange[] pages, ParcelFileDescriptor fd,
IWriteResultCallback callback, int sequence) { IWriteResultCallback callback, int sequence) {
synchronized (mLock) { synchronized (mLock) {
if (mLayoutOrWriteCancellation != null) { // Start not called or finish called - nothing to do.
mLayoutOrWriteCancellation.cancel(); if (!mStartReqeusted || mFinishRequested) {
return;
} }
// Write cancels previous writes.
if (mLastWriteSpec != null) {
IoUtils.closeQuietly(mLastWriteSpec.fd);
mLastWriteSpec = null;
}
mLastWriteSpec = new WriteSpec();
mLastWriteSpec.callback = callback;
mLastWriteSpec.pages = pages;
mLastWriteSpec.fd = fd;
mLastWriteSpec.sequence = sequence;
// Cancel the previous cancellable operation.When the
// cancellation completes we will do the pending work.
if (cancelPreviousCancellableOperationLocked()) {
return;
}
doPendingWorkLocked();
} }
SomeArgs args = SomeArgs.obtain();
args.arg1 = pages;
args.arg2 = fd;
args.arg3 = callback;
args.argi1 = sequence;
mHandler.removeMessages(MyHandler.MSG_WRITE);
mHandler.obtainMessage(MyHandler.MSG_WRITE, args).sendToTarget();
} }
@Override @Override
public void finish() { public void finish() {
mHandler.sendEmptyMessage(MyHandler.MSG_FINISH); synchronized (mLock) {
// Start not called or finish called - nothing to do.
if (!mStartReqeusted || mFinishRequested) {
return;
}
mFinishRequested = true;
// When the current write or layout complete we
// will do the pending work.
if (mLastLayoutSpec != null || mLastWriteSpec != null) {
if (DEBUG) {
Log.i(LOG_TAG, "Waiting for current operation");
}
return;
}
doPendingWorkLocked();
}
} }
private boolean isFinished() { private boolean isFinished() {
@@ -407,7 +474,49 @@ public final class PrintManager {
private void doFinish() { private void doFinish() {
mDocumentAdapter = null; mDocumentAdapter = null;
mHandler = null; mHandler = null;
mLayoutOrWriteCancellation = null; synchronized (mLock) {
mLayoutOrWriteCancellation = null;
}
}
private boolean cancelPreviousCancellableOperationLocked() {
if (mLayoutOrWriteCancellation != null) {
mLayoutOrWriteCancellation.cancel();
if (DEBUG) {
Log.i(LOG_TAG, "Cancelling previous operation");
}
return true;
}
return false;
}
private void doPendingWorkLocked() {
if (mStartReqeusted && !mStarted) {
mStarted = true;
mHandler.sendEmptyMessage(MyHandler.MSG_START);
} else if (mLastLayoutSpec != null) {
mHandler.sendEmptyMessage(MyHandler.MSG_LAYOUT);
} else if (mLastWriteSpec != null) {
mHandler.sendEmptyMessage(MyHandler.MSG_WRITE);
} else if (mFinishRequested && !mFinished) {
mFinished = true;
mHandler.sendEmptyMessage(MyHandler.MSG_FINISH);
}
}
private class LayoutSpec {
ILayoutResultCallback callback;
PrintAttributes oldAttributes;
PrintAttributes newAttributes;
Bundle metadata;
int sequence;
}
private class WriteSpec {
IWriteResultCallback callback;
PageRange[] pages;
ParcelFileDescriptor fd;
int sequence;
} }
private final class MyHandler extends Handler { private final class MyHandler extends Handler {
@@ -431,41 +540,52 @@ public final class PrintManager {
} break; } break;
case MSG_LAYOUT: { case MSG_LAYOUT: {
SomeArgs args = (SomeArgs) message.obj; final CancellationSignal cancellation;
PrintAttributes oldAttributes = (PrintAttributes) args.arg1; final LayoutSpec layoutSpec;
PrintAttributes newAttributes = (PrintAttributes) args.arg2;
ILayoutResultCallback callback = (ILayoutResultCallback) args.arg3;
Bundle metadata = (Bundle) args.arg4;
final int sequence = args.argi1;
args.recycle();
CancellationSignal cancellation = new CancellationSignal();
synchronized (mLock) { synchronized (mLock) {
layoutSpec = mLastLayoutSpec;
mLastLayoutSpec = null;
cancellation = new CancellationSignal();
mLayoutOrWriteCancellation = cancellation; mLayoutOrWriteCancellation = cancellation;
} }
mDocumentAdapter.onLayout(oldAttributes, newAttributes, cancellation, if (layoutSpec != null) {
new MyLayoutResultCallback(callback, sequence), metadata); if (DEBUG) {
Log.i(LOG_TAG, "Performing layout");
}
mDocumentAdapter.onLayout(layoutSpec.oldAttributes,
layoutSpec.newAttributes, cancellation,
new MyLayoutResultCallback(layoutSpec.callback,
layoutSpec.sequence), layoutSpec.metadata);
}
} break; } break;
case MSG_WRITE: { case MSG_WRITE: {
SomeArgs args = (SomeArgs) message.obj; final CancellationSignal cancellation;
PageRange[] pages = (PageRange[]) args.arg1; final WriteSpec writeSpec;
ParcelFileDescriptor fd = (ParcelFileDescriptor) args.arg2;
IWriteResultCallback callback = (IWriteResultCallback) args.arg3;
final int sequence = args.argi1;
args.recycle();
CancellationSignal cancellation = new CancellationSignal();
synchronized (mLock) { synchronized (mLock) {
writeSpec= mLastWriteSpec;
mLastWriteSpec = null;
cancellation = new CancellationSignal();
mLayoutOrWriteCancellation = cancellation; mLayoutOrWriteCancellation = cancellation;
} }
mDocumentAdapter.onWrite(pages, fd, cancellation, if (writeSpec != null) {
new MyWriteResultCallback(callback, fd, sequence)); if (DEBUG) {
Log.i(LOG_TAG, "Performing write");
}
mDocumentAdapter.onWrite(writeSpec.pages, writeSpec.fd,
cancellation, new MyWriteResultCallback(writeSpec.callback,
writeSpec.fd, writeSpec.sequence));
}
} break; } break;
case MSG_FINISH: { case MSG_FINISH: {
if (DEBUG) {
Log.i(LOG_TAG, "Performing finish");
}
mDocumentAdapter.onFinish(); mDocumentAdapter.onFinish();
doFinish(); doFinish();
} break; } break;
@@ -533,6 +653,7 @@ public final class PrintManager {
private void clearLocked() { private void clearLocked() {
mLayoutOrWriteCancellation = null; mLayoutOrWriteCancellation = null;
mCallback = null; mCallback = null;
doPendingWorkLocked();
} }
} }
@@ -598,6 +719,7 @@ public final class PrintManager {
IoUtils.closeQuietly(mFd); IoUtils.closeQuietly(mFd);
mCallback = null; mCallback = null;
mFd = null; mFd = null;
doPendingWorkLocked();
} }
} }
} }