Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b4fda134 authored by Svetoslav's avatar Svetoslav
Browse files

Complete implementation of the advanced print options.

1. Implemented the advanced printer options integration. Now a print service
    may declare an advanced print options activity which may be launched by
    the user if the current printer supports advanced print options. These options
    are visible only to the print service that added them and it is the only party
    that will interpret the options.

2. Fixed a couple of bugs in the saved print jobs parsing. One was that if there
    are more than one page range, a half of the print job properties was not
    properly parsed. The other was that the media size constructor was using
    incorrect argument order, thus creating a media size with wring width.

3. Fixed and edge case where old print jobs and their docs can get stuck in
    the spooler. If the app did not write the requested pages we were not showing
    an error message, rather just finish the activity without canceling the print
    job and this print job is stuck in the spooler. Now we show an error message
    and the user may retry, cancel. If the user cancels the print job is also
    cancelled, thus no leftover in the spooler.

4. Fixed the background color of the print dialog to meet UX spec.

bug:11241800

Change-Id: I352440bc86aec824a805883fc9579d96a06d11e6
parent 2ead7510
Loading
Loading
Loading
Loading
+88 −28
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package android.print;
package android.print;


import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable;


@@ -160,6 +161,9 @@ public final class PrintJobInfo implements Parcelable {
    /** Information about the printed document. */
    /** Information about the printed document. */
    private PrintDocumentInfo mDocumentInfo;
    private PrintDocumentInfo mDocumentInfo;


    /** Advanced printer specific options. */
    private Bundle mAdvancedOptions;

    /** Whether we are trying to cancel this print job. */
    /** Whether we are trying to cancel this print job. */
    private boolean mCanceling;
    private boolean mCanceling;


@@ -184,6 +188,7 @@ public final class PrintJobInfo implements Parcelable {
        mAttributes = other.mAttributes;
        mAttributes = other.mAttributes;
        mDocumentInfo = other.mDocumentInfo;
        mDocumentInfo = other.mDocumentInfo;
        mCanceling = other.mCanceling;
        mCanceling = other.mCanceling;
        mAdvancedOptions = other.mAdvancedOptions;
    }
    }


    private PrintJobInfo(Parcel parcel) {
    private PrintJobInfo(Parcel parcel) {
@@ -197,20 +202,17 @@ public final class PrintJobInfo implements Parcelable {
        mCreationTime = parcel.readLong();
        mCreationTime = parcel.readLong();
        mCopies = parcel.readInt();
        mCopies = parcel.readInt();
        mStateReason = parcel.readString();
        mStateReason = parcel.readString();
        if (parcel.readInt() == 1) {
        Parcelable[] parcelables = parcel.readParcelableArray(null);
        Parcelable[] parcelables = parcel.readParcelableArray(null);
        if (parcelables != null) {
            mPageRanges = new PageRange[parcelables.length];
            mPageRanges = new PageRange[parcelables.length];
            for (int i = 0; i < parcelables.length; i++) {
            for (int i = 0; i < parcelables.length; i++) {
                mPageRanges[i] = (PageRange) parcelables[i];
                mPageRanges[i] = (PageRange) parcelables[i];
            }
            }
        }
        }
        if (parcel.readInt() == 1) {
        mAttributes = (PrintAttributes) parcel.readParcelable(null);
            mAttributes = PrintAttributes.CREATOR.createFromParcel(parcel);
        mDocumentInfo = (PrintDocumentInfo) parcel.readParcelable(null);
        }
        if (parcel.readInt() == 1) {
            mDocumentInfo = PrintDocumentInfo.CREATOR.createFromParcel(parcel);
        }
        mCanceling = (parcel.readInt() == 1);
        mCanceling = (parcel.readInt() == 1);
        mAdvancedOptions = parcel.readBundle();
    }
    }


    /**
    /**
@@ -521,6 +523,71 @@ public final class PrintJobInfo implements Parcelable {
        mCanceling = cancelling;
        mCanceling = cancelling;
    }
    }


    /**
     * Gets whether this job has a given advanced (printer specific) print
     * option.
     *
     * @param key The option key.
     * @return Whether the option is present.
     *
     * @hide
     */
    public boolean hasAdvancedOption(String key) {
        return mAdvancedOptions != null && mAdvancedOptions.containsKey(key);
    }

    /**
     * Gets the value of an advanced (printer specific) print option.
     *
     * @param key The option key.
     * @return The option value.
     *
     * @hide
     */
    public String getAdvancedStringOption(String key) {
        if (mAdvancedOptions != null) {
            return mAdvancedOptions.getString(key);
        }
        return null;
    }

    /**
     * Gets the value of an advanced (printer specific) print option.
     *
     * @param key The option key.
     * @return The option value.
     *
     * @hide
     */
    public int getAdvancedIntOption(String key) {
        if (mAdvancedOptions != null) {
            return mAdvancedOptions.getInt(key);
        }
        return 0;
    }

    /**
     * Gets the advanced options.
     *
     * @return The advanced options.
     *
     * @hide
     */
    public Bundle getAdvancedOptions() {
        return mAdvancedOptions;
    }

    /**
     * Sets the advanced options.
     *
     * @param options The advanced options.
     *
     * @hide
     */
    public void setAdvancedOptions(Bundle options) {
        mAdvancedOptions = options;
    }

    @Override
    @Override
    public int describeContents() {
    public int describeContents() {
        return 0;
        return 0;
@@ -538,25 +605,11 @@ public final class PrintJobInfo implements Parcelable {
        parcel.writeLong(mCreationTime);
        parcel.writeLong(mCreationTime);
        parcel.writeInt(mCopies);
        parcel.writeInt(mCopies);
        parcel.writeString(mStateReason);
        parcel.writeString(mStateReason);
        if (mPageRanges != null) {
            parcel.writeInt(1);
        parcel.writeParcelableArray(mPageRanges, flags);
        parcel.writeParcelableArray(mPageRanges, flags);
        } else {
        parcel.writeParcelable(mAttributes, flags);
            parcel.writeInt(0);
        parcel.writeParcelable(mDocumentInfo, 0);
        }
        if (mAttributes != null) {
            parcel.writeInt(1);
            mAttributes.writeToParcel(parcel, flags);
        } else {
            parcel.writeInt(0);
        }
        if (mDocumentInfo != null) {
            parcel.writeInt(1);
            mDocumentInfo.writeToParcel(parcel, flags);
        } else {
            parcel.writeInt(0);
        }
        parcel.writeInt(mCanceling ? 1 : 0);
        parcel.writeInt(mCanceling ? 1 : 0);
        parcel.writeBundle(mAdvancedOptions);
    }
    }


    @Override
    @Override
@@ -577,6 +630,7 @@ public final class PrintJobInfo implements Parcelable {
        builder.append(", cancelling: " + mCanceling);
        builder.append(", cancelling: " + mCanceling);
        builder.append(", pages: " + (mPageRanges != null
        builder.append(", pages: " + (mPageRanges != null
                ? Arrays.toString(mPageRanges) : null));
                ? Arrays.toString(mPageRanges) : null));
        builder.append(", hasAdvancedOptions: " + (mAdvancedOptions != null));
        builder.append("}");
        builder.append("}");
        return builder.toString();
        return builder.toString();
    }
    }
@@ -663,7 +717,10 @@ public final class PrintJobInfo implements Parcelable {
         * @param value The option value.
         * @param value The option value.
         */
         */
        public void putAdvancedOption(String key, String value) {
        public void putAdvancedOption(String key, String value) {

            if (mPrototype.mAdvancedOptions == null) {
                mPrototype.mAdvancedOptions = new Bundle();
            }
            mPrototype.mAdvancedOptions.putString(key, value);
        }
        }


        /**
        /**
@@ -673,7 +730,10 @@ public final class PrintJobInfo implements Parcelable {
         * @param value The option value.
         * @param value The option value.
         */
         */
        public void putAdvancedOption(String key, int value) {
        public void putAdvancedOption(String key, int value) {

            if (mPrototype.mAdvancedOptions == null) {
                mPrototype.mAdvancedOptions = new Bundle();
            }
            mPrototype.mAdvancedOptions.putInt(key, value);
        }
        }


        /**
        /**
+3 −3
Original line number Original line Diff line number Diff line
@@ -321,7 +321,7 @@ public final class PrintJob {
     */
     */
    public String getAdvancedStringOption(String key) {
    public String getAdvancedStringOption(String key) {
        PrintService.throwIfNotCalledOnMainThread();
        PrintService.throwIfNotCalledOnMainThread();
        return null;
        return getInfo().getAdvancedStringOption(key);
    }
    }


    /**
    /**
@@ -333,7 +333,7 @@ public final class PrintJob {
     */
     */
    public boolean hasAdvancedOption(String key) {
    public boolean hasAdvancedOption(String key) {
        PrintService.throwIfNotCalledOnMainThread();
        PrintService.throwIfNotCalledOnMainThread();
        return false;
        return getInfo().hasAdvancedOption(key);
    }
    }


    /**
    /**
@@ -344,7 +344,7 @@ public final class PrintJob {
     */
     */
    public int getAdvancedIntOption(String key) {
    public int getAdvancedIntOption(String key) {
        PrintService.throwIfNotCalledOnMainThread();
        PrintService.throwIfNotCalledOnMainThread();
        return 0;
        return getInfo().getAdvancedIntOption(key);
    }
    }


    @Override
    @Override
+8 −0
Original line number Original line Diff line number Diff line
@@ -209,6 +209,14 @@ public abstract class PrintService extends Service {
     * PrintJob#getAdvancedStringOption(String) PrintJob.getAdvancedStringOption(String)}
     * PrintJob#getAdvancedStringOption(String) PrintJob.getAdvancedStringOption(String)}
     * and {@link PrintJob#getAdvancedIntOption(String) PrintJob.getAdvancedIntOption(String)}.
     * and {@link PrintJob#getAdvancedIntOption(String) PrintJob.getAdvancedIntOption(String)}.
     * </p>
     * </p>
     * <p>
     * If the advanced print options activity offers changes to the standard print
     * options, you can get the current {@link android.print.PrinterInfo} using the
     * "android.intent.extra.print.EXTRA_PRINTER_INFO" extra which will allow you to
     * present the user with UI options supported by the current printer. For example,
     * if the current printer does not support a give media size, you should not
     * offer it in the advanced print options dialog.
     * </p>
     */
     */
    public static final String EXTRA_PRINT_JOB_INFO = "android.intent.extra.print.PRINT_JOB_INFO";
    public static final String EXTRA_PRINT_JOB_INFO = "android.intent.extra.print.PRINT_JOB_INFO";


+28 −2
Original line number Original line Diff line number Diff line
@@ -60,6 +60,8 @@ public final class PrintServiceInfo implements Parcelable {


    private final String mAddPrintersActivityName;
    private final String mAddPrintersActivityName;


    private final String mAdvancedPrintOptionsActivityName;

    /**
    /**
     * Creates a new instance.
     * Creates a new instance.
     *
     *
@@ -70,6 +72,7 @@ public final class PrintServiceInfo implements Parcelable {
        mResolveInfo = parcel.readParcelable(null);
        mResolveInfo = parcel.readParcelable(null);
        mSettingsActivityName = parcel.readString();
        mSettingsActivityName = parcel.readString();
        mAddPrintersActivityName = parcel.readString();
        mAddPrintersActivityName = parcel.readString();
        mAdvancedPrintOptionsActivityName = parcel.readString();
    }
    }


    /**
    /**
@@ -78,14 +81,16 @@ public final class PrintServiceInfo implements Parcelable {
     * @param resolveInfo The service resolve info.
     * @param resolveInfo The service resolve info.
     * @param settingsActivityName Optional settings activity name.
     * @param settingsActivityName Optional settings activity name.
     * @param addPrintersActivityName Optional add printers activity name.
     * @param addPrintersActivityName Optional add printers activity name.
     * @param advancedPrintOptionsActivityName Optional advanced print options activity.
     */
     */
    public PrintServiceInfo(ResolveInfo resolveInfo, String settingsActivityName,
    public PrintServiceInfo(ResolveInfo resolveInfo, String settingsActivityName,
            String addPrintersActivityName) {
            String addPrintersActivityName, String advancedPrintOptionsActivityName) {
        mId = new ComponentName(resolveInfo.serviceInfo.packageName,
        mId = new ComponentName(resolveInfo.serviceInfo.packageName,
                resolveInfo.serviceInfo.name).flattenToString();
                resolveInfo.serviceInfo.name).flattenToString();
        mResolveInfo = resolveInfo;
        mResolveInfo = resolveInfo;
        mSettingsActivityName = settingsActivityName;
        mSettingsActivityName = settingsActivityName;
        mAddPrintersActivityName = addPrintersActivityName;
        mAddPrintersActivityName = addPrintersActivityName;
        mAdvancedPrintOptionsActivityName = advancedPrintOptionsActivityName;
    }
    }


    /**
    /**
@@ -99,6 +104,7 @@ public final class PrintServiceInfo implements Parcelable {
    public static PrintServiceInfo create(ResolveInfo resolveInfo, Context context) {
    public static PrintServiceInfo create(ResolveInfo resolveInfo, Context context) {
        String settingsActivityName = null;
        String settingsActivityName = null;
        String addPrintersActivityName = null;
        String addPrintersActivityName = null;
        String advancedPrintOptionsActivityName = null;


        XmlResourceParser parser = null;
        XmlResourceParser parser = null;
        PackageManager packageManager = context.getPackageManager();
        PackageManager packageManager = context.getPackageManager();
@@ -128,6 +134,9 @@ public final class PrintServiceInfo implements Parcelable {
                    addPrintersActivityName = attributes.getString(
                    addPrintersActivityName = attributes.getString(
                            com.android.internal.R.styleable.PrintService_addPrintersActivity);
                            com.android.internal.R.styleable.PrintService_addPrintersActivity);


                    advancedPrintOptionsActivityName = attributes.getString(com.android.internal
                            .R.styleable.PrintService_advancedPrintOptionsActivity);

                    attributes.recycle();
                    attributes.recycle();
                }
                }
            } catch (IOException ioe) {
            } catch (IOException ioe) {
@@ -144,7 +153,8 @@ public final class PrintServiceInfo implements Parcelable {
            }
            }
        }
        }


        return new PrintServiceInfo(resolveInfo, settingsActivityName, addPrintersActivityName);
        return new PrintServiceInfo(resolveInfo, settingsActivityName,
                addPrintersActivityName, advancedPrintOptionsActivityName);
    }
    }


    /**
    /**
@@ -194,6 +204,19 @@ public final class PrintServiceInfo implements Parcelable {
        return mAddPrintersActivityName;
        return mAddPrintersActivityName;
    }
    }


    /**
     * The advanced print options activity name.
     * <p>
     * <strong>Statically set from
     * {@link PrintService#SERVICE_META_DATA meta-data}.</strong>
     * </p>
     *
     * @return The advanced print options activity name.
     */
    public String getAdvancedOptionsActivityName() {
        return mAdvancedPrintOptionsActivityName;
    }

    /**
    /**
     * {@inheritDoc}
     * {@inheritDoc}
     */
     */
@@ -206,6 +229,7 @@ public final class PrintServiceInfo implements Parcelable {
        parcel.writeParcelable(mResolveInfo, 0);
        parcel.writeParcelable(mResolveInfo, 0);
        parcel.writeString(mSettingsActivityName);
        parcel.writeString(mSettingsActivityName);
        parcel.writeString(mAddPrintersActivityName);
        parcel.writeString(mAddPrintersActivityName);
        parcel.writeString(mAdvancedPrintOptionsActivityName);
    }
    }


    @Override
    @Override
@@ -243,6 +267,8 @@ public final class PrintServiceInfo implements Parcelable {
        builder.append(", resolveInfo=").append(mResolveInfo);
        builder.append(", resolveInfo=").append(mResolveInfo);
        builder.append(", settingsActivityName=").append(mSettingsActivityName);
        builder.append(", settingsActivityName=").append(mSettingsActivityName);
        builder.append(", addPrintersActivityName=").append(mAddPrintersActivityName);
        builder.append(", addPrintersActivityName=").append(mAddPrintersActivityName);
        builder.append(", advancedPrintOptionsActivityName=")
                .append(mAdvancedPrintOptionsActivityName);
        builder.append("}");
        builder.append("}");
        return builder.toString();
        return builder.toString();
    }
    }
+5 −1
Original line number Original line Diff line number Diff line
@@ -2622,7 +2622,11 @@
             add printers to this print service. -->
             add printers to this print service. -->
        <attr name="addPrintersActivity" format="string"/>
        <attr name="addPrintersActivity" format="string"/>
        <!-- Fully qualified class name of an activity with advanced print options
        <!-- Fully qualified class name of an activity with advanced print options
             specific to this print service. -->
             specific to this print service. If this activity is specified the system
             will allow the user a choice to open it given the currently selected printer
             has advanced options which is specified by the print service via
             {@link android.print.PrinterInfo.Builder#setHasAdvancedOptions(boolean)}.
             -->
        <attr name="advancedPrintOptionsActivity" format="string"/>
        <attr name="advancedPrintOptionsActivity" format="string"/>
        <!-- The vendor name if this print service is vendor specific. -->
        <!-- The vendor name if this print service is vendor specific. -->
        <attr name="vendor" format="string"/>
        <attr name="vendor" format="string"/>
Loading