1a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav/* 2a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * Copyright (C) 2014 The Android Open Source Project 3a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * 4a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * Licensed under the Apache License, Version 2.0 (the "License"); 5a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * you may not use this file except in compliance with the License. 6a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * You may obtain a copy of the License at 7a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * 8a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * http://www.apache.org/licenses/LICENSE-2.0 9a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * 10a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * Unless required by applicable law or agreed to in writing, software 11a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * distributed under the License is distributed on an "AS IS" BASIS, 12a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * See the License for the specific language governing permissions and 14a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * limitations under the License. 15a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav */ 16a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 17a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavpackage com.android.printspooler.model; 18a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 19645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmannimport android.annotation.NonNull; 20a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.content.ContentResolver; 21a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.content.Context; 22a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.net.Uri; 23a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.os.AsyncTask; 24a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.os.Bundle; 25a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.os.Handler; 26a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.os.IBinder.DeathRecipient; 27a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.os.ICancellationSignal; 28a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.os.Looper; 29a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.os.Message; 30a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.os.ParcelFileDescriptor; 31a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.os.RemoteException; 32a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.print.ILayoutResultCallback; 33a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.print.IPrintDocumentAdapter; 34a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.print.IPrintDocumentAdapterObserver; 35a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.print.IWriteResultCallback; 36a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.print.PageRange; 37a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.print.PrintAttributes; 38a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.print.PrintDocumentAdapter; 39a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.print.PrintDocumentInfo; 40a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.util.Log; 41a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 42a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport com.android.printspooler.R; 43a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport com.android.printspooler.util.PageRangeUtils; 44a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 45a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport libcore.io.IoUtils; 46a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 47a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport java.io.File; 48a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport java.io.FileInputStream; 49a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport java.io.FileOutputStream; 50a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport java.io.IOException; 51a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport java.io.InputStream; 52a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport java.io.OutputStream; 53a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport java.lang.ref.WeakReference; 54a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport java.util.Arrays; 55a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 56a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavpublic final class RemotePrintDocument { 57a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final String LOG_TAG = "RemotePrintDocument"; 58a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 596f249835a4ff9e7e7e3ca0190b7ecf72e689656dSvetoslav private static final boolean DEBUG = false; 60a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 61645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann private static final long FORCE_CANCEL_TIMEOUT = 1000; // ms 62645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann 63a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final int STATE_INITIAL = 0; 64a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final int STATE_STARTED = 1; 65a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final int STATE_UPDATING = 2; 66a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final int STATE_UPDATED = 3; 67a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final int STATE_FAILED = 4; 68a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final int STATE_FINISHED = 5; 69a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final int STATE_CANCELING = 6; 70a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final int STATE_CANCELED = 7; 71a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final int STATE_DESTROYED = 8; 72a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 73a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final Context mContext; 74a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 75a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final RemotePrintDocumentInfo mDocumentInfo; 76a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final UpdateSpec mUpdateSpec = new UpdateSpec(); 77a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 78a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final Looper mLooper; 79a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final IPrintDocumentAdapter mPrintDocumentAdapter; 80e17123dd6d3666c88b47172b8efc995523b47346Svetoslav private final RemoteAdapterDeathObserver mAdapterDeathObserver; 81a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 82a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final UpdateResultCallbacks mUpdateCallbacks; 83a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 84a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final CommandDoneCallback mCommandResultCallback = 85a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav new CommandDoneCallback() { 86a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav @Override 87a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void onDone() { 88a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mCurrentCommand.isCompleted()) { 89a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mCurrentCommand instanceof LayoutCommand) { 90a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // If there is a next command after a layout is done, then another 91a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // update was issued and the next command is another layout, so we 92a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // do nothing. However, if there is no next command we may need to 93a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // ask for some pages given we do not already have them or we do 94a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // but the content has changed. 95a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mNextCommand == null) { 96525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov if (mUpdateSpec.pages != null && (mDocumentInfo.changed 97525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov || (mDocumentInfo.info.getPageCount() 98525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov != PrintDocumentInfo.PAGE_COUNT_UNKNOWN 99525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov && !PageRangeUtils.contains(mDocumentInfo.writtenPages, 100525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov mUpdateSpec.pages, mDocumentInfo.info.getPageCount())))) { 101a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mNextCommand = new WriteCommand(mContext, mLooper, 102a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mPrintDocumentAdapter, mDocumentInfo, 103a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDocumentInfo.info.getPageCount(), mUpdateSpec.pages, 104525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov mDocumentInfo.fileProvider, mCommandResultCallback); 105a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } else { 106525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov if (mUpdateSpec.pages != null) { 107525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov // If we have the requested pages, update which ones to be printed. 108525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov mDocumentInfo.printedPages = PageRangeUtils.computePrintedPages( 109525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov mUpdateSpec.pages, mDocumentInfo.writtenPages, 110525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov mDocumentInfo.info.getPageCount()); 111525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov } 112a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Notify we are done. 11305ff998fd86eff15e91694bc205ea0af0de83284Svet Ganov mState = STATE_UPDATED; 114a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav notifyUpdateCompleted(); 115a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 116a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 117a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } else { 118a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // We always notify after a write. 11905ff998fd86eff15e91694bc205ea0af0de83284Svet Ganov mState = STATE_UPDATED; 120a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav notifyUpdateCompleted(); 121a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 122a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav runPendingCommand(); 123a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } else if (mCurrentCommand.isFailed()) { 124a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mState = STATE_FAILED; 125a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav CharSequence error = mCurrentCommand.getError(); 126a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mCurrentCommand = null; 127a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mNextCommand = null; 128a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mUpdateSpec.reset(); 129a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav notifyUpdateFailed(error); 130a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } else if (mCurrentCommand.isCanceled()) { 131a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mState == STATE_CANCELING) { 132a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mState = STATE_CANCELED; 133a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav notifyUpdateCanceled(); 134a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 135a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav runPendingCommand(); 136a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 137a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 138a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav }; 139a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 140a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final DeathRecipient mDeathRecipient = new DeathRecipient() { 141a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav @Override 142a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void binderDied() { 1434237c92d850b7fb0fa0be15df94e4d1689e353fcSvet Ganov onPrintingAppDied(); 144a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 145a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav }; 146a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 147a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private int mState = STATE_INITIAL; 148a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 149a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private AsyncCommand mCurrentCommand; 150a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private AsyncCommand mNextCommand; 151a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 152e17123dd6d3666c88b47172b8efc995523b47346Svetoslav public interface RemoteAdapterDeathObserver { 153e17123dd6d3666c88b47172b8efc995523b47346Svetoslav public void onDied(); 154a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 155a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 156a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public interface UpdateResultCallbacks { 157a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void onUpdateCompleted(RemotePrintDocumentInfo document); 158a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void onUpdateCanceled(); 159a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void onUpdateFailed(CharSequence error); 160a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 161a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 162a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public RemotePrintDocument(Context context, IPrintDocumentAdapter adapter, 163e17123dd6d3666c88b47172b8efc995523b47346Svetoslav MutexFileProvider fileProvider, RemoteAdapterDeathObserver deathObserver, 164525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov UpdateResultCallbacks callbacks) { 165a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mPrintDocumentAdapter = adapter; 166a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mLooper = context.getMainLooper(); 167a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mContext = context; 168e17123dd6d3666c88b47172b8efc995523b47346Svetoslav mAdapterDeathObserver = deathObserver; 169a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDocumentInfo = new RemotePrintDocumentInfo(); 170525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov mDocumentInfo.fileProvider = fileProvider; 171a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mUpdateCallbacks = callbacks; 172a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav connectToRemoteDocument(); 173a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 174a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 175a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void start() { 176a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 177a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[CALLED] start()"); 178a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 179f6114c4f1ea92e740191b173515e1fdbc7450583Philip P. Moltmann if (mState == STATE_FAILED) { 180f6114c4f1ea92e740191b173515e1fdbc7450583Philip P. Moltmann Log.w(LOG_TAG, "Failed before start."); 1817134fcc07ca71cdb9eeccfc7d1846e4408849aecPhilip P. Moltmann } else if (mState == STATE_DESTROYED) { 1827134fcc07ca71cdb9eeccfc7d1846e4408849aecPhilip P. Moltmann Log.w(LOG_TAG, "Destroyed before start."); 183f6114c4f1ea92e740191b173515e1fdbc7450583Philip P. Moltmann } else { 184f6114c4f1ea92e740191b173515e1fdbc7450583Philip P. Moltmann if (mState != STATE_INITIAL) { 185f6114c4f1ea92e740191b173515e1fdbc7450583Philip P. Moltmann throw new IllegalStateException("Cannot start in state:" + stateToString(mState)); 186f6114c4f1ea92e740191b173515e1fdbc7450583Philip P. Moltmann } 187f6114c4f1ea92e740191b173515e1fdbc7450583Philip P. Moltmann try { 188f6114c4f1ea92e740191b173515e1fdbc7450583Philip P. Moltmann mPrintDocumentAdapter.start(); 189f6114c4f1ea92e740191b173515e1fdbc7450583Philip P. Moltmann mState = STATE_STARTED; 190f6114c4f1ea92e740191b173515e1fdbc7450583Philip P. Moltmann } catch (RemoteException re) { 191f6114c4f1ea92e740191b173515e1fdbc7450583Philip P. Moltmann Log.e(LOG_TAG, "Error calling start()", re); 192f6114c4f1ea92e740191b173515e1fdbc7450583Philip P. Moltmann mState = STATE_FAILED; 193f6114c4f1ea92e740191b173515e1fdbc7450583Philip P. Moltmann } 194a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 195a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 196a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 197a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public boolean update(PrintAttributes attributes, PageRange[] pages, boolean preview) { 198a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav boolean willUpdate; 199a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 200a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 201a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[CALLED] update()"); 202a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 203a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 204a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (hasUpdateError()) { 205a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav throw new IllegalStateException("Cannot update without a clearing the failure"); 206a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 207a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 208a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mState == STATE_INITIAL || mState == STATE_FINISHED || mState == STATE_DESTROYED) { 209a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav throw new IllegalStateException("Cannot update in state:" + stateToString(mState)); 210a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 211a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 212a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // We schedule a layout if the constraints changed. 213a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (!mUpdateSpec.hasSameConstraints(attributes, preview)) { 214a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav willUpdate = true; 215a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 216a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // If there is a current command that is running we ask for a 217a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // cancellation and start over. 218a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mCurrentCommand != null && (mCurrentCommand.isRunning() 219a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav || mCurrentCommand.isPending())) { 220645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann mCurrentCommand.cancel(false); 221a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 222a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 223a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Schedule a layout command. 224a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav PrintAttributes oldAttributes = mDocumentInfo.attributes != null 225a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav ? mDocumentInfo.attributes : new PrintAttributes.Builder().build(); 226a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav AsyncCommand command = new LayoutCommand(mLooper, mPrintDocumentAdapter, 227a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDocumentInfo, oldAttributes, attributes, preview, mCommandResultCallback); 228a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav scheduleCommand(command); 229a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 230a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mState = STATE_UPDATING; 231a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // If no layout in progress and we don't have all pages - schedule a write. 232a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } else if ((!(mCurrentCommand instanceof LayoutCommand) 233a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav || (!mCurrentCommand.isPending() && !mCurrentCommand.isRunning())) 234525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov && pages != null && !PageRangeUtils.contains(mUpdateSpec.pages, pages, 235525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov mDocumentInfo.info.getPageCount())) { 236a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav willUpdate = true; 237a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 238a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Cancel the current write as a new one is to be scheduled. 239a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mCurrentCommand instanceof WriteCommand 240a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav && (mCurrentCommand.isPending() || mCurrentCommand.isRunning())) { 241645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann mCurrentCommand.cancel(false); 242a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 243a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 244a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Schedule a write command. 245a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav AsyncCommand command = new WriteCommand(mContext, mLooper, mPrintDocumentAdapter, 246a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDocumentInfo, mDocumentInfo.info.getPageCount(), pages, 247525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov mDocumentInfo.fileProvider, mCommandResultCallback); 248a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav scheduleCommand(command); 249a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 250a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mState = STATE_UPDATING; 251a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } else { 252a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav willUpdate = false; 253a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 254a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[SKIPPING] No update needed"); 255a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 256a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 257a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 258a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Keep track of what is requested. 259a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mUpdateSpec.update(attributes, preview, pages); 260a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 261a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav runPendingCommand(); 262a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 263a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return willUpdate; 264a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 265a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 266a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void finish() { 267a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 268a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[CALLED] finish()"); 269a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 270a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mState != STATE_STARTED && mState != STATE_UPDATED 2719c9888b8c59e35717ecfc32e9b96fb8702ceb480Svetoslav && mState != STATE_FAILED && mState != STATE_CANCELING 2727134fcc07ca71cdb9eeccfc7d1846e4408849aecPhilip P. Moltmann && mState != STATE_CANCELED && mState != STATE_DESTROYED) { 273a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav throw new IllegalStateException("Cannot finish in state:" 274a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav + stateToString(mState)); 275a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 276a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav try { 277a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mPrintDocumentAdapter.finish(); 278a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mState = STATE_FINISHED; 279a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } catch (RemoteException re) { 2804237c92d850b7fb0fa0be15df94e4d1689e353fcSvet Ganov Log.e(LOG_TAG, "Error calling finish()"); 281a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mState = STATE_FAILED; 282a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 283a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 284a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 285645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann public void cancel(boolean force) { 286a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 287645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann Log.i(LOG_TAG, "[CALLED] cancel(" + force + ")"); 288a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 289a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 290cc3fa0d295ea39e412e4a7e0dd4c916b5123bca5Philip P. Moltmann mNextCommand = null; 291a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 292a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mState != STATE_UPDATING) { 293cc3fa0d295ea39e412e4a7e0dd4c916b5123bca5Philip P. Moltmann return; 294a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 295a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 296a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mState = STATE_CANCELING; 297a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 298645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann mCurrentCommand.cancel(force); 299a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 300a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 301a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void destroy() { 302a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 303a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[CALLED] destroy()"); 304a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 305a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mState == STATE_DESTROYED) { 306a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav throw new IllegalStateException("Cannot destroy in state:" + stateToString(mState)); 307a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 308a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 309a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mState = STATE_DESTROYED; 310a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 311a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav disconnectFromRemoteDocument(); 312a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 313a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 314fce84f035c35606c5707e735f503f7bdcfd5b2a1Svet Ganov public void kill(String reason) { 315fce84f035c35606c5707e735f503f7bdcfd5b2a1Svet Ganov if (DEBUG) { 316fce84f035c35606c5707e735f503f7bdcfd5b2a1Svet Ganov Log.i(LOG_TAG, "[CALLED] kill()"); 317fce84f035c35606c5707e735f503f7bdcfd5b2a1Svet Ganov } 318fce84f035c35606c5707e735f503f7bdcfd5b2a1Svet Ganov 319fce84f035c35606c5707e735f503f7bdcfd5b2a1Svet Ganov try { 320fce84f035c35606c5707e735f503f7bdcfd5b2a1Svet Ganov mPrintDocumentAdapter.kill(reason); 321fce84f035c35606c5707e735f503f7bdcfd5b2a1Svet Ganov } catch (RemoteException re) { 322fce84f035c35606c5707e735f503f7bdcfd5b2a1Svet Ganov Log.e(LOG_TAG, "Error calling kill()", re); 323fce84f035c35606c5707e735f503f7bdcfd5b2a1Svet Ganov } 324fce84f035c35606c5707e735f503f7bdcfd5b2a1Svet Ganov } 325fce84f035c35606c5707e735f503f7bdcfd5b2a1Svet Ganov 326a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public boolean isUpdating() { 327a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return mState == STATE_UPDATING || mState == STATE_CANCELING; 328a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 329a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 330a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public boolean isDestroyed() { 331a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return mState == STATE_DESTROYED; 332a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 333a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 334a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public boolean hasUpdateError() { 335a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return mState == STATE_FAILED; 336a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 337a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 3386552bf3da60159607d9266eb295ee3c448f6c3deSvetoslav public boolean hasLaidOutPages() { 3396552bf3da60159607d9266eb295ee3c448f6c3deSvetoslav return mDocumentInfo.info != null 3406552bf3da60159607d9266eb295ee3c448f6c3deSvetoslav && mDocumentInfo.info.getPageCount() > 0; 3416552bf3da60159607d9266eb295ee3c448f6c3deSvetoslav } 3426552bf3da60159607d9266eb295ee3c448f6c3deSvetoslav 343a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void clearUpdateError() { 344a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (!hasUpdateError()) { 345a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav throw new IllegalStateException("No update error to clear"); 346a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 347a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mState = STATE_STARTED; 348a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 349a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 350a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public RemotePrintDocumentInfo getDocumentInfo() { 351a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return mDocumentInfo; 352a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 353a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 354a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void writeContent(ContentResolver contentResolver, Uri uri) { 355525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov File file = null; 356a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav InputStream in = null; 357a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav OutputStream out = null; 358a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav try { 359525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov file = mDocumentInfo.fileProvider.acquireFile(null); 360525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov in = new FileInputStream(file); 361a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav out = contentResolver.openOutputStream(uri); 362a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav final byte[] buffer = new byte[8192]; 363a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav while (true) { 364a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav final int readByteCount = in.read(buffer); 365a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (readByteCount < 0) { 366a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav break; 367a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 368a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav out.write(buffer, 0, readByteCount); 369a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 370a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } catch (IOException e) { 371a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.e(LOG_TAG, "Error writing document content.", e); 372a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } finally { 373a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav IoUtils.closeQuietly(in); 374a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav IoUtils.closeQuietly(out); 375525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov if (file != null) { 376525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov mDocumentInfo.fileProvider.releaseFile(); 377525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov } 378a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 379a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 380a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 381a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private void notifyUpdateCanceled() { 382a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 383a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[CALLING] onUpdateCanceled()"); 384a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 385a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mUpdateCallbacks.onUpdateCanceled(); 386a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 387a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 388a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private void notifyUpdateCompleted() { 389a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 390a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[CALLING] onUpdateCompleted()"); 391a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 392a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mUpdateCallbacks.onUpdateCompleted(mDocumentInfo); 393a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 394a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 395a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private void notifyUpdateFailed(CharSequence error) { 396a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 397a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[CALLING] onUpdateCompleted()"); 398a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 399a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mUpdateCallbacks.onUpdateFailed(error); 400a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 401a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 402a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private void connectToRemoteDocument() { 403a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav try { 404a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mPrintDocumentAdapter.asBinder().linkToDeath(mDeathRecipient, 0); 405a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } catch (RemoteException re) { 406a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.w(LOG_TAG, "The printing process is dead."); 407a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav destroy(); 408a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return; 409a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 410a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 411a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav try { 412a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mPrintDocumentAdapter.setObserver(new PrintDocumentAdapterObserver(this)); 413a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } catch (RemoteException re) { 414a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.w(LOG_TAG, "Error setting observer to the print adapter."); 415a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav destroy(); 416a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 417a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 418a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 419a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private void disconnectFromRemoteDocument() { 420a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav try { 421a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mPrintDocumentAdapter.setObserver(null); 422a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } catch (RemoteException re) { 423a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.w(LOG_TAG, "Error setting observer to the print adapter."); 424a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Keep going - best effort... 425a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 426a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 427a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mPrintDocumentAdapter.asBinder().unlinkToDeath(mDeathRecipient, 0); 428a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 429a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 430a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private void scheduleCommand(AsyncCommand command) { 431a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mCurrentCommand == null) { 432a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mCurrentCommand = command; 433a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } else { 434a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mNextCommand = command; 435a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 436a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 437a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 438a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private void runPendingCommand() { 439a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mCurrentCommand != null 440a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav && (mCurrentCommand.isCompleted() 441a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav || mCurrentCommand.isCanceled())) { 442a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mCurrentCommand = mNextCommand; 443a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mNextCommand = null; 444a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 445a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 446a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mCurrentCommand != null) { 447a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mCurrentCommand.isPending()) { 448a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mCurrentCommand.run(); 449645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann 450645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann mState = STATE_UPDATING; 451a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 452a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } else { 453a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mState = STATE_UPDATED; 454a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 455a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 456a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 457a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static String stateToString(int state) { 458a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav switch (state) { 459a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav case STATE_FINISHED: { 460a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return "STATE_FINISHED"; 461a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 462a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav case STATE_FAILED: { 463a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return "STATE_FAILED"; 464a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 465a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav case STATE_STARTED: { 466a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return "STATE_STARTED"; 467a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 468a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav case STATE_UPDATING: { 469a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return "STATE_UPDATING"; 470a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 471a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav case STATE_UPDATED: { 472a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return "STATE_UPDATED"; 473a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 474a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav case STATE_CANCELING: { 475a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return "STATE_CANCELING"; 476a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 477a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav case STATE_CANCELED: { 478a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return "STATE_CANCELED"; 479a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 480a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav case STATE_DESTROYED: { 481a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return "STATE_DESTROYED"; 482a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 483a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav default: { 484a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return "STATE_UNKNOWN"; 485a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 486a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 487a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 488a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 489a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav static final class UpdateSpec { 490a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav final PrintAttributes attributes = new PrintAttributes.Builder().build(); 491a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav boolean preview; 492a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav PageRange[] pages; 493a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 494a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void update(PrintAttributes attributes, boolean preview, 495a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav PageRange[] pages) { 496a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav this.attributes.copyFrom(attributes); 497a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav this.preview = preview; 498525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov this.pages = (pages != null) ? Arrays.copyOf(pages, pages.length) : null; 499a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 500a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 501a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void reset() { 502a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav attributes.clear(); 503a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav preview = false; 504a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav pages = null; 505a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 506a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 507a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public boolean hasSameConstraints(PrintAttributes attributes, boolean preview) { 508a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return this.attributes.equals(attributes) && this.preview == preview; 509a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 510a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 511a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 512a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public static final class RemotePrintDocumentInfo { 513a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public PrintAttributes attributes; 514a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public Bundle metadata; 515a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public PrintDocumentInfo info; 516a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public PageRange[] printedPages; 517a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public PageRange[] writtenPages; 518525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov public MutexFileProvider fileProvider; 519525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov public boolean changed; 520525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov public boolean updated; 521525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov public boolean laidout; 522a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 523a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 524a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private interface CommandDoneCallback { 525a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void onDone(); 526a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 527a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 528a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static abstract class AsyncCommand implements Runnable { 529a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final int STATE_PENDING = 0; 530a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final int STATE_RUNNING = 1; 531a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final int STATE_COMPLETED = 2; 532a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final int STATE_CANCELED = 3; 533a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final int STATE_CANCELING = 4; 534a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final int STATE_FAILED = 5; 535a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 536a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static int sSequenceCounter; 537a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 538a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav protected final int mSequence = sSequenceCounter++; 539a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav protected final IPrintDocumentAdapter mAdapter; 540a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav protected final RemotePrintDocumentInfo mDocument; 541a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 542a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav protected final CommandDoneCallback mDoneCallback; 543a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 544645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann private final Handler mHandler; 545645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann 546a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav protected ICancellationSignal mCancellation; 547a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 548a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private CharSequence mError; 549a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 550a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private int mState = STATE_PENDING; 551a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 552645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann public AsyncCommand(Looper looper, IPrintDocumentAdapter adapter, RemotePrintDocumentInfo document, 553a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav CommandDoneCallback doneCallback) { 554645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann mHandler = new AsyncCommandHandler(looper); 555a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mAdapter = adapter; 556a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDocument = document; 557a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDoneCallback = doneCallback; 558a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 559a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 560a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav protected final boolean isCanceling() { 561a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return mState == STATE_CANCELING; 562a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 563a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 564a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public final boolean isCanceled() { 565a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return mState == STATE_CANCELED; 566a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 567a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 568645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann /** 569645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann * If a force cancel is pending, remove it. This is usually called when a command returns 570645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann * and thereby does not need to be canceled anymore. 571645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann */ 572645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann protected void removeForceCancel() { 573645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann if (DEBUG) { 574645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann if (mHandler.hasMessages(AsyncCommandHandler.MSG_FORCE_CANCEL)) { 575645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann Log.i(LOG_TAG, "[FORCE CANCEL] Removed"); 576645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann } 577645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann } 578645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann 579645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann mHandler.removeMessages(AsyncCommandHandler.MSG_FORCE_CANCEL); 580645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann } 581645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann 582645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann /** 583645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann * Cancel the current command. 584645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann * 585645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann * @param force If set, does not wait for the {@link PrintDocumentAdapter} to cancel. This 586645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann * should only be used if this is the last command send to the as otherwise the 587645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann * {@link PrintDocumentAdapter adapter} might get commands while it is still 588645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann * running the old one. 589645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann */ 590645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann public final void cancel(boolean force) { 591a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (isRunning()) { 592a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav canceling(); 593a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mCancellation != null) { 594a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav try { 595a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mCancellation.cancel(); 596a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } catch (RemoteException re) { 597a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.w(LOG_TAG, "Error while canceling", re); 598a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 599a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 600645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann } 601645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann 602645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann if (isCanceling()) { 603645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann if (force) { 604645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann if (DEBUG) { 605645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann Log.i(LOG_TAG, "[FORCE CANCEL] queued"); 606645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann } 607645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann mHandler.sendMessageDelayed( 608645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann mHandler.obtainMessage(AsyncCommandHandler.MSG_FORCE_CANCEL), 609645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann FORCE_CANCEL_TIMEOUT); 610645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann } 611a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 612645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann return; 613a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 614645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann 615645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann canceled(); 616645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann 617645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann // Done. 618645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann mDoneCallback.onDone(); 619a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 620a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 621a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav protected final void canceling() { 622a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mState != STATE_PENDING && mState != STATE_RUNNING) { 623a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav throw new IllegalStateException("Command not pending or running."); 624a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 625a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mState = STATE_CANCELING; 626a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 627a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 628a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav protected final void canceled() { 629a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mState != STATE_CANCELING) { 630a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav throw new IllegalStateException("Not canceling."); 631a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 632a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mState = STATE_CANCELED; 633a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 634a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 635a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public final boolean isPending() { 636a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return mState == STATE_PENDING; 637a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 638a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 639a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav protected final void running() { 640a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mState != STATE_PENDING) { 641a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav throw new IllegalStateException("Not pending."); 642a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 643a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mState = STATE_RUNNING; 644a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 645a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 646a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public final boolean isRunning() { 647a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return mState == STATE_RUNNING; 648a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 649a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 650a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav protected final void completed() { 651a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (mState != STATE_RUNNING && mState != STATE_CANCELING) { 652a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav throw new IllegalStateException("Not running."); 653a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 654a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mState = STATE_COMPLETED; 655a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 656a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 657a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public final boolean isCompleted() { 658a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return mState == STATE_COMPLETED; 659a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 660a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 661a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav protected final void failed(CharSequence error) { 662645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann if (mState != STATE_RUNNING && mState != STATE_CANCELING) { 663a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav throw new IllegalStateException("Not running."); 664a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 665a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mState = STATE_FAILED; 666a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 667a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mError = error; 668a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 669a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 670a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public final boolean isFailed() { 671a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return mState == STATE_FAILED; 672a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 673a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 674a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public CharSequence getError() { 675a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return mError; 676a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 677645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann 678645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann /** 679645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann * Handler for the async command. 680645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann */ 681645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann private class AsyncCommandHandler extends Handler { 682645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann /** Message indicated the desire for to force cancel a command */ 683645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann final static int MSG_FORCE_CANCEL = 0; 684645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann 685645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann AsyncCommandHandler(@NonNull Looper looper) { 686645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann super(looper); 687645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann } 688645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann 689645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann @Override 690645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann public void handleMessage(Message msg) { 691645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann switch (msg.what) { 692645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann case MSG_FORCE_CANCEL: 693645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann if (isCanceling()) { 694645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann if (DEBUG) { 695645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann Log.i(LOG_TAG, "[FORCE CANCEL] executed"); 696645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann } 697645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann failed("Command did not respond to cancellation in " 698645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann + FORCE_CANCEL_TIMEOUT + " ms"); 699645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann 700645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann mDoneCallback.onDone(); 701645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann } 702645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann break; 703645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann default: 704645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann // not reached; 705645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann } 706645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann } 707645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann } 708a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 709a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 710a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final class LayoutCommand extends AsyncCommand { 711a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final PrintAttributes mOldAttributes = new PrintAttributes.Builder().build(); 712a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final PrintAttributes mNewAttributes = new PrintAttributes.Builder().build(); 713a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final Bundle mMetadata = new Bundle(); 714a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 715a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final ILayoutResultCallback mRemoteResultCallback; 716a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 717a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final Handler mHandler; 718a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 719a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public LayoutCommand(Looper looper, IPrintDocumentAdapter adapter, 720a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav RemotePrintDocumentInfo document, PrintAttributes oldAttributes, 721a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav PrintAttributes newAttributes, boolean preview, CommandDoneCallback callback) { 722645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann super(looper, adapter, document, callback); 723a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mHandler = new LayoutHandler(looper); 724a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mRemoteResultCallback = new LayoutResultCallback(mHandler); 725a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mOldAttributes.copyFrom(oldAttributes); 726a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mNewAttributes.copyFrom(newAttributes); 727a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mMetadata.putBoolean(PrintDocumentAdapter.EXTRA_PRINT_PREVIEW, preview); 728a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 729a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 730a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav @Override 731a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void run() { 732a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav running(); 733a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 734a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav try { 735a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 736a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[PERFORMING] layout"); 737a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 738525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov mDocument.changed = false; 739a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mAdapter.layout(mOldAttributes, mNewAttributes, mRemoteResultCallback, 740a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mMetadata, mSequence); 741a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } catch (RemoteException re) { 742a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.e(LOG_TAG, "Error calling layout", re); 743a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handleOnLayoutFailed(null, mSequence); 744a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 745a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 746a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 747a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private void handleOnLayoutStarted(ICancellationSignal cancellation, int sequence) { 748a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (sequence != mSequence) { 749a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return; 750a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 751a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 752a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 753a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[CALLBACK] onLayoutStarted"); 754a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 755a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 756a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (isCanceling()) { 757a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav try { 758a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav cancellation.cancel(); 759a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } catch (RemoteException re) { 760a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.e(LOG_TAG, "Error cancelling", re); 761a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handleOnLayoutFailed(null, mSequence); 762a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 763a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } else { 764a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mCancellation = cancellation; 765a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 766a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 767a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 768a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private void handleOnLayoutFinished(PrintDocumentInfo info, 769a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav boolean changed, int sequence) { 770a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (sequence != mSequence) { 771a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return; 772a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 773a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 774a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 775a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[CALLBACK] onLayoutFinished"); 776a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 777a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 778a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav completed(); 779a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 780a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // If the document description changed or the content in the 781a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // document changed, the we need to invalidate the pages. 782a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (changed || !equalsIgnoreSize(mDocument.info, info)) { 783a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // If the content changed we throw away all pages as 784a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // we will request them again with the new content. 785a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDocument.writtenPages = null; 786a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDocument.printedPages = null; 787525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov mDocument.changed = true; 788a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 789a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 790a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Update the document with data from the layout pass. 791a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDocument.attributes = mNewAttributes; 792a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDocument.metadata = mMetadata; 793525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov mDocument.laidout = true; 794a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDocument.info = info; 795a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 796a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Release the remote cancellation interface. 797a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mCancellation = null; 798a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 799a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Done. 800a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDoneCallback.onDone(); 801a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 802a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 803a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private void handleOnLayoutFailed(CharSequence error, int sequence) { 804a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (sequence != mSequence) { 805a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return; 806a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 807a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 808a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 809a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[CALLBACK] onLayoutFailed"); 810a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 811a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 812525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov mDocument.laidout = false; 813525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov 814a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav failed(error); 815a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 816a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Release the remote cancellation interface. 817a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mCancellation = null; 818a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 819a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Failed. 820a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDoneCallback.onDone(); 821a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 822a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 823a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private void handleOnLayoutCanceled(int sequence) { 824a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (sequence != mSequence) { 825a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return; 826a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 827a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 828a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 829a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[CALLBACK] onLayoutCanceled"); 830a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 831a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 832a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav canceled(); 833a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 834a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Release the remote cancellation interface. 835a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mCancellation = null; 836a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 837a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Done. 838a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDoneCallback.onDone(); 839a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 840a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 841a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private boolean equalsIgnoreSize(PrintDocumentInfo lhs, PrintDocumentInfo rhs) { 842a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (lhs == rhs) { 843a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return true; 844a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 845a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (lhs == null) { 846a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return false; 847a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } else { 848a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (rhs == null) { 849a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return false; 850a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 851a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (lhs.getContentType() != rhs.getContentType() 852a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav || lhs.getPageCount() != rhs.getPageCount()) { 853a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return false; 854a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 855a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 856a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return true; 857a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 858a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 859a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final class LayoutHandler extends Handler { 860a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public static final int MSG_ON_LAYOUT_STARTED = 1; 861a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public static final int MSG_ON_LAYOUT_FINISHED = 2; 862a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public static final int MSG_ON_LAYOUT_FAILED = 3; 863a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public static final int MSG_ON_LAYOUT_CANCELED = 4; 864a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 865a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public LayoutHandler(Looper looper) { 866a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav super(looper, null, false); 867a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 868a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 869a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav @Override 870a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void handleMessage(Message message) { 871645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann // The command might have been force canceled, see 872645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann // AsyncCommand.AsyncCommandHandler#handleMessage 873645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann if (isFailed()) { 874645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann if (DEBUG) { 87527db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann Log.i(LOG_TAG, "[CALLBACK] on failed layout command"); 876645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann } 877645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann 878645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann return; 87927db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann } 88027db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann 88127db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann int sequence; 88227db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann int what = message.what; 88327db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann switch (what) { 88427db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann case MSG_ON_LAYOUT_FINISHED: 885645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann removeForceCancel(); 88627db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann sequence = message.arg2; 88727db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann break; 88827db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann case MSG_ON_LAYOUT_FAILED: 88927db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann case MSG_ON_LAYOUT_CANCELED: 89027db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann removeForceCancel(); 89127db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann // $FALL-THROUGH - message uses the same format as "started" 89227db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann case MSG_ON_LAYOUT_STARTED: 89327db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann // Don't remote force-cancel as command is still running and might need to 89427db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann // be canceled later 89527db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann sequence = message.arg1; 89627db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann break; 89727db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann default: 89827db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann // not reached 89927db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann sequence = -1; 90027db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann } 90127db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann 90227db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann // If we are canceling any result is treated as a cancel 90327db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann if (isCanceling() && what != MSG_ON_LAYOUT_STARTED) { 90427db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann what = MSG_ON_LAYOUT_CANCELED; 905645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann } 906645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann 90727db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann switch (what) { 908a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav case MSG_ON_LAYOUT_STARTED: { 909a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav ICancellationSignal cancellation = (ICancellationSignal) message.obj; 910a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handleOnLayoutStarted(cancellation, sequence); 911a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } break; 912a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 913a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav case MSG_ON_LAYOUT_FINISHED: { 914a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav PrintDocumentInfo info = (PrintDocumentInfo) message.obj; 915a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav final boolean changed = (message.arg1 == 1); 916a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handleOnLayoutFinished(info, changed, sequence); 917a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } break; 918a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 919a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav case MSG_ON_LAYOUT_FAILED: { 920a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav CharSequence error = (CharSequence) message.obj; 921a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handleOnLayoutFailed(error, sequence); 922a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } break; 923a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 924a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav case MSG_ON_LAYOUT_CANCELED: { 925a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handleOnLayoutCanceled(sequence); 926a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } break; 927a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 928a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 929a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 930a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 931a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final class LayoutResultCallback extends ILayoutResultCallback.Stub { 932a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final WeakReference<Handler> mWeakHandler; 933a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 934a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public LayoutResultCallback(Handler handler) { 935a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mWeakHandler = new WeakReference<>(handler); 936a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 937a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 938a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav @Override 939a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void onLayoutStarted(ICancellationSignal cancellation, int sequence) { 940a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Handler handler = mWeakHandler.get(); 941a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (handler != null) { 942a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handler.obtainMessage(LayoutHandler.MSG_ON_LAYOUT_STARTED, 943a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav sequence, 0, cancellation).sendToTarget(); 944a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 945a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 946a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 947a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav @Override 948a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void onLayoutFinished(PrintDocumentInfo info, boolean changed, int sequence) { 949a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Handler handler = mWeakHandler.get(); 950a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (handler != null) { 951a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handler.obtainMessage(LayoutHandler.MSG_ON_LAYOUT_FINISHED, 952a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav changed ? 1 : 0, sequence, info).sendToTarget(); 953a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 954a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 955a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 956a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav @Override 957a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void onLayoutFailed(CharSequence error, int sequence) { 958a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Handler handler = mWeakHandler.get(); 959a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (handler != null) { 960a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handler.obtainMessage(LayoutHandler.MSG_ON_LAYOUT_FAILED, 961a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav sequence, 0, error).sendToTarget(); 962a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 963a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 964a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 965a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav @Override 966a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void onLayoutCanceled(int sequence) { 967a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Handler handler = mWeakHandler.get(); 968a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (handler != null) { 969a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handler.obtainMessage(LayoutHandler.MSG_ON_LAYOUT_CANCELED, 970a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav sequence, 0).sendToTarget(); 971a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 972a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 973a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 974a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 975a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 976a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final class WriteCommand extends AsyncCommand { 977a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final int mPageCount; 978a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final PageRange[] mPages; 979525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov private final MutexFileProvider mFileProvider; 980a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 981a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final IWriteResultCallback mRemoteResultCallback; 982c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann private final CommandDoneCallback mWriteDoneCallback; 983a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 984a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final Context mContext; 985a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final Handler mHandler; 986a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 987a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public WriteCommand(Context context, Looper looper, IPrintDocumentAdapter adapter, 988a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav RemotePrintDocumentInfo document, int pageCount, PageRange[] pages, 989525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov MutexFileProvider fileProvider, CommandDoneCallback callback) { 990645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann super(looper, adapter, document, callback); 991a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mContext = context; 992a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mHandler = new WriteHandler(looper); 993a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mRemoteResultCallback = new WriteResultCallback(mHandler); 994a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mPageCount = pageCount; 995a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mPages = Arrays.copyOf(pages, pages.length); 996525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov mFileProvider = fileProvider; 997c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann mWriteDoneCallback = callback; 998a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 999a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1000a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav @Override 1001a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void run() { 1002a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav running(); 1003a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1004a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // This is a long running operation as we will be reading fully 1005a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // the written data. In case of a cancellation, we ask the client 1006a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // to stop writing data and close the file descriptor after 1007a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // which we will reach the end of the stream, thus stop reading. 1008a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav new AsyncTask<Void, Void, Void>() { 1009a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav @Override 1010a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav protected Void doInBackground(Void... params) { 1011525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov File file = null; 1012a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav InputStream in = null; 1013a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav OutputStream out = null; 1014a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav ParcelFileDescriptor source = null; 1015a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav ParcelFileDescriptor sink = null; 1016a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav try { 1017525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov file = mFileProvider.acquireFile(null); 1018a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); 1019a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav source = pipe[0]; 1020a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav sink = pipe[1]; 1021a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1022a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav in = new FileInputStream(source.getFileDescriptor()); 1023525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov out = new FileOutputStream(file); 1024a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1025a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Async call to initiate the other process writing the data. 1026a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 1027a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[PERFORMING] write"); 1028a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1029a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mAdapter.write(mPages, sink, mRemoteResultCallback, mSequence); 1030a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1031a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Close the source. It is now held by the client. 1032a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav sink.close(); 1033a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav sink = null; 1034a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1035a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Read the data. 1036a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav final byte[] buffer = new byte[8192]; 1037a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav while (true) { 1038a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav final int readByteCount = in.read(buffer); 1039a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (readByteCount < 0) { 1040a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav break; 1041a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1042a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav out.write(buffer, 0, readByteCount); 1043a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1044a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } catch (RemoteException | IOException e) { 1045a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.e(LOG_TAG, "Error calling write()", e); 1046a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } finally { 1047a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav IoUtils.closeQuietly(in); 1048a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav IoUtils.closeQuietly(out); 1049a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav IoUtils.closeQuietly(sink); 1050a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav IoUtils.closeQuietly(source); 1051525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov if (file != null) { 1052525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov mFileProvider.releaseFile(); 1053525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov } 1054a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1055a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return null; 1056a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1057a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); 1058a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1059a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1060a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private void handleOnWriteStarted(ICancellationSignal cancellation, int sequence) { 1061a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (sequence != mSequence) { 1062a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return; 1063a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1064a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1065a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 1066a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[CALLBACK] onWriteStarted"); 1067a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1068a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1069a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (isCanceling()) { 1070a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav try { 1071a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav cancellation.cancel(); 1072a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } catch (RemoteException re) { 1073a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.e(LOG_TAG, "Error cancelling", re); 1074a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handleOnWriteFailed(null, sequence); 1075a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1076a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } else { 1077a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mCancellation = cancellation; 1078a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1079a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1080a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1081a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private void handleOnWriteFinished(PageRange[] pages, int sequence) { 1082a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (sequence != mSequence) { 1083a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return; 1084a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1085a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1086a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 1087a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[CALLBACK] onWriteFinished"); 1088a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1089a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1090a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav PageRange[] writtenPages = PageRangeUtils.normalize(pages); 1091525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov PageRange[] printedPages = PageRangeUtils.computePrintedPages( 1092525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov mPages, writtenPages, mPageCount); 1093a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1094a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Handle if we got invalid pages 1095a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (printedPages != null) { 1096a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDocument.writtenPages = writtenPages; 1097a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDocument.printedPages = printedPages; 1098a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav completed(); 1099a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } else { 1100a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDocument.writtenPages = null; 1101a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mDocument.printedPages = null; 1102a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav failed(mContext.getString(R.string.print_error_default_message)); 1103a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1104a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1105a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Release the remote cancellation interface. 1106a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mCancellation = null; 1107a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1108a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Done. 1109c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann mWriteDoneCallback.onDone(); 1110a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1111a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1112a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private void handleOnWriteFailed(CharSequence error, int sequence) { 1113a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (sequence != mSequence) { 1114a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return; 1115a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1116a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1117a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 1118a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[CALLBACK] onWriteFailed"); 1119a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1120a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1121a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav failed(error); 1122a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1123a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Release the remote cancellation interface. 1124a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mCancellation = null; 1125a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1126a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Done. 1127c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann mWriteDoneCallback.onDone(); 1128a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1129a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1130a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private void handleOnWriteCanceled(int sequence) { 1131a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (sequence != mSequence) { 1132a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav return; 1133a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1134a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1135a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (DEBUG) { 1136a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.i(LOG_TAG, "[CALLBACK] onWriteCanceled"); 1137a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1138a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1139a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav canceled(); 1140a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1141a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Release the remote cancellation interface. 1142a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mCancellation = null; 1143a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1144a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav // Done. 1145c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann mWriteDoneCallback.onDone(); 1146a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1147a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1148a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final class WriteHandler extends Handler { 1149a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public static final int MSG_ON_WRITE_STARTED = 1; 1150a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public static final int MSG_ON_WRITE_FINISHED = 2; 1151a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public static final int MSG_ON_WRITE_FAILED = 3; 1152a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public static final int MSG_ON_WRITE_CANCELED = 4; 1153a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1154a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public WriteHandler(Looper looper) { 1155a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav super(looper, null, false); 1156a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1157a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1158a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav @Override 1159a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void handleMessage(Message message) { 1160645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann // The command might have been force canceled, see 1161645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann // AsyncCommand.AsyncCommandHandler#handleMessage 1162645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann if (isFailed()) { 1163645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann if (DEBUG) { 116427db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann Log.i(LOG_TAG, "[CALLBACK] on failed write command"); 1165645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann } 1166645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann 1167645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann return; 116827db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann } 116927db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann 117027db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann int what = message.what; 117127db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann switch (what) { 117227db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann case MSG_ON_WRITE_FINISHED: 117327db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann case MSG_ON_WRITE_FAILED: 117427db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann case MSG_ON_WRITE_CANCELED: 1175645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann removeForceCancel(); 117627db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann case MSG_ON_WRITE_STARTED: 117727db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann // Don't remote force-cancel as command is still running and might need to 117827db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann // be canceled later 117927db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann break; 118027db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann } 118127db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann 118227db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann // If we are canceling any result is treated as a cancel 118327db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann if (isCanceling() && what != MSG_ON_WRITE_STARTED) { 118427db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann what = MSG_ON_WRITE_CANCELED; 1185645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann } 1186645a3e1ca6ce26da52fa158ca159a31bd38de77dPhilip P. Moltmann 118727db6611a76a11a5d271dd824167fa1d4b23f944Philip P. Moltmann switch (what) { 1188a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav case MSG_ON_WRITE_STARTED: { 1189a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav ICancellationSignal cancellation = (ICancellationSignal) message.obj; 1190a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav final int sequence = message.arg1; 1191a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handleOnWriteStarted(cancellation, sequence); 1192a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } break; 1193a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1194a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav case MSG_ON_WRITE_FINISHED: { 1195a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav PageRange[] pages = (PageRange[]) message.obj; 1196a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav final int sequence = message.arg1; 1197a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handleOnWriteFinished(pages, sequence); 1198a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } break; 1199a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1200a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav case MSG_ON_WRITE_FAILED: { 1201a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav CharSequence error = (CharSequence) message.obj; 1202a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav final int sequence = message.arg1; 1203a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handleOnWriteFailed(error, sequence); 1204a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } break; 1205a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1206a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav case MSG_ON_WRITE_CANCELED: { 1207a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav final int sequence = message.arg1; 1208a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handleOnWriteCanceled(sequence); 1209a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } break; 1210a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1211a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1212a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1213a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1214a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final class WriteResultCallback extends IWriteResultCallback.Stub { 1215a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final WeakReference<Handler> mWeakHandler; 1216a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1217a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public WriteResultCallback(Handler handler) { 1218a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mWeakHandler = new WeakReference<>(handler); 1219a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1220a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1221a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav @Override 1222a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void onWriteStarted(ICancellationSignal cancellation, int sequence) { 1223a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Handler handler = mWeakHandler.get(); 1224a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (handler != null) { 1225a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handler.obtainMessage(WriteHandler.MSG_ON_WRITE_STARTED, 1226a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav sequence, 0, cancellation).sendToTarget(); 1227a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1228a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1229a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1230a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav @Override 1231a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void onWriteFinished(PageRange[] pages, int sequence) { 1232a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Handler handler = mWeakHandler.get(); 1233a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (handler != null) { 1234a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handler.obtainMessage(WriteHandler.MSG_ON_WRITE_FINISHED, 1235a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav sequence, 0, pages).sendToTarget(); 1236a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1237a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1238a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1239a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav @Override 1240a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void onWriteFailed(CharSequence error, int sequence) { 1241a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Handler handler = mWeakHandler.get(); 1242a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (handler != null) { 1243a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handler.obtainMessage(WriteHandler.MSG_ON_WRITE_FAILED, 1244a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav sequence, 0, error).sendToTarget(); 1245a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1246a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1247a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1248a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav @Override 1249a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void onWriteCanceled(int sequence) { 1250a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Handler handler = mWeakHandler.get(); 1251a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (handler != null) { 1252a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav handler.obtainMessage(WriteHandler.MSG_ON_WRITE_CANCELED, 1253a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav sequence, 0).sendToTarget(); 1254a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1255a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1256a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1257a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1258a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 12594237c92d850b7fb0fa0be15df94e4d1689e353fcSvet Ganov private void onPrintingAppDied() { 12604237c92d850b7fb0fa0be15df94e4d1689e353fcSvet Ganov mState = STATE_FAILED; 12612fb64a5cb160a2615f07ed669aa5738dbb74ad6cSvetoslav new Handler(mLooper).post(new Runnable() { 12622fb64a5cb160a2615f07ed669aa5738dbb74ad6cSvetoslav @Override 12632fb64a5cb160a2615f07ed669aa5738dbb74ad6cSvetoslav public void run() { 12642fb64a5cb160a2615f07ed669aa5738dbb74ad6cSvetoslav mAdapterDeathObserver.onDied(); 12652fb64a5cb160a2615f07ed669aa5738dbb74ad6cSvetoslav } 12662fb64a5cb160a2615f07ed669aa5738dbb74ad6cSvetoslav }); 12672fb64a5cb160a2615f07ed669aa5738dbb74ad6cSvetoslav } 12682fb64a5cb160a2615f07ed669aa5738dbb74ad6cSvetoslav 1269a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private static final class PrintDocumentAdapterObserver 1270a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav extends IPrintDocumentAdapterObserver.Stub { 1271a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav private final WeakReference<RemotePrintDocument> mWeakDocument; 1272a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1273a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public PrintDocumentAdapterObserver(RemotePrintDocument document) { 1274a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav mWeakDocument = new WeakReference<>(document); 1275a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1276a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav 1277a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav @Override 1278a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public void onDestroy() { 1279a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav final RemotePrintDocument document = mWeakDocument.get(); 1280a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav if (document != null) { 12814237c92d850b7fb0fa0be15df94e4d1689e353fcSvet Ganov document.onPrintingAppDied(); 1282a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1283a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1284a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav } 1285a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav} 1286