FileDocCategorySizeDatePackage
RemotePrintDocument.javaAPI DocAndroid 5.1 API40372Thu Mar 12 22:22:42 GMT 2015com.android.printspooler.model

RemotePrintDocument

public final class RemotePrintDocument extends Object

Fields Summary
private static final String
LOG_TAG
private static final boolean
DEBUG
private static final int
STATE_INITIAL
private static final int
STATE_STARTED
private static final int
STATE_UPDATING
private static final int
STATE_UPDATED
private static final int
STATE_FAILED
private static final int
STATE_FINISHED
private static final int
STATE_CANCELING
private static final int
STATE_CANCELED
private static final int
STATE_DESTROYED
private final android.content.Context
mContext
private final RemotePrintDocumentInfo
mDocumentInfo
private final UpdateSpec
mUpdateSpec
private final android.os.Looper
mLooper
private final android.print.IPrintDocumentAdapter
mPrintDocumentAdapter
private final RemoteAdapterDeathObserver
mAdapterDeathObserver
private final UpdateResultCallbacks
mUpdateCallbacks
private final CommandDoneCallback
mCommandResultCallback
private final android.os.IBinder.DeathRecipient
mDeathRecipient
private int
mState
private AsyncCommand
mCurrentCommand
private AsyncCommand
mNextCommand
Constructors Summary
public RemotePrintDocument(android.content.Context context, android.print.IPrintDocumentAdapter adapter, MutexFileProvider fileProvider, RemoteAdapterDeathObserver deathObserver, UpdateResultCallbacks callbacks)


       
          
    

       
           
          
           
    

        
               
              
        mPrintDocumentAdapter = adapter;
        mLooper = context.getMainLooper();
        mContext = context;
        mAdapterDeathObserver = deathObserver;
        mDocumentInfo = new RemotePrintDocumentInfo();
        mDocumentInfo.fileProvider = fileProvider;
        mUpdateCallbacks = callbacks;
        connectToRemoteDocument();
    
Methods Summary
public voidcancel()

        if (DEBUG) {
            Log.i(LOG_TAG, "[CALLED] cancel()");
        }

        if (mState == STATE_CANCELING) {
            return;
        }

        if (mState != STATE_UPDATING) {
            throw new IllegalStateException("Cannot cancel in state:" + stateToString(mState));
        }

        mState = STATE_CANCELING;

        mCurrentCommand.cancel();
    
public voidclearUpdateError()

        if (!hasUpdateError()) {
            throw new IllegalStateException("No update error to clear");
        }
        mState = STATE_STARTED;
    
private voidconnectToRemoteDocument()

        try {
            mPrintDocumentAdapter.asBinder().linkToDeath(mDeathRecipient, 0);
        } catch (RemoteException re) {
            Log.w(LOG_TAG, "The printing process is dead.");
            destroy();
            return;
        }

        try {
            mPrintDocumentAdapter.setObserver(new PrintDocumentAdapterObserver(this));
        } catch (RemoteException re) {
            Log.w(LOG_TAG, "Error setting observer to the print adapter.");
            destroy();
        }
    
public voiddestroy()

        if (DEBUG) {
            Log.i(LOG_TAG, "[CALLED] destroy()");
        }
        if (mState == STATE_DESTROYED) {
            throw new IllegalStateException("Cannot destroy in state:" + stateToString(mState));
        }

        mState = STATE_DESTROYED;

        disconnectFromRemoteDocument();
    
private voiddisconnectFromRemoteDocument()

        try {
            mPrintDocumentAdapter.setObserver(null);
        } catch (RemoteException re) {
            Log.w(LOG_TAG, "Error setting observer to the print adapter.");
            // Keep going - best effort...
        }

        mPrintDocumentAdapter.asBinder().unlinkToDeath(mDeathRecipient, 0);
    
