/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.printspooler.ui;

import android.annotation.NonNull;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.LoaderManager;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.Loader;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.database.DataSetObserver;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.UserManager;
import android.print.IPrintDocumentAdapter;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintAttributes.MediaSize;
import android.print.PrintAttributes.Resolution;
import android.print.PrintDocumentInfo;
import android.print.PrintJobInfo;
import android.print.PrintManager;
import android.print.PrintServicesLoader;
import android.print.PrinterCapabilitiesInfo;
import android.print.PrinterId;
import android.print.PrinterInfo;
import android.printservice.PrintService;
import android.printservice.PrintServiceInfo;
import android.provider.DocumentsContract;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.printspooler.R;
import com.android.printspooler.model.MutexFileProvider;
import com.android.printspooler.model.PrintSpoolerProvider;
import com.android.printspooler.model.PrintSpoolerService;
import com.android.printspooler.model.RemotePrintDocument;
import com.android.printspooler.model.RemotePrintDocument.RemotePrintDocumentInfo;
import com.android.printspooler.renderer.IPdfEditor;
import com.android.printspooler.renderer.PdfManipulationService;
import com.android.printspooler.util.ApprovedPrintServices;
import com.android.printspooler.util.MediaSizeUtils;
import com.android.printspooler.util.MediaSizeUtils.MediaSizeComparator;
import com.android.printspooler.util.PageRangeUtils;
import com.android.printspooler.widget.ClickInterceptSpinner;
import com.android.printspooler.widget.PrintContentView;
import com.android.printspooler.widget.PrintContentView.OptionsStateChangeListener;
import com.android.printspooler.widget.PrintContentView.OptionsStateController;

import libcore.io.IoUtils;
import libcore.io.Streams;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;