public voidfinish()

        if (DEBUG) {
            Log.i(LOG_TAG, "[CALLED] finish()");
        }
        if (mState != STATE_STARTED && mState != STATE_UPDATED
                && mState != STATE_FAILED && mState != STATE_CANCELING
                && mState != STATE_CANCELED) {
            throw new IllegalStateException("Cannot finish in state:"
                    + stateToString(mState));
        }
        try {
            mPrintDocumentAdapter.finish();
            mState = STATE_FINISHED;
        } catch (RemoteException re) {
            Log.e(LOG_TAG, "Error calling finish()");
            mState = STATE_FAILED;
        }
    
public com.android.printspooler.model.RemotePrintDocument$RemotePrintDocumentInfogetDocumentInfo()

        return mDocumentInfo;
    
public booleanhasLaidOutPages()

        return mDocumentInfo.info != null
                && mDocumentInfo.info.getPageCount() > 0;
    
public booleanhasUpdateError()

        return mState == STATE_FAILED;
    
public booleanisDestroyed()

        return mState == STATE_DESTROYED;
    
public booleanisUpdating()

        return mState == STATE_UPDATING || mState == STATE_CANCELING;
    
public voidkill(java.lang.String reason)

        if (DEBUG) {
            Log.i(LOG_TAG, "[CALLED] kill()");
        }

        try {
            mPrintDocumentAdapter.kill(reason);
        } catch (RemoteException re) {
            Log.e(LOG_TAG, "Error calling kill()", re);
        }
    
private voidnotifyUpdateCanceled()

        if (DEBUG) {
            Log.i(LOG_TAG, "[CALLING] onUpdateCanceled()");
        }
        mUpdateCallbacks.onUpdateCanceled();
    
private voidnotifyUpdateCompleted()

        if (DEBUG) {
            Log.i(LOG_TAG, "[CALLING] onUpdateCompleted()");
        }
        mUpdateCallbacks.onUpdateCompleted(mDocumentInfo);
    
private voidnotifyUpdateFailed(java.lang.CharSequence error)

        if (DEBUG) {
            Log.i(LOG_TAG, "[CALLING] onUpdateCompleted()");
        }
        mUpdateCallbacks.onUpdateFailed(error);
    
private voidonPrintingAppDied()

        mState = STATE_FAILED;
        new Handler(mLooper).post(new Runnable() {
            @Override
            public void run() {
                mAdapterDeathObserver.onDied();
            }
        });
    
private voidrunPendingCommand()

        if (mCurrentCommand != null
                && (mCurrentCommand.isCompleted()
                        || mCurrentCommand.isCanceled())) {
            mCurrentCommand = mNextCommand;
            mNextCommand = null;
        }

        if (mCurrentCommand != null) {
            if (mCurrentCommand.isPending()) {
                mCurrentCommand.run();
            }
            mState = STATE_UPDATING;
        } else {
            mState = STATE_UPDATED;
        }
    
private voidscheduleCommand(com.android.printspooler.model.RemotePrintDocument$AsyncCommand command)

        if (mCurrentCommand == null) {
            mCurrentCommand = command;
        } else {
            mNextCommand = command;
        }
    
public voidstart()

        if (DEBUG) {
            Log.i(LOG_TAG, "[CALLED] start()");
        }
        if (mState != STATE_INITIAL) {
            throw new IllegalStateException("Cannot start in state:" + stateToString(mState));
        }
        try {
            mPrintDocumentAdapter.start();
            mState = STATE_STARTED;
        } catch (RemoteException re) {
            Log.e(LOG_TAG, "Error calling start()", re);
            mState = STATE_FAILED;
        }
    
private static java.lang.StringstateToString(int state)

        switch (state) {
            case STATE_FINISHED: {
                return "STATE_FINISHED";
            }
            case STATE_FAILED: {
                return "STATE_FAILED";
            }
            case STATE_STARTED: {
                return "STATE_STARTED";
            }
            case STATE_UPDATING: {
                return "STATE_UPDATING";
            }
            case STATE_UPDATED: {
                return "STATE_UPDATED";
            }
            case STATE_CANCELING: {
                return "STATE_CANCELING";
            }
            case STATE_CANCELED: {
                return "STATE_CANCELED";
            }
            case STATE_DESTROYED: {
                return "STATE_DESTROYED";
            }
            default: {
                return "STATE_UNKNOWN";
            }
        }
    
public booleanupdate(android.print.PrintAttributes attributes, android.print.PageRange[] pages, boolean preview)

        boolean willUpdate;

        if (DEBUG) {
            Log.i(LOG_TAG, "[CALLED] update()");
        }

        if (hasUpdateError()) {
            throw new IllegalStateException("Cannot update without a clearing the failure");
        }

        if (mState == STATE_INITIAL || mState == STATE_FINISHED || mState == STATE_DESTROYED) {
            throw new IllegalStateException("Cannot update in state:" + stateToString(mState));
        }

        // We schedule a layout if the constraints changed.
        if (!mUpdateSpec.hasSameConstraints(attributes, preview)) {
            willUpdate = true;

            // If there is a current command that is running we ask for a
            // cancellation and start over.
            if (mCurrentCommand != null && (mCurrentCommand.isRunning()
                    || mCurrentCommand.isPending())) {
                mCurrentCommand.cancel();
            }

            // Schedule a layout command.
            PrintAttributes oldAttributes = mDocumentInfo.attributes != null
                    ? mDocumentInfo.attributes : new PrintAttributes.Builder().build();
            AsyncCommand command = new LayoutCommand(mLooper, mPrintDocumentAdapter,
                  mDocumentInfo, oldAttributes, attributes, preview, mCommandResultCallback);
            scheduleCommand(command);

            mState = STATE_UPDATING;
        // If no layout in progress and we don't have all pages - schedule a write.
        } else if ((!(mCurrentCommand instanceof LayoutCommand)
                || (!mCurrentCommand.isPending() && !mCurrentCommand.isRunning()))
                && pages != null && !PageRangeUtils.contains(mUpdateSpec.pages, pages,
                mDocumentInfo.info.getPageCount())) {
            willUpdate = true;

            // Cancel the current write as a new one is to be scheduled.
            if (mCurrentCommand instanceof WriteCommand
                    && (mCurrentCommand.isPending() || mCurrentCommand.isRunning())) {
                mCurrentCommand.cancel();
            }

            // Schedule a write command.
            AsyncCommand command = new WriteCommand(mContext, mLooper, mPrintDocumentAdapter,
                    mDocumentInfo, mDocumentInfo.info.getPageCount(), pages,
                    mDocumentInfo.fileProvider, mCommandResultCallback);
            scheduleCommand(command);

            mState = STATE_UPDATING;
        } else {
            willUpdate = false;
            if (DEBUG) {
                Log.i(LOG_TAG, "[SKIPPING] No update needed");
            }
        }

        // Keep track of what is requested.
        mUpdateSpec.update(attributes, preview, pages);

        runPendingCommand();

        return willUpdate;
    
public voidwriteContent(android.content.ContentResolver contentResolver, android.net.Uri uri)

        File file = null;
        InputStream in = null;
        OutputStream out = null;
        try {
            file = mDocumentInfo.fileProvider.acquireFile(null);
            in = new FileInputStream(file);
            out = contentResolver.openOutputStream(uri);
            final byte[] buffer = new byte[8192];
            while (true) {
                final int readByteCount = in.read(buffer);
                if (readByteCount < 0) {
                    break;
                }
                out.write(buffer, 0, readByteCount);
            }
        } catch (IOException e) {
            Log.e(LOG_TAG, "Error writing document content.", e);
        } finally {
            IoUtils.closeQuietly(in);
            IoUtils.closeQuietly(out);
            if (file != null) {
                mDocumentInfo.fileProvider.releaseFile();
            }
        }