public class PrintActivity extends Activity implements RemotePrintDocument.UpdateResultCallbacks,
        PrintErrorFragment.OnActionListener, PageAdapter.ContentCallbacks,
        OptionsStateChangeListener, OptionsStateController,
        LoaderManager.LoaderCallbacks<List<PrintServiceInfo>> {
    private static final String LOG_TAG = "PrintActivity";

    private static final boolean DEBUG = false;

    // Constants for MetricsLogger.count and MetricsLogger.histo
    private static final String PRINT_PAGES_HISTO = "print_pages";
    private static final String PRINT_DEFAULT_COUNT = "print_default";
    private static final String PRINT_WORK_COUNT = "print_work";

    private static final String FRAGMENT_TAG = "FRAGMENT_TAG";

    private static final String HAS_PRINTED_PREF = "has_printed";

    private static final int LOADER_ID_ENABLED_PRINT_SERVICES = 1;
    private static final int LOADER_ID_PRINT_REGISTRY = 2;
    private static final int LOADER_ID_PRINT_REGISTRY_INT = 3;

    private static final int ORIENTATION_PORTRAIT = 0;
    private static final int ORIENTATION_LANDSCAPE = 1;

    private static final int ACTIVITY_REQUEST_CREATE_FILE = 1;
    private static final int ACTIVITY_REQUEST_SELECT_PRINTER = 2;
    private static final int ACTIVITY_REQUEST_POPULATE_ADVANCED_PRINT_OPTIONS = 3;

    private static final int DEST_ADAPTER_MAX_ITEM_COUNT = 9;

    private static final int DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF = Integer.MAX_VALUE;
    private static final int DEST_ADAPTER_ITEM_ID_MORE = Integer.MAX_VALUE - 1;

    private static final int STATE_INITIALIZING = 0;
    private static final int STATE_CONFIGURING = 1;
    private static final int STATE_PRINT_CONFIRMED = 2;
    private static final int STATE_PRINT_CANCELED = 3;
    private static final int STATE_UPDATE_FAILED = 4;
    private static final int STATE_CREATE_FILE_FAILED = 5;
    private static final int STATE_PRINTER_UNAVAILABLE = 6;
    private static final int STATE_UPDATE_SLOW = 7;
    private static final int STATE_PRINT_COMPLETED = 8;

    private static final int UI_STATE_PREVIEW = 0;
    private static final int UI_STATE_ERROR = 1;
    private static final int UI_STATE_PROGRESS = 2;

    // see frameworks/base/proto/src/metrics_constats.proto -> ACTION_PRINT_JOB_OPTIONS
    private static final int PRINT_JOB_OPTIONS_SUBTYPE_COPIES = 1;
    private static final int PRINT_JOB_OPTIONS_SUBTYPE_COLOR_MODE = 2;
    private static final int PRINT_JOB_OPTIONS_SUBTYPE_DUPLEX_MODE = 3;
    private static final int PRINT_JOB_OPTIONS_SUBTYPE_MEDIA_SIZE = 4;
    private static final int PRINT_JOB_OPTIONS_SUBTYPE_ORIENTATION = 5;
    private static final int PRINT_JOB_OPTIONS_SUBTYPE_PAGE_RANGE = 6;

    private static final int MIN_COPIES = 1;
    private static final String MIN_COPIES_STRING = String.valueOf(MIN_COPIES);

    private boolean mIsOptionsUiBound = false;

    private final PrinterAvailabilityDetector mPrinterAvailabilityDetector =
            new PrinterAvailabilityDetector();

    private final OnFocusChangeListener mSelectAllOnFocusListener = new SelectAllOnFocusListener();

    private PrintSpoolerProvider mSpoolerProvider;

    private PrintPreviewController mPrintPreviewController;

    private PrintJobInfo mPrintJob;
    private RemotePrintDocument mPrintedDocument;
    private PrinterRegistry mPrinterRegistry;

    private EditText mCopiesEditText;

    private TextView mPageRangeTitle;
    private EditText mPageRangeEditText;

    private ClickInterceptSpinner mDestinationSpinner;
    private DestinationAdapter mDestinationSpinnerAdapter;
    private boolean mShowDestinationPrompt;

    private Spinner mMediaSizeSpinner;
    private ArrayAdapter<SpinnerItem<MediaSize>> mMediaSizeSpinnerAdapter;

    private Spinner mColorModeSpinner;
    private ArrayAdapter<SpinnerItem<Integer>> mColorModeSpinnerAdapter;

    private Spinner mDuplexModeSpinner;
    private ArrayAdapter<SpinnerItem<Integer>> mDuplexModeSpinnerAdapter;

    private Spinner mOrientationSpinner;
    private ArrayAdapter<SpinnerItem<Integer>> mOrientationSpinnerAdapter;

    private Spinner mRangeOptionsSpinner;

    private PrintContentView mOptionsContent;

    private View mSummaryContainer;
    private TextView mSummaryCopies;
    private TextView mSummaryPaperSize;

    private Button mMoreOptionsButton;

    private ImageView mPrintButton;

    private ProgressMessageController mProgressMessageController;
    private MutexFileProvider mFileProvider;

    private MediaSizeComparator mMediaSizeComparator;

    private PrinterInfo mCurrentPrinter;

    private PageRange[] mSelectedPages;

    private String mCallingPackageName;

    private int mCurrentPageCount;

    private int mState = STATE_INITIALIZING;

    private int mUiState = UI_STATE_PREVIEW;

    /** The ID of the printer initially set */
    private PrinterId mDefaultPrinter;

    /** Observer for changes to the printers */
    private PrintersObserver mPrintersObserver;

    /** Advances options activity name for current printer */
    private ComponentName mAdvancedPrintOptionsActivity;

    /** Whether at least one print services is enabled or not */
    private boolean mArePrintServicesEnabled;

    /** Is doFinish() already in progress */
    private boolean mIsFinishing;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setTitle(R.string.print_dialog);

        Bundle extras = getIntent().getExtras();

        mPrintJob = extras.getParcelable(PrintManager.EXTRA_PRINT_JOB);
        if (mPrintJob == null) {
            throw new IllegalArgumentException(PrintManager.EXTRA_PRINT_JOB
                    + " cannot be null");
        }
        if (mPrintJob.getAttributes() == null) {
            mPrintJob.setAttributes(new PrintAttributes.Builder().build());
        }

        final IBinder adapter = extras.getBinder(PrintManager.EXTRA_PRINT_DOCUMENT_ADAPTER);
        if (adapter == null) {
            throw new IllegalArgumentException(PrintManager.EXTRA_PRINT_DOCUMENT_ADAPTER
                    + " cannot be null");
        }

        mCallingPackageName = extras.getString(DocumentsContract.EXTRA_PACKAGE_NAME);

        if (savedInstanceState == null) {
            MetricsLogger.action(this, MetricsEvent.PRINT_PREVIEW, mCallingPackageName);
        }

        // This will take just a few milliseconds, so just wait to
        // bind to the local service before showing the UI.
        mSpoolerProvider = new PrintSpoolerProvider(this,
                new Runnable() {
            @Override
            public void run() {
                if (isFinishing() || isDestroyed()) {
                    // onPause might have not been able to cancel the job, see PrintActivity#onPause
                    // To be sure, cancel the job again. Double canceling does no harm.
                    mSpoolerProvider.getSpooler().setPrintJobState(mPrintJob.getId(),
                            PrintJobInfo.STATE_CANCELED, null);
                } else {
                    onConnectedToPrintSpooler(adapter);
                }
            }
        });

        getLoaderManager().initLoader(LOADER_ID_ENABLED_PRINT_SERVICES, null, this);
    }

    private void onConnectedToPrintSpooler(final IBinder documentAdapter) {
        // Now that we are bound to the print spooler service,
        // create the printer registry and wait for it to get
        // the first batch of results which will be delivered
        // after reading historical data. This should be pretty
        // fast, so just wait before showing the UI.
        mPrinterRegistry = new PrinterRegistry(PrintActivity.this, () -> {
            (new Handler(getMainLooper())).post(() -> onPrinterRegistryReady(documentAdapter));
        }, LOADER_ID_PRINT_REGISTRY, LOADER_ID_PRINT_REGISTRY_INT);
    }

    private void onPrinterRegistryReady(IBinder documentAdapter) {
        // Now that we are bound to the local print spooler service
        // and the printer registry loaded the historical printers
        // we can show the UI without flickering.
        setContentView(R.layout.print_activity);

        try {
            mFileProvider = new MutexFileProvider(
                    PrintSpoolerService.generateFileForPrintJob(
                            PrintActivity.this, mPrintJob.getId()));
        } catch (IOException ioe) {
            // At this point we cannot recover, so just take it down.
            throw new IllegalStateException("Cannot create print job file", ioe);
        }

        mPrintPreviewController = new PrintPreviewController(PrintActivity.this,
                mFileProvider);
        mPrintedDocument = new RemotePrintDocument(PrintActivity.this,
                IPrintDocumentAdapter.Stub.asInterface(documentAdapter),
                mFileProvider, new RemotePrintDocument.RemoteAdapterDeathObserver() {
            @Override
            public void onDied() {
                Log.w(LOG_TAG, "Printing app died unexpectedly");

                // If we are finishing or we are in a state that we do not need any
                // data from the printing app, then no need to finish.
                if (isFinishing() || isDestroyed() ||
                        (isFinalState(mState) && !mPrintedDocument.isUpdating())) {
                    return;
                }
                setState(STATE_PRINT_CANCELED);
                mPrintedDocument.cancel(true);
                doFinish();
            }
        }, PrintActivity.this);
        mProgressMessageController = new ProgressMessageController(
                PrintActivity.this);
        mMediaSizeComparator = new MediaSizeComparator(PrintActivity.this);
        mDestinationSpinnerAdapter = new DestinationAdapter();

        bindUi();
        updateOptionsUi();

        // Now show the updated UI to avoid flicker.
        mOptionsContent.setVisibility(View.VISIBLE);
        mSelectedPages = computeSelectedPages();
        mPrintedDocument.start();

        ensurePreviewUiShown();

        setState(STATE_CONFIGURING);
    }

    @Override
    public void onStart() {
        super.onStart();
        if (mPrinterRegistry != null && mCurrentPrinter != null) {
            mPrinterRegistry.setTrackedPrinter(mCurrentPrinter.getId());
        }
    }

    @Override
    public void onPause() {
        PrintSpoolerService spooler = mSpoolerProvider.getSpooler();

        if (mState == STATE_INITIALIZING) {
            if (isFinishing()) {
                if (spooler != null) {
                    spooler.setPrintJobState(mPrintJob.getId(), PrintJobInfo.STATE_CANCELED, null);
                }
            }
            super.onPause();
            return;
        }

        if (isFinishing()) {
            spooler.updatePrintJobUserConfigurableOptionsNoPersistence(mPrintJob);

            switch (mState) {
                case STATE_PRINT_COMPLETED: {
                    if (mCurrentPrinter == mDestinationSpinnerAdapter.getPdfPrinter()) {
                        spooler.setPrintJobState(mPrintJob.getId(), PrintJobInfo.STATE_COMPLETED,
                                null);
                    } else {
                        spooler.setPrintJobState(mPrintJob.getId(), PrintJobInfo.STATE_QUEUED,
                                null);
                    }
                } break;

                case STATE_CREATE_FILE_FAILED: {
                    spooler.setPrintJobState(mPrintJob.getId(), PrintJobInfo.STATE_FAILED,
                            getString(R.string.print_write_error_message));
                } break;

                default: {
                    spooler.setPrintJobState(mPrintJob.getId(), PrintJobInfo.STATE_CANCELED, null);
                } break;
            }
        }

        super.onPause();
    }

    @Override
    protected void onStop() {
        mPrinterAvailabilityDetector.cancel();

        if (mPrinterRegistry != null) {
            mPrinterRegistry.setTrackedPrinter(null);
        }

        super.onStop();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            event.startTracking();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (mState == STATE_INITIALIZING) {
            doFinish();
            return true;
        }

        if (mState == STATE_PRINT_CANCELED || mState == STATE_PRINT_CONFIRMED
                || mState == STATE_PRINT_COMPLETED) {
            return true;
        }

        if (keyCode == KeyEvent.KEYCODE_BACK
                && event.isTracking() && !event.isCanceled()) {
            if (mPrintPreviewController != null && mPrintPreviewController.isOptionsOpened()
                    && !hasErrors()) {
                mPrintPreviewController.closeOptions();
            } else {
                cancelPrint();
            }
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }

    @Override
    public void onRequestContentUpdate() {
        if (canUpdateDocument()) {
            updateDocument(false);
        }
    }

    @Override
    public void onMalformedPdfFile() {
        onPrintDocumentError("Cannot print a malformed PDF file");
    }

    @Override
    public void onSecurePdfFile() {
        onPrintDocumentError("Cannot print a password protected PDF file");
    }

    private void onPrintDocumentError(String message) {
        setState(mProgressMessageController.cancel());
        ensureErrorUiShown(null, PrintErrorFragment.ACTION_RETRY);

        setState(STATE_UPDATE_FAILED);

        mPrintedDocument.kill(message);
    }

    @Override
    public void onActionPerformed() {
        if (mState == STATE_UPDATE_FAILED
                && canUpdateDocument() && updateDocument(true)) {
            ensurePreviewUiShown();
            setState(STATE_CONFIGURING);
        }
    }

    @Override
    public void onUpdateCanceled() {
        if (DEBUG) {
            Log.i(LOG_TAG, "onUpdateCanceled()");
        }

        setState(mProgressMessageController.cancel());
        ensurePreviewUiShown();

        switch (mState) {
            case STATE_PRINT_CONFIRMED: {
                requestCreatePdfFileOrFinish();
            } break;

            case STATE_CREATE_FILE_FAILED:
            case STATE_PRINT_COMPLETED:
            case STATE_PRINT_CANCELED: {
                doFinish();
            } break;
        }
    }

    @Override
    public void onUpdateCompleted(RemotePrintDocumentInfo document) {
        if (DEBUG) {
            Log.i(LOG_TAG, "onUpdateCompleted()");
        }

        setState(mProgressMessageController.cancel());
        ensurePreviewUiShown();

        // Update the print job with the info for the written document. The page
        // count we get from the remote document is the pages in the document from
        // the app perspective but the print job should contain the page count from
        // print service perspective which is the pages in the written PDF not the
        // pages in the printed document.
        PrintDocumentInfo info = document.info;
        if (info != null) {
            final int pageCount = PageRangeUtils.getNormalizedPageCount(
                    document.pagesWrittenToFile, getAdjustedPageCount(info));
            PrintDocumentInfo adjustedInfo = new PrintDocumentInfo.Builder(info.getName())
                    .setContentType(info.getContentType())
                    .setPageCount(pageCount)
                    .build();

            File file = mFileProvider.acquireFile(null);
            try {
                adjustedInfo.setDataSize(file.length());
            } finally {
                mFileProvider.releaseFile();
            }

            mPrintJob.setDocumentInfo(adjustedInfo);
            mPrintJob.setPages(document.pagesInFileToPrint);
        }

        switch (mState) {
            case STATE_PRINT_CONFIRMED: {
                requestCreatePdfFileOrFinish();
            } break;

            case STATE_CREATE_FILE_FAILED:
            case STATE_PRINT_COMPLETED:
            case STATE_PRINT_CANCELED: {
                updateOptionsUi();

                doFinish();
            } break;

            default: {
                updatePrintPreviewController(document.changed);

                setState(STATE_CONFIGURING);
            } break;
        }
    }

    @Override
    public void onUpdateFailed(CharSequence error) {
        if (DEBUG) {
            Log.i(LOG_TAG, "onUpdateFailed()");
        }

        setState(mProgressMessageController.cancel());
        ensureErrorUiShown(error, PrintErrorFragment.ACTION_RETRY);

        if (mState == STATE_CREATE_FILE_FAILED
                || mState == STATE_PRINT_COMPLETED
                || mState == STATE_PRINT_CANCELED) {
            doFinish();
        }

        setState(STATE_UPDATE_FAILED);
    }

    @Override
    public void onOptionsOpened() {
        MetricsLogger.action(this, MetricsEvent.PRINT_JOB_OPTIONS);
        updateSelectedPagesFromPreview();
    }

    @Override
    public void onOptionsClosed() {
        // Make sure the IME is not on the way of preview as
        // the user may have used it to type copies or range.
        InputMethodManager imm = getSystemService(InputMethodManager.class);
        imm.hideSoftInputFromWindow(mDestinationSpinner.getWindowToken(), 0);
    }

    private void updatePrintPreviewController(boolean contentUpdated) {
        // If we have not heard from the application, do nothing.
        RemotePrintDocumentInfo documentInfo = mPrintedDocument.getDocumentInfo();
        if (!documentInfo.laidout) {
            return;
        }

        // Update the preview controller.
        mPrintPreviewController.onContentUpdated(contentUpdated,
                getAdjustedPageCount(documentInfo.info),
                mPrintedDocument.getDocumentInfo().pagesWrittenToFile,
                mSelectedPages, mPrintJob.getAttributes().getMediaSize(),
                mPrintJob.getAttributes().getMinMargins());
    }


    @Override
    public boolean canOpenOptions() {
        return true;
    }

    @Override
    public boolean canCloseOptions() {
        return !hasErrors();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        mMediaSizeComparator.onConfigurationChanged(newConfig);

        if (mPrintPreviewController != null) {
            mPrintPreviewController.onOrientationChanged();
        }
    }

    @Override
    protected void onDestroy() {
        if (mPrintedDocument != null) {
            mPrintedDocument.cancel(true);
        }

        doFinish();

        super.onDestroy();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case ACTIVITY_REQUEST_CREATE_FILE: {
                onStartCreateDocumentActivityResult(resultCode, data);
            } break;

            case ACTIVITY_REQUEST_SELECT_PRINTER: {
                onSelectPrinterActivityResult(resultCode, data);
            } break;

            case ACTIVITY_REQUEST_POPULATE_ADVANCED_PRINT_OPTIONS: {
                onAdvancedPrintOptionsActivityResult(resultCode, data);
            } break;
        }
    }

    private void startCreateDocumentActivity() {
        if (!isResumed()) {
            return;
        }
        PrintDocumentInfo info = mPrintedDocument.getDocumentInfo().info;
        if (info == null) {
            return;
        }
        Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
        intent.setType("application/pdf");
        intent.putExtra(Intent.EXTRA_TITLE, info.getName());
        intent.putExtra(DocumentsContract.EXTRA_PACKAGE_NAME, mCallingPackageName);

        try {
            startActivityForResult(intent, ACTIVITY_REQUEST_CREATE_FILE);
        } catch (Exception e) {
            Log.e(LOG_TAG, "Could not create file", e);
            Toast.makeText(this, getString(R.string.could_not_create_file),
                    Toast.LENGTH_SHORT).show();
            onStartCreateDocumentActivityResult(RESULT_CANCELED, null);
        }
    }

    private void onStartCreateDocumentActivityResult(int resultCode, Intent data) {
        if (resultCode == RESULT_OK && data != null) {
            updateOptionsUi();
            final Uri uri = data.getData();

            countPrintOperation(getPackageName());

            // Calling finish here does not invoke lifecycle callbacks but we
            // update the print job in onPause if finishing, hence post a message.
            mDestinationSpinner.post(new Runnable() {
                @Override
                public void run() {
                    transformDocumentAndFinish(uri);
                }
            });
        } else if (resultCode == RESULT_CANCELED) {
            if (DEBUG) {
                Log.i(LOG_TAG, "[state]" + STATE_CONFIGURING);
            }

            mState = STATE_CONFIGURING;

            // The previous update might have been canceled
            updateDocument(false);

            updateOptionsUi();
        } else {
            setState(STATE_CREATE_FILE_FAILED);
            // Calling finish here does not invoke lifecycle callbacks but we
            // update the print job in onPause if finishing, hence post a message.
            mDestinationSpinner.post(new Runnable() {
                @Override
                public void run() {
                    doFinish();
                }
            });
        }
    }

    private void startSelectPrinterActivity() {
        Intent intent = new Intent(this, SelectPrinterActivity.class);
        startActivityForResult(intent, ACTIVITY_REQUEST_SELECT_PRINTER);
    }

    private void onSelectPrinterActivityResult(int resultCode, Intent data) {
        if (resultCode == RESULT_OK && data != null) {
            PrinterInfo printerInfo = data.getParcelableExtra(
                    SelectPrinterActivity.INTENT_EXTRA_PRINTER);
            if (printerInfo != null) {
                mCurrentPrinter = printerInfo;
                mPrintJob.setPrinterId(printerInfo.getId());
                mPrintJob.setPrinterName(printerInfo.getName());

                if (canPrint(printerInfo)) {
                    updatePrintAttributesFromCapabilities(printerInfo.getCapabilities());
                    onPrinterAvailable(printerInfo);
                } else {
                    onPrinterUnavailable(printerInfo);
                }

                mDestinationSpinnerAdapter.ensurePrinterInVisibleAdapterPosition(printerInfo);

                MetricsLogger.action(this, MetricsEvent.ACTION_PRINTER_SELECT_ALL,
                        printerInfo.getId().getServiceName().getPackageName());
            }
        }

        if (mCurrentPrinter != null) {
            // Trigger PrintersObserver.onChanged() to adjust selection back to current printer
            mDestinationSpinnerAdapter.notifyDataSetChanged();
        }
    }

    private void startAdvancedPrintOptionsActivity(PrinterInfo printer) {
        if (mAdvancedPrintOptionsActivity == null) {
            return;
        }

        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.setComponent(mAdvancedPrintOptionsActivity);

        List<ResolveInfo> resolvedActivities = getPackageManager()
                .queryIntentActivities(intent, 0);
        if (resolvedActivities.isEmpty()) {
            return;
        }

        // The activity is a component name, therefore it is one or none.
        if (resolvedActivities.get(0).activityInfo.exported) {
            PrintJobInfo.Builder printJobBuilder = new PrintJobInfo.Builder(mPrintJob);
            printJobBuilder.setPages(mSelectedPages);

            intent.putExtra(PrintService.EXTRA_PRINT_JOB_INFO, printJobBuilder.build());
            intent.putExtra(PrintService.EXTRA_PRINTER_INFO, printer);
            intent.putExtra(PrintService.EXTRA_PRINT_DOCUMENT_INFO,
                    mPrintedDocument.getDocumentInfo().info);

            // This is external activity and may not be there.
            try {
                startActivityForResult(intent, ACTIVITY_REQUEST_POPULATE_ADVANCED_PRINT_OPTIONS);
            } catch (ActivityNotFoundException anfe) {
                Log.e(LOG_TAG, "Error starting activity for intent: " + intent, anfe);
            }
        }
    }

    private void onAdvancedPrintOptionsActivityResult(int resultCode, Intent data) {
        if (resultCode != RESULT_OK || data == null) {
            return;
        }

        PrintJobInfo printJobInfo = data.getParcelableExtra(PrintService.EXTRA_PRINT_JOB_INFO);

        if (printJobInfo == null) {
            return;
        }

        // Take the advanced options without interpretation.
        mPrintJob.setAdvancedOptions(printJobInfo.getAdvancedOptions());

        if (printJobInfo.getCopies() < 1) {
            Log.w(LOG_TAG, "Cannot apply return value from advanced options activity. Copies " +
                    "must be 1 or more. Actual value is: " + printJobInfo.getCopies() + ". " +
                    "Ignoring.");
        } else {
            mCopiesEditText.setText(String.valueOf(printJobInfo.getCopies()));
            mPrintJob.setCopies(printJobInfo.getCopies());
        }

        PrintAttributes currAttributes = mPrintJob.getAttributes();
        PrintAttributes newAttributes = printJobInfo.getAttributes();

        if (newAttributes != null) {
            // Take the media size only if the current printer supports is.
            MediaSize oldMediaSize = currAttributes.getMediaSize();
            MediaSize newMediaSize = newAttributes.getMediaSize();
            if (newMediaSize != null && !oldMediaSize.equals(newMediaSize)) {
                final int mediaSizeCount = mMediaSizeSpinnerAdapter.getCount();
                MediaSize newMediaSizePortrait = newAttributes.getMediaSize().asPortrait();
                for (int i = 0; i < mediaSizeCount; i++) {
                    MediaSize supportedSizePortrait = mMediaSizeSpinnerAdapter.getItem(i)
                            .value.asPortrait();
                    if (supportedSizePortrait.equals(newMediaSizePortrait)) {
                        currAttributes.setMediaSize(newMediaSize);
                        mMediaSizeSpinner.setSelection(i);
                        if (currAttributes.getMediaSize().isPortrait()) {
                            if (mOrientationSpinner.getSelectedItemPosition() != 0) {
                                mOrientationSpinner.setSelection(0);
                            }
                        } else {
                            if (mOrientationSpinner.getSelectedItemPosition() != 1) {
                                mOrientationSpinner.setSelection(1);
                            }
                        }
                        break;
                    }
                }
            }

            // Take the resolution only if the current printer supports is.
            Resolution oldResolution = currAttributes.getResolution();
            Resolution newResolution = newAttributes.getResolution();
            if (!oldResolution.equals(newResolution)) {
                PrinterCapabilitiesInfo capabilities = mCurrentPrinter.getCapabilities();
                if (capabilities != null) {
                    List<Resolution> resolutions = capabilities.getResolutions();
                    final int resolutionCount = resolutions.size();
                    for (int i = 0; i < resolutionCount; i++) {
                        Resolution resolution = resolutions.get(i);
                        if (resolution.equals(newResolution)) {
                            currAttributes.setResolution(resolution);
                            break;
                        }
                    }
                }
            }

            // Take the color mode only if the current printer supports it.
            final int currColorMode = currAttributes.getColorMode();
            final int newColorMode = newAttributes.getColorMode();
            if (currColorMode != newColorMode) {
                final int colorModeCount = mColorModeSpinner.getCount();
                for (int i = 0; i < colorModeCount; i++) {
                    final int supportedColorMode = mColorModeSpinnerAdapter.getItem(i).value;
                    if (supportedColorMode == newColorMode) {
                        currAttributes.setColorMode(newColorMode);
                        mColorModeSpinner.setSelection(i);
                        break;
                    }
                }
            }

            // Take the duplex mode only if the current printer supports it.
            final int currDuplexMode = currAttributes.getDuplexMode();
            final int newDuplexMode = newAttributes.getDuplexMode();
            if (currDuplexMode != newDuplexMode) {
                final int duplexModeCount = mDuplexModeSpinner.getCount();
                for (int i = 0; i < duplexModeCount; i++) {
                    final int supportedDuplexMode = mDuplexModeSpinnerAdapter.getItem(i).value;
                    if (supportedDuplexMode == newDuplexMode) {
                        currAttributes.setDuplexMode(newDuplexMode);
                        mDuplexModeSpinner.setSelection(i);
                        break;
                    }
                }
            }
        }

        // Handle selected page changes making sure they are in the doc.
        PrintDocumentInfo info = mPrintedDocument.getDocumentInfo().info;
        final int pageCount = (info != null) ? getAdjustedPageCount(info) : 0;
        PageRange[] pageRanges = printJobInfo.getPages();
        if (pageRanges != null && pageCount > 0) {
            pageRanges = PageRangeUtils.normalize(pageRanges);

            List<PageRange> validatedList = new ArrayList<>();
            final int rangeCount = pageRanges.length;
            for (int i = 0; i < rangeCount; i++) {
                PageRange pageRange = pageRanges[i];
                if (pageRange.getEnd() >= pageCount) {
                    final int rangeStart = pageRange.getStart();
                    final int rangeEnd = pageCount - 1;
                    if (rangeStart <= rangeEnd) {
                        pageRange = new PageRange(rangeStart, rangeEnd);
                        validatedList.add(pageRange);
                    }
                    break;
                }
                validatedList.add(pageRange);
            }

            if (!validatedList.isEmpty()) {
                PageRange[] validatedArray = new PageRange[validatedList.size()];
                validatedList.toArray(validatedArray);
                updateSelectedPages(validatedArray, pageCount);
            }
        }

        // Update the content if needed.
        if (canUpdateDocument()) {
            updateDocument(false);
        }
    }

    private void setState(int state) {
        if (isFinalState(mState)) {
            if (isFinalState(state)) {
                if (DEBUG) {
                    Log.i(LOG_TAG, "[state]" + state);
                }
                mState = state;
                updateOptionsUi();
            }
        } else {
            if (DEBUG) {
                Log.i(LOG_TAG, "[state]" + state);
            }
            mState = state;
            updateOptionsUi();
        }
    }

    private static boolean isFinalState(int state) {
        return state == STATE_PRINT_CANCELED
                || state == STATE_PRINT_COMPLETED
                || state == STATE_CREATE_FILE_FAILED;
    }

    private void updateSelectedPagesFromPreview() {
        PageRange[] selectedPages = mPrintPreviewController.getSelectedPages();
        if (!Arrays.equals(mSelectedPages, selectedPages)) {
            updateSelectedPages(selectedPages,
                    getAdjustedPageCount(mPrintedDocument.getDocumentInfo().info));
        }
    }

    private void updateSelectedPages(PageRange[] selectedPages, int pageInDocumentCount) {
        if (selectedPages == null || selectedPages.length <= 0) {
            return;
        }

        selectedPages = PageRangeUtils.normalize(selectedPages);

        // Handle the case where all pages are specified explicitly
        // instead of the *all pages* constant.
        if (PageRangeUtils.isAllPages(selectedPages, pageInDocumentCount)) {
            selectedPages = new PageRange[] {PageRange.ALL_PAGES};
        }

        if (Arrays.equals(mSelectedPages, selectedPages)) {
            return;
        }

        mSelectedPages = selectedPages;
        mPrintJob.setPages(selectedPages);

        if (Arrays.equals(selectedPages, PageRange.ALL_PAGES_ARRAY)) {
            if (mRangeOptionsSpinner.getSelectedItemPosition() != 0) {
                mRangeOptionsSpinner.setSelection(0);
                mPageRangeEditText.setText("");
            }
        } else if (selectedPages[0].getStart() >= 0
                && selectedPages[selectedPages.length - 1].getEnd() < pageInDocumentCount) {
            if (mRangeOptionsSpinner.getSelectedItemPosition() != 1) {
                mRangeOptionsSpinner.setSelection(1);
            }

            StringBuilder builder = new StringBuilder();
            final int pageRangeCount = selectedPages.length;
            for (int i = 0; i < pageRangeCount; i++) {
                if (builder.length() > 0) {
                    builder.append(',');
                }

                final int shownStartPage;
                final int shownEndPage;
                PageRange pageRange = selectedPages[i];
                if (pageRange.equals(PageRange.ALL_PAGES)) {
                    shownStartPage = 1;
                    shownEndPage = pageInDocumentCount;
                } else {
                    shownStartPage = pageRange.getStart() + 1;
                    shownEndPage = pageRange.getEnd() + 1;
                }

                builder.append(shownStartPage);

                if (shownStartPage != shownEndPage) {
                    builder.append('-');
                    builder.append(shownEndPage);
                }
            }

            mPageRangeEditText.setText(builder.toString());
        }
    }

    private void ensureProgressUiShown() {
        if (isFinishing() || isDestroyed()) {
            return;
        }
        if (mUiState != UI_STATE_PROGRESS) {
            mUiState = UI_STATE_PROGRESS;
            mPrintPreviewController.setUiShown(false);
            Fragment fragment = PrintProgressFragment.newInstance();
            showFragment(fragment);
        }
    }

    private void ensurePreviewUiShown() {
        if (isFinishing() || isDestroyed()) {
            return;
        }
        if (mUiState != UI_STATE_PREVIEW) {
            mUiState = UI_STATE_PREVIEW;
            mPrintPreviewController.setUiShown(true);
            showFragment(null);
        }
    }

    private void ensureErrorUiShown(CharSequence message, int action) {
        if (isFinishing() || isDestroyed()) {
            return;
        }
        if (mUiState != UI_STATE_ERROR) {
            mUiState = UI_STATE_ERROR;
            mPrintPreviewController.setUiShown(false);
            Fragment fragment = PrintErrorFragment.newInstance(message, action);
            showFragment(fragment);
        }
    }

    private void showFragment(Fragment newFragment) {
        FragmentTransaction transaction = getFragmentManager().beginTransaction();
        Fragment oldFragment = getFragmentManager().findFragmentByTag(FRAGMENT_TAG);
        if (oldFragment != null) {
            transaction.remove(oldFragment);
        }
        if (newFragment != null) {
            transaction.add(R.id.embedded_content_container, newFragment, FRAGMENT_TAG);
        }
        transaction.commitAllowingStateLoss();
        getFragmentManager().executePendingTransactions();
    }

    /**
     * Count that a print operation has been confirmed.
     *
     * @param packageName The package name of the print service used
     */
    private void countPrintOperation(@NonNull String packageName) {
        MetricsLogger.action(this, MetricsEvent.ACTION_PRINT, packageName);

        MetricsLogger.histogram(this, PRINT_PAGES_HISTO,
                getAdjustedPageCount(mPrintJob.getDocumentInfo()));

        if (mPrintJob.getPrinterId().equals(mDefaultPrinter)) {
            MetricsLogger.histogram(this, PRINT_DEFAULT_COUNT, 1);
        }

        UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
        if (um.isManagedProfile()) {
            MetricsLogger.histogram(this, PRINT_WORK_COUNT, 1);
        }
    }

    private void requestCreatePdfFileOrFinish() {
        mPrintedDocument.cancel(false);

        if (mCurrentPrinter == mDestinationSpinnerAdapter.getPdfPrinter()) {
            startCreateDocumentActivity();
        } else {
            countPrintOperation(mCurrentPrinter.getId().getServiceName().getPackageName());

            transformDocumentAndFinish(null);
        }
    }

    /**
     * Clear the selected page range and update the preview if needed.
     */
    private void clearPageRanges() {
        mRangeOptionsSpinner.setSelection(0);
        mPageRangeEditText.setError(null);
        mPageRangeEditText.setText("");
        mSelectedPages = PageRange.ALL_PAGES_ARRAY;

        if (!Arrays.equals(mSelectedPages, mPrintPreviewController.getSelectedPages())) {
            updatePrintPreviewController(false);
        }
    }

    private void updatePrintAttributesFromCapabilities(PrinterCapabilitiesInfo capabilities) {
        boolean clearRanges = false;
        PrintAttributes defaults = capabilities.getDefaults();

        // Sort the media sizes based on the current locale.
        List<MediaSize> sortedMediaSizes = new ArrayList<>(capabilities.getMediaSizes());
        Collections.sort(sortedMediaSizes, mMediaSizeComparator);

        PrintAttributes attributes = mPrintJob.getAttributes();

        // Media size.
        MediaSize currMediaSize = attributes.getMediaSize();
        if (currMediaSize == null) {
            clearRanges = true;
            attributes.setMediaSize(defaults.getMediaSize());
        } else {
            MediaSize newMediaSize = null;
            boolean isPortrait = currMediaSize.isPortrait();

            // Try to find the current media size in the capabilities as
            // it may be in a different orientation.
            MediaSize currMediaSizePortrait = currMediaSize.asPortrait();
            final int mediaSizeCount = sortedMediaSizes.size();
            for (int i = 0; i < mediaSizeCount; i++) {
                MediaSize mediaSize = sortedMediaSizes.get(i);
                if (currMediaSizePortrait.equals(mediaSize.asPortrait())) {
                    newMediaSize = mediaSize;
                    break;
                }
            }
            // If we did not find the current media size fall back to default.
            if (newMediaSize == null) {
                clearRanges = true;
                newMediaSize = defaults.getMediaSize();
            }

            if (newMediaSize != null) {
                if (isPortrait) {
                    attributes.setMediaSize(newMediaSize.asPortrait());
                } else {
                    attributes.setMediaSize(newMediaSize.asLandscape());
                }
            }
        }

        // Color mode.
        final int colorMode = attributes.getColorMode();
        if ((capabilities.getColorModes() & colorMode) == 0) {
            attributes.setColorMode(defaults.getColorMode());
        }

        // Duplex mode.
        final int duplexMode = attributes.getDuplexMode();
        if ((capabilities.getDuplexModes() & duplexMode) == 0) {
            attributes.setDuplexMode(defaults.getDuplexMode());
        }

        // Resolution
        Resolution resolution = attributes.getResolution();
        if (resolution == null || !capabilities.getResolutions().contains(resolution)) {
            attributes.setResolution(defaults.getResolution());
        }

        // Margins.
        if (!Objects.equals(attributes.getMinMargins(), defaults.getMinMargins())) {
            clearRanges = true;
        }
        attributes.setMinMargins(defaults.getMinMargins());

        if (clearRanges) {
            clearPageRanges();
        }
    }

    private boolean updateDocument(boolean clearLastError) {
        if (!clearLastError && mPrintedDocument.hasUpdateError()) {
            return false;
        }

        if (clearLastError && mPrintedDocument.hasUpdateError()) {
            mPrintedDocument.clearUpdateError();
        }

        final boolean preview = mState != STATE_PRINT_CONFIRMED;
        final PageRange[] pages;
        if (preview) {
            pages = mPrintPreviewController.getRequestedPages();
        } else {
            pages = mPrintPreviewController.getSelectedPages();
        }

        final boolean willUpdate = mPrintedDocument.update(mPrintJob.getAttributes(),
                pages, preview);
        updateOptionsUi();

        if (willUpdate && !mPrintedDocument.hasLaidOutPages()) {
            // When the update is done we update the print preview.
            mProgressMessageController.post();
            return true;
        } else if (!willUpdate) {
            // Update preview.
            updatePrintPreviewController(false);
        }

        return false;
    }

    private void addCurrentPrinterToHistory() {
        if (mCurrentPrinter != null) {
            PrinterId fakePdfPrinterId = mDestinationSpinnerAdapter.getPdfPrinter().getId();
            if (!mCurrentPrinter.getId().equals(fakePdfPrinterId)) {
                mPrinterRegistry.addHistoricalPrinter(mCurrentPrinter);
            }
        }
    }

    private void cancelPrint() {
        setState(STATE_PRINT_CANCELED);
        mPrintedDocument.cancel(true);
        doFinish();
    }

    /**
     * Update the selected pages from the text field.
     */
    private void updateSelectedPagesFromTextField() {
        PageRange[] selectedPages = computeSelectedPages();
        if (!Arrays.equals(mSelectedPages, selectedPages)) {
            mSelectedPages = selectedPages;
            // Update preview.
            updatePrintPreviewController(false);
        }
    }

    private void confirmPrint() {
        setState(STATE_PRINT_CONFIRMED);

        addCurrentPrinterToHistory();
        setUserPrinted();

        // updateSelectedPagesFromTextField migth update the preview, hence apply the preview first
        updateSelectedPagesFromPreview();
        updateSelectedPagesFromTextField();

        mPrintPreviewController.closeOptions();

        if (canUpdateDocument()) {
            updateDocument(false);
        }

        if (!mPrintedDocument.isUpdating()) {
            requestCreatePdfFileOrFinish();
        }
    }

    private void bindUi() {
        // Summary
        mSummaryContainer = findViewById(R.id.summary_content);
        mSummaryCopies = findViewById(R.id.copies_count_summary);
        mSummaryPaperSize = findViewById(R.id.paper_size_summary);

        // Options container
        mOptionsContent = findViewById(R.id.options_content);
        mOptionsContent.setOptionsStateChangeListener(this);
        mOptionsContent.setOpenOptionsController(this);

        OnItemSelectedListener itemSelectedListener = new MyOnItemSelectedListener();
        OnClickListener clickListener = new MyClickListener();

        // Copies
        mCopiesEditText = findViewById(R.id.copies_edittext);
        mCopiesEditText.setOnFocusChangeListener(mSelectAllOnFocusListener);
        mCopiesEditText.setText(MIN_COPIES_STRING);
        mCopiesEditText.setSelection(mCopiesEditText.getText().length());
        mCopiesEditText.addTextChangedListener(new EditTextWatcher());

        // Destination.
        mPrintersObserver = new PrintersObserver();
        mDestinationSpinnerAdapter.registerDataSetObserver(mPrintersObserver);
        mDestinationSpinner = findViewById(R.id.destination_spinner);
        mDestinationSpinner.setAdapter(mDestinationSpinnerAdapter);
        mDestinationSpinner.setOnItemSelectedListener(itemSelectedListener);

        // Media size.
        mMediaSizeSpinnerAdapter = new ArrayAdapter<>(
                this, android.R.layout.simple_spinner_dropdown_item, android.R.id.text1);
        mMediaSizeSpinner = findViewById(R.id.paper_size_spinner);
        mMediaSizeSpinner.setAdapter(mMediaSizeSpinnerAdapter);
        mMediaSizeSpinner.setOnItemSelectedListener(itemSelectedListener);

        // Color mode.
        mColorModeSpinnerAdapter = new ArrayAdapter<>(
                this, android.R.layout.simple_spinner_dropdown_item, android.R.id.text1);
        mColorModeSpinner = findViewById(R.id.color_spinner);
        mColorModeSpinner.setAdapter(mColorModeSpinnerAdapter);
        mColorModeSpinner.setOnItemSelectedListener(itemSelectedListener);

        // Duplex mode.
        mDuplexModeSpinnerAdapter = new ArrayAdapter<>(
                this, android.R.layout.simple_spinner_dropdown_item, android.R.id.text1);
        mDuplexModeSpinner = findViewById(R.id.duplex_spinner);
        mDuplexModeSpinner.setAdapter(mDuplexModeSpinnerAdapter);
        mDuplexModeSpinner.setOnItemSelectedListener(itemSelectedListener);

        // Orientation
        mOrientationSpinnerAdapter = new ArrayAdapter<>(
                this, android.R.layout.simple_spinner_dropdown_item, android.R.id.text1);
        String[] orientationLabels = getResources().getStringArray(
                R.array.orientation_labels);
        mOrientationSpinnerAdapter.add(new SpinnerItem<>(
                ORIENTATION_PORTRAIT, orientationLabels[0]));
        mOrientationSpinnerAdapter.add(new SpinnerItem<>(
                ORIENTATION_LANDSCAPE, orientationLabels[1]));
        mOrientationSpinner = findViewById(R.id.orientation_spinner);
        mOrientationSpinner.setAdapter(mOrientationSpinnerAdapter);
        mOrientationSpinner.setOnItemSelectedListener(itemSelectedListener);

        // Range options
        ArrayAdapter<SpinnerItem<Integer>> rangeOptionsSpinnerAdapter = new ArrayAdapter<>(
                this, android.R.layout.simple_spinner_dropdown_item, android.R.id.text1);
        mRangeOptionsSpinner = findViewById(R.id.range_options_spinner);
        mRangeOptionsSpinner.setAdapter(rangeOptionsSpinnerAdapter);
        mRangeOptionsSpinner.setOnItemSelectedListener(itemSelectedListener);
        updatePageRangeOptions(PrintDocumentInfo.PAGE_COUNT_UNKNOWN);

        // Page range
        mPageRangeTitle = findViewById(R.id.page_range_title);
        mPageRangeEditText = findViewById(R.id.page_range_edittext);
        mPageRangeEditText.setVisibility(View.GONE);
        mPageRangeTitle.setVisibility(View.GONE);
        mPageRangeEditText.setOnFocusChangeListener(mSelectAllOnFocusListener);
        mPageRangeEditText.addTextChangedListener(new RangeTextWatcher());

        // Advanced options button.
        mMoreOptionsButton = findViewById(R.id.more_options_button);
        mMoreOptionsButton.setOnClickListener(clickListener);

        // Print button
        mPrintButton = findViewById(R.id.print_button);
        mPrintButton.setOnClickListener(clickListener);

        // The UI is now initialized
        mIsOptionsUiBound = true;

        // Special prompt instead of destination spinner for the first time the user printed
        if (!hasUserEverPrinted()) {
            mShowDestinationPrompt = true;

            mSummaryCopies.setEnabled(false);
            mSummaryPaperSize.setEnabled(false);

            mDestinationSpinner.setPerformClickListener((v) -> {
                mShowDestinationPrompt = false;
                mSummaryCopies.setEnabled(true);
                mSummaryPaperSize.setEnabled(true);
                updateOptionsUi();

                mDestinationSpinner.setPerformClickListener(null);
                mDestinationSpinnerAdapter.notifyDataSetChanged();
            });
        }
    }

    @Override
    public Loader<List<PrintServiceInfo>> onCreateLoader(int id, Bundle args) {
        return new PrintServicesLoader((PrintManager) getSystemService(Context.PRINT_SERVICE), this,
                PrintManager.ENABLED_SERVICES);
    }

    @Override
    public void onLoadFinished(Loader<List<PrintServiceInfo>> loader,
            List<PrintServiceInfo> services) {
        ComponentName newAdvancedPrintOptionsActivity = null;
        if (mCurrentPrinter != null && services != null) {
            final int numServices = services.size();
            for (int i = 0; i < numServices; i++) {
                PrintServiceInfo service = services.get(i);

                if (service.getComponentName().equals(mCurrentPrinter.getId().getServiceName())) {
                    String advancedOptionsActivityName = service.getAdvancedOptionsActivityName();

                    if (!TextUtils.isEmpty(advancedOptionsActivityName)) {
                        newAdvancedPrintOptionsActivity = new ComponentName(
                                service.getComponentName().getPackageName(),
                                advancedOptionsActivityName);

                        break;
                    }
                }
            }
        }

        if (!Objects.equals(newAdvancedPrintOptionsActivity, mAdvancedPrintOptionsActivity)) {
            mAdvancedPrintOptionsActivity = newAdvancedPrintOptionsActivity;
            updateOptionsUi();
        }

        boolean newArePrintServicesEnabled = services != null && !services.isEmpty();
        if (mArePrintServicesEnabled != newArePrintServicesEnabled) {
            mArePrintServicesEnabled = newArePrintServicesEnabled;

            // Reload mDestinationSpinnerAdapter as mArePrintServicesEnabled changed and the adapter
            // reads that in DestinationAdapter#getMoreItemTitle
            if (mDestinationSpinnerAdapter != null) {
                mDestinationSpinnerAdapter.notifyDataSetChanged();
            }
        }
    }

    @Override
    public void onLoaderReset(Loader<List<PrintServiceInfo>> loader) {
        if (!(isFinishing() || isDestroyed())) {
            onLoadFinished(loader, null);
        }
    }

    /**
     * A dialog that asks the user to approve a {@link PrintService}. This dialog is automatically
     * dismissed if the same {@link PrintService} gets approved by another
     * {@link PrintServiceApprovalDialog}.
     */
    public static final class PrintServiceApprovalDialog extends DialogFragment
            implements OnSharedPreferenceChangeListener {
        private static final String PRINTSERVICE_KEY = "PRINTSERVICE";
        private ApprovedPrintServices mApprovedServices;

        /**
         * Create a new {@link PrintServiceApprovalDialog} that ask the user to approve a
         * {@link PrintService}.
         *
         * @param printService The {@link ComponentName} of the service to approve
         * @return A new {@link PrintServiceApprovalDialog} that might approve the service
         */
        static PrintServiceApprovalDialog newInstance(ComponentName printService) {
            PrintServiceApprovalDialog dialog = new PrintServiceApprovalDialog();

            Bundle args = new Bundle();
            args.putParcelable(PRINTSERVICE_KEY, printService);
            dialog.setArguments(args);

            return dialog;
        }

        @Override
        public void onStop() {
            super.onStop();

            mApprovedServices.unregisterChangeListener(this);
        }

        @Override
        public void onStart() {
            super.onStart();

            ComponentName printService = getArguments().getParcelable(PRINTSERVICE_KEY);
            synchronized (ApprovedPrintServices.sLock) {
                if (mApprovedServices.isApprovedService(printService)) {
                    dismiss();
                } else {
                    mApprovedServices.registerChangeListenerLocked(this);
                }
            }
        }

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            super.onCreateDialog(savedInstanceState);

            mApprovedServices = new ApprovedPrintServices(getActivity());

            PackageManager packageManager = getActivity().getPackageManager();
            CharSequence serviceLabel;
            try {
                ComponentName printService = getArguments().getParcelable(PRINTSERVICE_KEY);

                serviceLabel = packageManager.getApplicationInfo(printService.getPackageName(), 0)
                        .loadLabel(packageManager);
            } catch (NameNotFoundException e) {
                serviceLabel = null;
            }

            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle(getString(R.string.print_service_security_warning_title,
                    serviceLabel))
                    .setMessage(getString(R.string.print_service_security_warning_summary,
                            serviceLabel))
                    .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int id) {
                            ComponentName printService =
                                    getArguments().getParcelable(PRINTSERVICE_KEY);
                            // Prevent onSharedPreferenceChanged from getting triggered
                            mApprovedServices
                                    .unregisterChangeListener(PrintServiceApprovalDialog.this);

                            mApprovedServices.addApprovedService(printService);
                            ((PrintActivity) getActivity()).confirmPrint();
                        }
                    })
                    .setNegativeButton(android.R.string.cancel, null);

            return builder.create();
        }

        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            ComponentName printService = getArguments().getParcelable(PRINTSERVICE_KEY);

            synchronized (ApprovedPrintServices.sLock) {
                if (mApprovedServices.isApprovedService(printService)) {
                    dismiss();
                }
            }
        }
    }

    private final class MyClickListener implements OnClickListener {
        @Override
        public void onClick(View view) {
            if (view == mPrintButton) {
                if (mCurrentPrinter != null) {
                    if (mDestinationSpinnerAdapter.getPdfPrinter() == mCurrentPrinter) {
                        confirmPrint();
                    } else {
                        ApprovedPrintServices approvedServices =
                                new ApprovedPrintServices(PrintActivity.this);

                        ComponentName printService = mCurrentPrinter.getId().getServiceName();
                        if (approvedServices.isApprovedService(printService)) {
                            confirmPrint();
                        } else {
                            PrintServiceApprovalDialog.newInstance(printService)
                                    .show(getFragmentManager(), "approve");
                        }
                    }
                } else {
                    cancelPrint();
                }
            } else if (view == mMoreOptionsButton) {
                if (mPageRangeEditText.getError() == null) {
                    // The selected pages is only applied once the user leaves the text field. A click
                    // on this button, does not count as leaving.
                    updateSelectedPagesFromTextField();
                }

                if (mCurrentPrinter != null) {
                    startAdvancedPrintOptionsActivity(mCurrentPrinter);
                }
            }
        }
    }

    private static boolean canPrint(PrinterInfo printer) {
        return printer.getCapabilities() != null
                && printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE;
    }

    /**
     * Disable all options UI elements, beside the {@link #mDestinationSpinner}
     *
     * @param disableRange If the range selection options should be disabled
     */
    private void disableOptionsUi(boolean disableRange) {
        mCopiesEditText.setEnabled(false);
        mCopiesEditText.setFocusable(false);
        mMediaSizeSpinner.setEnabled(false);
        mColorModeSpinner.setEnabled(false);
        mDuplexModeSpinner.setEnabled(false);
        mOrientationSpinner.setEnabled(false);
        mPrintButton.setVisibility(View.GONE);
        mMoreOptionsButton.setEnabled(false);

        if (disableRange) {
            mRangeOptionsSpinner.setEnabled(false);
            mPageRangeEditText.setEnabled(false);
        }
    }

    void updateOptionsUi() {
        if (!mIsOptionsUiBound) {
            return;
        }

        // Always update the summary.
        updateSummary();

        mDestinationSpinner.setEnabled(!isFinalState(mState));

        if (mState == STATE_PRINT_CONFIRMED
                || mState == STATE_PRINT_COMPLETED
                || mState == STATE_PRINT_CANCELED
                || mState == STATE_UPDATE_FAILED
                || mState == STATE_CREATE_FILE_FAILED
                || mState == STATE_PRINTER_UNAVAILABLE
                || mState == STATE_UPDATE_SLOW) {
            disableOptionsUi(isFinalState(mState));
            return;
        }

        // If no current printer, or it has no capabilities, or it is not
        // available, we disable all print options except the destination.
        if (mCurrentPrinter == null || !canPrint(mCurrentPrinter)) {
            disableOptionsUi(false);
            return;
        }

        PrinterCapabilitiesInfo capabilities = mCurrentPrinter.getCapabilities();
        PrintAttributes defaultAttributes = capabilities.getDefaults();

        // Destination.
        mDestinationSpinner.setEnabled(true);

        // Media size.
        mMediaSizeSpinner.setEnabled(true);

        List<MediaSize> mediaSizes = new ArrayList<>(capabilities.getMediaSizes());
        // Sort the media sizes based on the current locale.
        Collections.sort(mediaSizes, mMediaSizeComparator);

        PrintAttributes attributes = mPrintJob.getAttributes();

        // If the media sizes changed, we update the adapter and the spinner.
        boolean mediaSizesChanged = false;
        final int mediaSizeCount = mediaSizes.size();
        if (mediaSizeCount != mMediaSizeSpinnerAdapter.getCount()) {
            mediaSizesChanged = true;
        } else {
            for (int i = 0; i < mediaSizeCount; i++) {
                if (!mediaSizes.get(i).equals(mMediaSizeSpinnerAdapter.getItem(i).value)) {
                    mediaSizesChanged = true;
                    break;
                }
            }
        }
        if (mediaSizesChanged) {
            // Remember the old media size to try selecting it again.
            int oldMediaSizeNewIndex = AdapterView.INVALID_POSITION;
            MediaSize oldMediaSize = attributes.getMediaSize();

            // Rebuild the adapter data.
            mMediaSizeSpinnerAdapter.clear();
            for (int i = 0; i < mediaSizeCount; i++) {
                MediaSize mediaSize = mediaSizes.get(i);
                if (oldMediaSize != null
                        && mediaSize.asPortrait().equals(oldMediaSize.asPortrait())) {
                    // Update the index of the old selection.
                    oldMediaSizeNewIndex = i;
                }
                mMediaSizeSpinnerAdapter.add(new SpinnerItem<>(
                        mediaSize, mediaSize.getLabel(getPackageManager())));
            }

            if (oldMediaSizeNewIndex != AdapterView.INVALID_POSITION) {
                // Select the old media size - nothing really changed.
                if (mMediaSizeSpinner.getSelectedItemPosition() != oldMediaSizeNewIndex) {
                    mMediaSizeSpinner.setSelection(oldMediaSizeNewIndex);
                }
            } else {
                // Select the first or the default.
                final int mediaSizeIndex = Math.max(mediaSizes.indexOf(
                        defaultAttributes.getMediaSize()), 0);
                if (mMediaSizeSpinner.getSelectedItemPosition() != mediaSizeIndex) {
                    mMediaSizeSpinner.setSelection(mediaSizeIndex);
                }
                // Respect the orientation of the old selection.
                if (oldMediaSize != null) {
                    if (oldMediaSize.isPortrait()) {
                        attributes.setMediaSize(mMediaSizeSpinnerAdapter
                                .getItem(mediaSizeIndex).value.asPortrait());
                    } else {
                        attributes.setMediaSize(mMediaSizeSpinnerAdapter
                                .getItem(mediaSizeIndex).value.asLandscape());
                    }
                }
            }
        }

        // Color mode.
        mColorModeSpinner.setEnabled(true);
        final int colorModes = capabilities.getColorModes();

        // If the color modes changed, we update the adapter and the spinner.
        boolean colorModesChanged = false;
        if (Integer.bitCount(colorModes) != mColorModeSpinnerAdapter.getCount()) {
            colorModesChanged = true;
        } else {
            int remainingColorModes = colorModes;
            int adapterIndex = 0;
            while (remainingColorModes != 0) {
                final int colorBitOffset = Integer.numberOfTrailingZeros(remainingColorModes);
                final int colorMode = 1 << colorBitOffset;
                remainingColorModes &= ~colorMode;
                if (colorMode != mColorModeSpinnerAdapter.getItem(adapterIndex).value) {
                    colorModesChanged = true;
                    break;
                }
                adapterIndex++;
            }
        }
        if (colorModesChanged) {
            // Remember the old color mode to try selecting it again.
            int oldColorModeNewIndex = AdapterView.INVALID_POSITION;
            final int oldColorMode = attributes.getColorMode();

            // Rebuild the adapter data.
            mColorModeSpinnerAdapter.clear();
            String[] colorModeLabels = getResources().getStringArray(R.array.color_mode_labels);
            int remainingColorModes = colorModes;
            while (remainingColorModes != 0) {
                final int colorBitOffset = Integer.numberOfTrailingZeros(remainingColorModes);
                final int colorMode = 1 << colorBitOffset;
                if (colorMode == oldColorMode) {
                    // Update the index of the old selection.
                    oldColorModeNewIndex = mColorModeSpinnerAdapter.getCount();
                }
                remainingColorModes &= ~colorMode;
                mColorModeSpinnerAdapter.add(new SpinnerItem<>(colorMode,
                        colorModeLabels[colorBitOffset]));
            }
            if (oldColorModeNewIndex != AdapterView.INVALID_POSITION) {
                // Select the old color mode - nothing really changed.
                if (mColorModeSpinner.getSelectedItemPosition() != oldColorModeNewIndex) {
                    mColorModeSpinner.setSelection(oldColorModeNewIndex);
                }
            } else {
                // Select the default.
                final int selectedColorMode = colorModes & defaultAttributes.getColorMode();
                final int itemCount = mColorModeSpinnerAdapter.getCount();
                for (int i = 0; i < itemCount; i++) {
                    SpinnerItem<Integer> item = mColorModeSpinnerAdapter.getItem(i);
                    if (selectedColorMode == item.value) {
                        if (mColorModeSpinner.getSelectedItemPosition() != i) {
                            mColorModeSpinner.setSelection(i);
                        }
                        attributes.setColorMode(selectedColorMode);
                        break;
                    }
                }
            }
        }

        // Duplex mode.
        mDuplexModeSpinner.setEnabled(true);
        final int duplexModes = capabilities.getDuplexModes();

        // If the duplex modes changed, we update the adapter and the spinner.
        // Note that we use bit count +1 to account for the no duplex option.
        boolean duplexModesChanged = false;
        if (Integer.bitCount(duplexModes) != mDuplexModeSpinnerAdapter.getCount()) {
            duplexModesChanged = true;
        } else {
            int remainingDuplexModes = duplexModes;
            int adapterIndex = 0;
            while (remainingDuplexModes != 0) {
                final int duplexBitOffset = Integer.numberOfTrailingZeros(remainingDuplexModes);
                final int duplexMode = 1 << duplexBitOffset;
                remainingDuplexModes &= ~duplexMode;
                if (duplexMode != mDuplexModeSpinnerAdapter.getItem(adapterIndex).value) {
                    duplexModesChanged = true;
                    break;
                }
                adapterIndex++;
            }
        }
        if (duplexModesChanged) {
            // Remember the old duplex mode to try selecting it again. Also the fallback
            // is no duplexing which is always the first item in the dropdown.
            int oldDuplexModeNewIndex = AdapterView.INVALID_POSITION;
            final int oldDuplexMode = attributes.getDuplexMode();

            // Rebuild the adapter data.
            mDuplexModeSpinnerAdapter.clear();
            String[] duplexModeLabels = getResources().getStringArray(R.array.duplex_mode_labels);
            int remainingDuplexModes = duplexModes;
            while (remainingDuplexModes != 0) {
                final int duplexBitOffset = Integer.numberOfTrailingZeros(remainingDuplexModes);
                final int duplexMode = 1 << duplexBitOffset;
                if (duplexMode == oldDuplexMode) {
                    // Update the index of the old selection.
                    oldDuplexModeNewIndex = mDuplexModeSpinnerAdapter.getCount();
                }
                remainingDuplexModes &= ~duplexMode;
                mDuplexModeSpinnerAdapter.add(new SpinnerItem<>(duplexMode,
                        duplexModeLabels[duplexBitOffset]));
            }

            if (oldDuplexModeNewIndex != AdapterView.INVALID_POSITION) {
                // Select the old duplex mode - nothing really changed.
                if (mDuplexModeSpinner.getSelectedItemPosition() != oldDuplexModeNewIndex) {
                    mDuplexModeSpinner.setSelection(oldDuplexModeNewIndex);
                }
            } else {
                // Select the default.
                final int selectedDuplexMode = defaultAttributes.getDuplexMode();
                final int itemCount = mDuplexModeSpinnerAdapter.getCount();
                for (int i = 0; i < itemCount; i++) {
                    SpinnerItem<Integer> item = mDuplexModeSpinnerAdapter.getItem(i);
                    if (selectedDuplexMode == item.value) {
                        if (mDuplexModeSpinner.getSelectedItemPosition() != i) {
                            mDuplexModeSpinner.setSelection(i);
                        }
                        attributes.setDuplexMode(selectedDuplexMode);
                        break;
                    }
                }
            }
        }

        mDuplexModeSpinner.setEnabled(mDuplexModeSpinnerAdapter.getCount() > 1);

        // Orientation
        mOrientationSpinner.setEnabled(true);
        MediaSize mediaSize = attributes.getMediaSize();
        if (mediaSize != null) {
            if (mediaSize.isPortrait()
                    && mOrientationSpinner.getSelectedItemPosition() != 0) {
                mOrientationSpinner.setSelection(0);
            } else if (!mediaSize.isPortrait()
                    && mOrientationSpinner.getSelectedItemPosition() != 1) {
                mOrientationSpinner.setSelection(1);
            }
        }

        // Range options
        PrintDocumentInfo info = mPrintedDocument.getDocumentInfo().info;
        final int pageCount = getAdjustedPageCount(info);
        if (pageCount > 0) {
            if (info != null) {
                if (pageCount == 1) {
                    mRangeOptionsSpinner.setEnabled(false);
                } else {
                    mRangeOptionsSpinner.setEnabled(true);
                    if (mRangeOptionsSpinner.getSelectedItemPosition() > 0) {
                        if (!mPageRangeEditText.isEnabled()) {
                            mPageRangeEditText.setEnabled(true);
                            mPageRangeEditText.setVisibility(View.VISIBLE);
                            mPageRangeTitle.setVisibility(View.VISIBLE);
                            mPageRangeEditText.requestFocus();
                            InputMethodManager imm = (InputMethodManager)
                                    getSystemService(Context.INPUT_METHOD_SERVICE);
                            imm.showSoftInput(mPageRangeEditText, 0);
                        }
                    } else {
                        mPageRangeEditText.setEnabled(false);
                        mPageRangeEditText.setVisibility(View.GONE);
                        mPageRangeTitle.setVisibility(View.GONE);
                    }
                }
            } else {
                if (mRangeOptionsSpinner.getSelectedItemPosition() != 0) {
                    mRangeOptionsSpinner.setSelection(0);
                    mPageRangeEditText.setText("");
                }
                mRangeOptionsSpinner.setEnabled(false);
                mPageRangeEditText.setEnabled(false);
                mPageRangeEditText.setVisibility(View.GONE);
                mPageRangeTitle.setVisibility(View.GONE);
            }
        }

        final int newPageCount = getAdjustedPageCount(info);
        if (newPageCount != mCurrentPageCount) {
            mCurrentPageCount = newPageCount;
            updatePageRangeOptions(newPageCount);
        }

        // Advanced print options
        if (mAdvancedPrintOptionsActivity != null) {
            mMoreOptionsButton.setVisibility(View.VISIBLE);
            mMoreOptionsButton.setEnabled(true);
        } else {
            mMoreOptionsButton.setVisibility(View.GONE);
            mMoreOptionsButton.setEnabled(false);
        }

        // Print
        if (mDestinationSpinnerAdapter.getPdfPrinter() != mCurrentPrinter) {
            mPrintButton.setImageResource(com.android.internal.R.drawable.ic_print);
            mPrintButton.setContentDescription(getString(R.string.print_button));
        } else {
            mPrintButton.setImageResource(R.drawable.ic_menu_savetopdf);
            mPrintButton.setContentDescription(getString(R.string.savetopdf_button));
        }
        if (!mPrintedDocument.getDocumentInfo().updated
                ||(mRangeOptionsSpinner.getSelectedItemPosition() == 1
                && (TextUtils.isEmpty(mPageRangeEditText.getText()) || hasErrors()))
                || (mRangeOptionsSpinner.getSelectedItemPosition() == 0
                && (mPrintedDocument.getDocumentInfo() == null || hasErrors()))) {
            mPrintButton.setVisibility(View.GONE);
        } else {
            mPrintButton.setVisibility(View.VISIBLE);
        }

        // Copies
        if (mDestinationSpinnerAdapter.getPdfPrinter() != mCurrentPrinter) {
            mCopiesEditText.setEnabled(true);
            mCopiesEditText.setFocusableInTouchMode(true);
        } else {
            CharSequence text = mCopiesEditText.getText();
            if (TextUtils.isEmpty(text) || !MIN_COPIES_STRING.equals(text.toString())) {
                mCopiesEditText.setText(MIN_COPIES_STRING);
            }
            mCopiesEditText.setEnabled(false);
            mCopiesEditText.setFocusable(false);
        }
        if (mCopiesEditText.getError() == null
                && TextUtils.isEmpty(mCopiesEditText.getText())) {
            mCopiesEditText.setText(MIN_COPIES_STRING);
            mCopiesEditText.requestFocus();
        }

        if (mShowDestinationPrompt) {
            disableOptionsUi(false);
        }
    }

    private void updateSummary() {
        if (!mIsOptionsUiBound) {
            return;
        }

        CharSequence copiesText = null;
        CharSequence mediaSizeText = null;

        if (!TextUtils.isEmpty(mCopiesEditText.getText())) {
            copiesText = mCopiesEditText.getText();
            mSummaryCopies.setText(copiesText);
        }

        final int selectedMediaIndex = mMediaSizeSpinner.getSelectedItemPosition();
        if (selectedMediaIndex >= 0) {
            SpinnerItem<MediaSize> mediaItem = mMediaSizeSpinnerAdapter.getItem(selectedMediaIndex);
            mediaSizeText = mediaItem.label;
            mSummaryPaperSize.setText(mediaSizeText);
        }

        if (!TextUtils.isEmpty(copiesText) && !TextUtils.isEmpty(mediaSizeText)) {
            String summaryText = getString(R.string.summary_template, copiesText, mediaSizeText);
            mSummaryContainer.setContentDescription(summaryText);
        }
    }

    private void updatePageRangeOptions(int pageCount) {
        @SuppressWarnings("unchecked")
        ArrayAdapter<SpinnerItem<Integer>> rangeOptionsSpinnerAdapter =
                (ArrayAdapter<SpinnerItem<Integer>>) mRangeOptionsSpinner.getAdapter();
        rangeOptionsSpinnerAdapter.clear();

        final int[] rangeOptionsValues = getResources().getIntArray(
                R.array.page_options_values);

        String pageCountLabel = (pageCount > 0) ? String.valueOf(pageCount) : "";
        String[] rangeOptionsLabels = new String[] {
            getString(R.string.template_all_pages, pageCountLabel),
            getString(R.string.template_page_range, pageCountLabel)
        };

        final int rangeOptionsCount = rangeOptionsLabels.length;
        for (int i = 0; i < rangeOptionsCount; i++) {
            rangeOptionsSpinnerAdapter.add(new SpinnerItem<>(
                    rangeOptionsValues[i], rangeOptionsLabels[i]));
        }
    }

    private PageRange[] computeSelectedPages() {
        if (hasErrors()) {
            return null;
        }

        if (mRangeOptionsSpinner.getSelectedItemPosition() > 0) {
            PrintDocumentInfo info = mPrintedDocument.getDocumentInfo().info;
            final int pageCount = (info != null) ? getAdjustedPageCount(info) : 0;

            return PageRangeUtils.parsePageRanges(mPageRangeEditText.getText(), pageCount);
        }

        return PageRange.ALL_PAGES_ARRAY;
    }

    private int getAdjustedPageCount(PrintDocumentInfo info) {
        if (info != null) {
            final int pageCount = info.getPageCount();
            if (pageCount != PrintDocumentInfo.PAGE_COUNT_UNKNOWN) {
                return pageCount;
            }
        }
        // If the app does not tell us how many pages are in the
        // doc we ask for all pages and use the document page count.
        return mPrintPreviewController.getFilePageCount();
    }

    private boolean hasErrors() {
        return (mCopiesEditText.getError() != null)
                || (mPageRangeEditText.getVisibility() == View.VISIBLE
                && mPageRangeEditText.getError() != null);
    }

    public void onPrinterAvailable(PrinterInfo printer) {
        if (mCurrentPrinter != null && mCurrentPrinter.equals(printer)) {
            setState(STATE_CONFIGURING);
            if (canUpdateDocument()) {
                updateDocument(false);
            }
            ensurePreviewUiShown();
        }
    }

    public void onPrinterUnavailable(PrinterInfo printer) {
        if (mCurrentPrinter == null || mCurrentPrinter.getId().equals(printer.getId())) {
            setState(STATE_PRINTER_UNAVAILABLE);
            mPrintedDocument.cancel(false);
            ensureErrorUiShown(getString(R.string.print_error_printer_unavailable),
                    PrintErrorFragment.ACTION_NONE);
        }
    }

    private boolean canUpdateDocument() {
        if (mPrintedDocument.isDestroyed()) {
            return false;
        }

        if (hasErrors()) {
            return false;
        }

        PrintAttributes attributes = mPrintJob.getAttributes();

        final int colorMode = attributes.getColorMode();
        if (colorMode != PrintAttributes.COLOR_MODE_COLOR
                && colorMode != PrintAttributes.COLOR_MODE_MONOCHROME) {
            return false;
        }
        if (attributes.getMediaSize() == null) {
            return false;
        }
        if (attributes.getMinMargins() == null) {
            return false;
        }
        if (attributes.getResolution() == null) {
            return false;
        }

        if (mCurrentPrinter == null) {
            return false;
        }
        PrinterCapabilitiesInfo capabilities = mCurrentPrinter.getCapabilities();
        if (capabilities == null) {
            return false;
        }
        if (mCurrentPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE) {
            return false;
        }

        return true;
    }

    private void transformDocumentAndFinish(final Uri writeToUri) {
        // If saving to PDF, apply the attibutes as we are acting as a print service.
        PrintAttributes attributes = mDestinationSpinnerAdapter.getPdfPrinter() == mCurrentPrinter
                ?  mPrintJob.getAttributes() : null;
        new DocumentTransformer(this, mPrintJob, mFileProvider, attributes, error -> {
            if (error == null) {
                if (writeToUri != null) {
                    mPrintedDocument.writeContent(getContentResolver(), writeToUri);
                }
                setState(STATE_PRINT_COMPLETED);
                doFinish();
            } else {
                onPrintDocumentError(error);
            }
        }).transform();
    }

    private void doFinish() {
        if (mPrintedDocument != null && mPrintedDocument.isUpdating()) {
            // The printedDocument will call doFinish() when the current command finishes
            return;
        }

        if (mIsFinishing) {
            return;
        }

        mIsFinishing = true;

        if (mPrinterRegistry != null) {
            mPrinterRegistry.setTrackedPrinter(null);
            mPrinterRegistry.setOnPrintersChangeListener(null);
        }

        if (mPrintersObserver != null) {
            mDestinationSpinnerAdapter.unregisterDataSetObserver(mPrintersObserver);
        }

        if (mSpoolerProvider != null) {
            mSpoolerProvider.destroy();
        }

        if (mProgressMessageController != null) {
            setState(mProgressMessageController.cancel());
        }

        if (mState != STATE_INITIALIZING) {
            mPrintedDocument.finish();
            mPrintedDocument.destroy();
            mPrintPreviewController.destroy(new Runnable() {
                @Override
                public void run() {
                    finish();
                }
            });
        } else {
            finish();
        }
    }

    private final class SpinnerItem<T> {
        final T value;
        final CharSequence label;

        public SpinnerItem(T value, CharSequence label) {
            this.value = value;
            this.label = label;
        }

        @Override
        public String toString() {
            return label.toString();
        }
    }

    private final class PrinterAvailabilityDetector implements Runnable {
        private static final long UNAVAILABLE_TIMEOUT_MILLIS = 10000; // 10sec

        private boolean mPosted;

        private boolean mPrinterUnavailable;

        private PrinterInfo mPrinter;

        public void updatePrinter(PrinterInfo printer) {
            if (printer.equals(mDestinationSpinnerAdapter.getPdfPrinter())) {
                return;
            }

            final boolean available = printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE
                    && printer.getCapabilities() != null;
            final boolean notifyIfAvailable;

            if (mPrinter == null || !mPrinter.getId().equals(printer.getId())) {
                notifyIfAvailable = true;
                unpostIfNeeded();
                mPrinterUnavailable = false;
                mPrinter = new PrinterInfo.Builder(printer).build();
            } else {
                notifyIfAvailable =
                        (mPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE
                                && printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE)
                                || (mPrinter.getCapabilities() == null
                                && printer.getCapabilities() != null);
                mPrinter = printer;
            }

            if (available) {
                unpostIfNeeded();
                mPrinterUnavailable = false;
                if (notifyIfAvailable) {
                    onPrinterAvailable(mPrinter);
                }
            } else {
                if (!mPrinterUnavailable) {
                    postIfNeeded();
                }
            }
        }

        public void cancel() {
            unpostIfNeeded();
            mPrinterUnavailable = false;
        }

        private void postIfNeeded() {
            if (!mPosted) {
                mPosted = true;
                mDestinationSpinner.postDelayed(this, UNAVAILABLE_TIMEOUT_MILLIS);
            }
        }

        private void unpostIfNeeded() {
            if (mPosted) {
                mPosted = false;
                mDestinationSpinner.removeCallbacks(this);
            }
        }

        @Override
        public void run() {
            mPosted = false;
            mPrinterUnavailable = true;
            onPrinterUnavailable(mPrinter);
        }
    }

    private static final class PrinterHolder {
        PrinterInfo printer;
        boolean removed;

        public PrinterHolder(PrinterInfo printer) {
            this.printer = printer;
        }
    }


    /**
     * Check if the user has ever printed a document
     *
     * @return true iff the user has ever printed a document
     */
    private boolean hasUserEverPrinted() {
        SharedPreferences preferences = getSharedPreferences(HAS_PRINTED_PREF, MODE_PRIVATE);

        return preferences.getBoolean(HAS_PRINTED_PREF, false);
    }

    /**
     * Remember that the user printed a document
     */
    private void setUserPrinted() {
        SharedPreferences preferences = getSharedPreferences(HAS_PRINTED_PREF, MODE_PRIVATE);

        if (!preferences.getBoolean(HAS_PRINTED_PREF, false)) {
            SharedPreferences.Editor edit = preferences.edit();

            edit.putBoolean(HAS_PRINTED_PREF, true);
            edit.apply();
        }
    }

    private final class DestinationAdapter extends BaseAdapter
            implements PrinterRegistry.OnPrintersChangeListener {
        private final List<PrinterHolder> mPrinterHolders = new ArrayList<>();

        private final PrinterHolder mFakePdfPrinterHolder;

        private boolean mHistoricalPrintersLoaded;

        /**
         * Has the {@link #mDestinationSpinner} ever used a view from printer_dropdown_prompt
         */
        private boolean hadPromptView;

        public DestinationAdapter() {
            mHistoricalPrintersLoaded = mPrinterRegistry.areHistoricalPrintersLoaded();
            if (mHistoricalPrintersLoaded) {
                addPrinters(mPrinterHolders, mPrinterRegistry.getPrinters());
            }
            mPrinterRegistry.setOnPrintersChangeListener(this);
            mFakePdfPrinterHolder = new PrinterHolder(createFakePdfPrinter());
        }

        public PrinterInfo getPdfPrinter() {
            return mFakePdfPrinterHolder.printer;
        }

        public int getPrinterIndex(PrinterId printerId) {
            for (int i = 0; i < getCount(); i++) {
                PrinterHolder printerHolder = (PrinterHolder) getItem(i);
                if (printerHolder != null && printerHolder.printer.getId().equals(printerId)) {
                    return i;
                }
            }
            return AdapterView.INVALID_POSITION;
        }

        public void ensurePrinterInVisibleAdapterPosition(PrinterInfo printer) {
            final int printerCount = mPrinterHolders.size();
            boolean isKnownPrinter = false;
            for (int i = 0; i < printerCount; i++) {
                PrinterHolder printerHolder = mPrinterHolders.get(i);

                if (printerHolder.printer.getId().equals(printer.getId())) {
                    isKnownPrinter = true;

                    // If already in the list - do nothing.
                    if (i < getCount() - 2) {
                        break;
                    }
                    // Else replace the last one (two items are not printers).
                    final int lastPrinterIndex = getCount() - 3;
                    mPrinterHolders.set(i, mPrinterHolders.get(lastPrinterIndex));
                    mPrinterHolders.set(lastPrinterIndex, printerHolder);
                    break;
                }
            }

            if (!isKnownPrinter) {
                PrinterHolder printerHolder = new PrinterHolder(printer);
                printerHolder.removed = true;

                mPrinterHolders.add(Math.max(0, getCount() - 3), printerHolder);
            }

            // Force reload to adjust selection in PrintersObserver.onChanged()
            notifyDataSetChanged();
        }

        @Override
        public int getCount() {
            if (mHistoricalPrintersLoaded) {
                return Math.min(mPrinterHolders.size() + 2, DEST_ADAPTER_MAX_ITEM_COUNT);
            }
            return 0;
        }

        @Override
        public boolean isEnabled(int position) {
            Object item = getItem(position);
            if (item instanceof PrinterHolder) {
                PrinterHolder printerHolder = (PrinterHolder) item;
                return !printerHolder.removed
                        && printerHolder.printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE;
            }
            return true;
        }

        @Override
        public Object getItem(int position) {
            if (mPrinterHolders.isEmpty()) {
                if (position == 0) {
                    return mFakePdfPrinterHolder;
                }
            } else {
                if (position < 1) {
                    return mPrinterHolders.get(position);
                }
                if (position == 1) {
                    return mFakePdfPrinterHolder;
                }
                if (position < getCount() - 1) {
                    return mPrinterHolders.get(position - 1);
                }
            }
            return null;
        }

        @Override
        public long getItemId(int position) {
            if (mPrinterHolders.isEmpty()) {
                if (position == 0) {
                    return DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF;
                } else if (position == 1) {
                    return DEST_ADAPTER_ITEM_ID_MORE;
                }
            } else {
                if (position == 1) {
                    return DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF;
                }
                if (position == getCount() - 1) {
                    return DEST_ADAPTER_ITEM_ID_MORE;
                }
            }
            return position;
        }

        @Override
        public View getDropDownView(int position, View convertView, ViewGroup parent) {
            View view = getView(position, convertView, parent);
            view.setEnabled(isEnabled(position));
            return view;
        }

        private String getMoreItemTitle() {
            if (mArePrintServicesEnabled) {
                return getString(R.string.all_printers);
            } else {
                return getString(R.string.print_add_printer);
            }
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (mShowDestinationPrompt) {
                if (convertView == null) {
                    convertView = getLayoutInflater().inflate(
                            R.layout.printer_dropdown_prompt, parent, false);
                    hadPromptView = true;
                }

                return convertView;
            } else {
                // We don't know if we got an recyled printer_dropdown_prompt, hence do not use it
                if (hadPromptView || convertView == null) {
                    convertView = getLayoutInflater().inflate(
                            R.layout.printer_dropdown_item, parent, false);
                }
            }

            CharSequence title = null;
            CharSequence subtitle = null;
            Drawable icon = null;

            if (mPrinterHolders.isEmpty()) {
                if (position == 0 && getPdfPrinter() != null) {
                    PrinterHolder printerHolder = (PrinterHolder) getItem(position);
                    title = printerHolder.printer.getName();
                    icon = getResources().getDrawable(R.drawable.ic_pdf_printer, null);
                } else if (position == 1) {
                    title = getMoreItemTitle();
                }
            } else {
                if (position == 1 && getPdfPrinter() != null) {
                    PrinterHolder printerHolder = (PrinterHolder) getItem(position);
                    title = printerHolder.printer.getName();
                    icon = getResources().getDrawable(R.drawable.ic_pdf_printer, null);
                } else if (position == getCount() - 1) {
                    title = getMoreItemTitle();
                } else {
                    PrinterHolder printerHolder = (PrinterHolder) getItem(position);
                    PrinterInfo printInfo = printerHolder.printer;

                    title = printInfo.getName();
                    icon = printInfo.loadIcon(PrintActivity.this);
                    subtitle = printInfo.getDescription();
                }
            }

            TextView titleView = (TextView) convertView.findViewById(R.id.title);
            titleView.setText(title);

            TextView subtitleView = (TextView) convertView.findViewById(R.id.subtitle);
            if (!TextUtils.isEmpty(subtitle)) {
                subtitleView.setText(subtitle);
                subtitleView.setVisibility(View.VISIBLE);
            } else {
                subtitleView.setText(null);
                subtitleView.setVisibility(View.GONE);
            }

            ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
            if (icon != null) {
                iconView.setVisibility(View.VISIBLE);
                if (!isEnabled(position)) {
                    icon.mutate();

                    TypedValue value = new TypedValue();
                    getTheme().resolveAttribute(android.R.attr.disabledAlpha, value, true);
                    icon.setAlpha((int)(value.getFloat() * 255));
                }
                iconView.setImageDrawable(icon);
            } else {
                iconView.setVisibility(View.INVISIBLE);
            }

            return convertView;
        }

        @Override
        public void onPrintersChanged(List<PrinterInfo> printers) {
            // We rearrange the printers if the user selects a printer
            // not shown in the initial short list. Therefore, we have
            // to keep the printer order.

            // Check if historical printers are loaded as this adapter is open
            // for busyness only if they are. This member is updated here and
            // when the adapter is created because the historical printers may
            // be loaded before or after the adapter is created.
            mHistoricalPrintersLoaded = mPrinterRegistry.areHistoricalPrintersLoaded();

            // No old printers - do not bother keeping their position.
            if (mPrinterHolders.isEmpty()) {
                addPrinters(mPrinterHolders, printers);
                notifyDataSetChanged();
                return;
            }

            // Add the new printers to a map.
            ArrayMap<PrinterId, PrinterInfo> newPrintersMap = new ArrayMap<>();
            final int printerCount = printers.size();
            for (int i = 0; i < printerCount; i++) {
                PrinterInfo printer = printers.get(i);
                newPrintersMap.put(printer.getId(), printer);
            }

            List<PrinterHolder> newPrinterHolders = new ArrayList<>();

            // Update printers we already have which are either updated or removed.
            // We do not remove the currently selected printer.
            final int oldPrinterCount = mPrinterHolders.size();
            for (int i = 0; i < oldPrinterCount; i++) {
                PrinterHolder printerHolder = mPrinterHolders.get(i);
                PrinterId oldPrinterId = printerHolder.printer.getId();
                PrinterInfo updatedPrinter = newPrintersMap.remove(oldPrinterId);

                if (updatedPrinter != null) {
                    printerHolder.printer = updatedPrinter;
                    printerHolder.removed = false;
                    if (canPrint(printerHolder.printer)) {
                        onPrinterAvailable(printerHolder.printer);
                    } else {
                        onPrinterUnavailable(printerHolder.printer);
                    }
                    newPrinterHolders.add(printerHolder);
                } else if (mCurrentPrinter != null && mCurrentPrinter.getId().equals(oldPrinterId)){
                    printerHolder.removed = true;
                    onPrinterUnavailable(printerHolder.printer);
                    newPrinterHolders.add(printerHolder);
                }
            }

            // Add the rest of the new printers, i.e. what is left.
            addPrinters(newPrinterHolders, newPrintersMap.values());

            mPrinterHolders.clear();
            mPrinterHolders.addAll(newPrinterHolders);

            notifyDataSetChanged();
        }

        @Override
        public void onPrintersInvalid() {
            mPrinterHolders.clear();
            notifyDataSetInvalidated();
        }

        public PrinterHolder getPrinterHolder(PrinterId printerId) {
            final int itemCount = getCount();
            for (int i = 0; i < itemCount; i++) {
                Object item = getItem(i);
                if (item instanceof PrinterHolder) {
                    PrinterHolder printerHolder = (PrinterHolder) item;
                    if (printerId.equals(printerHolder.printer.getId())) {
                        return printerHolder;
                    }
                }
            }
            return null;
        }

        /**
         * Remove a printer from the holders if it is marked as removed.
         *
         * @param printerId the id of the printer to remove.
         *
         * @return true iff the printer was removed.
         */
        public boolean pruneRemovedPrinter(PrinterId printerId) {
            final int holderCounts = mPrinterHolders.size();
            for (int i = holderCounts - 1; i >= 0; i--) {
                PrinterHolder printerHolder = mPrinterHolders.get(i);

                if (printerHolder.printer.getId().equals(printerId) && printerHolder.removed) {
                    mPrinterHolders.remove(i);
                    return true;
                }
            }

            return false;
        }

        private void addPrinters(List<PrinterHolder> list, Collection<PrinterInfo> printers) {
            for (PrinterInfo printer : printers) {
                PrinterHolder printerHolder = new PrinterHolder(printer);
                list.add(printerHolder);
            }
        }

        private PrinterInfo createFakePdfPrinter() {
            ArraySet<MediaSize> allMediaSizes = MediaSize.getAllPredefinedSizes();
            MediaSize defaultMediaSize = MediaSizeUtils.getDefault(PrintActivity.this);

            PrinterId printerId = new PrinterId(getComponentName(), "PDF printer");

            PrinterCapabilitiesInfo.Builder builder =
                    new PrinterCapabilitiesInfo.Builder(printerId);

            final int mediaSizeCount = allMediaSizes.size();
            for (int i = 0; i < mediaSizeCount; i++) {
                MediaSize mediaSize = allMediaSizes.valueAt(i);
                builder.addMediaSize(mediaSize, mediaSize.equals(defaultMediaSize));
            }

            builder.addResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300),
                    true);
            builder.setColorModes(PrintAttributes.COLOR_MODE_COLOR
                    | PrintAttributes.COLOR_MODE_MONOCHROME, PrintAttributes.COLOR_MODE_COLOR);

            return new PrinterInfo.Builder(printerId, getString(R.string.save_as_pdf),
                    PrinterInfo.STATUS_IDLE).setCapabilities(builder.build()).build();
        }
    }

    private final class PrintersObserver extends DataSetObserver {
        @Override
        public void onChanged() {
            PrinterInfo oldPrinterState = mCurrentPrinter;
            if (oldPrinterState == null) {
                return;
            }

            PrinterHolder printerHolder = mDestinationSpinnerAdapter.getPrinterHolder(
                    oldPrinterState.getId());
            PrinterInfo newPrinterState = printerHolder.printer;

            if (printerHolder.removed) {
                onPrinterUnavailable(newPrinterState);
            }

            if (mDestinationSpinner.getSelectedItem() != printerHolder) {
                mDestinationSpinner.setSelection(
                        mDestinationSpinnerAdapter.getPrinterIndex(newPrinterState.getId()));
            }

            if (oldPrinterState.equals(newPrinterState)) {
                return;
            }

            PrinterCapabilitiesInfo oldCapab = oldPrinterState.getCapabilities();
            PrinterCapabilitiesInfo newCapab = newPrinterState.getCapabilities();

            final boolean hadCabab = oldCapab != null;
            final boolean hasCapab = newCapab != null;
            final boolean gotCapab = oldCapab == null && newCapab != null;
            final boolean lostCapab = oldCapab != null && newCapab == null;
            final boolean capabChanged = capabilitiesChanged(oldCapab, newCapab);

            final int oldStatus = oldPrinterState.getStatus();
            final int newStatus = newPrinterState.getStatus();

            final boolean isActive = newStatus != PrinterInfo.STATUS_UNAVAILABLE;
            final boolean becameActive = (oldStatus == PrinterInfo.STATUS_UNAVAILABLE
                    && oldStatus != newStatus);
            final boolean becameInactive = (newStatus == PrinterInfo.STATUS_UNAVAILABLE
                    && oldStatus != newStatus);

            mPrinterAvailabilityDetector.updatePrinter(newPrinterState);

            mCurrentPrinter = newPrinterState;

            final boolean updateNeeded = ((capabChanged && hasCapab && isActive)
                    || (becameActive && hasCapab) || (isActive && gotCapab));

            if (capabChanged && hasCapab) {
                updatePrintAttributesFromCapabilities(newCapab);
            }

            if (updateNeeded) {
                updatePrintPreviewController(false);
            }

            if ((isActive && gotCapab) || (becameActive && hasCapab)) {
                onPrinterAvailable(newPrinterState);
            } else if ((becameInactive && hadCabab) || (isActive && lostCapab)) {
                onPrinterUnavailable(newPrinterState);
            }

            if (updateNeeded && canUpdateDocument()) {
                updateDocument(false);
            }

            // Force a reload of the enabled print services to update mAdvancedPrintOptionsActivity
            // in onLoadFinished();
            getLoaderManager().getLoader(LOADER_ID_ENABLED_PRINT_SERVICES).forceLoad();

            updateOptionsUi();
            updateSummary();
        }

        private boolean capabilitiesChanged(PrinterCapabilitiesInfo oldCapabilities,
                PrinterCapabilitiesInfo newCapabilities) {
            if (oldCapabilities == null) {
                if (newCapabilities != null) {
                    return true;
                }
            } else if (!oldCapabilities.equals(newCapabilities)) {
                return true;
            }
            return false;
        }
    }

    private final class MyOnItemSelectedListener implements AdapterView.OnItemSelectedListener {
        @Override
        public void onItemSelected(AdapterView<?> spinner, View view, int position, long id) {
            boolean clearRanges = false;

            if (spinner == mDestinationSpinner) {
                if (position == AdapterView.INVALID_POSITION) {
                    return;
                }

                if (id == DEST_ADAPTER_ITEM_ID_MORE) {
                    startSelectPrinterActivity();
                    return;
                }

                PrinterHolder currentItem = (PrinterHolder) mDestinationSpinner.getSelectedItem();
                PrinterInfo currentPrinter = (currentItem != null) ? currentItem.printer : null;

                // Why on earth item selected is called if no selection changed.
                if (mCurrentPrinter == currentPrinter) {
                    return;
                }

                if (mDefaultPrinter == null) {
                    mDefaultPrinter = currentPrinter.getId();
                }

                PrinterId oldId = null;
                if (mCurrentPrinter != null) {
                    oldId = mCurrentPrinter.getId();
                }
                mCurrentPrinter = currentPrinter;

                if (oldId != null) {
                    boolean printerRemoved = mDestinationSpinnerAdapter.pruneRemovedPrinter(oldId);

                    if (printerRemoved) {
                        // Trigger PrinterObserver.onChanged to adjust selection. This will call
                        // this function again.
                        mDestinationSpinnerAdapter.notifyDataSetChanged();
                        return;
                    }

                    if (mState != STATE_INITIALIZING) {
                        if (currentPrinter != null) {
                            MetricsLogger.action(PrintActivity.this,
                                    MetricsEvent.ACTION_PRINTER_SELECT_DROPDOWN,
                                    currentPrinter.getId().getServiceName().getPackageName());
                        } else {
                            MetricsLogger.action(PrintActivity.this,
                                    MetricsEvent.ACTION_PRINTER_SELECT_DROPDOWN, "");
                        }
                    }
                }

                PrinterHolder printerHolder = mDestinationSpinnerAdapter.getPrinterHolder(
                        currentPrinter.getId());
                if (!printerHolder.removed) {
                    setState(STATE_CONFIGURING);
                    ensurePreviewUiShown();
                }

                mPrintJob.setPrinterId(currentPrinter.getId());
                mPrintJob.setPrinterName(currentPrinter.getName());

                mPrinterRegistry.setTrackedPrinter(currentPrinter.getId());

                PrinterCapabilitiesInfo capabilities = currentPrinter.getCapabilities();
                if (capabilities != null) {
                    updatePrintAttributesFromCapabilities(capabilities);
                }

                mPrinterAvailabilityDetector.updatePrinter(currentPrinter);

                // Force a reload of the enabled print services to update
                // mAdvancedPrintOptionsActivity in onLoadFinished();
                getLoaderManager().getLoader(LOADER_ID_ENABLED_PRINT_SERVICES).forceLoad();
            } else if (spinner == mMediaSizeSpinner) {
                SpinnerItem<MediaSize> mediaItem = mMediaSizeSpinnerAdapter.getItem(position);
                PrintAttributes attributes = mPrintJob.getAttributes();

                MediaSize newMediaSize;
                if (mOrientationSpinner.getSelectedItemPosition() == 0) {
                    newMediaSize = mediaItem.value.asPortrait();
                } else {
                    newMediaSize = mediaItem.value.asLandscape();
                }

                if (newMediaSize != attributes.getMediaSize()) {
                    if (!newMediaSize.equals(attributes.getMediaSize())
                            && !attributes.getMediaSize().equals(MediaSize.UNKNOWN_LANDSCAPE)
                            && !attributes.getMediaSize().equals(MediaSize.UNKNOWN_PORTRAIT)
                            && mState != STATE_INITIALIZING) {
                        MetricsLogger.action(PrintActivity.this,
                                MetricsEvent.ACTION_PRINT_JOB_OPTIONS,
                                PRINT_JOB_OPTIONS_SUBTYPE_MEDIA_SIZE);
                    }

                    clearRanges = true;
                    attributes.setMediaSize(newMediaSize);
                }
            } else if (spinner == mColorModeSpinner) {
                SpinnerItem<Integer> colorModeItem = mColorModeSpinnerAdapter.getItem(position);
                int newMode = colorModeItem.value;

                if (mPrintJob.getAttributes().getColorMode() != newMode
                        && mState != STATE_INITIALIZING) {
                    MetricsLogger.action(PrintActivity.this, MetricsEvent.ACTION_PRINT_JOB_OPTIONS,
                            PRINT_JOB_OPTIONS_SUBTYPE_COLOR_MODE);
                }

                mPrintJob.getAttributes().setColorMode(newMode);
            } else if (spinner == mDuplexModeSpinner) {
                SpinnerItem<Integer> duplexModeItem = mDuplexModeSpinnerAdapter.getItem(position);
                int newMode = duplexModeItem.value;

                if (mPrintJob.getAttributes().getDuplexMode() != newMode
                        && mState != STATE_INITIALIZING) {
                    MetricsLogger.action(PrintActivity.this, MetricsEvent.ACTION_PRINT_JOB_OPTIONS,
                            PRINT_JOB_OPTIONS_SUBTYPE_DUPLEX_MODE);
                }

                mPrintJob.getAttributes().setDuplexMode(newMode);
            } else if (spinner == mOrientationSpinner) {
                SpinnerItem<Integer> orientationItem = mOrientationSpinnerAdapter.getItem(position);
                PrintAttributes attributes = mPrintJob.getAttributes();

                if (mMediaSizeSpinner.getSelectedItem() != null) {
                    boolean isPortrait = attributes.isPortrait();
                    boolean newIsPortrait = orientationItem.value == ORIENTATION_PORTRAIT;

                    if (isPortrait != newIsPortrait) {
                        if (mState != STATE_INITIALIZING) {
                            MetricsLogger.action(PrintActivity.this,
                                    MetricsEvent.ACTION_PRINT_JOB_OPTIONS,
                                    PRINT_JOB_OPTIONS_SUBTYPE_ORIENTATION);
                        }

                        clearRanges = true;
                        if (newIsPortrait) {
                            attributes.copyFrom(attributes.asPortrait());
                        } else {
                            attributes.copyFrom(attributes.asLandscape());
                        }
                    }
                }
            } else if (spinner == mRangeOptionsSpinner) {
                if (mRangeOptionsSpinner.getSelectedItemPosition() == 0) {
                    clearRanges = true;
                    mPageRangeEditText.setText("");

                    if (mPageRangeEditText.getVisibility() == View.VISIBLE &&
                            mState != STATE_INITIALIZING) {
                        MetricsLogger.action(PrintActivity.this,
                                MetricsEvent.ACTION_PRINT_JOB_OPTIONS,
                                PRINT_JOB_OPTIONS_SUBTYPE_PAGE_RANGE);
                    }
                } else if (TextUtils.isEmpty(mPageRangeEditText.getText())) {
                    mPageRangeEditText.setError("");

                    if (mPageRangeEditText.getVisibility() != View.VISIBLE &&
                            mState != STATE_INITIALIZING) {
                        MetricsLogger.action(PrintActivity.this,
                                MetricsEvent.ACTION_PRINT_JOB_OPTIONS,
                                PRINT_JOB_OPTIONS_SUBTYPE_PAGE_RANGE);
                    }
                }
            }

            if (clearRanges) {
                clearPageRanges();
            }

            updateOptionsUi();

            if (canUpdateDocument()) {
                updateDocument(false);
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            /* do nothing*/
        }
    }

    private final class SelectAllOnFocusListener implements OnFocusChangeListener {
        @Override
        public void onFocusChange(View view, boolean hasFocus) {
            EditText editText = (EditText) view;
            if (!TextUtils.isEmpty(editText.getText())) {
                editText.setSelection(editText.getText().length());
            }

            if (view == mPageRangeEditText && !hasFocus && mPageRangeEditText.getError() == null) {
                updateSelectedPagesFromTextField();
            }
        }
    }

    private final class RangeTextWatcher implements TextWatcher {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            /* do nothing */
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            /* do nothing */
        }

        @Override
        public void afterTextChanged(Editable editable) {
            final boolean hadErrors = hasErrors();

            PrintDocumentInfo info = mPrintedDocument.getDocumentInfo().info;
            final int pageCount = (info != null) ? getAdjustedPageCount(info) : 0;
            PageRange[] ranges = PageRangeUtils.parsePageRanges(editable, pageCount);

            if (ranges.length == 0) {
                if (mPageRangeEditText.getError() == null) {
                    mPageRangeEditText.setError("");
                    updateOptionsUi();
                }
                return;
            }

            if (mPageRangeEditText.getError() != null) {
                mPageRangeEditText.setError(null);
                updateOptionsUi();
            }

            if (hadErrors && canUpdateDocument()) {
                updateDocument(false);
            }
        }
    }

    private final class EditTextWatcher implements TextWatcher {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            /* do nothing */
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            /* do nothing */
        }

        @Override
        public void afterTextChanged(Editable editable) {
            final boolean hadErrors = hasErrors();

            if (editable.length() == 0) {
                if (mCopiesEditText.getError() == null) {
                    mCopiesEditText.setError("");
                    updateOptionsUi();
                }
                return;
            }

            int copies = 0;
            try {
                copies = Integer.parseInt(editable.toString());
            } catch (NumberFormatException nfe) {
                /* ignore */
            }

            if (mState != STATE_INITIALIZING) {
                MetricsLogger.action(PrintActivity.this, MetricsEvent.ACTION_PRINT_JOB_OPTIONS,
                        PRINT_JOB_OPTIONS_SUBTYPE_COPIES);
            }

            if (copies < MIN_COPIES) {
                if (mCopiesEditText.getError() == null) {
                    mCopiesEditText.setError("");
                    updateOptionsUi();
                }
                return;
            }

            mPrintJob.setCopies(copies);

            if (mCopiesEditText.getError() != null) {
                mCopiesEditText.setError(null);
                updateOptionsUi();
            }

            if (hadErrors && canUpdateDocument()) {
                updateDocument(false);
            }
        }
    }

    private final class ProgressMessageController implements Runnable {
        private static final long PROGRESS_TIMEOUT_MILLIS = 1000;

        private final Handler mHandler;

        private boolean mPosted;

        /** State before run was executed */
        private int mPreviousState = -1;

        public ProgressMessageController(Context context) {
            mHandler = new Handler(context.getMainLooper(), null, false);
        }

        public void post() {
            if (mState == STATE_UPDATE_SLOW) {
                setState(STATE_UPDATE_SLOW);
                ensureProgressUiShown();

                return;
            } else if (mPosted) {
                return;
            }
            mPreviousState = -1;
            mPosted = true;
            mHandler.postDelayed(this, PROGRESS_TIMEOUT_MILLIS);
        }

        private int getStateAfterCancel() {
            if (mPreviousState == -1) {
                return mState;
            } else {
                return mPreviousState;
            }
        }

        public int cancel() {
            int state;

            if (!mPosted) {
                state = getStateAfterCancel();
            } else {
                mPosted = false;
                mHandler.removeCallbacks(this);

                state = getStateAfterCancel();
            }

            mPreviousState = -1;

            return state;
        }

        @Override
        public void run() {
            mPosted = false;
            mPreviousState = mState;
            setState(STATE_UPDATE_SLOW);
            ensureProgressUiShown();
        }
    }

    private static final class DocumentTransformer implements ServiceConnection {
        private static final String TEMP_FILE_PREFIX = "print_job";
        private static final String TEMP_FILE_EXTENSION = ".pdf";

        private final Context mContext;

        private final MutexFileProvider mFileProvider;

        private final PrintJobInfo mPrintJob;

        private final PageRange[] mPagesToShred;

        private final PrintAttributes mAttributesToApply;

        private final Consumer<String> mCallback;

        public DocumentTransformer(Context context, PrintJobInfo printJob,
                MutexFileProvider fileProvider, PrintAttributes attributes,
                Consumer<String> callback) {
            mContext = context;
            mPrintJob = printJob;
            mFileProvider = fileProvider;
            mCallback = callback;
            mPagesToShred = computePagesToShred(mPrintJob);
            mAttributesToApply = attributes;
        }

        public void transform() {
            // If we have only the pages we want, done.
            if (mPagesToShred.length <= 0 && mAttributesToApply == null) {
                mCallback.accept(null);
                return;
            }

            // Bind to the manipulation service and the work
            // will be performed upon connection to the service.
            Intent intent = new Intent(PdfManipulationService.ACTION_GET_EDITOR);
            intent.setClass(mContext, PdfManipulationService.class);
            mContext.bindService(intent, this, Context.BIND_AUTO_CREATE);
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            final IPdfEditor editor = IPdfEditor.Stub.asInterface(service);
            new AsyncTask<Void, Void, String>() {
                @Override
                protected String doInBackground(Void... params) {
                    // It's OK to access the data members as they are
                    // final and this code is the last one to touch
                    // them as shredding is the very last step, so the
                    // UI is not interactive at this point.
                    try {
                        doTransform(editor);
                        updatePrintJob();
                        return null;
                    } catch (IOException | RemoteException | IllegalStateException e) {
                        return e.toString();
                    }
                }

                @Override
                protected void onPostExecute(String error) {
                    mContext.unbindService(DocumentTransformer.this);
                    mCallback.accept(error);
                }
            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            /* do nothing */
        }

        private void doTransform(IPdfEditor editor) throws IOException, RemoteException {
            File tempFile = null;
            ParcelFileDescriptor src = null;
            ParcelFileDescriptor dst = null;
            InputStream in = null;
            OutputStream out = null;
            try {
                File jobFile = mFileProvider.acquireFile(null);
                src = ParcelFileDescriptor.open(jobFile, ParcelFileDescriptor.MODE_READ_WRITE);

                // Open the document.
                editor.openDocument(src);

                // We passed the fd over IPC, close this one.
                src.close();

                // Drop the pages.
                editor.removePages(mPagesToShred);

                // Apply print attributes if needed.
                if (mAttributesToApply != null) {
                    editor.applyPrintAttributes(mAttributesToApply);
                }

                // Write the modified PDF to a temp file.
                tempFile = File.createTempFile(TEMP_FILE_PREFIX, TEMP_FILE_EXTENSION,
                        mContext.getCacheDir());
                dst = ParcelFileDescriptor.open(tempFile, ParcelFileDescriptor.MODE_READ_WRITE);
                editor.write(dst);
                dst.close();

                // Close the document.
                editor.closeDocument();

                // Copy the temp file over the print job file.
                jobFile.delete();
                in = new FileInputStream(tempFile);
                out = new FileOutputStream(jobFile);
                Streams.copy(in, out);
            } finally {
                IoUtils.closeQuietly(src);
                IoUtils.closeQuietly(dst);
                IoUtils.closeQuietly(in);
                IoUtils.closeQuietly(out);
                if (tempFile != null) {
                    tempFile.delete();
                }
                mFileProvider.releaseFile();
            }
        }

        private void updatePrintJob() {
            // Update the print job pages.
            final int newPageCount = PageRangeUtils.getNormalizedPageCount(
                    mPrintJob.getPages(), 0);
            mPrintJob.setPages(new PageRange[]{PageRange.ALL_PAGES});

            // Update the print job document info.
            PrintDocumentInfo oldDocInfo = mPrintJob.getDocumentInfo();
            PrintDocumentInfo newDocInfo = new PrintDocumentInfo
                    .Builder(oldDocInfo.getName())
                    .setContentType(oldDocInfo.getContentType())
                    .setPageCount(newPageCount)
                    .build();

            File file = mFileProvider.acquireFile(null);
            try {
                newDocInfo.setDataSize(file.length());
            } finally {
                mFileProvider.releaseFile();
            }

            mPrintJob.setDocumentInfo(newDocInfo);
        }

        private static PageRange[] computePagesToShred(PrintJobInfo printJob) {
            List<PageRange> rangesToShred = new ArrayList<>();
            PageRange previousRange = null;

            PageRange[] printedPages = printJob.getPages();
            final int rangeCount = printedPages.length;
            for (int i = 0; i < rangeCount; i++) {
                PageRange range = printedPages[i];

                if (previousRange == null) {
                    final int startPageIdx = 0;
                    final int endPageIdx = range.getStart() - 1;
                    if (startPageIdx <= endPageIdx) {
                        PageRange removedRange = new PageRange(startPageIdx, endPageIdx);
                        rangesToShred.add(removedRange);
                    }
                } else {
                    final int startPageIdx = previousRange.getEnd() + 1;
                    final int endPageIdx = range.getStart() - 1;
                    if (startPageIdx <= endPageIdx) {
                        PageRange removedRange = new PageRange(startPageIdx, endPageIdx);
                        rangesToShred.add(removedRange);
                    }
                }

                if (i == rangeCount - 1) {
                    if (range.getEnd() != Integer.MAX_VALUE) {
                        rangesToShred.add(new PageRange(range.getEnd() + 1, Integer.MAX_VALUE));
                    }
                }

                previousRange = range;
            }

            PageRange[] result = new PageRange[rangesToShred.size()];
            rangesToShred.toArray(result);
            return result;
        }
    }
}
